mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-01 18:25:59 +00:00
1859 lines
55 KiB
Perl
1859 lines
55 KiB
Perl
#!/usr/bin/perl
|
|
|
|
BEGIN {
|
|
die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n"
|
|
unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH};
|
|
unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib";
|
|
};
|
|
|
|
use strict;
|
|
use warnings FATAL => 'all';
|
|
use English qw(-no_match_vars);
|
|
use Test::More;
|
|
|
|
use ProtocolParser;
|
|
use MySQLProtocolParser;
|
|
use TcpdumpParser;
|
|
use PerconaTest;
|
|
|
|
my $sample = "t/lib/samples/tcpdump";
|
|
my $tcpdump = new TcpdumpParser();
|
|
my $protocol; # Create a new MySQLProtocolParser for each test.
|
|
|
|
# Check that I can parse a really simple session.
|
|
$protocol = new MySQLProtocolParser();
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump001.txt",
|
|
result => [
|
|
{ ts => '090412 09:50:16.805123',
|
|
db => undef,
|
|
user => undef,
|
|
Thread_id => 4294967296,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '42167',
|
|
arg => 'select "hello world" as greeting',
|
|
Query_time => sprintf('%.6f', .805123 - .804849),
|
|
pos_in_log => 0,
|
|
bytes => length('select "hello world" as greeting'),
|
|
cmd => 'Query',
|
|
Rows_affected => 0,
|
|
Warning_count => 0,
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
},
|
|
],
|
|
);
|
|
|
|
$protocol = new MySQLProtocolParser(port=>3307);
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump-1402776.txt",
|
|
result => [
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.001271',
|
|
Rows_affected => 0,
|
|
Thread_id => 3826,
|
|
Warning_count => 0,
|
|
arg => 'administrator command: Connect',
|
|
bytes => 30,
|
|
cmd => 'Admin',
|
|
db => '',
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '38784',
|
|
pos_in_log => 2011,
|
|
ts => '161215 17:07:52.041966',
|
|
user => 'root'
|
|
}
|
|
],
|
|
);
|
|
|
|
# A more complex session with a complete login/logout cycle.
|
|
$protocol = new MySQLProtocolParser();
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump002.txt",
|
|
result => [
|
|
{ ts => "090412 11:00:13.118191",
|
|
db => 'mysql',
|
|
user => 'msandbox',
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '57890',
|
|
arg => 'administrator command: Connect',
|
|
Query_time => '0.011152',
|
|
Thread_id => 8,
|
|
pos_in_log => 1470,
|
|
bytes => length('administrator command: Connect'),
|
|
cmd => 'Admin',
|
|
Rows_affected => 0,
|
|
Warning_count => 0,
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
},
|
|
{ Query_time => '0.000265',
|
|
Thread_id => 8,
|
|
arg => 'select @@version_comment limit 1',
|
|
bytes => length('select @@version_comment limit 1'),
|
|
cmd => 'Query',
|
|
db => 'mysql',
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '57890',
|
|
pos_in_log => 2449,
|
|
ts => '090412 11:00:13.118643',
|
|
user => 'msandbox',
|
|
Rows_affected => 0,
|
|
Warning_count => 0,
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
},
|
|
{ Query_time => '0.000167',
|
|
Thread_id => 8,
|
|
arg => 'select "paris in the the spring" as trick',
|
|
bytes => length('select "paris in the the spring" as trick'),
|
|
cmd => 'Query',
|
|
db => 'mysql',
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '57890',
|
|
pos_in_log => 3298,
|
|
ts => '090412 11:00:13.119079',
|
|
user => 'msandbox',
|
|
Rows_affected => 0,
|
|
Warning_count => 0,
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
},
|
|
{ Query_time => '0.000000',
|
|
Thread_id => 8,
|
|
arg => 'administrator command: Quit',
|
|
bytes => 27,
|
|
cmd => 'Admin',
|
|
db => 'mysql',
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '57890',
|
|
pos_in_log => '4186',
|
|
ts => '090412 11:00:13.119487',
|
|
user => 'msandbox',
|
|
Rows_affected => 0,
|
|
Warning_count => 0,
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
},
|
|
],
|
|
);
|
|
|
|
# A session that has an error during login.
|
|
$protocol = new MySQLProtocolParser();
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump003.txt",
|
|
result => [
|
|
{ ts => "090412 12:41:46.357853",
|
|
db => '',
|
|
user => 'msandbox',
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '44488',
|
|
arg => 'administrator command: Connect',
|
|
Query_time => '0.010753',
|
|
Thread_id => 9,
|
|
pos_in_log => 1455,
|
|
bytes => length('administrator command: Connect'),
|
|
cmd => 'Admin',
|
|
Error_no => 1045,
|
|
Error_msg => 'Access denied for user \'msandbox\'@\'localhost\' (using password: YES)',
|
|
Rows_affected => 0,
|
|
Warning_count => 0,
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
},
|
|
],
|
|
);
|
|
|
|
# A session that has an error executing a query
|
|
$protocol = new MySQLProtocolParser();
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump004.txt",
|
|
result => [
|
|
{ ts => "090412 12:58:02.036002",
|
|
db => undef,
|
|
user => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '60439',
|
|
arg => 'select 5 from foo',
|
|
Query_time => '0.000251',
|
|
Thread_id => 4294967296,
|
|
pos_in_log => 0,
|
|
bytes => length('select 5 from foo'),
|
|
cmd => 'Query',
|
|
Error_no => "1046",
|
|
Error_msg => 'No database selected',
|
|
Rows_affected => 0,
|
|
Warning_count => 0,
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
},
|
|
],
|
|
);
|
|
|
|
# A session that has a single-row insert and a multi-row insert
|
|
$protocol = new MySQLProtocolParser();
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump005.txt",
|
|
result => [
|
|
{
|
|
Rows_affected => 1,
|
|
Query_time => '0.000435',
|
|
Thread_id => 4294967296,
|
|
arg => 'insert into test.t values(1)',
|
|
bytes => 28,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '55300',
|
|
pos_in_log => '0',
|
|
ts => '090412 16:46:02.978340',
|
|
user => undef,
|
|
Warning_count => 0,
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
},
|
|
{
|
|
Rows_affected => 2,
|
|
Query_time => '0.000565',
|
|
Thread_id => 4294967296,
|
|
arg => 'insert into test.t values(1),(2)',
|
|
bytes => 32,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '55300',
|
|
pos_in_log => '1033',
|
|
ts => '090412 16:46:20.245088',
|
|
user => undef,
|
|
Warning_count => 0,
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
},
|
|
],
|
|
);
|
|
|
|
# A session that causes a slow query because it doesn't use an index.
|
|
$protocol = new MySQLProtocolParser();
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump006.txt",
|
|
result => [
|
|
{ ts => '100412 20:46:10.776899',
|
|
db => undef,
|
|
user => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '48259',
|
|
arg => 'select * from t',
|
|
Query_time => '0.000205',
|
|
Thread_id => 4294967296,
|
|
pos_in_log => 0,
|
|
bytes => length('select * from t'),
|
|
cmd => 'Query',
|
|
Rows_affected => 0,
|
|
Warning_count => 0,
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'Yes',
|
|
},
|
|
],
|
|
);
|
|
|
|
# A session that truncates an insert.
|
|
$protocol = new MySQLProtocolParser();
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump007.txt",
|
|
result => [
|
|
{ ts => '090412 20:57:22.798296',
|
|
db => undef,
|
|
user => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '38381',
|
|
arg => 'insert into t values(current_date)',
|
|
Query_time => '0.000020',
|
|
Thread_id => 4294967296,
|
|
pos_in_log => 0,
|
|
bytes => length('insert into t values(current_date)'),
|
|
cmd => 'Query',
|
|
Rows_affected => 1,
|
|
Warning_count => 1,
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
},
|
|
],
|
|
);
|
|
|
|
# #############################################################################
|
|
# Check the individual packet parsing subs.
|
|
# #############################################################################
|
|
|
|
is_deeply(
|
|
MySQLProtocolParser::parse_error_packet(load_data("t/lib/samples/mysql_proto_001.txt")),
|
|
{
|
|
errno => '1046',
|
|
sqlstate => '#3D000',
|
|
message => 'No database selected',
|
|
},
|
|
'Parse error packet'
|
|
);
|
|
|
|
is_deeply(
|
|
MySQLProtocolParser::parse_ok_packet('010002000100'),
|
|
{
|
|
affected_rows => 1,
|
|
insert_id => 0,
|
|
status => 2,
|
|
warnings => 1,
|
|
message => '',
|
|
},
|
|
'Parse ok packet'
|
|
);
|
|
|
|
is_deeply(
|
|
MySQLProtocolParser::parse_server_handshake_packet(load_data("t/lib/samples/mysql_proto_002.txt")),
|
|
{
|
|
thread_id => '9',
|
|
server_version => '5.0.67-0ubuntu6-log',
|
|
flags => {
|
|
CLIENT_COMPRESS => 1,
|
|
CLIENT_CONNECT_WITH_DB => 1,
|
|
CLIENT_FOUND_ROWS => 0,
|
|
CLIENT_IGNORE_SIGPIPE => 0,
|
|
CLIENT_IGNORE_SPACE => 0,
|
|
CLIENT_INTERACTIVE => 0,
|
|
CLIENT_LOCAL_FILES => 0,
|
|
CLIENT_LONG_FLAG => 1,
|
|
CLIENT_LONG_PASSWORD => 0,
|
|
CLIENT_MULTI_RESULTS => 0,
|
|
CLIENT_MULTI_STATEMENTS => 0,
|
|
CLIENT_NO_SCHEMA => 0,
|
|
CLIENT_ODBC => 0,
|
|
CLIENT_PROTOCOL_41 => 1,
|
|
CLIENT_RESERVED => 0,
|
|
CLIENT_SECURE_CONNECTION => 1,
|
|
CLIENT_SSL => 0,
|
|
CLIENT_TRANSACTIONS => 1,
|
|
}
|
|
},
|
|
'Parse server handshake packet'
|
|
);
|
|
|
|
is_deeply(
|
|
MySQLProtocolParser::parse_client_handshake_packet(load_data("t/lib/samples/mysql_proto_003.txt")),
|
|
{
|
|
db => 'mysql',
|
|
user => 'msandbox',
|
|
flags => {
|
|
CLIENT_COMPRESS => 0,
|
|
CLIENT_CONNECT_WITH_DB => 1,
|
|
CLIENT_FOUND_ROWS => 0,
|
|
CLIENT_IGNORE_SIGPIPE => 0,
|
|
CLIENT_IGNORE_SPACE => 0,
|
|
CLIENT_INTERACTIVE => 0,
|
|
CLIENT_LOCAL_FILES => 1,
|
|
CLIENT_LONG_FLAG => 1,
|
|
CLIENT_LONG_PASSWORD => 1,
|
|
CLIENT_MULTI_RESULTS => 1,
|
|
CLIENT_MULTI_STATEMENTS => 1,
|
|
CLIENT_NO_SCHEMA => 0,
|
|
CLIENT_ODBC => 0,
|
|
CLIENT_PROTOCOL_41 => 1,
|
|
CLIENT_RESERVED => 0,
|
|
CLIENT_SECURE_CONNECTION => 1,
|
|
CLIENT_SSL => 0,
|
|
CLIENT_TRANSACTIONS => 1,
|
|
},
|
|
},
|
|
'Parse client handshake packet'
|
|
);
|
|
|
|
is_deeply(
|
|
MySQLProtocolParser::parse_com_packet('0373686f77207761726e696e67738d2dacbc', 14),
|
|
{
|
|
code => '03',
|
|
com => 'COM_QUERY',
|
|
data => 'show warnings',
|
|
},
|
|
'Parse COM_QUERY packet'
|
|
);
|
|
|
|
# Test that we can parse with a non-standard port etc.
|
|
$protocol = new MySQLProtocolParser(
|
|
server => '192.168.1.1',
|
|
port => '3307',
|
|
);
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump012.txt",
|
|
result => [
|
|
{ ts => '090412 09:50:16.805123',
|
|
db => undef,
|
|
user => undef,
|
|
Thread_id => 4294967296,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '42167',
|
|
arg => 'select "hello world" as greeting',
|
|
Query_time => sprintf('%.6f', .805123 - .804849),
|
|
pos_in_log => 0,
|
|
bytes => length('select "hello world" as greeting'),
|
|
cmd => 'Query',
|
|
Rows_affected => 0,
|
|
Warning_count => 0,
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
},
|
|
],
|
|
);
|
|
|
|
# #############################################################################
|
|
# Issue 447: MySQLProtocolParser does not handle old password algo or
|
|
# compressed packets
|
|
# #############################################################################
|
|
$protocol = new MySQLProtocolParser(
|
|
server => '10.55.200.15',
|
|
);
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump013.txt",
|
|
desc => 'old password and compression',
|
|
result => [
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.034355',
|
|
Rows_affected => 0,
|
|
Thread_id => 36947020,
|
|
Warning_count => 0,
|
|
arg => 'administrator command: Connect',
|
|
bytes => 30,
|
|
cmd => 'Admin',
|
|
db => 'nepool_ftr',
|
|
host => '10.54.212.171',
|
|
ip => '10.54.212.171',
|
|
port => '49663',
|
|
pos_in_log => 1834,
|
|
ts => '090603 10:52:24.578817',
|
|
user => 'luck'
|
|
},
|
|
],
|
|
);
|
|
|
|
# Check in-stream compression detection.
|
|
$protocol = new MySQLProtocolParser(
|
|
server => '10.55.200.15',
|
|
);
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump014.txt",
|
|
desc => 'in-stream compression detection',
|
|
result => [
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.001375',
|
|
Rows_affected => 0,
|
|
Thread_id => 4294967296,
|
|
Warning_count => 0,
|
|
arg => 'show databases',
|
|
bytes => 14,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '10.54.212.171',
|
|
ip => '10.54.212.171',
|
|
port => '49663',
|
|
pos_in_log => 0,
|
|
ts => '090603 10:52:24.587685',
|
|
user => undef,
|
|
},
|
|
],
|
|
);
|
|
|
|
eval { require IO::Uncompress::Inflate; };
|
|
SKIP: {
|
|
skip "IO::Uncompress::Inflate not installed", 2 if $EVAL_ERROR;
|
|
|
|
# Check data decompression.
|
|
$protocol = new MySQLProtocolParser(
|
|
server => '127.0.0.1',
|
|
port => '12345',
|
|
);
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump015.txt",
|
|
desc => 'compressed data',
|
|
result => [
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.006415',
|
|
Rows_affected => 0,
|
|
Thread_id => 20,
|
|
Warning_count => 0,
|
|
arg => 'administrator command: Connect',
|
|
bytes => 30,
|
|
cmd => 'Admin',
|
|
db => 'mysql',
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '44489',
|
|
pos_in_log => 664,
|
|
ts => '090612 08:39:05.316805',
|
|
user => 'msandbox',
|
|
},
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'Yes',
|
|
Query_time => '0.002884',
|
|
Rows_affected => 0,
|
|
Thread_id => 20,
|
|
Warning_count => 0,
|
|
arg => 'select * from help_relation',
|
|
bytes => 27,
|
|
cmd => 'Query',
|
|
db => 'mysql',
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '44489',
|
|
pos_in_log => 1637,
|
|
ts => '090612 08:39:08.428913',
|
|
user => 'msandbox',
|
|
},
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000000',
|
|
Rows_affected => 0,
|
|
Thread_id => 20,
|
|
Warning_count => 0,
|
|
arg => 'administrator command: Quit',
|
|
bytes => 27,
|
|
cmd => 'Admin',
|
|
db => 'mysql',
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '44489',
|
|
pos_in_log => 15782,
|
|
ts => '090612 08:39:09.145334',
|
|
user => 'msandbox',
|
|
},
|
|
],
|
|
);
|
|
}
|
|
|
|
# TCP retransmission.
|
|
$protocol = new MySQLProtocolParser(
|
|
server => '10.55.200.15',
|
|
);
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump016.txt",
|
|
desc => 'TCP retransmission',
|
|
result => [
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.001000',
|
|
Rows_affected => 0,
|
|
Thread_id => 38559282,
|
|
Warning_count => 0,
|
|
arg => 'administrator command: Connect',
|
|
bytes => 30,
|
|
cmd => 'Admin',
|
|
db => '',
|
|
host => '10.55.200.31',
|
|
ip => '10.55.200.31',
|
|
port => '64987',
|
|
pos_in_log => 468,
|
|
ts => '090609 16:53:17.112346',
|
|
user => 'ppppadri',
|
|
},
|
|
],
|
|
);
|
|
|
|
# #############################################################################
|
|
# Issue 537: MySQLProtocolParser and MemcachedProtocolParser do not handle
|
|
# multiple servers.
|
|
# #############################################################################
|
|
$protocol = new MySQLProtocolParser();
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump018.txt",
|
|
desc => 'Multiple servers',
|
|
result => [
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000206',
|
|
Rows_affected => 0,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'select * from foo',
|
|
bytes => 17,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '42275',
|
|
pos_in_log => 0,
|
|
ts => '090727 08:28:41.723651',
|
|
user => undef,
|
|
},
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000203',
|
|
Rows_affected => 0,
|
|
Thread_id => '4294967297',
|
|
Warning_count => 0,
|
|
arg => 'select * from bar',
|
|
bytes => 17,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '34233',
|
|
pos_in_log => 987,
|
|
ts => '090727 08:29:34.232748',
|
|
user => undef,
|
|
},
|
|
],
|
|
);
|
|
|
|
# Test that --watch-server causes just the given server to be watched.
|
|
$protocol = new MySQLProtocolParser(server=>'10.0.0.1',port=>'3306');
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump018.txt",
|
|
desc => 'Multiple servers but watch only one',
|
|
result => [
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000206',
|
|
Rows_affected => 0,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'select * from foo',
|
|
bytes => 17,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '42275',
|
|
pos_in_log => 0,
|
|
ts => '090727 08:28:41.723651',
|
|
user => undef,
|
|
},
|
|
]
|
|
);
|
|
|
|
|
|
# #############################################################################
|
|
# Issue 558: Make mk-query-digest handle big/fragmented packets
|
|
# #############################################################################
|
|
$protocol = new MySQLProtocolParser(server=>'127.0.0.1',port=>'12345');
|
|
my $e = test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump019.txt",
|
|
);
|
|
|
|
like(
|
|
$e->[0]->{arg},
|
|
qr/--THE END--'\)$/,
|
|
'Handles big, fragmented MySQL packets (issue 558)'
|
|
);
|
|
|
|
my $arg = load_file("$sample/tcpdump019-arg.txt");
|
|
chomp $arg;
|
|
is(
|
|
$e->[0]->{arg},
|
|
$arg,
|
|
'Re-assembled data is correct (issue 558)'
|
|
);
|
|
|
|
# #############################################################################
|
|
# Issue 740: Handle prepared statements
|
|
# #############################################################################
|
|
$protocol = new MySQLProtocolParser(server=>'127.0.0.1',port=>'12345');
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump021.txt",
|
|
desc => 'prepared statements, simple, no NULL',
|
|
result => [
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000286',
|
|
Rows_affected => 0,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'PREPARE SELECT i FROM d.t WHERE i=?',
|
|
bytes => 35,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '58619',
|
|
pos_in_log => 0,
|
|
ts => '091208 09:23:49.637394',
|
|
user => undef,
|
|
Statement_id => 2,
|
|
},
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'Yes',
|
|
Query_time => '0.000281',
|
|
Rows_affected => 0,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'EXECUTE SELECT i FROM d.t WHERE i="3"',
|
|
bytes => 37,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '58619',
|
|
pos_in_log => 1106,
|
|
ts => '091208 09:23:49.637892',
|
|
user => undef,
|
|
Statement_id => 2,
|
|
},
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000000',
|
|
Rows_affected => 0,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'administrator command: Quit',
|
|
bytes => 27,
|
|
cmd => 'Admin',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '58619',
|
|
pos_in_log => 1850,
|
|
ts => '091208 09:23:49.638381',
|
|
user => undef
|
|
},
|
|
],
|
|
);
|
|
|
|
$protocol = new MySQLProtocolParser(server=>'127.0.0.1',port=>'12345');
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump022.txt",
|
|
desc => 'prepared statements, NULL value',
|
|
result => [
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000303',
|
|
Rows_affected => 0,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'PREPARE SELECT i,j FROM d.t2 WHERE i=? AND j=?',
|
|
bytes => 46,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '44545',
|
|
pos_in_log => 0,
|
|
ts => '091208 13:41:12.811188',
|
|
user => undef,
|
|
Statement_id => 2,
|
|
},
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000186',
|
|
Rows_affected => 0,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'EXECUTE SELECT i,j FROM d.t2 WHERE i=NULL AND j="5"',
|
|
bytes => 51,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '44545',
|
|
pos_in_log => 1330,
|
|
ts => '091208 13:41:12.811591',
|
|
user => undef,
|
|
Statement_id => 2,
|
|
}
|
|
],
|
|
);
|
|
|
|
$protocol = new MySQLProtocolParser(server=>'127.0.0.1',port=>'12345');
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump023.txt",
|
|
desc => 'prepared statements, string, char and float',
|
|
result => [
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000315',
|
|
Rows_affected => 0,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'PREPARE SELECT * FROM d.t3 WHERE v=? OR c=? OR f=?',
|
|
bytes => 50,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '49806',
|
|
pos_in_log => 0,
|
|
ts => '091208 14:14:55.951863',
|
|
user => undef,
|
|
Statement_id => 2,
|
|
},
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000249',
|
|
Rows_affected => 0,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'EXECUTE SELECT * FROM d.t3 WHERE v="hello world" OR c="a" OR f="1.23"',
|
|
bytes => 69,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '49806',
|
|
pos_in_log => 1540,
|
|
ts => '091208 14:14:55.952344',
|
|
user => undef,
|
|
Statement_id => 2,
|
|
}
|
|
],
|
|
);
|
|
|
|
$protocol = new MySQLProtocolParser(server=>'127.0.0.1',port=>'12345');
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump024.txt",
|
|
desc => 'prepared statements, all NULL',
|
|
result => [
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000278',
|
|
Rows_affected => 0,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'PREPARE SELECT * FROM d.t3 WHERE v=? OR c=? OR f=?',
|
|
bytes => 50,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '32810',
|
|
pos_in_log => 0,
|
|
ts => '091208 14:33:13.711351',
|
|
user => undef,
|
|
Statement_id => 2,
|
|
},
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000159',
|
|
Rows_affected => 0,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'EXECUTE SELECT * FROM d.t3 WHERE v=NULL OR c=NULL OR f=NULL',
|
|
bytes => 59,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '32810',
|
|
pos_in_log => 1540,
|
|
ts => '091208 14:33:13.711642',
|
|
user => undef,
|
|
Statement_id => 2,
|
|
},
|
|
],
|
|
);
|
|
|
|
$protocol = new MySQLProtocolParser(server=>'127.0.0.1',port=>'12345');
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump025.txt",
|
|
desc => 'prepared statements, no params',
|
|
result => [
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000268',
|
|
Rows_affected => 0,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'PREPARE SELECT * FROM d.t WHERE 1 LIMIT 1;',
|
|
bytes => 42,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '48585',
|
|
pos_in_log => 0,
|
|
ts => '091208 14:44:52.709181',
|
|
user => undef,
|
|
Statement_id => 2,
|
|
},
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'Yes',
|
|
Query_time => '0.000234',
|
|
Rows_affected => 0,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'EXECUTE SELECT * FROM d.t WHERE 1 LIMIT 1;',
|
|
bytes => 42,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '48585',
|
|
pos_in_log => 1014,
|
|
ts => '091208 14:44:52.709597',
|
|
user => undef,
|
|
Statement_id => 2,
|
|
}
|
|
],
|
|
);
|
|
|
|
$protocol = new MySQLProtocolParser(server=>'127.0.0.1',port=>'3306');
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump026.txt",
|
|
desc => 'prepared statements, close statement',
|
|
result => [
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000000',
|
|
Rows_affected => 0,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'DEALLOCATE PREPARE 50',
|
|
bytes => 21,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '1.2.3.4',
|
|
ip => '1.2.3.4',
|
|
port => '34162',
|
|
pos_in_log => 0,
|
|
ts => '091208 17:42:12.696547',
|
|
user => undef
|
|
}
|
|
],
|
|
);
|
|
|
|
$protocol = new MySQLProtocolParser(server=>'127.0.0.1',port=>'3306');
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump027.txt",
|
|
desc => 'prepared statements, reset statement',
|
|
result => [
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000023',
|
|
Rows_affected => 0,
|
|
Statement_id => 51,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'RESET 51',
|
|
bytes => 8,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '1.2.3.4',
|
|
ip => '1.2.3.4',
|
|
port => '34162',
|
|
pos_in_log => 0,
|
|
ts => '091208 17:42:12.698093',
|
|
user => undef
|
|
}
|
|
],
|
|
);
|
|
|
|
$protocol = new MySQLProtocolParser(server=>'127.0.0.1',port=>'12345');
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump028.txt",
|
|
desc => 'prepared statements, multiple exec, new param',
|
|
result => [
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000292',
|
|
Rows_affected => 0,
|
|
Statement_id => 2,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'PREPARE SELECT * FROM d.t WHERE i=?',
|
|
bytes => 35,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '38682',
|
|
pos_in_log => 0,
|
|
ts => '091208 17:35:37.433248',
|
|
user => undef
|
|
},
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'Yes',
|
|
Query_time => '0.000254',
|
|
Rows_affected => 0,
|
|
Statement_id => 2,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'EXECUTE SELECT * FROM d.t WHERE i="1"',
|
|
bytes => 37,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '38682',
|
|
pos_in_log => 1106,
|
|
ts => '091208 17:35:37.433700',
|
|
user => undef
|
|
},
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'Yes',
|
|
Query_time => '0.000190',
|
|
Rows_affected => 0,
|
|
Statement_id => 2,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'EXECUTE SELECT * FROM d.t WHERE i="3"',
|
|
bytes => 37,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '38682',
|
|
pos_in_log => 1850,
|
|
ts => '091208 17:35:37.434303',
|
|
user => undef
|
|
},
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'Yes',
|
|
Query_time => '0.000166',
|
|
Rows_affected => 0,
|
|
Statement_id => 2,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'EXECUTE SELECT * FROM d.t WHERE i=NULL',
|
|
bytes => 38,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '38682',
|
|
pos_in_log => 2589,
|
|
ts => '091208 17:35:37.434708',
|
|
user => undef
|
|
}
|
|
],
|
|
);
|
|
|
|
$protocol = new MySQLProtocolParser(server=>'127.0.0.1',port=>'12345');
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump029.txt",
|
|
desc => 'prepared statements, real param types',
|
|
result => [
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000221',
|
|
Rows_affected => 0,
|
|
Statement_id => 1,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'PREPARE SELECT * FROM d.t WHERE i=? OR u=? OR v=? OR d=? OR f=? OR t > ? OR dt > ?',
|
|
bytes => 82,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '36496',
|
|
pos_in_log => 0,
|
|
ts => '091209 09:20:59.293775',
|
|
user => undef
|
|
},
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000203',
|
|
Rows_affected => 0,
|
|
Statement_id => 1,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'EXECUTE SELECT * FROM d.t WHERE i=42 OR u=2009 OR v="hello world" OR d=1.23 OR f=4.56 OR t > "2009-12-01" OR dt > "2009-12-01"',
|
|
bytes => 126,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '36496',
|
|
pos_in_log => 2109,
|
|
ts => '091209 09:20:59.294409',
|
|
user => undef
|
|
},
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000000',
|
|
Rows_affected => 0,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'DEALLOCATE PREPARE 1',
|
|
bytes => 20,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '36496',
|
|
pos_in_log => 3787,
|
|
ts => '091209 09:20:59.294926',
|
|
user => undef
|
|
},
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000000',
|
|
Rows_affected => 0,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'administrator command: Quit',
|
|
bytes => 27,
|
|
cmd => 'Admin',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '36496',
|
|
pos_in_log => 4051,
|
|
ts => '091209 09:20:59.295064',
|
|
user => undef
|
|
},
|
|
]
|
|
);
|
|
|
|
$protocol = new MySQLProtocolParser(server=>'127.0.0.1',port=>'3306');
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump030.txt",
|
|
desc => 'prepared statements, ok response to execute',
|
|
result => [
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000046',
|
|
Rows_affected => 0,
|
|
Statement_id => 1,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'PREPARE SET SESSION sql_mode="STRICT_ALL_TABLES"',
|
|
bytes => 48,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '1.2.3.24',
|
|
ip => '1.2.3.24',
|
|
port => '60696',
|
|
pos_in_log => 0,
|
|
ts => '091210 14:21:16.956302',
|
|
user => undef
|
|
},
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000024',
|
|
Rows_affected => 0,
|
|
Statement_id => 1,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'EXECUTE SET SESSION sql_mode="STRICT_ALL_TABLES"',
|
|
bytes => 48,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '1.2.3.24',
|
|
ip => '1.2.3.24',
|
|
port => '60696',
|
|
pos_in_log => 700,
|
|
ts => '091210 14:21:16.956446',
|
|
user => undef
|
|
}
|
|
],
|
|
);
|
|
|
|
$protocol = new MySQLProtocolParser(server=>'127.0.0.1',port=>'3306');
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump034.txt",
|
|
desc => 'prepared statements, NULL bitmap',
|
|
result => [
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000288',
|
|
Rows_affected => 0,
|
|
Statement_id => 1,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'PREPARE SELECT * FROM d.t WHERE i=? OR u=? OR v=? OR d=? OR f=? OR t > ? OR dt > ? OR i2=? OR i3=? OR i4=?',
|
|
bytes => 106,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '43607',
|
|
pos_in_log => 0,
|
|
ts => '091224 16:47:24.204501',
|
|
user => undef
|
|
},
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000322',
|
|
Rows_affected => 0,
|
|
Statement_id => 1,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'EXECUTE SELECT * FROM d.t WHERE i=42 OR u=2009 OR v="hello world" OR d=1.23 OR f=4.56 OR t > "2009-12-01" OR dt > "2009-12-01" OR i2=NULL OR i3=NULL OR i4=NULL',
|
|
bytes => 159,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '43607',
|
|
pos_in_log => 2748,
|
|
ts => '091224 16:47:24.204965',
|
|
user => undef
|
|
}
|
|
],
|
|
);
|
|
|
|
# #############################################################################
|
|
# Issue 761: mk-query-digest --tcpdump does not handle incomplete packets
|
|
# #############################################################################
|
|
$protocol = new MySQLProtocolParser(server=>'127.0.0.1',port=>'3306');
|
|
$protocol->{_no_save_error} = 1;
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump032.txt",
|
|
desc => 'issue 761',
|
|
result => [
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000431',
|
|
Rows_affected => 1,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 21032,
|
|
arg => 'UPDATEDDDDNNNN',
|
|
bytes => 14,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '1.2.3.4',
|
|
ip => '1.2.3.4',
|
|
port => '35957',
|
|
pos_in_log => 1768,
|
|
ts => '091208 20:54:54.795250',
|
|
user => undef
|
|
}
|
|
],
|
|
);
|
|
|
|
# #############################################################################
|
|
# Issue 760: mk-query-digest --tcpdump might not get the whole query
|
|
# #############################################################################
|
|
$protocol = new MySQLProtocolParser(server=>'127.0.0.1',port=>'3306');
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump031.txt",
|
|
desc => 'issue 760',
|
|
result => [
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000430',
|
|
Rows_affected => 1,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 21032,
|
|
arg => 'UPDATEDDDDNNNN',
|
|
bytes => 14,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '1.2.3.4',
|
|
ip => '1.2.3.4',
|
|
port => '35957',
|
|
pos_in_log => 534,
|
|
ts => '091207 20:54:54.795250',
|
|
user => undef
|
|
}
|
|
],
|
|
);
|
|
|
|
# #############################################################################
|
|
# Issue 794: MySQLProtocolParser does not handle client port reuse
|
|
# #############################################################################
|
|
$protocol = new MySQLProtocolParser();
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump035.txt",
|
|
desc => 'client port reuse (issue 794)',
|
|
result => [
|
|
{ ts => "090412 11:00:13.118191",
|
|
db => 'mysql',
|
|
user => 'msandbox',
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '57890',
|
|
arg => 'administrator command: Connect',
|
|
Query_time => '0.011152',
|
|
Thread_id => 8,
|
|
pos_in_log => 1470,
|
|
bytes => length('administrator command: Connect'),
|
|
cmd => 'Admin',
|
|
Rows_affected => 0,
|
|
Warning_count => 0,
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
},
|
|
{ Query_time => '0.000167',
|
|
Thread_id => 8,
|
|
arg => 'select "paris in the the spring" as trick',
|
|
bytes => length('select "paris in the the spring" as trick'),
|
|
cmd => 'Query',
|
|
db => 'mysql',
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '57890',
|
|
pos_in_log => 2449,
|
|
ts => '090412 11:00:13.119079',
|
|
user => 'msandbox',
|
|
Rows_affected => 0,
|
|
Warning_count => 0,
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
},
|
|
{ Query_time => '0.000000',
|
|
Thread_id => 8,
|
|
arg => 'administrator command: Quit',
|
|
bytes => 27,
|
|
cmd => 'Admin',
|
|
db => 'mysql',
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '57890',
|
|
pos_in_log => 3337,
|
|
ts => '090412 11:00:13.119487',
|
|
user => 'msandbox',
|
|
Rows_affected => 0,
|
|
Warning_count => 0,
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
},
|
|
# port reused...
|
|
{ ts => '090412 12:00:00.800000',
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.700000',
|
|
Rows_affected => 0,
|
|
Thread_id => 8,
|
|
Warning_count => 0,
|
|
arg => 'administrator command: Connect',
|
|
bytes => 30,
|
|
cmd => 'Admin',
|
|
db => 'mysql',
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '57890',
|
|
pos_in_log => 5791,
|
|
user => 'msandbox',
|
|
},
|
|
{ ts => '090412 12:00:01.000000',
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.100000',
|
|
Rows_affected => 0,
|
|
Thread_id => 8,
|
|
Warning_count => 0,
|
|
arg => 'select "paris in the the spring" as trick',
|
|
bytes => 41,
|
|
cmd => 'Query',
|
|
db => 'mysql',
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '57890',
|
|
pos_in_log => 6770,
|
|
user => 'msandbox',
|
|
},
|
|
{ ts => '090412 12:00:01.100000',
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000000',
|
|
Rows_affected => 0,
|
|
Thread_id => 8,
|
|
Warning_count => 0,
|
|
arg => 'administrator command: Quit',
|
|
bytes => 27,
|
|
cmd => 'Admin',
|
|
db => 'mysql',
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '57890',
|
|
pos_in_log => 7658,
|
|
user => 'msandbox',
|
|
}
|
|
],
|
|
);
|
|
|
|
$protocol = new MySQLProtocolParser();
|
|
$protocol->{_no_save_error} = 1;
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump036.txt",
|
|
desc => 'Houdini data (issue 794)',
|
|
result => [
|
|
{ ts => "090412 11:00:13.118191",
|
|
db => 'mysql',
|
|
user => 'msandbox',
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '57890',
|
|
arg => 'administrator command: Connect',
|
|
Query_time => '0.011152',
|
|
Thread_id => 8,
|
|
pos_in_log => 1470,
|
|
bytes => length('administrator command: Connect'),
|
|
cmd => 'Admin',
|
|
Rows_affected => 0,
|
|
Warning_count => 0,
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
},
|
|
# port reused...
|
|
{ ts => '090412 12:00:00.800000',
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.700000',
|
|
Rows_affected => 0,
|
|
Thread_id => 8,
|
|
Warning_count => 0,
|
|
arg => 'administrator command: Connect',
|
|
bytes => 30,
|
|
cmd => 'Admin',
|
|
db => 'mysql',
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '57890',
|
|
pos_in_log => 4161,
|
|
user => 'msandbox',
|
|
},
|
|
{ ts => '090412 12:00:01.000000',
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.100000',
|
|
Rows_affected => 0,
|
|
Thread_id => 8,
|
|
Warning_count => 0,
|
|
arg => 'select "paris in the the spring" as trick',
|
|
bytes => 41,
|
|
cmd => 'Query',
|
|
db => 'mysql',
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '57890',
|
|
pos_in_log => 5140,
|
|
user => 'msandbox',
|
|
},
|
|
{ ts => '090412 12:00:01.100000',
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000000',
|
|
Rows_affected => 0,
|
|
Thread_id => 8,
|
|
Warning_count => 0,
|
|
arg => 'administrator command: Quit',
|
|
bytes => 27,
|
|
cmd => 'Admin',
|
|
db => 'mysql',
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '57890',
|
|
pos_in_log => 6028,
|
|
user => 'msandbox',
|
|
}
|
|
],
|
|
);
|
|
|
|
$protocol = new MySQLProtocolParser();
|
|
$protocol->{_no_save_error} = 1;
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump037.txt",
|
|
desc => 'no server ok (issue 794)',
|
|
result => [
|
|
{ ts => '090412 12:00:01.000000',
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000000',
|
|
Rows_affected => 0,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'administrator command: Quit',
|
|
bytes => 27,
|
|
cmd => 'Admin',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '57890',
|
|
pos_in_log => 390,
|
|
user => undef
|
|
},
|
|
{ ts => '090412 12:00:03.000000',
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '1.000000',
|
|
Rows_affected => 0,
|
|
Thread_id => 4294967297,
|
|
Warning_count => 0,
|
|
arg => 'select "paris in the the spring" as trick',
|
|
bytes => 41,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '57890',
|
|
pos_in_log => 646,
|
|
user => undef,
|
|
},
|
|
],
|
|
);
|
|
|
|
# #############################################################################
|
|
# Issue 832: mk-query-digest tcpdump crashes on successive, fragmented
|
|
# client query
|
|
# #############################################################################
|
|
$protocol = new MySQLProtocolParser(server => '127.0.0.1',port=>'12345');
|
|
$protocol->{_no_save_error} = 1;
|
|
$e = test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump038.txt",
|
|
);
|
|
|
|
like(
|
|
$e->[0]->{arg},
|
|
qr/--THE END--'\)$/,
|
|
'2nd, fragmented client query (issue 832)',
|
|
);
|
|
|
|
# #############################################################################
|
|
# Issue 670: Make mk-query-digest capture the error message from tcpdump
|
|
# #############################################################################
|
|
$protocol = new MySQLProtocolParser(
|
|
server => '127.0.0.1',
|
|
port => '3306',
|
|
);
|
|
$protocol->{_no_save_error} = 1;
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump040.txt",
|
|
desc => 'Error (issue 670)',
|
|
result =>
|
|
[
|
|
{
|
|
Error_msg => "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1",
|
|
Error_no => '1064',
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000316',
|
|
Rows_affected => 0,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'select',
|
|
bytes => 6,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '39640',
|
|
pos_in_log => 0,
|
|
ts => '091101 14:54:44.293453',
|
|
user => undef,
|
|
},
|
|
{
|
|
Error_msg => 'Unknown system variable \'nono\'',
|
|
Error_no => '1193',
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '0.000329',
|
|
Rows_affected => 0,
|
|
Thread_id => '4294967296',
|
|
Warning_count => 0,
|
|
arg => 'set global nono = 2',
|
|
bytes => 19,
|
|
cmd => 'Query',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '39640',
|
|
pos_in_log => 1250,
|
|
ts => '091101 14:54:52.813941',
|
|
user => undef,
|
|
},
|
|
],
|
|
);
|
|
|
|
# #############################################################################
|
|
# Bug 1103045: pt-query-digest fails to parse non-SQL errors
|
|
# https://bugs.launchpad.net/percona-toolkit/+bug/1103045
|
|
# #############################################################################
|
|
|
|
$protocol = new MySQLProtocolParser(
|
|
server => '127.0.0.1',
|
|
port => '12345',
|
|
);
|
|
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump043.txt",
|
|
desc => 'Bad connection',
|
|
result =>
|
|
[
|
|
{
|
|
Error_msg => 'Got packets out of order',
|
|
Error_no => 1156,
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '3.536306',
|
|
Rows_affected => 0,
|
|
Thread_id => 27,
|
|
Warning_count => 0,
|
|
arg => 'administrator command: Connect',
|
|
bytes => 30,
|
|
cmd => 'Admin',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '62160',
|
|
pos_in_log => undef,
|
|
ts => '130124 13:03:28.672987',
|
|
user => undef,
|
|
}
|
|
],
|
|
);
|
|
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump042.txt",
|
|
desc => 'Client went away during handshake',
|
|
result => [
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '9.998411',
|
|
Rows_affected => 0,
|
|
Thread_id => 24,
|
|
Warning_count => 0,
|
|
arg => 'administrator command: Connect',
|
|
bytes => 30,
|
|
cmd => 'Admin',
|
|
db => undef,
|
|
host => '127.0.0.1',
|
|
ip => '127.0.0.1',
|
|
port => '62133',
|
|
pos_in_log => undef,
|
|
ts => '130124 12:55:48.274417',
|
|
user => undef,
|
|
Error_msg => 'Client closed connection during handshake',
|
|
}
|
|
],
|
|
);
|
|
|
|
$protocol = new MySQLProtocolParser(
|
|
server => '100.0.0.1',
|
|
);
|
|
|
|
test_protocol_parser(
|
|
parser => $tcpdump,
|
|
protocol => $protocol,
|
|
file => "$sample/tcpdump044.txt",
|
|
desc => 'Client aborted connection (bug 1103045)',
|
|
result => [
|
|
{
|
|
No_good_index_used => 'No',
|
|
No_index_used => 'No',
|
|
Query_time => '3.819507',
|
|
Rows_affected => 0,
|
|
Thread_id => 13,
|
|
Warning_count => 0,
|
|
arg => 'administrator command: Connect',
|
|
bytes => 30,
|
|
cmd => 'Admin',
|
|
db => undef,
|
|
host => '100.0.0.2',
|
|
ip => '100.0.0.2',
|
|
port => '44432',
|
|
pos_in_log => undef,
|
|
ts => '130122 09:55:57.793375',
|
|
user => undef,
|
|
Error_msg => 'Client closed connection during handshake',
|
|
},
|
|
],
|
|
);
|
|
|
|
# #############################################################################
|
|
# Save errors by default
|
|
# #############################################################################
|
|
$protocol = new MySQLProtocolParser(server=>'127.0.0.1',port=>'3306');
|
|
|
|
my $out = output(sub {
|
|
open my $fh, "<", "$sample/tcpdump032.txt" or die "Cannot open tcpdump032.txt: $OS_ERROR";
|
|
my %parser_args = (
|
|
next_event => sub { return <$fh>; },
|
|
tell => sub { return tell($fh); },
|
|
);
|
|
while ( my $p = $tcpdump->parse_event(%parser_args) ) {
|
|
$protocol->parse_event(%parser_args, event => $p);
|
|
}
|
|
close $fh;
|
|
}, stderr => 1);
|
|
|
|
like(
|
|
$out,
|
|
qr/had errors, will save them in /,
|
|
"Saves errors by default"
|
|
);
|
|
|
|
close $protocol->{errors_fh}; # flush the handle
|
|
|
|
like(
|
|
slurp_file($protocol->{errors_file}),
|
|
qr/got server response before full buffer/,
|
|
"The right error is saved"
|
|
);
|
|
|
|
$out = output(sub {
|
|
open my $fh, "<", "$sample/tcpdump032.txt" or die "Cannot open tcpdump032.txt: $OS_ERROR";
|
|
my %parser_args = (
|
|
next_event => sub { return <$fh>; },
|
|
tell => sub { return tell($fh); },
|
|
);
|
|
while ( my $p = $tcpdump->parse_event(%parser_args) ) {
|
|
$protocol->parse_event(%parser_args, event => $p);
|
|
}
|
|
close $fh;
|
|
}, stderr => 1);
|
|
|
|
is(
|
|
$out,
|
|
'',
|
|
"No warnings the second time around"
|
|
);
|
|
|
|
{
|
|
$protocol = new MySQLProtocolParser(server=>'127.0.0.1',port=>'3306');
|
|
# ..but allow setting the filename through an ENV var:
|
|
local $ENV{PERCONA_TOOLKIT_TCP_ERRORS_FILE} = '/dev/null';
|
|
|
|
$out = output(sub {
|
|
open my $fh, "<", "$sample/tcpdump032.txt" or die "Cannot open tcpdump032.txt: $OS_ERROR";
|
|
my %parser_args = (
|
|
next_event => sub { return <$fh>; },
|
|
tell => sub { return tell($fh); },
|
|
);
|
|
while ( my $p = $tcpdump->parse_event(%parser_args) ) {
|
|
$protocol->parse_event(%parser_args, event => $p);
|
|
}
|
|
close $fh;
|
|
}, stderr => 1);
|
|
|
|
like(
|
|
$out,
|
|
qr/had errors, will save them in /,
|
|
"Still tries saving the errors with PERCONA_TOOLKIT_TCP_ERRORS_FILE"
|
|
);
|
|
|
|
is(
|
|
$protocol->{errors_file},
|
|
'/dev/null',
|
|
"...but uses the provided file"
|
|
);
|
|
}
|
|
# #############################################################################
|
|
# Done.
|
|
# #############################################################################
|
|
|
|
# Get rid of error files
|
|
`rm /tmp/MySQLProtocolParser.t-errors.*`;
|
|
done_testing;
|