diff --git a/bin/pt-duplicate-key-checker b/bin/pt-duplicate-key-checker index 72aecbcd..beff3671 100755 --- a/bin/pt-duplicate-key-checker +++ b/bin/pt-duplicate-key-checker @@ -3443,7 +3443,14 @@ sub _iterate_dbh { && $self->_resume_from_table($tbl) && $self->table_is_allowed($self->{db}, $tbl); } - @{$dbh->selectall_arrayref($sql)}; + + eval { @{$dbh->selectall_arrayref($sql)}; }; + if ($EVAL_ERROR) { + warn "Skipping $self->{db}..."; + $self->{db} = undef; + next; + } + PTDEBUG && _d('Found', scalar @tbls, 'tables in database',$self->{db}); $self->{tbls} = \@tbls; } diff --git a/bin/pt-index-usage b/bin/pt-index-usage index 3cd45b1b..de937c0b 100755 --- a/bin/pt-index-usage +++ b/bin/pt-index-usage @@ -4221,7 +4221,14 @@ sub _iterate_dbh { && $self->_resume_from_table($tbl) && $self->table_is_allowed($self->{db}, $tbl); } - @{$dbh->selectall_arrayref($sql)}; + + eval { @{$dbh->selectall_arrayref($sql)}; }; + if ($EVAL_ERROR) { + warn "Skipping $self->{db}..."; + $self->{db} = undef; + next; + } + PTDEBUG && _d('Found', scalar @tbls, 'tables in database',$self->{db}); $self->{tbls} = \@tbls; } diff --git a/bin/pt-table-checksum b/bin/pt-table-checksum index 4e2f2a09..3048e2d6 100755 --- a/bin/pt-table-checksum +++ b/bin/pt-table-checksum @@ -7566,7 +7566,14 @@ sub _iterate_dbh { && $self->_resume_from_table($tbl) && $self->table_is_allowed($self->{db}, $tbl); } - @{$dbh->selectall_arrayref($sql)}; + + eval { @{$dbh->selectall_arrayref($sql)}; }; + if ($EVAL_ERROR) { + warn "Skipping $self->{db}..."; + $self->{db} = undef; + next; + } + PTDEBUG && _d('Found', scalar @tbls, 'tables in database',$self->{db}); $self->{tbls} = \@tbls; } diff --git a/bin/pt-table-sync b/bin/pt-table-sync index 91455e48..90a5f411 100755 --- a/bin/pt-table-sync +++ b/bin/pt-table-sync @@ -7777,7 +7777,14 @@ sub _iterate_dbh { && $self->_resume_from_table($tbl) && $self->table_is_allowed($self->{db}, $tbl); } - @{$dbh->selectall_arrayref($sql)}; + + eval { @{$dbh->selectall_arrayref($sql)}; }; + if ($EVAL_ERROR) { + warn "Skipping $self->{db}..."; + $self->{db} = undef; + next; + } + PTDEBUG && _d('Found', scalar @tbls, 'tables in database',$self->{db}); $self->{tbls} = \@tbls; } diff --git a/lib/SchemaIterator.pm b/lib/SchemaIterator.pm index 928ec4c6..923b894d 100644 --- a/lib/SchemaIterator.pm +++ b/lib/SchemaIterator.pm @@ -353,7 +353,14 @@ sub _iterate_dbh { && $self->_resume_from_table($tbl) && $self->table_is_allowed($self->{db}, $tbl); } - @{$dbh->selectall_arrayref($sql)}; + + eval { @{$dbh->selectall_arrayref($sql)}; }; + if ($EVAL_ERROR) { + warn "Skipping $self->{db}..."; + $self->{db} = undef; + next; + } + PTDEBUG && _d('Found', scalar @tbls, 'tables in database',$self->{db}); $self->{tbls} = \@tbls; } diff --git a/t/pt-table-checksum/pt-105.t b/t/pt-table-checksum/pt-105.t new file mode 100644 index 00000000..d52bd67d --- /dev/null +++ b/t/pt-table-checksum/pt-105.t @@ -0,0 +1,84 @@ +#!/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 PerconaTest; +use Sandbox; +use SqlModes; +use threads; +use Time::HiRes qw( usleep ); +use constant PTDEBUG => $ENV{PTDEBUG} || 0; + +require "$trunk/bin/pt-table-checksum"; + +my $dp = new DSNParser(opts=>$dsn_opts); +my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); +my $dbh = $sb->get_dbh_for('master'); + +if ( !$dbh ) { + plan skip_all => 'Cannot connect to sandbox master'; +} +else { + plan tests => 2; +} + +my $db_count = 100; + +sub start_thread { + my ($dsn_opts, $initial_sleep_time, $sleep_time, $db_count) = @_; + my $dp = new DSNParser(opts=>$dsn_opts); + my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); + my $dbh = $sb->get_dbh_for('master'); + PTDEBUG && diag("Thread started: Sleeping $initial_sleep_time milliseconds before start dropping DBs"); + usleep($initial_sleep_time ); + for (my $i=0; $i < $db_count; $i++) { + PTDEBUG && diag("Dropping drop_test_$i"); + $dbh->do("DROP DATABASE IF EXISTS drop_test_$i"); + usleep($sleep_time * 1000) + } + PTDEBUG && diag("Exit thread") +} +my $thr = threads->create('start_thread', $dsn_opts, 1000, 100, $db_count); +threads->yield(); + +sleep(3); +for (my $i=0; $i < $db_count; $i++) { + $dbh->do("DROP DATABASE IF EXISTS drop_test_$i"); + $dbh->do("CREATE SCHEMA drop_test_$i") +} + +# The sandbox servers run with lock_wait_timeout=3 and it's not dynamic +# so we need to specify --set-vars innodb_lock_wait_timeout=3 else the tool will die. +# And --max-load "" prevents waiting for status variables. +my $master_dsn = 'h=127.1,P=12345,u=msandbox,p=msandbox'; +my @args = ($master_dsn, qw(--no-check-binlog-format)); +my $output; + +$output = output( + sub { pt_table_checksum::main(@args) }, + stderr => 1, +); + +unlike( + $output, + qr/db selectall_arrayref failed/, + "Dropping tables while checksum is running" +); + +$thr->join(); + +# ############################################################################# +# Done. +# ############################################################################# +$sb->wipe_clean($dbh); +ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); +exit;