LoginSignup
0
0

More than 3 years have passed since last update.

pt-query-digestの2020年問題にハマった話

Posted at

背景

弊社ではDBのチューニング用にprconaのpt-query-digestを使っている
※スローログの集計に便利な「pt-query-digest」を使ってみよう

突然動かなくなった

何もしてないのに壊れた

Pipeline process 4 (MySQLProtocolParser) caused an error: Argument "" isn't numeric in multiplication (*) at /usr/bin/pt-query-digest line 4525, <STDIN> line 293.
Will retry pipeline process 3 (MySQLProtocolParser) 1 more time.
The pipeline caused an error: Pipeline process 4 (MySQLProtocolParser) caused an error: Argument "" isn't numeric in multiplication (*) at /usr/bin/pt-query-digest line 4525, <STDIN> line 305.
Terminating pipeline because process 3 (MySQLProtocolParser) caused too many errors.

該当箇所を読んでみる

 4519 sub timestamp_diff {
 4520    my ( $start, $end ) = @_;
 4521    my $sd = substr($start, 0, 11, '');
 4522    my $ed = substr($end,   0, 11, '');
 4523    my ( $sh, $sm, $ss ) = split(/:/, $start);
 4524    my ( $eh, $em, $es ) = split(/:/, $end);
 4525    my $esecs = ($eh * 3600 + $em * 60 + $es);
 4526    my $ssecs = ($sh * 3600 + $sm * 60 + $ss);
 4527    if ( $sd eq $ed ) {
 4528       return sprintf '%.6f', $esecs - $ssecs;
 4529    }
 4530    else { # Assume only one day boundary has been crossed, no DST, etc
 4531       return sprintf '%.6f', ( 86_400 - $ssecs ) + $esecs;
 4532    }
 4533 }

何か時間関係でエラーになってるようだ・・・
2019年末には動いていたので、誰かがいじっていなければ2020年になった事が要因と考えられる

フォーラムにあった

全く同じ。2019年のdumpなら動くが2020年になると日付計算でエラーになる模様

修正をアテる

/usr/bin/pt-query.digest

 3627 sub parse_event {
 3628    my ( $self, %args ) = @_;
 3629    my @required_args = qw(next_event tell);
 3630    foreach my $arg ( @required_args ) {
 3631       die "I need a $arg argument" unless $args{$arg};
 3632    }
 3633    my ($next_event, $tell) = @args{@required_args};
 3634
 3635    local $INPUT_RECORD_SEPARATOR = "\n20";
 3636
 3637    my $pos_in_log = $tell->();
 3638    while ( defined(my $raw_packet = $next_event->()) ) {
 3639       next if $raw_packet =~ m/^$/;  # issue 564
 3640       $pos_in_log -= 1 if $pos_in_log;
 3641
 3642       $raw_packet =~ s/\n20\Z//;
 3643       $raw_packet = "20$raw_packet" if $raw_packet =~ /\A20-\d\d-\d\d/; # workaround for year 2020 problem
 3644       $raw_packet = "20$raw_packet" unless $raw_packet =~ m/\A20/;
 3645
 3646       $raw_packet =~ s/0x0000:.+?(450.) /0x0000:  $1 /;
 3647
 3648       my $packet = $self->_parse_packet($raw_packet);
 3649       $packet->{pos_in_log} = $pos_in_log;
 3650       $packet->{raw_packet} = $raw_packet;
 3651
 3652       $args{stats}->{events_read}++ if $args{stats};
 3653
 3654       return $packet;
 3655    }
 3656
 3657    $args{oktorun}->(0) if $args{oktorun};
 3658    return;
 3659 }

これで無事に動いた。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0