mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-10 13:11:32 +00:00
pqs: Removed tcpdump-errors, made the library always save the errors in a tempfile
This commit is contained in:
@@ -3531,20 +3531,6 @@ $Data::Dumper::Indent = 1;
|
|||||||
$Data::Dumper::Sortkeys = 1;
|
$Data::Dumper::Sortkeys = 1;
|
||||||
$Data::Dumper::Quotekeys = 0;
|
$Data::Dumper::Quotekeys = 0;
|
||||||
|
|
||||||
require Exporter;
|
|
||||||
our @ISA = qw(Exporter);
|
|
||||||
our %EXPORT_TAGS = ();
|
|
||||||
our @EXPORT = ();
|
|
||||||
our @EXPORT_OK = qw(
|
|
||||||
parse_error_packet
|
|
||||||
parse_ok_packet
|
|
||||||
parse_ok_prepared_statement_packet
|
|
||||||
parse_server_handshake_packet
|
|
||||||
parse_client_handshake_packet
|
|
||||||
parse_com_packet
|
|
||||||
parse_flags
|
|
||||||
);
|
|
||||||
|
|
||||||
use constant {
|
use constant {
|
||||||
COM_SLEEP => '00',
|
COM_SLEEP => '00',
|
||||||
COM_QUIT => '01',
|
COM_QUIT => '01',
|
||||||
|
@@ -51,19 +51,7 @@ $Data::Dumper::Indent = 1;
|
|||||||
$Data::Dumper::Sortkeys = 1;
|
$Data::Dumper::Sortkeys = 1;
|
||||||
$Data::Dumper::Quotekeys = 0;
|
$Data::Dumper::Quotekeys = 0;
|
||||||
|
|
||||||
require Exporter;
|
use base 'ProtocolParser';
|
||||||
our @ISA = qw(Exporter);
|
|
||||||
our %EXPORT_TAGS = ();
|
|
||||||
our @EXPORT = ();
|
|
||||||
our @EXPORT_OK = qw(
|
|
||||||
parse_error_packet
|
|
||||||
parse_ok_packet
|
|
||||||
parse_ok_prepared_statement_packet
|
|
||||||
parse_server_handshake_packet
|
|
||||||
parse_client_handshake_packet
|
|
||||||
parse_com_packet
|
|
||||||
parse_flags
|
|
||||||
);
|
|
||||||
|
|
||||||
use constant {
|
use constant {
|
||||||
COM_SLEEP => '00',
|
COM_SLEEP => '00',
|
||||||
@@ -1526,46 +1514,6 @@ sub remove_mysql_header {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub _get_errors_fh {
|
|
||||||
my ( $self ) = @_;
|
|
||||||
my $errors_fh = $self->{errors_fh};
|
|
||||||
return $errors_fh if $errors_fh;
|
|
||||||
|
|
||||||
# Errors file isn't open yet; try to open it.
|
|
||||||
my $o = $self->{o};
|
|
||||||
if ( $o && $o->has('tcpdump-errors') && $o->got('tcpdump-errors') ) {
|
|
||||||
my $errors_file = $o->get('tcpdump-errors');
|
|
||||||
PTDEBUG && _d('tcpdump-errors file:', $errors_file);
|
|
||||||
open $errors_fh, '>>', $errors_file
|
|
||||||
or die "Cannot open tcpdump-errors file $errors_file: $OS_ERROR";
|
|
||||||
}
|
|
||||||
|
|
||||||
$self->{errors_fh} = $errors_fh;
|
|
||||||
return $errors_fh;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub fail_session {
|
|
||||||
my ( $self, $session, $reason ) = @_;
|
|
||||||
PTDEBUG && _d('Client', $session->{client}, 'failed because', $reason);
|
|
||||||
my $errors_fh = $self->_get_errors_fh();
|
|
||||||
if ( $errors_fh ) {
|
|
||||||
my $raw_packets = $session->{raw_packets};
|
|
||||||
delete $session->{raw_packets}; # Don't dump, it's printed below.
|
|
||||||
$session->{reason_for_failure} = $reason;
|
|
||||||
my $session_dump = '# ' . Dumper($session);
|
|
||||||
chomp $session_dump;
|
|
||||||
$session_dump =~ s/\n/\n# /g;
|
|
||||||
print $errors_fh "$session_dump\n";
|
|
||||||
{
|
|
||||||
local $LIST_SEPARATOR = "\n";
|
|
||||||
print $errors_fh "@$raw_packets";
|
|
||||||
print $errors_fh "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete $self->{sessions}->{$session->{client}};
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Delete anything we added to the session related to
|
# Delete anything we added to the session related to
|
||||||
# buffering a large query received in multiple packets.
|
# buffering a large query received in multiple packets.
|
||||||
sub _delete_buff {
|
sub _delete_buff {
|
||||||
|
@@ -448,6 +448,7 @@ sub test_protocol_parser {
|
|||||||
keys %args;
|
keys %args;
|
||||||
|
|
||||||
my $file = "$trunk/$args{file}";
|
my $file = "$trunk/$args{file}";
|
||||||
|
my ($base_file_name) = $args{file} =~ m/([^\/]+)$/;
|
||||||
my @e;
|
my @e;
|
||||||
eval {
|
eval {
|
||||||
open my $fh, "<", $file or die "Cannot open $file: $OS_ERROR";
|
open my $fh, "<", $file or die "Cannot open $file: $OS_ERROR";
|
||||||
@@ -463,11 +464,10 @@ sub test_protocol_parser {
|
|||||||
close $fh;
|
close $fh;
|
||||||
};
|
};
|
||||||
|
|
||||||
my ($base_file_name) = $args{file} =~ m/([^\/]+)$/;
|
|
||||||
is(
|
is(
|
||||||
$EVAL_ERROR,
|
$EVAL_ERROR,
|
||||||
'',
|
'',
|
||||||
"$base_file_name: no errors"
|
"$base_file_name: no perl errors"
|
||||||
);
|
);
|
||||||
|
|
||||||
if ( defined $args{result} ) {
|
if ( defined $args{result} ) {
|
||||||
|
@@ -27,6 +27,9 @@ use warnings FATAL => 'all';
|
|||||||
use English qw(-no_match_vars);
|
use English qw(-no_match_vars);
|
||||||
use constant PTDEBUG => $ENV{PTDEBUG} || 0;
|
use constant PTDEBUG => $ENV{PTDEBUG} || 0;
|
||||||
|
|
||||||
|
use File::Basename qw(basename);
|
||||||
|
use File::Temp qw(tempfile);
|
||||||
|
|
||||||
eval {
|
eval {
|
||||||
require IO::Uncompress::Inflate; # yum: perl-IO-Compress-Zlib
|
require IO::Uncompress::Inflate; # yum: perl-IO-Compress-Zlib
|
||||||
IO::Uncompress::Inflate->import(qw(inflate $InflateError));
|
IO::Uncompress::Inflate->import(qw(inflate $InflateError));
|
||||||
@@ -245,39 +248,34 @@ sub make_event {
|
|||||||
|
|
||||||
sub _get_errors_fh {
|
sub _get_errors_fh {
|
||||||
my ( $self ) = @_;
|
my ( $self ) = @_;
|
||||||
my $errors_fh = $self->{errors_fh};
|
return $self->{errors_fh} if $self->{errors_fh};
|
||||||
return $errors_fh if $errors_fh;
|
|
||||||
|
|
||||||
|
my $exec = basename($0);
|
||||||
# Errors file isn't open yet; try to open it.
|
# Errors file isn't open yet; try to open it.
|
||||||
my $o = $self->{o};
|
my ($errors_fh, $filename) = tempfile("/tmp/$exec-errors.XXXXXXX", UNLINK => 0);
|
||||||
if ( $o && $o->has('tcpdump-errors') && $o->got('tcpdump-errors') ) {
|
|
||||||
my $errors_file = $o->get('tcpdump-errors');
|
|
||||||
PTDEBUG && _d('tcpdump-errors file:', $errors_file);
|
|
||||||
open $errors_fh, '>>', $errors_file
|
|
||||||
or die "Cannot open tcpdump-errors file $errors_file: $OS_ERROR";
|
|
||||||
}
|
|
||||||
|
|
||||||
$self->{errors_fh} = $errors_fh;
|
$self->{errors_file} = $filename;
|
||||||
|
$self->{errors_fh} = $errors_fh;
|
||||||
return $errors_fh;
|
return $errors_fh;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub fail_session {
|
sub fail_session {
|
||||||
my ( $self, $session, $reason ) = @_;
|
my ( $self, $session, $reason ) = @_;
|
||||||
my $errors_fh = $self->_get_errors_fh();
|
|
||||||
if ( $errors_fh ) {
|
|
||||||
$session->{reason_for_failure} = $reason;
|
|
||||||
my $session_dump = '# ' . Dumper($session);
|
|
||||||
chomp $session_dump;
|
|
||||||
$session_dump =~ s/\n/\n# /g;
|
|
||||||
print $errors_fh "$session_dump\n";
|
|
||||||
{
|
|
||||||
local $LIST_SEPARATOR = "\n";
|
|
||||||
print $errors_fh "@{$session->{raw_packets}}";
|
|
||||||
print $errors_fh "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PTDEBUG && _d('Failed session', $session->{client}, 'because', $reason);
|
PTDEBUG && _d('Failed session', $session->{client}, 'because', $reason);
|
||||||
delete $self->{sessions}->{$session->{client}};
|
delete $self->{sessions}->{$session->{client}};
|
||||||
|
|
||||||
|
return if $self->{_no_save_error};
|
||||||
|
|
||||||
|
my $errors_fh = $self->_get_errors_fh();
|
||||||
|
|
||||||
|
print "Session $session->{client} had errors, will save them in $self->{errors_file}\n";
|
||||||
|
|
||||||
|
my $raw_packets = delete $session->{raw_packets};
|
||||||
|
$session->{reason_for_failure} = $reason;
|
||||||
|
my $session_dump = '# ' . Dumper($session);
|
||||||
|
chomp $session_dump;
|
||||||
|
$session_dump =~ s/\n/\n# /g;
|
||||||
|
print $errors_fh join("\n", $session_dump, @$raw_packets), "\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -285,16 +285,9 @@ test_protocol_parser(
|
|||||||
# #############################################################################
|
# #############################################################################
|
||||||
# Check the individual packet parsing subs.
|
# Check the individual packet parsing subs.
|
||||||
# #############################################################################
|
# #############################################################################
|
||||||
MySQLProtocolParser->import(qw(
|
|
||||||
parse_error_packet
|
|
||||||
parse_ok_packet
|
|
||||||
parse_server_handshake_packet
|
|
||||||
parse_client_handshake_packet
|
|
||||||
parse_com_packet
|
|
||||||
));
|
|
||||||
|
|
||||||
is_deeply(
|
is_deeply(
|
||||||
parse_error_packet(load_data("t/lib/samples/mysql_proto_001.txt")),
|
MySQLProtocolParser::parse_error_packet(load_data("t/lib/samples/mysql_proto_001.txt")),
|
||||||
{
|
{
|
||||||
errno => '1046',
|
errno => '1046',
|
||||||
sqlstate => '#3D000',
|
sqlstate => '#3D000',
|
||||||
@@ -304,7 +297,7 @@ is_deeply(
|
|||||||
);
|
);
|
||||||
|
|
||||||
is_deeply(
|
is_deeply(
|
||||||
parse_ok_packet('010002000100'),
|
MySQLProtocolParser::parse_ok_packet('010002000100'),
|
||||||
{
|
{
|
||||||
affected_rows => 1,
|
affected_rows => 1,
|
||||||
insert_id => 0,
|
insert_id => 0,
|
||||||
@@ -316,7 +309,7 @@ is_deeply(
|
|||||||
);
|
);
|
||||||
|
|
||||||
is_deeply(
|
is_deeply(
|
||||||
parse_server_handshake_packet(load_data("t/lib/samples/mysql_proto_002.txt")),
|
MySQLProtocolParser::parse_server_handshake_packet(load_data("t/lib/samples/mysql_proto_002.txt")),
|
||||||
{
|
{
|
||||||
thread_id => '9',
|
thread_id => '9',
|
||||||
server_version => '5.0.67-0ubuntu6-log',
|
server_version => '5.0.67-0ubuntu6-log',
|
||||||
@@ -345,7 +338,7 @@ is_deeply(
|
|||||||
);
|
);
|
||||||
|
|
||||||
is_deeply(
|
is_deeply(
|
||||||
parse_client_handshake_packet(load_data("t/lib/samples/mysql_proto_003.txt")),
|
MySQLProtocolParser::parse_client_handshake_packet(load_data("t/lib/samples/mysql_proto_003.txt")),
|
||||||
{
|
{
|
||||||
db => 'mysql',
|
db => 'mysql',
|
||||||
user => 'msandbox',
|
user => 'msandbox',
|
||||||
@@ -374,7 +367,7 @@ is_deeply(
|
|||||||
);
|
);
|
||||||
|
|
||||||
is_deeply(
|
is_deeply(
|
||||||
parse_com_packet('0373686f77207761726e696e67738d2dacbc', 14),
|
MySQLProtocolParser::parse_com_packet('0373686f77207761726e696e67738d2dacbc', 14),
|
||||||
{
|
{
|
||||||
code => '03',
|
code => '03',
|
||||||
com => 'COM_QUERY',
|
com => 'COM_QUERY',
|
||||||
@@ -1274,6 +1267,7 @@ test_protocol_parser(
|
|||||||
# Issue 761: mk-query-digest --tcpdump does not handle incomplete packets
|
# Issue 761: mk-query-digest --tcpdump does not handle incomplete packets
|
||||||
# #############################################################################
|
# #############################################################################
|
||||||
$protocol = new MySQLProtocolParser(server=>'127.0.0.1',port=>'3306');
|
$protocol = new MySQLProtocolParser(server=>'127.0.0.1',port=>'3306');
|
||||||
|
$protocol->{_no_save_error} = 1;
|
||||||
test_protocol_parser(
|
test_protocol_parser(
|
||||||
parser => $tcpdump,
|
parser => $tcpdump,
|
||||||
protocol => $protocol,
|
protocol => $protocol,
|
||||||
@@ -1449,6 +1443,7 @@ test_protocol_parser(
|
|||||||
);
|
);
|
||||||
|
|
||||||
$protocol = new MySQLProtocolParser();
|
$protocol = new MySQLProtocolParser();
|
||||||
|
$protocol->{_no_save_error} = 1;
|
||||||
test_protocol_parser(
|
test_protocol_parser(
|
||||||
parser => $tcpdump,
|
parser => $tcpdump,
|
||||||
protocol => $protocol,
|
protocol => $protocol,
|
||||||
@@ -1528,6 +1523,7 @@ test_protocol_parser(
|
|||||||
);
|
);
|
||||||
|
|
||||||
$protocol = new MySQLProtocolParser();
|
$protocol = new MySQLProtocolParser();
|
||||||
|
$protocol->{_no_save_error} = 1;
|
||||||
test_protocol_parser(
|
test_protocol_parser(
|
||||||
parser => $tcpdump,
|
parser => $tcpdump,
|
||||||
protocol => $protocol,
|
protocol => $protocol,
|
||||||
@@ -1576,6 +1572,7 @@ test_protocol_parser(
|
|||||||
# client query
|
# client query
|
||||||
# #############################################################################
|
# #############################################################################
|
||||||
$protocol = new MySQLProtocolParser(server => '127.0.0.1',port=>'12345');
|
$protocol = new MySQLProtocolParser(server => '127.0.0.1',port=>'12345');
|
||||||
|
$protocol->{_no_save_error} = 1;
|
||||||
$e = test_protocol_parser(
|
$e = test_protocol_parser(
|
||||||
parser => $tcpdump,
|
parser => $tcpdump,
|
||||||
protocol => $protocol,
|
protocol => $protocol,
|
||||||
@@ -1595,6 +1592,7 @@ $protocol = new MySQLProtocolParser(
|
|||||||
server => '127.0.0.1',
|
server => '127.0.0.1',
|
||||||
port => '3306',
|
port => '3306',
|
||||||
);
|
);
|
||||||
|
$protocol->{_no_save_error} = 1;
|
||||||
test_protocol_parser(
|
test_protocol_parser(
|
||||||
parser => $tcpdump,
|
parser => $tcpdump,
|
||||||
protocol => $protocol,
|
protocol => $protocol,
|
||||||
@@ -1745,6 +1743,37 @@ test_protocol_parser(
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
# #############################################################################
|
||||||
|
# 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;
|
||||||
|
});
|
||||||
|
|
||||||
|
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"
|
||||||
|
);
|
||||||
|
|
||||||
# #############################################################################
|
# #############################################################################
|
||||||
# Done.
|
# Done.
|
||||||
# #############################################################################
|
# #############################################################################
|
||||||
|
Reference in New Issue
Block a user