Merge lp:~percona-toolkit-dev/percona-toolkit/fix-1047335-crashed-tables into lp:percona-toolkit/2.1

Proposed by Brian Fraser
Status: Superseded
Proposed branch: lp:~percona-toolkit-dev/percona-toolkit/fix-1047335-crashed-tables
Merge into: lp:percona-toolkit/2.1
Diff against target: 593 lines (+232/-68)
18 files modified
bin/pt-archiver (+2/-4)
bin/pt-config-diff (+3/-1)
bin/pt-duplicate-key-checker (+14/-5)
bin/pt-find (+2/-4)
bin/pt-heartbeat (+2/-4)
bin/pt-index-usage (+14/-5)
bin/pt-kill (+5/-5)
bin/pt-online-schema-change (+5/-5)
bin/pt-query-advisor (+2/-4)
bin/pt-query-digest (+2/-4)
bin/pt-table-checksum (+14/-5)
bin/pt-table-sync (+2/-2)
bin/pt-upgrade (+2/-4)
lib/SchemaIterator.pm (+16/-1)
lib/TableParser.pm (+2/-8)
t/lib/SchemaIterator.t (+70/-2)
t/lib/TableParser.t (+64/-5)
t/lib/samples/bug_1047335_crashed_table.sql (+11/-0)
To merge this branch: bzr merge lp:~percona-toolkit-dev/percona-toolkit/fix-1047335-crashed-tables
Reviewer Review Type Date Requested Status
Daniel Nichter Needs Resubmitting
Review via email: mp+132185@code.launchpad.net

This proposal has been superseded by a proposal from 2012-10-30.

To post a comment you must log in.
Revision history for this message
Daniel Nichter (daniel-nichter) wrote :

This diff has other stuff, for MasterSlave and PXC. Can you isolate just the changes for this branch/bug?

review: Needs Resubmitting
Revision history for this message
Daniel Nichter (daniel-nichter) wrote :

Also, the local $EVAL_ERROR (re another branch).

I think we have a crashed .frm in the source somewhere; I just looked but couldn't find it; I recall testing this before for something else.

Re 469 +# This might fail. Doesn't matter -- stop_sandbox will just rm -rf the folder -- will this cause output to STDERR? If so, that's bad because it shows up as an error.

436. By Brian Fraser

Fix for 1047335: SchemaIterator fails when it encounters a crashed table

437. By Brian Fraser

Removed local $EVAL_ERROR, added a test using t/lib/samples/broken_tbl.frm, and updated all modules

438. By Brian Fraser

Fixes per Daniel's review

439. By Brian Fraser

t/lib/samples/bug_1047335_crashed_table.sql: Use a single INSERT with all the values instead of 1k statements

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'bin/pt-archiver'
--- bin/pt-archiver 2012-10-22 18:17:08 +0000
+++ bin/pt-archiver 2012-10-30 21:38:20 +0000
@@ -1584,13 +1584,11 @@
1584 PTDEBUG && _d($show_sql);1584 PTDEBUG && _d($show_sql);
1585 my $href;1585 my $href;
1586 eval { $href = $dbh->selectrow_hashref($show_sql); };1586 eval { $href = $dbh->selectrow_hashref($show_sql); };
1587 if ( $EVAL_ERROR ) {1587 if ( my $e = $EVAL_ERROR ) {
1588 PTDEBUG && _d($EVAL_ERROR);
1589
1590 PTDEBUG && _d($old_sql_mode);1588 PTDEBUG && _d($old_sql_mode);
1591 $dbh->do($old_sql_mode);1589 $dbh->do($old_sql_mode);
15921590
1593 return;1591 die $e;
1594 }1592 }
15951593
1596 PTDEBUG && _d($old_sql_mode);1594 PTDEBUG && _d($old_sql_mode);
15971595
=== modified file 'bin/pt-config-diff'
--- bin/pt-config-diff 2012-10-22 18:17:08 +0000
+++ bin/pt-config-diff 2012-10-30 21:38:20 +0000
@@ -1576,7 +1576,9 @@
1576 PTDEBUG && _d($sql);1576 PTDEBUG && _d($sql);
1577 my $row = $self->{dbh}->selectrow_arrayref($sql);1577 my $row = $self->{dbh}->selectrow_arrayref($sql);
1578 PTDEBUG && _d(defined $row ? @$row : 'undef');1578 PTDEBUG && _d(defined $row ? @$row : 'undef');
1579 $self->{is_cluster_node} = $row && $row->[0] ? 1 : 0;1579 $self->{is_cluster_node} = $row && $row->[1]
1580 ? ($row->[1] eq 'ON' || $row->[1] eq '1')
1581 : 0;
1580 1582
1581 return $self->{is_cluster_node};1583 return $self->{is_cluster_node};
1582}1584}
15831585
=== modified file 'bin/pt-duplicate-key-checker'
--- bin/pt-duplicate-key-checker 2012-10-22 18:17:08 +0000
+++ bin/pt-duplicate-key-checker 2012-10-30 21:38:20 +0000
@@ -226,13 +226,11 @@
226 PTDEBUG && _d($show_sql);226 PTDEBUG && _d($show_sql);
227 my $href;227 my $href;
228 eval { $href = $dbh->selectrow_hashref($show_sql); };228 eval { $href = $dbh->selectrow_hashref($show_sql); };
229 if ( $EVAL_ERROR ) {229 if ( my $e = $EVAL_ERROR ) {
230 PTDEBUG && _d($EVAL_ERROR);
231
232 PTDEBUG && _d($old_sql_mode);230 PTDEBUG && _d($old_sql_mode);
233 $dbh->do($old_sql_mode);231 $dbh->do($old_sql_mode);
234232
235 return;233 die $e;
236 }234 }
237235
238 PTDEBUG && _d($old_sql_mode);236 PTDEBUG && _d($old_sql_mode);
@@ -3138,7 +3136,18 @@
3138 }3136 }
31393137
3140 while ( my $tbl = shift @{$self->{tbls}} ) {3138 while ( my $tbl = shift @{$self->{tbls}} ) {
3141 my $ddl = $tp->get_create_table($dbh, $self->{db}, $tbl);3139 local $EVAL_ERROR;
3140 my $ddl = eval { $tp->get_create_table($dbh, $self->{db}, $tbl) };
3141 if ( my $e = $EVAL_ERROR ) {
3142 my $table_name = "$self->{db}.$tbl";
3143 if ( $e =~ /\QTable '$table_name' doesn't exist/ ) {
3144 PTDEBUG && _d("Skipping $table_name because it no longer exists");
3145 }
3146 else {
3147 warn "Skipping $table_name because SHOW CREATE TABLE failed: $e";
3148 }
3149 next;
3150 }
3142 my $tbl_struct = $tp->parse($ddl);3151 my $tbl_struct = $tp->parse($ddl);
3143 if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {3152 if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {
3144 return {3153 return {
31453154
=== modified file 'bin/pt-find'
--- bin/pt-find 2012-10-22 18:17:08 +0000
+++ bin/pt-find 2012-10-30 21:38:20 +0000
@@ -1623,13 +1623,11 @@
1623 PTDEBUG && _d($show_sql);1623 PTDEBUG && _d($show_sql);
1624 my $href;1624 my $href;
1625 eval { $href = $dbh->selectrow_hashref($show_sql); };1625 eval { $href = $dbh->selectrow_hashref($show_sql); };
1626 if ( $EVAL_ERROR ) {1626 if ( my $e = $EVAL_ERROR ) {
1627 PTDEBUG && _d($EVAL_ERROR);
1628
1629 PTDEBUG && _d($old_sql_mode);1627 PTDEBUG && _d($old_sql_mode);
1630 $dbh->do($old_sql_mode);1628 $dbh->do($old_sql_mode);
16311629
1632 return;1630 die $e;
1633 }1631 }
16341632
1635 PTDEBUG && _d($old_sql_mode);1633 PTDEBUG && _d($old_sql_mode);
16361634
=== modified file 'bin/pt-heartbeat'
--- bin/pt-heartbeat 2012-10-22 18:17:08 +0000
+++ bin/pt-heartbeat 2012-10-30 21:38:20 +0000
@@ -2549,13 +2549,11 @@
2549 PTDEBUG && _d($show_sql);2549 PTDEBUG && _d($show_sql);
2550 my $href;2550 my $href;
2551 eval { $href = $dbh->selectrow_hashref($show_sql); };2551 eval { $href = $dbh->selectrow_hashref($show_sql); };
2552 if ( $EVAL_ERROR ) {2552 if ( my $e = $EVAL_ERROR ) {
2553 PTDEBUG && _d($EVAL_ERROR);
2554
2555 PTDEBUG && _d($old_sql_mode);2553 PTDEBUG && _d($old_sql_mode);
2556 $dbh->do($old_sql_mode);2554 $dbh->do($old_sql_mode);
25572555
2558 return;2556 die $e;
2559 }2557 }
25602558
2561 PTDEBUG && _d($old_sql_mode);2559 PTDEBUG && _d($old_sql_mode);
25622560
=== modified file 'bin/pt-index-usage'
--- bin/pt-index-usage 2012-10-22 18:17:08 +0000
+++ bin/pt-index-usage 2012-10-30 21:38:20 +0000
@@ -2821,13 +2821,11 @@
2821 PTDEBUG && _d($show_sql);2821 PTDEBUG && _d($show_sql);
2822 my $href;2822 my $href;
2823 eval { $href = $dbh->selectrow_hashref($show_sql); };2823 eval { $href = $dbh->selectrow_hashref($show_sql); };
2824 if ( $EVAL_ERROR ) {2824 if ( my $e = $EVAL_ERROR ) {
2825 PTDEBUG && _d($EVAL_ERROR);
2826
2827 PTDEBUG && _d($old_sql_mode);2825 PTDEBUG && _d($old_sql_mode);
2828 $dbh->do($old_sql_mode);2826 $dbh->do($old_sql_mode);
28292827
2830 return;2828 die $e;
2831 }2829 }
28322830
2833 PTDEBUG && _d($old_sql_mode);2831 PTDEBUG && _d($old_sql_mode);
@@ -3968,7 +3966,18 @@
3968 }3966 }
39693967
3970 while ( my $tbl = shift @{$self->{tbls}} ) {3968 while ( my $tbl = shift @{$self->{tbls}} ) {
3971 my $ddl = $tp->get_create_table($dbh, $self->{db}, $tbl);3969 local $EVAL_ERROR;
3970 my $ddl = eval { $tp->get_create_table($dbh, $self->{db}, $tbl) };
3971 if ( my $e = $EVAL_ERROR ) {
3972 my $table_name = "$self->{db}.$tbl";
3973 if ( $e =~ /\QTable '$table_name' doesn't exist/ ) {
3974 PTDEBUG && _d("Skipping $table_name because it no longer exists");
3975 }
3976 else {
3977 warn "Skipping $table_name because SHOW CREATE TABLE failed: $e";
3978 }
3979 next;
3980 }
3972 my $tbl_struct = $tp->parse($ddl);3981 my $tbl_struct = $tp->parse($ddl);
3973 if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {3982 if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {
3974 return {3983 return {
39753984
=== modified file 'bin/pt-kill'
--- bin/pt-kill 2012-10-22 18:17:08 +0000
+++ bin/pt-kill 2012-10-30 21:38:20 +0000
@@ -2499,13 +2499,11 @@
2499 PTDEBUG && _d($show_sql);2499 PTDEBUG && _d($show_sql);
2500 my $href;2500 my $href;
2501 eval { $href = $dbh->selectrow_hashref($show_sql); };2501 eval { $href = $dbh->selectrow_hashref($show_sql); };
2502 if ( $EVAL_ERROR ) {2502 if ( my $e = $EVAL_ERROR ) {
2503 PTDEBUG && _d($EVAL_ERROR);
2504
2505 PTDEBUG && _d($old_sql_mode);2503 PTDEBUG && _d($old_sql_mode);
2506 $dbh->do($old_sql_mode);2504 $dbh->do($old_sql_mode);
25072505
2508 return;2506 die $e;
2509 }2507 }
25102508
2511 PTDEBUG && _d($old_sql_mode);2509 PTDEBUG && _d($old_sql_mode);
@@ -4807,7 +4805,9 @@
4807 PTDEBUG && _d($sql);4805 PTDEBUG && _d($sql);
4808 my $row = $self->{dbh}->selectrow_arrayref($sql);4806 my $row = $self->{dbh}->selectrow_arrayref($sql);
4809 PTDEBUG && _d(defined $row ? @$row : 'undef');4807 PTDEBUG && _d(defined $row ? @$row : 'undef');
4810 $self->{is_cluster_node} = $row && $row->[0] ? 1 : 0;4808 $self->{is_cluster_node} = $row && $row->[1]
4809 ? ($row->[1] eq 'ON' || $row->[1] eq '1')
4810 : 0;
4811 4811
4812 return $self->{is_cluster_node};4812 return $self->{is_cluster_node};
4813}4813}
48144814
=== modified file 'bin/pt-online-schema-change'
--- bin/pt-online-schema-change 2012-10-22 20:23:05 +0000
+++ bin/pt-online-schema-change 2012-10-30 21:38:20 +0000
@@ -2733,13 +2733,11 @@
2733 PTDEBUG && _d($show_sql);2733 PTDEBUG && _d($show_sql);
2734 my $href;2734 my $href;
2735 eval { $href = $dbh->selectrow_hashref($show_sql); };2735 eval { $href = $dbh->selectrow_hashref($show_sql); };
2736 if ( $EVAL_ERROR ) {2736 if ( my $e = $EVAL_ERROR ) {
2737 PTDEBUG && _d($EVAL_ERROR);
2738
2739 PTDEBUG && _d($old_sql_mode);2737 PTDEBUG && _d($old_sql_mode);
2740 $dbh->do($old_sql_mode);2738 $dbh->do($old_sql_mode);
27412739
2742 return;2740 die $e;
2743 }2741 }
27442742
2745 PTDEBUG && _d($old_sql_mode);2743 PTDEBUG && _d($old_sql_mode);
@@ -3437,7 +3435,9 @@
3437 PTDEBUG && _d($sql);3435 PTDEBUG && _d($sql);
3438 my $row = $self->{dbh}->selectrow_arrayref($sql);3436 my $row = $self->{dbh}->selectrow_arrayref($sql);
3439 PTDEBUG && _d(defined $row ? @$row : 'undef');3437 PTDEBUG && _d(defined $row ? @$row : 'undef');
3440 $self->{is_cluster_node} = $row && $row->[0] ? 1 : 0;3438 $self->{is_cluster_node} = $row && $row->[1]
3439 ? ($row->[1] eq 'ON' || $row->[1] eq '1')
3440 : 0;
3441 3441
3442 return $self->{is_cluster_node};3442 return $self->{is_cluster_node};
3443}3443}
34443444
=== modified file 'bin/pt-query-advisor'
--- bin/pt-query-advisor 2012-10-22 18:17:08 +0000
+++ bin/pt-query-advisor 2012-10-30 21:38:20 +0000
@@ -5311,13 +5311,11 @@
5311 PTDEBUG && _d($show_sql);5311 PTDEBUG && _d($show_sql);
5312 my $href;5312 my $href;
5313 eval { $href = $dbh->selectrow_hashref($show_sql); };5313 eval { $href = $dbh->selectrow_hashref($show_sql); };
5314 if ( $EVAL_ERROR ) {5314 if ( my $e = $EVAL_ERROR ) {
5315 PTDEBUG && _d($EVAL_ERROR);
5316
5317 PTDEBUG && _d($old_sql_mode);5315 PTDEBUG && _d($old_sql_mode);
5318 $dbh->do($old_sql_mode);5316 $dbh->do($old_sql_mode);
53195317
5320 return;5318 die $e;
5321 }5319 }
53225320
5323 PTDEBUG && _d($old_sql_mode);5321 PTDEBUG && _d($old_sql_mode);
53245322
=== modified file 'bin/pt-query-digest'
--- bin/pt-query-digest 2012-10-22 18:17:08 +0000
+++ bin/pt-query-digest 2012-10-30 21:38:20 +0000
@@ -8140,13 +8140,11 @@
8140 PTDEBUG && _d($show_sql);8140 PTDEBUG && _d($show_sql);
8141 my $href;8141 my $href;
8142 eval { $href = $dbh->selectrow_hashref($show_sql); };8142 eval { $href = $dbh->selectrow_hashref($show_sql); };
8143 if ( $EVAL_ERROR ) {8143 if ( my $e = $EVAL_ERROR ) {
8144 PTDEBUG && _d($EVAL_ERROR);
8145
8146 PTDEBUG && _d($old_sql_mode);8144 PTDEBUG && _d($old_sql_mode);
8147 $dbh->do($old_sql_mode);8145 $dbh->do($old_sql_mode);
81488146
8149 return;8147 die $e;
8150 }8148 }
81518149
8152 PTDEBUG && _d($old_sql_mode);8150 PTDEBUG && _d($old_sql_mode);
81538151
=== modified file 'bin/pt-table-checksum'
--- bin/pt-table-checksum 2012-10-26 23:06:21 +0000
+++ bin/pt-table-checksum 2012-10-30 21:38:20 +0000
@@ -3725,13 +3725,11 @@
3725 PTDEBUG && _d($show_sql);3725 PTDEBUG && _d($show_sql);
3726 my $href;3726 my $href;
3727 eval { $href = $dbh->selectrow_hashref($show_sql); };3727 eval { $href = $dbh->selectrow_hashref($show_sql); };
3728 if ( $EVAL_ERROR ) {3728 if ( my $e = $EVAL_ERROR ) {
3729 PTDEBUG && _d($EVAL_ERROR);
3730
3731 PTDEBUG && _d($old_sql_mode);3729 PTDEBUG && _d($old_sql_mode);
3732 $dbh->do($old_sql_mode);3730 $dbh->do($old_sql_mode);
37333731
3734 return;3732 die $e;
3735 }3733 }
37363734
3737 PTDEBUG && _d($old_sql_mode);3735 PTDEBUG && _d($old_sql_mode);
@@ -6784,7 +6782,18 @@
6784 }6782 }
67856783
6786 while ( my $tbl = shift @{$self->{tbls}} ) {6784 while ( my $tbl = shift @{$self->{tbls}} ) {
6787 my $ddl = $tp->get_create_table($dbh, $self->{db}, $tbl);6785 local $EVAL_ERROR;
6786 my $ddl = eval { $tp->get_create_table($dbh, $self->{db}, $tbl) };
6787 if ( my $e = $EVAL_ERROR ) {
6788 my $table_name = "$self->{db}.$tbl";
6789 if ( $e =~ /\QTable '$table_name' doesn't exist/ ) {
6790 PTDEBUG && _d("Skipping $table_name because it no longer exists");
6791 }
6792 else {
6793 warn "Skipping $table_name because SHOW CREATE TABLE failed: $e";
6794 }
6795 next;
6796 }
6788 my $tbl_struct = $tp->parse($ddl);6797 my $tbl_struct = $tp->parse($ddl);
6789 if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {6798 if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {
6790 return {6799 return {
67916800
=== modified file 'bin/pt-table-sync'
--- bin/pt-table-sync 2012-10-22 18:17:08 +0000
+++ bin/pt-table-sync 2012-10-30 21:38:20 +0000
@@ -2990,7 +2990,7 @@
2990 my ( $self, $dbh, $quoter, $db, $tbl, $what ) = @_;2990 my ( $self, $dbh, $quoter, $db, $tbl, $what ) = @_;
29912991
2992 if ( $what eq 'table' ) {2992 if ( $what eq 'table' ) {
2993 my $ddl = $self->get_create_table($dbh, $quoter, $db, $tbl);2993 my $ddl = $self->get_create_table($dbh, $dbh, $db, $tbl);
2994 return unless $ddl;2994 return unless $ddl;
2995 if ( $ddl->[0] eq 'table' ) {2995 if ( $ddl->[0] eq 'table' ) {
2996 return $before2996 return $before
@@ -3033,7 +3033,7 @@
3033 }3033 }
3034 }3034 }
3035 elsif ( $what eq 'view' ) {3035 elsif ( $what eq 'view' ) {
3036 my $ddl = $self->get_create_table($dbh, $quoter, $db, $tbl);3036 my $ddl = $self->get_create_table($dbh, $dbh, $db, $tbl);
3037 return '/*!50001 DROP TABLE IF EXISTS ' . $quoter->quote($tbl) . "*/;\n"3037 return '/*!50001 DROP TABLE IF EXISTS ' . $quoter->quote($tbl) . "*/;\n"
3038 . '/*!50001 DROP VIEW IF EXISTS ' . $quoter->quote($tbl) . "*/;\n"3038 . '/*!50001 DROP VIEW IF EXISTS ' . $quoter->quote($tbl) . "*/;\n"
3039 . '/*!50001 ' . $ddl->[1] . "*/;\n";3039 . '/*!50001 ' . $ddl->[1] . "*/;\n";
30403040
=== modified file 'bin/pt-upgrade'
--- bin/pt-upgrade 2012-10-22 18:17:08 +0000
+++ bin/pt-upgrade 2012-10-30 21:38:20 +0000
@@ -498,13 +498,11 @@
498 PTDEBUG && _d($show_sql);498 PTDEBUG && _d($show_sql);
499 my $href;499 my $href;
500 eval { $href = $dbh->selectrow_hashref($show_sql); };500 eval { $href = $dbh->selectrow_hashref($show_sql); };
501 if ( $EVAL_ERROR ) {501 if ( my $e = $EVAL_ERROR ) {
502 PTDEBUG && _d($EVAL_ERROR);
503
504 PTDEBUG && _d($old_sql_mode);502 PTDEBUG && _d($old_sql_mode);
505 $dbh->do($old_sql_mode);503 $dbh->do($old_sql_mode);
506504
507 return;505 die $e;
508 }506 }
509507
510 PTDEBUG && _d($old_sql_mode);508 PTDEBUG && _d($old_sql_mode);
511509
=== modified file 'lib/SchemaIterator.pm'
--- lib/SchemaIterator.pm 2012-04-03 18:21:15 +0000
+++ lib/SchemaIterator.pm 2012-10-30 21:38:20 +0000
@@ -352,7 +352,22 @@
352 }352 }
353353
354 while ( my $tbl = shift @{$self->{tbls}} ) {354 while ( my $tbl = shift @{$self->{tbls}} ) {
355 my $ddl = $tp->get_create_table($dbh, $self->{db}, $tbl);355 local $EVAL_ERROR;
356 my $ddl = eval { $tp->get_create_table($dbh, $self->{db}, $tbl) };
357 if ( my $e = $EVAL_ERROR ) {
358 my $table_name = "$self->{db}.$tbl";
359 # SHOW CREATE TABLE failed. This is a bit puzzling;
360 # maybe the table got dropped, or crashed. Not much we can
361 # do about it; If the table is missing, just PTDEBUG it, but
362 # otherwise, warn with the error.
363 if ( $e =~ /\QTable '$table_name' doesn't exist/ ) {
364 PTDEBUG && _d("Skipping $table_name because it no longer exists");
365 }
366 else {
367 warn "Skipping $table_name because SHOW CREATE TABLE failed: $e";
368 }
369 next;
370 }
356 my $tbl_struct = $tp->parse($ddl);371 my $tbl_struct = $tp->parse($ddl);
357 if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {372 if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {
358 return {373 return {
359374
=== modified file 'lib/TableParser.pm'
--- lib/TableParser.pm 2012-10-19 23:14:07 +0000
+++ lib/TableParser.pm 2012-10-30 21:38:20 +0000
@@ -82,18 +82,12 @@
82 PTDEBUG && _d($show_sql);82 PTDEBUG && _d($show_sql);
83 my $href;83 my $href;
84 eval { $href = $dbh->selectrow_hashref($show_sql); };84 eval { $href = $dbh->selectrow_hashref($show_sql); };
85 if ( $EVAL_ERROR ) {85 if ( my $e = $EVAL_ERROR ) {
86 # TODO: I think we fail silently for tools which may try to call
87 # this on temp tables, or don't care if the table goes away. We
88 # should warn $EVAL_ERROR and require callers to eval us and do
89 # what they want with the warning.
90 PTDEBUG && _d($EVAL_ERROR);
91
92 # Restore old SQL mode.86 # Restore old SQL mode.
93 PTDEBUG && _d($old_sql_mode);87 PTDEBUG && _d($old_sql_mode);
94 $dbh->do($old_sql_mode);88 $dbh->do($old_sql_mode);
9589
96 return;90 die $e;
97 }91 }
9892
99 # Restore old SQL mode.93 # Restore old SQL mode.
10094
=== modified file 't/lib/SchemaIterator.t'
--- t/lib/SchemaIterator.t 2012-06-07 03:14:20 +0000
+++ t/lib/SchemaIterator.t 2012-10-30 21:38:20 +0000
@@ -9,7 +9,7 @@
9use strict;9use strict;
10use warnings FATAL => 'all';10use warnings FATAL => 'all';
11use English qw(-no_match_vars);11use English qw(-no_match_vars);
12use Test::More tests => 30;12use Test::More;
1313
14use SchemaIterator;14use SchemaIterator;
15use FileIterator;15use FileIterator;
@@ -407,7 +407,75 @@
407);407);
408408
409# #############################################################################409# #############################################################################
410# Bug 1047335: pt-duplicate-key-checker fails when it encounters a crashed table
411# https://bugs.launchpad.net/percona-toolkit/+bug/1047335
412# #############################################################################
413
414use File::Spec;
415
416my $master3_port = 2900;
417diag(`$trunk/sandbox/stop-sandbox $master3_port >/dev/null`);
418diag(`$trunk/sandbox/start-sandbox master $master3_port >/dev/null`);
419my $dbh3 = $sb->get_dbh_for("master3");
420
421$sb->load_file('master3', File::Spec->catfile(qw(t lib samples bug_1047335_crashed_table.sql)));
422my $sth = $dbh3->prepare("INSERT INTO bug_1047335.crashed_table (trx_id, etc) VALUES(?, ?)");
423$sth->execute($_, $_ x 100) for 1..1000;
424$sth->finish();
425
426# Create the SI object before crashing the table
427my $tmp_si = new SchemaIterator(
428 dbh => $dbh3,
429 OptionParser => $o,
430 Quoter => $q,
431 TableParser => $tp,
432 # This is needed because the way we corrupt tables
433 # accidentally removes the database from SHOW DATABASES
434 db => 'bug_1047335',
435 );
436
437my $master_basedir = File::Spec->catdir(File::Spec->tmpdir(), $master3_port);
438my $db_dir = File::Spec->catdir($master_basedir, "data", "bug_1047335");
439my $myi = glob(File::Spec->catfile($db_dir, "crashed_table.[Mm][Yy][Iy]"));
440my $frm = glob(File::Spec->catfile($db_dir, "crashed_table.[Ff][Rr][Mm]"));
441
442die "Cannot find .myi file for crashed_table" unless $myi && -f $myi;
443
444# Truncate the .myi file to corrupt it
445truncate($myi, 4096);
446
447use File::Slurp qw( prepend_file append_file write_file );
448
449# Corrupt the .frm file
450open my $urand_fh, q{<}, "/dev/urandom"
451 or die "Cannot open /dev/urandom";
452prepend_file($frm, scalar(<$urand_fh>));
453append_file($frm, scalar(<$urand_fh>));
454close $urand_fh;
455
456$dbh3->do("FLUSH TABLES");
457eval { $dbh3->do("SELECT etc FROM bug_1047335.crashed_table WHERE etc LIKE '10001' ORDER BY id ASC LIMIT 1") };
458
459my $w = '';
460{
461 local $SIG{__WARN__} = sub { $w .= shift };
462 1 while $tmp_si->next();
463}
464
465like(
466 $w,
467 qr/because SHOW CREATE TABLE failed:/,
468 "->next() gives a warning if ->get_create_table dies from a strange error",
469);
470
471# This might fail. Doesn't matter -- stop_sandbox will just rm -rf the folder
472eval { $dbh3->do("DROP DATABASE IF EXISTS bug_1047335") };
473
474diag(`$trunk/sandbox/stop-sandbox $master3_port >/dev/null`);
475
476# #############################################################################
410# Done.477# Done.
411# #############################################################################478# #############################################################################
412ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");479ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
413exit;480
481done_testing;
414482
=== modified file 't/lib/TableParser.t'
--- t/lib/TableParser.t 2012-10-20 23:59:28 +0000
+++ t/lib/TableParser.t 2012-10-30 21:38:20 +0000
@@ -9,7 +9,7 @@
9use strict;9use strict;
10use warnings FATAL => 'all';10use warnings FATAL => 'all';
11use English qw(-no_match_vars);11use English qw(-no_match_vars);
12use Test::More tests => 40;12use Test::More;
1313
14use TableParser;14use TableParser;
15use Quoter;15use Quoter;
@@ -32,10 +32,10 @@
32 skip 'Sandbox master does not have the sakila database', 232 skip 'Sandbox master does not have the sakila database', 2
33 unless @{$dbh->selectcol_arrayref("SHOW DATABASES LIKE 'sakila'")};33 unless @{$dbh->selectcol_arrayref("SHOW DATABASES LIKE 'sakila'")};
3434
35 is(35 eval { $tp->get_create_table($dbh, 'sakila', 'FOO') };
36 $tp->get_create_table($dbh, 'sakila', 'FOO'),36 ok(
37 undef,37 $EVAL_ERROR,
38 "get_create_table(nonexistent table)"38 "get_create_table(nonexistent table) dies"
39 );39 );
4040
41 my $ddl = $tp->get_create_table($dbh, 'sakila', 'actor');41 my $ddl = $tp->get_create_table($dbh, 'sakila', 'actor');
@@ -893,8 +893,67 @@
893);893);
894894
895# #############################################################################895# #############################################################################
896# Bug 1047335: pt-duplicate-key-checker fails when it encounters a crashed table
897# https://bugs.launchpad.net/percona-toolkit/+bug/1047335
898# #############################################################################
899
900# We need to create a new server here, otherwise the whole test suite might die
901# if the crashed table can't be dropped.
902
903use File::Spec;
904
905my $master3_port = 2900;
906diag(`$trunk/sandbox/stop-sandbox $master3_port >/dev/null`);
907diag(`$trunk/sandbox/start-sandbox master $master3_port >/dev/null`);
908my $dbh3 = $sb->get_dbh_for("master3");
909
910$sb->load_file('master3', File::Spec->catfile(qw(t lib samples bug_1047335_crashed_table.sql)));
911my $sth = $dbh3->prepare("INSERT INTO bug_1047335.crashed_table (trx_id, etc) VALUES(?, ?)");
912$sth->execute($_, $_ x 100) for 1..1000;
913$sth->finish();
914
915
916my $master_basedir = File::Spec->catdir(File::Spec->tmpdir(), $master3_port);
917my $db_dir = File::Spec->catdir($master_basedir, "data", "bug_1047335");
918my $myi = glob(File::Spec->catfile($db_dir, "crashed_table.[Mm][Yy][Iy]"));
919my $frm = glob(File::Spec->catfile($db_dir, "crashed_table.[Ff][Rr][Mm]"));
920
921die "Cannot find .myi file for crashed_table" unless $myi && -f $myi;
922
923# Truncate the .myi file to corrupt it
924truncate($myi, 4096);
925
926# Corrupt the .frm file
927open my $urand_fh, q{<}, "/dev/urandom"
928 or die "Cannot open /dev/urandom: $OS_ERROR";
929
930open my $tmp_fh, q{>}, $frm
931 or die "Cannot open $frm: $OS_ERROR";
932print { $tmp_fh } scalar(<$urand_fh>), slurp_file($frm), scalar(<$urand_fh>);
933close $tmp_fh;
934
935close $urand_fh;
936
937$dbh3->do("FLUSH TABLES");
938eval { $dbh3->do("SELECT etc FROM bug_1047335.crashed_table WHERE etc LIKE '10001' ORDER BY id ASC LIMIT 1") };
939
940eval { $tp->get_create_table($dbh3, 'bug_1047335', 'crashed_table') };
941ok(
942 $EVAL_ERROR,
943 "get_create_table dies if SHOW CREATE TABLE failed",
944);
945
946# This might fail. Doesn't matter -- stop_sandbox will just rm -rf the folder
947eval { $dbh3->do("DROP DATABASE IF EXISTS bug_1047335") };
948
949diag(`$trunk/sandbox/stop-sandbox $master3_port >/dev/null`);
950
951# #############################################################################
896# Done.952# Done.
897# #############################################################################953# #############################################################################
898$sb->wipe_clean($dbh) if $dbh;954$sb->wipe_clean($dbh) if $dbh;
899ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");955ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
956
957done_testing;
958
900exit;959exit;
901960
=== added file 't/lib/samples/bug_1047335_crashed_table.sql'
--- t/lib/samples/bug_1047335_crashed_table.sql 1970-01-01 00:00:00 +0000
+++ t/lib/samples/bug_1047335_crashed_table.sql 2012-10-30 21:38:20 +0000
@@ -0,0 +1,11 @@
1DROP DATABASE IF EXISTS bug_1047335;
2CREATE DATABASE bug_1047335;
3USE bug_1047335;
4CREATE TABLE bug_1047335.crashed_table (
5 `id` int(10) unsigned NOT NULL auto_increment,
6 `trx_id` int(10) unsigned default NULL,
7 `etc` text,
8 PRIMARY KEY (`id`),
9 KEY `idx1` (`trx_id`),
10 KEY `idx2` (`trx_id`, `etc`(128))
11) ENGINE=MyISAM;

Subscribers

People subscribed via source and target branches