ハマったのでメモ。
サンドボックスな環境でMySQLのポートを64055にしていたら、pt-query-digest --type tcpdumpでそのまま食ってくれなかった。
結論、--portとかじゃなく、--watch-serverで指定するんだった。
あっれぇ。。
取り敢えずまずはPTDEBUG=1にして様子を見てみる。
どばー。
取り敢えず、MySQLProtocolParserの中で"Packet is not to or from a MySQL server"って言われてる。3916行目あたりにダイブ。
3894 my $src_host = "$packet->{src_host}:$packet->{src_port}";
3895 my $dst_host = "$packet->{dst_host}:$packet->{dst_port}";
..
3905 my $packet_from;
3906 my $client;
3907 if ( $src_host =~ m/:$self->{port}$/ ) {
3908 $packet_from = 'server';
3909 $client = $dst_host;
3910 }
3911 elsif ( $dst_host =~ m/:$self->{port}$/ ) {
3912 $packet_from = 'client';
3913 $client = $src_host;
3914 }
3915 else {
3916 PTDEBUG && _d('Packet is not to or from a MySQL server');
3917 return $self->{null_event};
3918 }
パケットの127.0.0.1:64055が$self->{port}を含んでいないのがいけないらしい。$self->{port}は何になってるかというと
3306。オプションで--port 64055とかDSN形式でP=64055とか渡してやってもずっと3306。むぅ。デフォルトで3306になるのはMySQLProtocolParser::newでそうなってるからで、
3870 sub new {
3871 my ( $class, %args ) = @_;
3872
3873 my $self = {
3874 server => $args{server},
3875 port => $args{port} || '3306',
3876 version => '41', # MySQL proto version; not used yet
3877 sessions => {},
3878 o => $args{o},
3879 fake_thread_id => 2**32, # see _make_event()
3880 null_event => $args{null_event},
3881 };
3882 PTDEBUG && $self->{server} && _d('Watching only server', $self->{server});
3883 return bless $self, $class;
3884 }
これがどこから呼ばれてるかというとmainの中のここだった。
13393 my ($server, $port);
13394 if ( my $watch_server = $o->get('watch-server') ) {
13395 # This should match all combinations of HOST and PORT except
13396 # "host-name.port" because "host.mysql" could be either
13397 # host "host" and port "mysql" or just host "host.mysql"
13398 # (e.g. if someone added "127.1 host.mysql" to etc/hosts).
13399 # So host-name* requires a colon between it and a port.
13400 ($server, $port) = $watch_server
13401 =~ m/^((?:\d+\.\d+\.\d+\.\d+|[\w\.\-]+\w))(?:[\:\.](\S+))?/;
13402 PTDEBUG && _d('Watch server', $server, 'port', $port);
13403 }
13404
13405 foreach my $module ( @$type ) {
13406 my $parser;
13407 eval {
13408 $parser = $module->new(
13409 server => $server,
13410 port => $port,
13411 o => $o,
13412 );
13413 };
--portとかじゃなくて、--watch-serverから取ってたのか。。
無事食えた。確かにマニュアルにもフツーに書いてあった。。
http://www.percona.com/doc/percona-toolkit/2.2/pt-query-digest.html#cmdoption-pt-query-digest--watch-server
サンドボックスな環境でMySQLのポートを64055にしていたら、pt-query-digest --type tcpdumpでそのまま食ってくれなかった。
結論、--portとかじゃなく、--watch-serverで指定するんだった。
$ sudo tcpdump -i any -p /tmp/test.cap -c 100
$ tcpdump -r /tmp/test.cap -n -x -q -tttt | pt-query-digest --type tcpdump
reading from file /tmp/test.cap, link-type LINUX_SLL (Linux cooked)
# No events processed.
あっれぇ。。
取り敢えずまずはPTDEBUG=1にして様子を見てみる。
$ tcpdump -r /tmp/test.cap -n -x -q -tttt | PTDEBUG=1 pt-query-digest --type tcpdump
reading from file /tmp/test.cap, link-type LINUX_SLL (Linux cooked)
# /usr/bin/perl 5.010001
# Linux dev-personal-04 2.6.32-279.19.1.el6.x86_64 #1 SMP Wed Dec 19 07:05:20 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
# Arguments: _[--type]_ _[tcpdump]_
# OptionParser:1522 29673 Option rule: This tool accepts additional command-line arguments. Refer to the SYNOPSIS and usage information for details.
..
# Pipeline:11539 29673 Pipeline restarting early after MySQLProtocolParser
# Pipeline:11527 29673 Pipeline process prep
# Pipeline:11527 29673 Pipeline process input
# Pipeline:11527 29673 Pipeline process TcpdumpParser
# TcpdumpParser:3658 29673 packet: $VAR1 = {
# ack => 3530724024,
# complete => 1,
# data => '',
# data_len => 0,
# dgram_len => 40,
# dst_host => '127.0.0.1',
# dst_port => '42872',
# fin => 1,
# ip_hlen => 5,
# rst => 0,
# seq => 2831704995,
# src_host => '127.0.0.1',
# src_port => '64055',
# syn => 0,
# tcp_hlen => 5,
# ts => '2014-12-01 16:40:11.599600'
# };
#
# Pipeline:11527 29673 Pipeline process MySQLProtocolParser
# MySQLProtocolParser:3916 29673 Packet is not to or from a MySQL server
# pt_query_digest:13442 29673 No more events, input EOF
..
どばー。
取り敢えず、MySQLProtocolParserの中で"Packet is not to or from a MySQL server"って言われてる。3916行目あたりにダイブ。
3894 my $src_host = "$packet->{src_host}:$packet->{src_port}";
3895 my $dst_host = "$packet->{dst_host}:$packet->{dst_port}";
..
3905 my $packet_from;
3906 my $client;
3907 if ( $src_host =~ m/:$self->{port}$/ ) {
3908 $packet_from = 'server';
3909 $client = $dst_host;
3910 }
3911 elsif ( $dst_host =~ m/:$self->{port}$/ ) {
3912 $packet_from = 'client';
3913 $client = $src_host;
3914 }
3915 else {
3916 PTDEBUG && _d('Packet is not to or from a MySQL server');
3917 return $self->{null_event};
3918 }
パケットの127.0.0.1:64055が$self->{port}を含んでいないのがいけないらしい。$self->{port}は何になってるかというと
$ tcpdump -r /tmp/test.cap -n -x -q -tttt | perl -d /usr/bin/pt-query-digest --type tcpdump
reading from file /tmp/test.cap, link-type LINUX_SLL (Linux cooked)
Loading DB routines from perl5db.pl version 1.32
Editor support available.
Enter h or `h h' for help, or `man perldebug' for more help.
main::(/usr/bin/pt-query-digest:65):
65: package Percona::Toolkit;
DB<1> c 3916
MySQLProtocolParser::parse_event(/usr/bin/pt-query-digest:3916):
3916: PTDEBUG && _d('Packet is not to or from a MySQL server');
DB<2> p Dumper $self
$VAR1 = bless( {
fake_thread_id => '4294967296',
null_event => undef,
..
}, 'OptionParser' ),
port => '3306',
server => undef,
sessions => {},
version => '41'
}, 'MySQLProtocolParser' );
3306。オプションで--port 64055とかDSN形式でP=64055とか渡してやってもずっと3306。むぅ。デフォルトで3306になるのはMySQLProtocolParser::newでそうなってるからで、
3870 sub new {
3871 my ( $class, %args ) = @_;
3872
3873 my $self = {
3874 server => $args{server},
3875 port => $args{port} || '3306',
3876 version => '41', # MySQL proto version; not used yet
3877 sessions => {},
3878 o => $args{o},
3879 fake_thread_id => 2**32, # see _make_event()
3880 null_event => $args{null_event},
3881 };
3882 PTDEBUG && $self->{server} && _d('Watching only server', $self->{server});
3883 return bless $self, $class;
3884 }
これがどこから呼ばれてるかというとmainの中のここだった。
13393 my ($server, $port);
13394 if ( my $watch_server = $o->get('watch-server') ) {
13395 # This should match all combinations of HOST and PORT except
13396 # "host-name.port" because "host.mysql" could be either
13397 # host "host" and port "mysql" or just host "host.mysql"
13398 # (e.g. if someone added "127.1 host.mysql" to etc/hosts).
13399 # So host-name* requires a colon between it and a port.
13400 ($server, $port) = $watch_server
13401 =~ m/^((?:\d+\.\d+\.\d+\.\d+|[\w\.\-]+\w))(?:[\:\.](\S+))?/;
13402 PTDEBUG && _d('Watch server', $server, 'port', $port);
13403 }
13404
13405 foreach my $module ( @$type ) {
13406 my $parser;
13407 eval {
13408 $parser = $module->new(
13409 server => $server,
13410 port => $port,
13411 o => $o,
13412 );
13413 };
--portとかじゃなくて、--watch-serverから取ってたのか。。
$ tcpdump -r /tmp/test.cap -n -x -q -tttt | /usr/bin/pt-query-digest --watch-server 127.0.0.1.64055 --type tcpdump
reading from file /tmp/test.cap, link-type LINUX_SLL (Linux cooked)
# 410ms user time, 30ms system time, 25.84M rss, 212.79M vsz
# Current date: Mon Dec 1 17:44:12 2014
# Hostname: xxxx
# Files: STDIN
# Overall: 8 total, 6 unique, 0.35 QPS, 0.02x concurrency ________________
# Time range: 2014-12-01 16:39:48.680810 to 16:40:11.597656
# Attribute total min max avg 95% stddev median
# ============ ======= ======= ======= ======= ======= ======= =======
# Exec time 399ms 0 150ms 50ms 148ms 48ms 65ms
# Rows affecte 3 0 1 0.38 0.99 0.48 0
# Query size 220 16 36 27.50 34.95 6.66 30.22
# Warning coun 0 0 0 0 0 0 0
..
無事食えた。確かにマニュアルにもフツーに書いてあった。。
http://www.percona.com/doc/percona-toolkit/2.2/pt-query-digest.html#cmdoption-pt-query-digest--watch-server