diff --git a/bin/pt-upgrade b/bin/pt-upgrade index c0158bfb..9e43d4a1 100755 --- a/bin/pt-upgrade +++ b/bin/pt-upgrade @@ -5143,6 +5143,13 @@ has 'read_timeout' => ( default => 0, ); +has 'progress' => ( + is => 'ro', + isa => 'Maybe[Object]', + required => 0, + default => sub { return }, +); + has 'stats' => ( is => 'ro', @@ -5255,6 +5262,10 @@ sub next { ) { $self->stats->{queries_read}++; + if ( my $pr = $self->progress ) { + $pr->update($self->_parser_args->{tell}); + } + if ( ($event->{cmd} || '') ne 'Query' ) { PTDEBUG && _d('Skipping non-Query cmd'); $self->stats->{not_query}++; @@ -6170,6 +6181,13 @@ has 'dir' => ( required => 1, ); +has 'progress' => ( + is => 'ro', + isa => 'Maybe[Object]', + required => 0, + default => sub { return }, +); + has '_query_fh' => ( is => 'rw', isa => 'Maybe[FileHandle]', @@ -6261,6 +6279,10 @@ sub next { $results->{query} = $query; $results->{rows} = $rows; + + if ( my $pr = $self->progress ) { + $pr->update(sub { tell $_query_fh }); + } PTDEBUG && _d('Results:', Dumper($results)); return $results; @@ -9085,6 +9107,11 @@ sub main { # 2 DSN and LOGS $o->save_error('No log files specified; at least one is required.'); } + elsif ( @dsns < 2 ) { + # 1 DSN, LOGS, but no --save-results a 2nd DSN + $o->save_error('A DSN and at least one log file was specified, ' + . 'but a second DSN or --save-results must also be specified.'); + } foreach my $val ( keys %$report ) { if ( $val !~ m/^(?:hosts|logs|queries|stats)$/ ) { @@ -9255,7 +9282,8 @@ sub main { $progress = new Progress( jobsize => $jobsize, spec => $spec, - name => (@logs ? 'Reading logs' : 'Reading reference results'), + name => (@logs && $results_dir ? 'Saving results' + : 'Executing queries'), ); } @@ -9533,6 +9561,7 @@ sub compare_host_to_host { my $read_only = $args{read_only}; my $read_timeout = $args{read_timeout}; my $allowed_errors = $args{allowed_errors} || 0; + my $progress = $args{progress}; # Get set up to execute and compare queries. my $clear_warnings_sql = "SELECT * FROM $upgrade_table LIMIT 1 " @@ -9560,6 +9589,7 @@ sub compare_host_to_host { ($filter ? (filter => $filter) : ()), ($read_only ? (read_only => $read_only) : ()), ($read_timeout ? (read_timeout => $read_timeout) : ()), + ($progress ? (progress => $progress) : ()), ); my $executor = EventExecutor->new( @@ -9642,6 +9672,7 @@ sub save_results { my $read_only = $args{read_only}; my $read_timeout = $args{read_timeout}; my $allowed_errors = $args{allowed_errors} || 0; + my $progress = $args{progress}; # Get set up to execute queries and save the results. my $clear_warnings_sql = "SELECT * FROM $upgrade_table LIMIT 1 " @@ -9668,6 +9699,7 @@ sub save_results { ($filter ? (filter => $filter) : ()), ($read_only ? (read_only => $read_only) : ()), ($read_timeout ? (read_timeout => $read_timeout) : ()), + ($progress ? (progress => $progress) : ()), ); my $executor = EventExecutor->new( @@ -9740,6 +9772,7 @@ sub compare_results_to_host { my $database = $args{database}; my $ignore_warnings = $args{ignore_warnings}; my $allowed_errors = $args{allowed_errors} || 0; + my $progress = $args{progress}; my $clear_warnings_sql = "SELECT * FROM $upgrade_table LIMIT 1 " . "/* pt-upgrade clear warnings */"; @@ -9754,7 +9787,8 @@ sub compare_results_to_host { # Results from host1, obtained earlier with --save-results. my $result_iter = ResultIterator->new( - dir => $results_dir, + dir => $results_dir, + progress => $progress, ); # Results for host2, obtaining now. diff --git a/lib/QueryIterator.pm b/lib/QueryIterator.pm index 1910e93f..33fd396f 100644 --- a/lib/QueryIterator.pm +++ b/lib/QueryIterator.pm @@ -82,6 +82,13 @@ has 'read_timeout' => ( default => 0, ); +has 'progress' => ( + is => 'ro', + isa => 'Maybe[Object]', + required => 0, + default => sub { return }, +); + ## # Private ## @@ -197,6 +204,10 @@ sub next { ) { $self->stats->{queries_read}++; + if ( my $pr = $self->progress ) { + $pr->update($self->_parser_args->{tell}); + } + if ( ($event->{cmd} || '') ne 'Query' ) { PTDEBUG && _d('Skipping non-Query cmd'); $self->stats->{not_query}++; diff --git a/lib/ResultIterator.pm b/lib/ResultIterator.pm index b67dd989..68d3ea0f 100644 --- a/lib/ResultIterator.pm +++ b/lib/ResultIterator.pm @@ -35,6 +35,13 @@ has 'dir' => ( required => 1, ); +has 'progress' => ( + is => 'ro', + isa => 'Maybe[Object]', + required => 0, + default => sub { return }, +); + has '_query_fh' => ( is => 'rw', isa => 'Maybe[FileHandle]', @@ -126,6 +133,10 @@ sub next { $results->{query} = $query; $results->{rows} = $rows; + + if ( my $pr = $self->progress ) { + $pr->update(sub { tell $_query_fh }); + } PTDEBUG && _d('Results:', Dumper($results)); return $results; diff --git a/t/pt-upgrade/run_time.t b/t/pt-upgrade/run_time.t new file mode 100644 index 00000000..9a68c21c --- /dev/null +++ b/t/pt-upgrade/run_time.t @@ -0,0 +1,80 @@ +#!/usr/bin/env 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 Time::HiRes qw(time); + +$ENV{PERCONA_TOOLKIT_TEST_USE_DSN_NAMES} = 1; + +use PerconaTest; +use Sandbox; +require "$trunk/bin/pt-upgrade"; + +# This runs immediately if the server is already running, else it starts it. +#diag(`$trunk/sandbox/start-sandbox master 12348 >/dev/null`); + +my $dp = new DSNParser(opts=>$dsn_opts); +my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); +my $dbh1 = $sb->get_dbh_for('host1'); +my $dbh2 = $sb->get_dbh_for('host2'); + +if ( !$dbh1 ) { + plan skip_all => 'Cannot connect to sandbox host1'; +} +elsif ( !$dbh2 ) { + plan skip_all => 'Cannot connect to sandbox host2'; +} + +my $host1_dsn = $sb->dsn_for('host1'); +my $host2_dsn = $sb->dsn_for('host2'); +my $samples = "$trunk/t/pt-upgrade/samples"; +my $exit_status = 0; +my $output; + +my $t0 = time; + +$output = output( + sub { + $exit_status = pt_upgrade::main($host1_dsn, $host2_dsn, + "$samples/slow_slow.log", qw(--run-time 3), + '--progress', 'time,1', + )}, + stderr => 1, +); + +my $t = time - $t0; + +ok( + $t >= 3 && $t <= 6, + "Ran for roughly --run-time seconds" +) or diag($output, 'Actual run time:', $t); + +# Exit status 8 = --run-time expired (an no other errors/problems) +is( + $exit_status, + 8, + "Exit status 8" +) or diag($output); + +like( + $output, + qr/Executing queries.+?remain/, + "--progress while executing queries" +); + +# ############################################################################# +# Done. +# ############################################################################# +#$sb->wipe_clean($dbh2); +$sb->wipe_clean($dbh1); +#diag(`$trunk/sandbox/stop-sandbox 12348 >/dev/null`); +#ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); +done_testing; diff --git a/t/pt-upgrade/samples/slow_slow.log b/t/pt-upgrade/samples/slow_slow.log new file mode 100644 index 00000000..c7d31bb7 --- /dev/null +++ b/t/pt-upgrade/samples/slow_slow.log @@ -0,0 +1,30 @@ +# User@Host: root[root] @ localhost [] +# Query_time: 1 Lock_time: 0 Rows_sent: 7 Rows_examined: 7 +select sleep(1); +# User@Host: root[root] @ localhost [] +# Query_time: 1 Lock_time: 0 Rows_sent: 7 Rows_examined: 7 +select sleep(1); +# User@Host: root[root] @ localhost [] +# Query_time: 1 Lock_time: 0 Rows_sent: 7 Rows_examined: 7 +select sleep(1); +# User@Host: root[root] @ localhost [] +# Query_time: 1 Lock_time: 0 Rows_sent: 7 Rows_examined: 7 +select sleep(1); +# User@Host: root[root] @ localhost [] +# Query_time: 1 Lock_time: 0 Rows_sent: 7 Rows_examined: 7 +select sleep(1); +# User@Host: root[root] @ localhost [] +# Query_time: 1 Lock_time: 0 Rows_sent: 7 Rows_examined: 7 +select sleep(1); +# User@Host: root[root] @ localhost [] +# Query_time: 1 Lock_time: 0 Rows_sent: 7 Rows_examined: 7 +select sleep(1); +# User@Host: root[root] @ localhost [] +# Query_time: 1 Lock_time: 0 Rows_sent: 7 Rows_examined: 7 +select sleep(1); +# User@Host: root[root] @ localhost [] +# Query_time: 1 Lock_time: 0 Rows_sent: 7 Rows_examined: 7 +select sleep(1); +# User@Host: root[root] @ localhost [] +# Query_time: 1 Lock_time: 0 Rows_sent: 7 Rows_examined: 7 +select sleep(1);