diff --git a/bin/pt-kill b/bin/pt-kill index a04fc502..e662657c 100755 --- a/bin/pt-kill +++ b/bin/pt-kill @@ -3458,14 +3458,9 @@ sub main { unless $o->got('interval'); } - if ( !-t STDIN ) { - PTDEBUG && _d("STDIN is piped"); - @ARGV = ('-'); - } - # Disable opts that don't make sense when reading proclist # from a file (or STDIN). - if ( @ARGV ) { + if ( $o->get('test-matching') ) { $o->set('run-time', 0); $o->set('interval', 0); $o->set('ignore-self', 0); @@ -3502,13 +3497,14 @@ sub main { my $dbh; my $kill_sth; my $get_proclist; - if ( @ARGV ) { - PTDEBUG && _d('Getting processlist from files:', @ARGV); + my $files; + if ( $files = $o->get('test-matching') ) { + PTDEBUG && _d('Getting processlist from files:', @$files); my $trp = new TextResultSetParser(); my $fh; $get_proclist = sub { if ( !$fh ) { - my $file = shift @ARGV; + my $file = shift @$files; die 'No more files' unless $file; if ( $file eq '-' ) { $fh = *STDIN; @@ -3570,7 +3566,7 @@ sub main { # ######################################################################## msg("$PROGRAM_NAME starting"); msg($dbh ? "Connected to host " . $dp->as_string($dsn) - : "Reading files @ARGV"); + : "Test matching files @$files"); # Class-based match criteria. my $query_count = $o->get('query-count'); @@ -3874,7 +3870,7 @@ pt-kill - Kill MySQL queries that match certain criteria. =head1 SYNOPSIS -Usage: pt-kill [OPTION]... [FILE...] +Usage: pt-kill [OPTIONS] pt-kill kills MySQL connections. pt-kill connects to MySQL and gets queries from SHOW PROCESSLIST if no FILE is given. Else, it reads queries from one @@ -3899,7 +3895,8 @@ Print all login processes: See which queries in the processlist right now would match: - mysql -e "SHOW PROCESSLIST" | pt-kill --busy-time 60 --print + mysql -e "SHOW PROCESSLIST" > proclist.txt + pt-kill --test-matching proclist.txt --busy-time 60 --print =head1 RISKS @@ -4012,8 +4009,7 @@ L<"--any-busy-time"> and L<"--each-busy-time"> are mutually exclusive. L<"--kill"> and L<"--kill-query"> are mutually exclusive. -This tool accepts additional command-line arguments. Refer to the -L<"SYNOPSIS"> and usage information for details. +L<"--daemonize"> and L<"--test-matching"> are mutually exclusive. =over @@ -4418,6 +4414,17 @@ By default, matches do not apply to replication threads; i.e. replication threads are completely ignored. Specifying this option allows matches to match (and potentially kill) replication threads on masters and slaves. +=item --test-matching + +type: array; group: Query Matches + +Files with processlist snapshots to test matching options against. Since +the matching options can be complex, you can save snapshots of processlist +in files, then test matching options against queries in those files. + +This option disables L<"--run-time">, L<"--interval">, +and L<"--[no]ignore-self">. + =back =head2 CLASS MATCHES diff --git a/t/pt-kill/basics.t b/t/pt-kill/basics.t index 918bef1a..ed9d42b9 100644 --- a/t/pt-kill/basics.t +++ b/t/pt-kill/basics.t @@ -23,7 +23,7 @@ if ( !$master_dbh ) { plan skip_all => 'Cannot connect to sandbox master'; } else { - plan tests => 4; + plan tests => 3; } my $output; @@ -72,16 +72,6 @@ like( '--verbose' ); -# ############################################################################ -# Reading file (or STDIN) should require connection. -# ############################################################################ -$output = `/tmp/12345/use -e "SHOW PROCESSLIST" | $trunk/bin/pt-kill -F $cnf --busy-time 1 --print --verbose`; -like( - $output, - qr/Reading files -/, - "Read STDIN from pipe" -); - # ############################################################################# # Done. # ############################################################################# diff --git a/t/pt-kill/execute_command.t b/t/pt-kill/execute_command.t index fb6fc468..1ae8c348 100644 --- a/t/pt-kill/execute_command.t +++ b/t/pt-kill/execute_command.t @@ -29,7 +29,7 @@ my $out = "/tmp/mk-kill-test.txt"; # ############################################################################# diag(`rm $out 2>/dev/null`); -$output = `$cmd $trunk/t/lib/samples/pl/recset001.txt --match-command Query --execute-command 'echo hello > $out'`; +$output = `$cmd --test-matching $trunk/t/lib/samples/pl/recset001.txt --match-command Query --execute-command 'echo hello > $out'`; is( $output, '', diff --git a/t/pt-kill/group_by.t b/t/pt-kill/group_by.t index 81bdafb4..228c2219 100644 --- a/t/pt-kill/group_by.t +++ b/t/pt-kill/group_by.t @@ -16,6 +16,7 @@ use Sandbox; require "$trunk/bin/pt-kill"; my $sample = "$trunk/t/lib/samples/pl/"; +my @args = qw(--test-matching); my $output; # ############################################################################# @@ -25,7 +26,7 @@ my $output; # The 3rd query (id 4) is user=root. Next we'll test that we can filter # that one out. $output = output( - sub { pt_kill::main("$sample/recset010.txt", qw(--print), + sub { pt_kill::main(@args, "$sample/recset010.txt", qw(--group-by info --query-count 2 --each-busy-time 2 --match-all), qw(--victims all-but-oldest --print)); } ); @@ -37,7 +38,7 @@ like( # Now with --match-user user1, the 3rd query is not matched. $output = output( - sub { pt_kill::main("$sample/recset010.txt", qw(--print), + sub { pt_kill::main(@args, "$sample/recset010.txt", qw(--group-by info --query-count 2 --each-busy-time 2 --match-user user1), qw(--victims all-but-oldest --print)); } ); @@ -52,7 +53,7 @@ like( # 9, but the 10 does. This is correct (see issue 1221) because --victims # is applied *after* per-class query matching. $output = output( - sub { pt_kill::main("$sample/recset010.txt", qw(--print), + sub { pt_kill::main(@args, "$sample/recset010.txt", qw(--group-by info --query-count 2 --any-busy-time 10 --match-user user1), qw(--victims oldest --print)); } ); @@ -63,7 +64,7 @@ is( ); $output = output( - sub { pt_kill::main("$sample/recset010.txt", qw(--print), + sub { pt_kill::main(@args, "$sample/recset010.txt", qw(--group-by info --query-count 2 --any-busy-time 9 --match-user user1), qw(--victims oldest --print)); } ); @@ -75,7 +76,7 @@ like( # Nothing matches because --each-busy-time isn't satifised. $output = output( - sub { pt_kill::main("$sample/recset010.txt", qw(--print), + sub { pt_kill::main(@args, "$sample/recset010.txt", qw(--group-by info --query-count 2 --each-busy-time 10 --match-user user1), qw(--victims all-but-oldest --print)); } ); @@ -87,7 +88,7 @@ is( # Each busy time matches on the lowest possible value. $output = output( - sub { pt_kill::main("$sample/recset010.txt", qw(--print), + sub { pt_kill::main(@args, "$sample/recset010.txt", qw(--group-by info --query-count 2 --each-busy-time 8 --match-user user1), qw(--victims all-but-oldest --print)); } ); @@ -99,7 +100,7 @@ like( # Nothing matches because --query-count isn't satisified. $output = output( - sub { pt_kill::main("$sample/recset010.txt", qw(--print), + sub { pt_kill::main(@args, "$sample/recset010.txt", qw(--group-by info --query-count 4 --each-busy-time 1 --match-user user1), qw(--victims all-but-oldest --print)); } ); @@ -111,7 +112,7 @@ is( # Without stripping comments, the queries won't be grouped into a class. $output = output( - sub { pt_kill::main("$sample/recset010.txt", qw(--print), + sub { pt_kill::main(@args, "$sample/recset010.txt", qw(--group-by info --query-count 2 --each-busy-time 2 --match-user user1), qw(--victims all-but-oldest --print --no-strip-comments)); } ); diff --git a/t/pt-kill/match.t b/t/pt-kill/match.t index 7b362389..de414c26 100644 --- a/t/pt-kill/match.t +++ b/t/pt-kill/match.t @@ -18,13 +18,14 @@ my $dp = new DSNParser(opts=>$dsn_opts); my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); my $slave_dbh = $sb->get_dbh_for('slave1'); +my @args = qw(--test-matching); my $output; # ############################################################################# # Test match commands. # ############################################################################# $output = output( - sub { pt_kill::main("$trunk/t/lib/samples/pl/recset001.txt", qw(--match-info show --print)); } + sub { pt_kill::main(@args, "$trunk/t/lib/samples/pl/recset001.txt", qw(--match-info show --print)); } ); like( $output, @@ -33,7 +34,7 @@ like( ); $output = output( - sub { pt_kill::main("$trunk/t/lib/samples/pl/recset002.txt", qw(--match-command Query --print)); } + sub { pt_kill::main(@args, "$trunk/t/lib/samples/pl/recset002.txt", qw(--match-command Query --print)); } ); is( $output, @@ -42,7 +43,7 @@ is( ); $output = output( - sub { pt_kill::main("$trunk/t/lib/samples/pl/recset002.txt", qw(--match-command Query --ignore-state), "''", "--print"); } + sub { pt_kill::main(@args, "$trunk/t/lib/samples/pl/recset002.txt", qw(--match-command Query --ignore-state), "''", "--print"); } ); like( $output, @@ -51,7 +52,7 @@ like( ); $output = output( - sub { pt_kill::main("$trunk/t/lib/samples/pl/recset003.txt", "--match-state", "Sorting result", "--print"); } + sub { pt_kill::main(@args, "$trunk/t/lib/samples/pl/recset003.txt", "--match-state", "Sorting result", "--print"); } ); like( $output, @@ -60,7 +61,7 @@ like( ); $output = output( - sub { pt_kill::main("$trunk/t/lib/samples/pl/recset003.txt", qw(--match-state Updating --print --victims all)); } + sub { pt_kill::main(@args, "$trunk/t/lib/samples/pl/recset003.txt", qw(--match-state Updating --print --victims all)); } ); like( $output, @@ -69,7 +70,7 @@ like( ); $output = output( - sub { pt_kill::main("$trunk/t/lib/samples/pl/recset003.txt", qw(--ignore-user remote --match-command Query --print)); } + sub { pt_kill::main(@args, "$trunk/t/lib/samples/pl/recset003.txt", qw(--ignore-user remote --match-command Query --print)); } ); like( $output, @@ -78,7 +79,7 @@ like( ); $output = output( - sub { pt_kill::main("$trunk/t/lib/samples/pl/recset004.txt", qw(--busy-time 25 --print)); } + sub { pt_kill::main(@args, "$trunk/t/lib/samples/pl/recset004.txt", qw(--busy-time 25 --print)); } ); like( $output, @@ -87,7 +88,7 @@ like( ); $output = output( - sub { pt_kill::main("$trunk/t/lib/samples/pl/recset004.txt", qw(--busy-time 30 --print)); } + sub { pt_kill::main(@args, "$trunk/t/lib/samples/pl/recset004.txt", qw(--busy-time 30 --print)); } ); is( $output, @@ -96,7 +97,7 @@ is( ); $output = output( - sub { pt_kill::main("$trunk/t/lib/samples/pl/recset005.txt", qw(--idle-time 15 --print)); } + sub { pt_kill::main(@args, "$trunk/t/lib/samples/pl/recset005.txt", qw(--idle-time 15 --print)); } ); like( $output, @@ -105,7 +106,7 @@ like( ); $output = output( - sub { pt_kill::main("$trunk/t/lib/samples/pl/recset006.txt", qw(--match-state Locked --ignore-state), "''", qw(--busy-time 5 --print)); } + sub { pt_kill::main(@args, "$trunk/t/lib/samples/pl/recset006.txt", qw(--match-state Locked --ignore-state), "''", qw(--busy-time 5 --print)); } ); like( $output, @@ -116,7 +117,7 @@ like( # The queries in recset002 are both State: Locked which is ignored # by default so nothing should match, not even for --match-all. $output = output( - sub { pt_kill::main("$trunk/t/lib/samples/pl/recset002.txt", + sub { pt_kill::main(@args, "$trunk/t/lib/samples/pl/recset002.txt", qw(--match-all --print)); } ); is( @@ -127,7 +128,7 @@ is( # Now --match-all should match. $output = output( - sub { pt_kill::main("$trunk/t/lib/samples/pl/recset002.txt", + sub { pt_kill::main(@args, "$trunk/t/lib/samples/pl/recset002.txt", qw(--match-all --victims all --print --ignore-state blahblah)); } ); like( diff --git a/t/pt-kill/standard_options.t b/t/pt-kill/standard_options.t index 76ce4f1f..f22871e2 100644 --- a/t/pt-kill/standard_options.t +++ b/t/pt-kill/standard_options.t @@ -61,7 +61,7 @@ SKIP: { # Issue 391: Add --pid option to all scripts # ######################################################################### `touch /tmp/pt-script.pid`; -$output = `$cmd $trunk/t/lib/samples/pl/recset006.txt --match-state Locked --print --pid /tmp/pt-script.pid 2>&1`; +$output = `$cmd --test-matching $trunk/t/lib/samples/pl/recset006.txt --match-state Locked --print --pid /tmp/pt-script.pid 2>&1`; like( $output, qr{PID file /tmp/pt-script.pid already exists},