mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-10 13:11:32 +00:00
Merged fix-1047335-crashed-tables
This commit is contained in:
@@ -1583,13 +1583,11 @@ sub get_create_table {
|
|||||||
PTDEBUG && _d($show_sql);
|
PTDEBUG && _d($show_sql);
|
||||||
my $href;
|
my $href;
|
||||||
eval { $href = $dbh->selectrow_hashref($show_sql); };
|
eval { $href = $dbh->selectrow_hashref($show_sql); };
|
||||||
if ( $EVAL_ERROR ) {
|
if ( my $e = $EVAL_ERROR ) {
|
||||||
PTDEBUG && _d($EVAL_ERROR);
|
|
||||||
|
|
||||||
PTDEBUG && _d($old_sql_mode);
|
PTDEBUG && _d($old_sql_mode);
|
||||||
$dbh->do($old_sql_mode);
|
$dbh->do($old_sql_mode);
|
||||||
|
|
||||||
return;
|
die $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
PTDEBUG && _d($old_sql_mode);
|
PTDEBUG && _d($old_sql_mode);
|
||||||
|
@@ -227,13 +227,11 @@ sub get_create_table {
|
|||||||
PTDEBUG && _d($show_sql);
|
PTDEBUG && _d($show_sql);
|
||||||
my $href;
|
my $href;
|
||||||
eval { $href = $dbh->selectrow_hashref($show_sql); };
|
eval { $href = $dbh->selectrow_hashref($show_sql); };
|
||||||
if ( $EVAL_ERROR ) {
|
if ( my $e = $EVAL_ERROR ) {
|
||||||
PTDEBUG && _d($EVAL_ERROR);
|
|
||||||
|
|
||||||
PTDEBUG && _d($old_sql_mode);
|
PTDEBUG && _d($old_sql_mode);
|
||||||
$dbh->do($old_sql_mode);
|
$dbh->do($old_sql_mode);
|
||||||
|
|
||||||
return;
|
die $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
PTDEBUG && _d($old_sql_mode);
|
PTDEBUG && _d($old_sql_mode);
|
||||||
@@ -3152,7 +3150,17 @@ sub _iterate_dbh {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while ( my $tbl = shift @{$self->{tbls}} ) {
|
while ( my $tbl = shift @{$self->{tbls}} ) {
|
||||||
my $ddl = $tp->get_create_table($dbh, $self->{db}, $tbl);
|
my $ddl = eval { $tp->get_create_table($dbh, $self->{db}, $tbl) };
|
||||||
|
if ( my $e = $EVAL_ERROR ) {
|
||||||
|
my $table_name = "$self->{db}.$tbl";
|
||||||
|
if ( $e =~ /\QTable '$table_name' doesn't exist/ ) {
|
||||||
|
PTDEBUG && _d("Skipping $table_name because it no longer exists");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
warn "Skipping $table_name because SHOW CREATE TABLE failed: $e";
|
||||||
|
}
|
||||||
|
next;
|
||||||
|
}
|
||||||
my $tbl_struct = $tp->parse($ddl);
|
my $tbl_struct = $tp->parse($ddl);
|
||||||
if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {
|
if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {
|
||||||
return {
|
return {
|
||||||
|
@@ -1625,13 +1625,11 @@ sub get_create_table {
|
|||||||
PTDEBUG && _d($show_sql);
|
PTDEBUG && _d($show_sql);
|
||||||
my $href;
|
my $href;
|
||||||
eval { $href = $dbh->selectrow_hashref($show_sql); };
|
eval { $href = $dbh->selectrow_hashref($show_sql); };
|
||||||
if ( $EVAL_ERROR ) {
|
if ( my $e = $EVAL_ERROR ) {
|
||||||
PTDEBUG && _d($EVAL_ERROR);
|
|
||||||
|
|
||||||
PTDEBUG && _d($old_sql_mode);
|
PTDEBUG && _d($old_sql_mode);
|
||||||
$dbh->do($old_sql_mode);
|
$dbh->do($old_sql_mode);
|
||||||
|
|
||||||
return;
|
die $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
PTDEBUG && _d($old_sql_mode);
|
PTDEBUG && _d($old_sql_mode);
|
||||||
|
@@ -2563,13 +2563,11 @@ sub get_create_table {
|
|||||||
PTDEBUG && _d($show_sql);
|
PTDEBUG && _d($show_sql);
|
||||||
my $href;
|
my $href;
|
||||||
eval { $href = $dbh->selectrow_hashref($show_sql); };
|
eval { $href = $dbh->selectrow_hashref($show_sql); };
|
||||||
if ( $EVAL_ERROR ) {
|
if ( my $e = $EVAL_ERROR ) {
|
||||||
PTDEBUG && _d($EVAL_ERROR);
|
|
||||||
|
|
||||||
PTDEBUG && _d($old_sql_mode);
|
PTDEBUG && _d($old_sql_mode);
|
||||||
$dbh->do($old_sql_mode);
|
$dbh->do($old_sql_mode);
|
||||||
|
|
||||||
return;
|
die $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
PTDEBUG && _d($old_sql_mode);
|
PTDEBUG && _d($old_sql_mode);
|
||||||
|
@@ -2823,13 +2823,11 @@ sub get_create_table {
|
|||||||
PTDEBUG && _d($show_sql);
|
PTDEBUG && _d($show_sql);
|
||||||
my $href;
|
my $href;
|
||||||
eval { $href = $dbh->selectrow_hashref($show_sql); };
|
eval { $href = $dbh->selectrow_hashref($show_sql); };
|
||||||
if ( $EVAL_ERROR ) {
|
if ( my $e = $EVAL_ERROR ) {
|
||||||
PTDEBUG && _d($EVAL_ERROR);
|
|
||||||
|
|
||||||
PTDEBUG && _d($old_sql_mode);
|
PTDEBUG && _d($old_sql_mode);
|
||||||
$dbh->do($old_sql_mode);
|
$dbh->do($old_sql_mode);
|
||||||
|
|
||||||
return;
|
die $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
PTDEBUG && _d($old_sql_mode);
|
PTDEBUG && _d($old_sql_mode);
|
||||||
@@ -3970,7 +3968,17 @@ sub _iterate_dbh {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while ( my $tbl = shift @{$self->{tbls}} ) {
|
while ( my $tbl = shift @{$self->{tbls}} ) {
|
||||||
my $ddl = $tp->get_create_table($dbh, $self->{db}, $tbl);
|
my $ddl = eval { $tp->get_create_table($dbh, $self->{db}, $tbl) };
|
||||||
|
if ( my $e = $EVAL_ERROR ) {
|
||||||
|
my $table_name = "$self->{db}.$tbl";
|
||||||
|
if ( $e =~ /\QTable '$table_name' doesn't exist/ ) {
|
||||||
|
PTDEBUG && _d("Skipping $table_name because it no longer exists");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
warn "Skipping $table_name because SHOW CREATE TABLE failed: $e";
|
||||||
|
}
|
||||||
|
next;
|
||||||
|
}
|
||||||
my $tbl_struct = $tp->parse($ddl);
|
my $tbl_struct = $tp->parse($ddl);
|
||||||
if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {
|
if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {
|
||||||
return {
|
return {
|
||||||
|
@@ -2514,13 +2514,11 @@ sub get_create_table {
|
|||||||
PTDEBUG && _d($show_sql);
|
PTDEBUG && _d($show_sql);
|
||||||
my $href;
|
my $href;
|
||||||
eval { $href = $dbh->selectrow_hashref($show_sql); };
|
eval { $href = $dbh->selectrow_hashref($show_sql); };
|
||||||
if ( $EVAL_ERROR ) {
|
if ( my $e = $EVAL_ERROR ) {
|
||||||
PTDEBUG && _d($EVAL_ERROR);
|
|
||||||
|
|
||||||
PTDEBUG && _d($old_sql_mode);
|
PTDEBUG && _d($old_sql_mode);
|
||||||
$dbh->do($old_sql_mode);
|
$dbh->do($old_sql_mode);
|
||||||
|
|
||||||
return;
|
die $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
PTDEBUG && _d($old_sql_mode);
|
PTDEBUG && _d($old_sql_mode);
|
||||||
|
@@ -3108,13 +3108,11 @@ sub get_create_table {
|
|||||||
PTDEBUG && _d($show_sql);
|
PTDEBUG && _d($show_sql);
|
||||||
my $href;
|
my $href;
|
||||||
eval { $href = $dbh->selectrow_hashref($show_sql); };
|
eval { $href = $dbh->selectrow_hashref($show_sql); };
|
||||||
if ( $EVAL_ERROR ) {
|
if ( my $e = $EVAL_ERROR ) {
|
||||||
PTDEBUG && _d($EVAL_ERROR);
|
|
||||||
|
|
||||||
PTDEBUG && _d($old_sql_mode);
|
PTDEBUG && _d($old_sql_mode);
|
||||||
$dbh->do($old_sql_mode);
|
$dbh->do($old_sql_mode);
|
||||||
|
|
||||||
return;
|
die $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
PTDEBUG && _d($old_sql_mode);
|
PTDEBUG && _d($old_sql_mode);
|
||||||
|
@@ -5325,13 +5325,11 @@ sub get_create_table {
|
|||||||
PTDEBUG && _d($show_sql);
|
PTDEBUG && _d($show_sql);
|
||||||
my $href;
|
my $href;
|
||||||
eval { $href = $dbh->selectrow_hashref($show_sql); };
|
eval { $href = $dbh->selectrow_hashref($show_sql); };
|
||||||
if ( $EVAL_ERROR ) {
|
if ( my $e = $EVAL_ERROR ) {
|
||||||
PTDEBUG && _d($EVAL_ERROR);
|
|
||||||
|
|
||||||
PTDEBUG && _d($old_sql_mode);
|
PTDEBUG && _d($old_sql_mode);
|
||||||
$dbh->do($old_sql_mode);
|
$dbh->do($old_sql_mode);
|
||||||
|
|
||||||
return;
|
die $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
PTDEBUG && _d($old_sql_mode);
|
PTDEBUG && _d($old_sql_mode);
|
||||||
|
@@ -8142,13 +8142,11 @@ sub get_create_table {
|
|||||||
PTDEBUG && _d($show_sql);
|
PTDEBUG && _d($show_sql);
|
||||||
my $href;
|
my $href;
|
||||||
eval { $href = $dbh->selectrow_hashref($show_sql); };
|
eval { $href = $dbh->selectrow_hashref($show_sql); };
|
||||||
if ( $EVAL_ERROR ) {
|
if ( my $e = $EVAL_ERROR ) {
|
||||||
PTDEBUG && _d($EVAL_ERROR);
|
|
||||||
|
|
||||||
PTDEBUG && _d($old_sql_mode);
|
PTDEBUG && _d($old_sql_mode);
|
||||||
$dbh->do($old_sql_mode);
|
$dbh->do($old_sql_mode);
|
||||||
|
|
||||||
return;
|
die $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
PTDEBUG && _d($old_sql_mode);
|
PTDEBUG && _d($old_sql_mode);
|
||||||
|
@@ -3758,13 +3758,11 @@ sub get_create_table {
|
|||||||
PTDEBUG && _d($show_sql);
|
PTDEBUG && _d($show_sql);
|
||||||
my $href;
|
my $href;
|
||||||
eval { $href = $dbh->selectrow_hashref($show_sql); };
|
eval { $href = $dbh->selectrow_hashref($show_sql); };
|
||||||
if ( $EVAL_ERROR ) {
|
if ( my $e = $EVAL_ERROR ) {
|
||||||
PTDEBUG && _d($EVAL_ERROR);
|
|
||||||
|
|
||||||
PTDEBUG && _d($old_sql_mode);
|
PTDEBUG && _d($old_sql_mode);
|
||||||
$dbh->do($old_sql_mode);
|
$dbh->do($old_sql_mode);
|
||||||
|
|
||||||
return;
|
die $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
PTDEBUG && _d($old_sql_mode);
|
PTDEBUG && _d($old_sql_mode);
|
||||||
@@ -6830,7 +6828,17 @@ sub _iterate_dbh {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while ( my $tbl = shift @{$self->{tbls}} ) {
|
while ( my $tbl = shift @{$self->{tbls}} ) {
|
||||||
my $ddl = $tp->get_create_table($dbh, $self->{db}, $tbl);
|
my $ddl = eval { $tp->get_create_table($dbh, $self->{db}, $tbl) };
|
||||||
|
if ( my $e = $EVAL_ERROR ) {
|
||||||
|
my $table_name = "$self->{db}.$tbl";
|
||||||
|
if ( $e =~ /\QTable '$table_name' doesn't exist/ ) {
|
||||||
|
PTDEBUG && _d("Skipping $table_name because it no longer exists");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
warn "Skipping $table_name because SHOW CREATE TABLE failed: $e";
|
||||||
|
}
|
||||||
|
next;
|
||||||
|
}
|
||||||
my $tbl_struct = $tp->parse($ddl);
|
my $tbl_struct = $tp->parse($ddl);
|
||||||
if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {
|
if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {
|
||||||
return {
|
return {
|
||||||
|
@@ -3002,7 +3002,7 @@ sub dump {
|
|||||||
my ( $self, $dbh, $quoter, $db, $tbl, $what ) = @_;
|
my ( $self, $dbh, $quoter, $db, $tbl, $what ) = @_;
|
||||||
|
|
||||||
if ( $what eq 'table' ) {
|
if ( $what eq 'table' ) {
|
||||||
my $ddl = $self->get_create_table($dbh, $quoter, $db, $tbl);
|
my $ddl = $self->get_create_table($dbh, $dbh, $db, $tbl);
|
||||||
return unless $ddl;
|
return unless $ddl;
|
||||||
if ( $ddl->[0] eq 'table' ) {
|
if ( $ddl->[0] eq 'table' ) {
|
||||||
return $before
|
return $before
|
||||||
@@ -3045,7 +3045,7 @@ sub dump {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
elsif ( $what eq 'view' ) {
|
elsif ( $what eq 'view' ) {
|
||||||
my $ddl = $self->get_create_table($dbh, $quoter, $db, $tbl);
|
my $ddl = $self->get_create_table($dbh, $dbh, $db, $tbl);
|
||||||
return '/*!50001 DROP TABLE IF EXISTS ' . $quoter->quote($tbl) . "*/;\n"
|
return '/*!50001 DROP TABLE IF EXISTS ' . $quoter->quote($tbl) . "*/;\n"
|
||||||
. '/*!50001 DROP VIEW IF EXISTS ' . $quoter->quote($tbl) . "*/;\n"
|
. '/*!50001 DROP VIEW IF EXISTS ' . $quoter->quote($tbl) . "*/;\n"
|
||||||
. '/*!50001 ' . $ddl->[1] . "*/;\n";
|
. '/*!50001 ' . $ddl->[1] . "*/;\n";
|
||||||
|
@@ -503,13 +503,11 @@ sub get_create_table {
|
|||||||
PTDEBUG && _d($show_sql);
|
PTDEBUG && _d($show_sql);
|
||||||
my $href;
|
my $href;
|
||||||
eval { $href = $dbh->selectrow_hashref($show_sql); };
|
eval { $href = $dbh->selectrow_hashref($show_sql); };
|
||||||
if ( $EVAL_ERROR ) {
|
if ( my $e = $EVAL_ERROR ) {
|
||||||
PTDEBUG && _d($EVAL_ERROR);
|
|
||||||
|
|
||||||
PTDEBUG && _d($old_sql_mode);
|
PTDEBUG && _d($old_sql_mode);
|
||||||
$dbh->do($old_sql_mode);
|
$dbh->do($old_sql_mode);
|
||||||
|
|
||||||
return;
|
die $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
PTDEBUG && _d($old_sql_mode);
|
PTDEBUG && _d($old_sql_mode);
|
||||||
|
@@ -352,7 +352,21 @@ sub _iterate_dbh {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while ( my $tbl = shift @{$self->{tbls}} ) {
|
while ( my $tbl = shift @{$self->{tbls}} ) {
|
||||||
my $ddl = $tp->get_create_table($dbh, $self->{db}, $tbl);
|
my $ddl = eval { $tp->get_create_table($dbh, $self->{db}, $tbl) };
|
||||||
|
if ( my $e = $EVAL_ERROR ) {
|
||||||
|
my $table_name = "$self->{db}.$tbl";
|
||||||
|
# SHOW CREATE TABLE failed. This is a bit puzzling;
|
||||||
|
# maybe the table got dropped, or crashed. Not much we can
|
||||||
|
# do about it; If the table is missing, just PTDEBUG it, but
|
||||||
|
# otherwise, warn with the error.
|
||||||
|
if ( $e =~ /\QTable '$table_name' doesn't exist/ ) {
|
||||||
|
PTDEBUG && _d("Skipping $table_name because it no longer exists");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
warn "Skipping $table_name because SHOW CREATE TABLE failed: $e";
|
||||||
|
}
|
||||||
|
next;
|
||||||
|
}
|
||||||
my $tbl_struct = $tp->parse($ddl);
|
my $tbl_struct = $tp->parse($ddl);
|
||||||
if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {
|
if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {
|
||||||
return {
|
return {
|
||||||
|
@@ -91,18 +91,12 @@ sub get_create_table {
|
|||||||
PTDEBUG && _d($show_sql);
|
PTDEBUG && _d($show_sql);
|
||||||
my $href;
|
my $href;
|
||||||
eval { $href = $dbh->selectrow_hashref($show_sql); };
|
eval { $href = $dbh->selectrow_hashref($show_sql); };
|
||||||
if ( $EVAL_ERROR ) {
|
if ( my $e = $EVAL_ERROR ) {
|
||||||
# TODO: I think we fail silently for tools which may try to call
|
|
||||||
# this on temp tables, or don't care if the table goes away. We
|
|
||||||
# should warn $EVAL_ERROR and require callers to eval us and do
|
|
||||||
# what they want with the warning.
|
|
||||||
PTDEBUG && _d($EVAL_ERROR);
|
|
||||||
|
|
||||||
# Restore old SQL mode.
|
# Restore old SQL mode.
|
||||||
PTDEBUG && _d($old_sql_mode);
|
PTDEBUG && _d($old_sql_mode);
|
||||||
$dbh->do($old_sql_mode);
|
$dbh->do($old_sql_mode);
|
||||||
|
|
||||||
return;
|
die $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Restore old SQL mode.
|
# Restore old SQL mode.
|
||||||
|
@@ -9,7 +9,7 @@ BEGIN {
|
|||||||
use strict;
|
use strict;
|
||||||
use warnings FATAL => 'all';
|
use warnings FATAL => 'all';
|
||||||
use English qw(-no_match_vars);
|
use English qw(-no_match_vars);
|
||||||
use Test::More tests => 30;
|
use Test::More;
|
||||||
|
|
||||||
use SchemaIterator;
|
use SchemaIterator;
|
||||||
use FileIterator;
|
use FileIterator;
|
||||||
@@ -406,8 +406,112 @@ test_so(
|
|||||||
test_name => "Resume from ignored table"
|
test_name => "Resume from ignored table"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
# #############################################################################
|
||||||
|
# Bug 1047335: pt-duplicate-key-checker fails when it encounters a crashed table
|
||||||
|
# https://bugs.launchpad.net/percona-toolkit/+bug/1047335
|
||||||
|
# #############################################################################
|
||||||
|
|
||||||
|
my $master3_port = 2900;
|
||||||
|
my $master_basedir = "/tmp/$master3_port";
|
||||||
|
diag(`$trunk/sandbox/stop-sandbox $master3_port >/dev/null`);
|
||||||
|
diag(`$trunk/sandbox/start-sandbox master $master3_port >/dev/null`);
|
||||||
|
my $dbh3 = $sb->get_dbh_for("master3");
|
||||||
|
|
||||||
|
SKIP: {
|
||||||
|
skip "No /dev/urandom, can't corrupt the database", 1
|
||||||
|
unless -e q{/dev/urandom};
|
||||||
|
|
||||||
|
$sb->load_file('master3', "t/lib/samples/bug_1047335_crashed_table.sql");
|
||||||
|
|
||||||
|
# Create the SI object before crashing the table
|
||||||
|
my $tmp_si = new SchemaIterator(
|
||||||
|
dbh => $dbh3,
|
||||||
|
OptionParser => $o,
|
||||||
|
Quoter => $q,
|
||||||
|
TableParser => $tp,
|
||||||
|
# This is needed because the way we corrupt tables
|
||||||
|
# accidentally removes the database from SHOW DATABASES
|
||||||
|
db => 'bug_1047335',
|
||||||
|
);
|
||||||
|
|
||||||
|
my $db_dir = "$master_basedir/data/bug_1047335";
|
||||||
|
my $myi = glob("$db_dir/crashed_table.[Mm][Yy][Iy]");
|
||||||
|
my $frm = glob("$db_dir/crashed_table.[Ff][Rr][Mm]");
|
||||||
|
|
||||||
|
die "Cannot find .myi file for crashed_table" unless $myi && -f $myi;
|
||||||
|
|
||||||
|
# Truncate the .myi file to corrupt it
|
||||||
|
truncate($myi, 4096);
|
||||||
|
|
||||||
|
use File::Slurp qw( prepend_file append_file write_file );
|
||||||
|
|
||||||
|
# Corrupt the .frm file
|
||||||
|
open my $urand_fh, q{<}, "/dev/urandom"
|
||||||
|
or die "Cannot open /dev/urandom";
|
||||||
|
prepend_file($frm, scalar(<$urand_fh>));
|
||||||
|
append_file($frm, scalar(<$urand_fh>));
|
||||||
|
close $urand_fh;
|
||||||
|
|
||||||
|
$dbh3->do("FLUSH TABLES");
|
||||||
|
eval { $dbh3->do("SELECT etc FROM bug_1047335.crashed_table WHERE etc LIKE '10001' ORDER BY id ASC LIMIT 1") };
|
||||||
|
|
||||||
|
my $w = '';
|
||||||
|
{
|
||||||
|
local $SIG{__WARN__} = sub { $w .= shift };
|
||||||
|
1 while $tmp_si->next();
|
||||||
|
}
|
||||||
|
|
||||||
|
like(
|
||||||
|
$w,
|
||||||
|
qr/bug_1047335.crashed_table because SHOW CREATE TABLE failed:/,
|
||||||
|
"->next() gives a warning if ->get_create_table dies from a strange error",
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$dbh3->do(q{DROP DATABASE IF EXISTS bug_1047335_2});
|
||||||
|
$dbh3->do(q{CREATE DATABASE bug_1047335_2});
|
||||||
|
|
||||||
|
my $broken_frm = "$trunk/t/lib/samples/broken_tbl.frm";
|
||||||
|
my $db_dir_2 = "$master_basedir/data/bug_1047335_2";
|
||||||
|
|
||||||
|
diag(`cp $broken_frm $db_dir_2 2>&1`);
|
||||||
|
|
||||||
|
$dbh3->do("FLUSH TABLES");
|
||||||
|
|
||||||
|
my $tmp_si2 = new SchemaIterator(
|
||||||
|
dbh => $dbh3,
|
||||||
|
OptionParser => $o,
|
||||||
|
Quoter => $q,
|
||||||
|
TableParser => $tp,
|
||||||
|
# This is needed because the way we corrupt tables
|
||||||
|
# accidentally removes the database from SHOW DATABASES
|
||||||
|
db => 'bug_1047335_2',
|
||||||
|
);
|
||||||
|
|
||||||
|
my $w = '';
|
||||||
|
{
|
||||||
|
local $SIG{__WARN__} = sub { $w .= shift };
|
||||||
|
1 while $tmp_si2->next();
|
||||||
|
}
|
||||||
|
|
||||||
|
like(
|
||||||
|
$w,
|
||||||
|
qr/\QSkipping bug_1047335_2.broken_tbl because SHOW CREATE TABLE failed:/,
|
||||||
|
"...same as above, but using t/lib/samples/broken_tbl.frm",
|
||||||
|
);
|
||||||
|
|
||||||
|
# This might fail. Doesn't matter -- stop_sandbox will just rm -rf the folder
|
||||||
|
eval {
|
||||||
|
$dbh3->do("DROP DATABASE IF EXISTS bug_1047335");
|
||||||
|
$dbh3->do("DROP DATABASE IF EXISTS bug_1047335_2");
|
||||||
|
};
|
||||||
|
|
||||||
|
diag(`$trunk/sandbox/stop-sandbox $master3_port >/dev/null`);
|
||||||
|
|
||||||
# #############################################################################
|
# #############################################################################
|
||||||
# Done.
|
# Done.
|
||||||
# #############################################################################
|
# #############################################################################
|
||||||
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
|
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
|
||||||
exit;
|
|
||||||
|
done_testing;
|
||||||
|
@@ -32,10 +32,10 @@ SKIP: {
|
|||||||
skip 'Sandbox master does not have the sakila database', 2
|
skip 'Sandbox master does not have the sakila database', 2
|
||||||
unless @{$dbh->selectcol_arrayref("SHOW DATABASES LIKE 'sakila'")};
|
unless @{$dbh->selectcol_arrayref("SHOW DATABASES LIKE 'sakila'")};
|
||||||
|
|
||||||
is(
|
eval { $tp->get_create_table($dbh, 'sakila', 'FOO') };
|
||||||
$tp->get_create_table($dbh, 'sakila', 'FOO'),
|
ok(
|
||||||
undef,
|
$EVAL_ERROR,
|
||||||
"get_create_table(nonexistent table)"
|
"get_create_table(nonexistent table) dies"
|
||||||
);
|
);
|
||||||
|
|
||||||
my $ddl = $tp->get_create_table($dbh, 'sakila', 'actor');
|
my $ddl = $tp->get_create_table($dbh, 'sakila', 'actor');
|
||||||
@@ -892,9 +892,82 @@ is_deeply(
|
|||||||
'Index with comma in its name (issue 388)'
|
'Index with comma in its name (issue 388)'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
# #############################################################################
|
||||||
|
# Bug 1047335: pt-duplicate-key-checker fails when it encounters a crashed table
|
||||||
|
# https://bugs.launchpad.net/percona-toolkit/+bug/1047335
|
||||||
|
# #############################################################################
|
||||||
|
|
||||||
|
# We need to create a new server here, otherwise the whole test suite might die
|
||||||
|
# if the crashed table can't be dropped.
|
||||||
|
|
||||||
|
my $master3_port = 2900;
|
||||||
|
my $master_basedir = "/tmp/$master3_port";
|
||||||
|
diag(`$trunk/sandbox/stop-sandbox $master3_port >/dev/null`);
|
||||||
|
diag(`$trunk/sandbox/start-sandbox master $master3_port >/dev/null`);
|
||||||
|
my $dbh3 = $sb->get_dbh_for("master3");
|
||||||
|
|
||||||
|
$sb->load_file('master3', "t/lib/samples/bug_1047335_crashed_table.sql");
|
||||||
|
|
||||||
|
SKIP: {
|
||||||
|
skip "No /dev/urandom, can't corrupt the database", 1
|
||||||
|
unless -e q{/dev/urandom};
|
||||||
|
|
||||||
|
my $db_dir = "$master_basedir/data/bug_1047335";
|
||||||
|
my $myi = glob("$db_dir/crashed_table.[Mm][Yy][Iy]");
|
||||||
|
my $frm = glob("$db_dir/crashed_table.[Ff][Rr][Mm]");
|
||||||
|
|
||||||
|
die "Cannot find .myi file for crashed_table" unless $myi && -f $myi;
|
||||||
|
|
||||||
|
# Truncate the .myi file to corrupt it
|
||||||
|
truncate($myi, 4096);
|
||||||
|
|
||||||
|
# Corrupt the .frm file
|
||||||
|
open my $urand_fh, q{<}, "/dev/urandom"
|
||||||
|
or die "Cannot open /dev/urandom: $OS_ERROR";
|
||||||
|
|
||||||
|
open my $tmp_fh, q{>}, $frm
|
||||||
|
or die "Cannot open $frm: $OS_ERROR";
|
||||||
|
print { $tmp_fh } scalar(<$urand_fh>), slurp_file($frm), scalar(<$urand_fh>);
|
||||||
|
close $tmp_fh;
|
||||||
|
|
||||||
|
close $urand_fh;
|
||||||
|
|
||||||
|
$dbh3->do("FLUSH TABLES");
|
||||||
|
eval { $dbh3->do("SELECT etc FROM bug_1047335.crashed_table WHERE etc LIKE '10001' ORDER BY id ASC LIMIT 1") };
|
||||||
|
|
||||||
|
eval { $tp->get_create_table($dbh3, 'bug_1047335', 'crashed_table') };
|
||||||
|
ok(
|
||||||
|
$EVAL_ERROR,
|
||||||
|
"get_create_table dies if SHOW CREATE TABLE failed",
|
||||||
|
);
|
||||||
|
|
||||||
|
# This might fail. Doesn't matter -- stop_sandbox will just rm -rf the folder
|
||||||
|
eval { $dbh3->do("DROP DATABASE IF EXISTS bug_1047335") };
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$dbh3->do(q{DROP DATABASE IF EXISTS bug_1047335_2});
|
||||||
|
$dbh3->do(q{CREATE DATABASE bug_1047335_2});
|
||||||
|
|
||||||
|
my $broken_frm = "$trunk/t/lib/samples/broken_tbl.frm";
|
||||||
|
my $db_dir_2 = "$master_basedir/data/bug_1047335_2";
|
||||||
|
|
||||||
|
diag(`cp $broken_frm $db_dir_2 2>&1`);
|
||||||
|
|
||||||
|
$dbh3->do("FLUSH TABLES");
|
||||||
|
|
||||||
|
eval { $tp->get_create_table($dbh3, 'bug_1047335_2', 'broken_tbl') };
|
||||||
|
ok(
|
||||||
|
$EVAL_ERROR,
|
||||||
|
"get_create_table dies if SHOW CREATE TABLE failed (using broken_tbl.frm)",
|
||||||
|
);
|
||||||
|
|
||||||
|
diag(`$trunk/sandbox/stop-sandbox $master3_port >/dev/null`);
|
||||||
|
|
||||||
# #############################################################################
|
# #############################################################################
|
||||||
# Done.
|
# Done.
|
||||||
# #############################################################################
|
# #############################################################################
|
||||||
$sb->wipe_clean($dbh) if $dbh;
|
$sb->wipe_clean($dbh) if $dbh;
|
||||||
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
|
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
|
||||||
done_testing;
|
done_testing;
|
||||||
|
exit;
|
12
t/lib/samples/bug_1047335_crashed_table.sql
Normal file
12
t/lib/samples/bug_1047335_crashed_table.sql
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user