Merge lp:~percona-toolkit-dev/percona-toolkit/pt-online-schema-change-doesnt-work-with-HASH-indexes-1340728 into lp:~percona-toolkit-dev/percona-toolkit/release-2.2.10

Proposed by Frank Cizmich
Status: Merged
Approved by: Daniel Nichter
Approved revision: 621
Merged at revision: 613
Proposed branch: lp:~percona-toolkit-dev/percona-toolkit/pt-online-schema-change-doesnt-work-with-HASH-indexes-1340728
Merge into: lp:~percona-toolkit-dev/percona-toolkit/release-2.2.10
Diff against target: 288 lines (+116/-111)
5 files modified
bin/pt-online-schema-change (+40/-33)
t/pt-online-schema-change/bug-1315130.t (+0/-78)
t/pt-online-schema-change/bugs.t (+64/-0)
t/pt-online-schema-change/samples/bug-1340728.sql (+10/-0)
t/pt-online-schema-change/samples/bug-1340728_cleanup.sql (+2/-0)
To merge this branch: bzr merge lp:~percona-toolkit-dev/percona-toolkit/pt-online-schema-change-doesnt-work-with-HASH-indexes-1340728
Reviewer Review Type Date Requested Status
Daniel Nichter Approve
Review via email: mp+228726@code.launchpad.net

Description of the change

Intended to make pt-osc work with engines that allow a HASH index (MEMORY , NDB) . When issued the EXPLAIN query, this type of index sometimes doesn't select a primary key even though it's available.
This fix makes the --nocheck-plan option skip *all* checks on the key chosen by EXPLAIN.

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

We talked on IRC about some changes. I'll set this as "Needs Fixing" until then.

review: Needs Fixing
620. By Frank Cizmich

Skipped another plan check. Skipped running explain when unnecessary. Added test. Fixed test that set check-plan off by default

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

Code is good, let's just tweak the test a little.

review: Needs Fixing
621. By Frank Cizmich

used output instead of full_output. merged bug tests into bugs.t

Revision history for this message
Daniel Nichter (daniel-nichter) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/pt-online-schema-change'
2--- bin/pt-online-schema-change 2014-07-04 17:16:08 +0000
3+++ bin/pt-online-schema-change 2014-08-05 15:51:35 +0000
4@@ -8908,28 +8908,31 @@
5 # boundary sql. This check applies to the next nibble. So if
6 # the current nibble number is 5, then nibble 5 is already done
7 # and we're checking nibble number 6.
8- my $expl = explain_statement(
9- tbl => $tbl,
10- sth => $sth->{explain_upper_boundary},
11- vals => [ @{$boundary->{lower}}, $nibble_iter->limit() ],
12- );
13- if (lc($expl->{key} || '') ne lc($nibble_iter->nibble_index() || '')) {
14- my $msg
15- = "Aborting copying table $tbl->{name} at chunk "
16- . ($nibble_iter->nibble_number() + 1)
17- . " because it is not safe to ascend. Chunking should "
18- . "use the "
19- . ($nibble_iter->nibble_index() || '?')
20- . " index, but MySQL EXPLAIN reports that "
21- . ($expl->{key} ? "the $expl->{key}" : "no")
22- . " index will be used for "
23- . $sth->{upper_boundary}->{Statement}
24- . " with values "
25- . join(", ", map { defined $_ ? $_ : "NULL" }
26- (@{$boundary->{lower}}, $nibble_iter->limit()))
27- . "\n";
28- die ts($msg);
29- }
30+ # Skip if --nocheck-plan See: https://bugs.launchpad.net/percona-toolkit/+bug/1340728
31+ if ( $o->get('check-plan') ) {
32+ my $expl = explain_statement(
33+ tbl => $tbl,
34+ sth => $sth->{explain_upper_boundary},
35+ vals => [ @{$boundary->{lower}}, $nibble_iter->limit() ],
36+ );
37+ if ( lc($expl->{key} || '') ne lc($nibble_iter->nibble_index() || '') ) {
38+ my $msg
39+ = "Aborting copying table $tbl->{name} at chunk "
40+ . ($nibble_iter->nibble_number() + 1)
41+ . " because it is not safe to ascend. Chunking should "
42+ . "use the "
43+ . ($nibble_iter->nibble_index() || '?')
44+ . " index, but MySQL EXPLAIN reports that "
45+ . ($expl->{key} ? "the $expl->{key}" : "no")
46+ . " index will be used for "
47+ . $sth->{upper_boundary}->{Statement}
48+ . " with values "
49+ . join(", ", map { defined $_ ? $_ : "NULL" }
50+ (@{$boundary->{lower}}, $nibble_iter->limit()))
51+ . "\n";
52+ die ts($msg);
53+ }
54+ }
55
56 # Once nibbling begins for a table, control does not return to this
57 # tool until nibbling is done because, as noted above, all work is
58@@ -9531,15 +9534,17 @@
59 vals => [ @{$boundary->{lower}}, @{$boundary->{upper}} ],
60 );
61
62- # Ensure that MySQL is using the chunk index if the table is being chunked.
63- if ( !$nibble_iter->one_nibble()
64- && lc($expl->{key} || '') ne lc($nibble_iter->nibble_index() || '') )
65- {
66- die ts("Error copying rows at chunk " . $nibble_iter->nibble_number()
67- . " of $tbl->{db}.$tbl->{tbl} because MySQL chose "
68- . ($expl->{key} ? "the $expl->{key}" : "no") . " index "
69- . " instead of the " . $nibble_iter->nibble_index() . "index.\n");
70- }
71+ # Ensure that MySQL is using the chunk index if the table is being chunked.
72+ # Skip if --nocheck-plan See: https://bugs.launchpad.net/percona-toolkit/+bug/1340728
73+ if ( !$nibble_iter->one_nibble()
74+ && lc($expl->{key} || '') ne lc($nibble_iter->nibble_index() || '')
75+ && $o->get('check-plan') )
76+ {
77+ die ts("Error copying rows at chunk " . $nibble_iter->nibble_number()
78+ . " of $tbl->{db}.$tbl->{tbl} because MySQL chose "
79+ . ($expl->{key} ? "the $expl->{key}" : "no") . " index "
80+ . " instead of the " . $nibble_iter->nibble_index() . "index.\n");
81+ }
82
83 # Ensure that the chunk isn't too large if there's a --chunk-size-limit.
84 # If single-chunking the table, this has already been checked, so it
85@@ -9564,11 +9569,13 @@
86 }
87 }
88
89- # Ensure that MySQL is still using the entire index.
90+ # Ensure that MySQL is still using the entire index.
91 # https://bugs.launchpad.net/percona-toolkit/+bug/1010232
92+ # Skip if --nocheck-plan See: https://bugs.launchpad.net/percona-toolkit/+bug/1340728
93 if ( !$nibble_iter->one_nibble()
94 && $tbl->{key_len}
95- && ($expl->{key_len} || 0) < $tbl->{key_len} )
96+ && ($expl->{key_len} || 0) < $tbl->{key_len}
97+ && $o->get('check-plan') )
98 {
99 die ts("Error copying rows at chunk " . $nibble_iter->nibble_number()
100 . " of $tbl->{db}.$tbl->{tbl} because MySQL used "
101
102=== removed file 't/pt-online-schema-change/bug-1315130.t'
103--- t/pt-online-schema-change/bug-1315130.t 2014-06-20 21:31:30 +0000
104+++ t/pt-online-schema-change/bug-1315130.t 1970-01-01 00:00:00 +0000
105@@ -1,78 +0,0 @@
106-#!/usr/bin/env perl
107-
108-BEGIN {
109- die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n"
110- unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH};
111- unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib";
112-};
113-
114-use strict;
115-use warnings FATAL => 'all';
116-use English qw(-no_match_vars);
117-use Test::More;
118-use Time::HiRes qw(sleep);
119-
120-$ENV{PTTEST_FAKE_TS} = 1;
121-$ENV{PERCONA_TOOLKIT_TEST_USE_DSN_NAMES} = 1;
122-
123-use PerconaTest;
124-use Sandbox;
125-require "$trunk/bin/pt-online-schema-change";
126-require VersionParser;
127-
128-use Data::Dumper;
129-$Data::Dumper::Indent = 1;
130-$Data::Dumper::Sortkeys = 1;
131-$Data::Dumper::Quotekeys = 0;
132-
133-my $dp = new DSNParser(opts=>$dsn_opts);
134-my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
135-my $master_dbh = $sb->get_dbh_for('master');
136-my $slave_dbh = $sb->get_dbh_for('slave1');
137-
138-if ( !$master_dbh ) {
139- plan skip_all => 'Cannot connect to sandbox master';
140-}
141-elsif ( !$slave_dbh ) {
142- plan skip_all => 'Cannot connect to sandbox slave';
143-}
144-
145-my $q = new Quoter();
146-my $tp = new TableParser(Quoter => $q);
147-my @args = qw(--set-vars innodb_lock_wait_timeout=3);
148-my $output = "";
149-my $dsn = "h=127.1,P=12345,u=msandbox,p=msandbox";
150-my $exit = 0;
151-my $sample = "t/pt-online-schema-change/samples";
152-my $rows;
153-
154-
155-# #############################################################################
156-# Issue 1315130
157-# Failed to detect child tables in other schema, and falsely identified
158-# child tables in own schema
159-# #############################################################################
160-
161-$sb->load_file('master', "$sample/bug-1315130_cleanup.sql");
162-$sb->load_file('master', "$sample/bug-1315130.sql");
163-($output, $exit) = full_output(
164- sub { pt_online_schema_change::main(@args, "$dsn,D=bug_1315130_a,t=parent_table",
165- '--dry-run',
166- '--alter', "add column c varchar(16)",
167- '--alter-foreign-keys-method', 'auto'),
168- },
169-);
170-print STDERR "[$output]\n";
171- like(
172- $output,
173- qr/Child tables:\s*`bug_1315130_a`\.`child_table_in_same_schema` \(approx\. 1 rows\)\s*`bug_1315130_b`\.`child_table_in_second_schema` \(approx\. 1 rows\)[^`]*?Will/s,
174- "Correctly identify child tables from other schemas and ignores tables from same schema referencig same named parent in other schema.",
175- );
176-# clear databases with their foreign keys
177-$sb->load_file('master', "$sample/bug-1315130_cleanup.sql");
178-
179-# Done.
180-# #############################################################################
181-$sb->wipe_clean($master_dbh);
182-ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
183-done_testing;
184
185=== modified file 't/pt-online-schema-change/bugs.t'
186--- t/pt-online-schema-change/bugs.t 2013-06-26 20:28:27 +0000
187+++ t/pt-online-schema-change/bugs.t 2014-08-05 15:51:35 +0000
188@@ -124,7 +124,11 @@
189 {
190 my $o = new OptionParser(file => "$trunk/bin/pt-table-checksum");
191 $o->get_specs();
192+
193+ $o->set('check-plan', 1); # check-plan is true by default
194+
195 no warnings;
196+
197 local *pt_online_schema_change::explain_statement = sub {
198 return { key => 'some_key' }
199 };
200@@ -369,6 +373,66 @@
201 "Bug 1188264: warning about expected MySQL error 1265"
202 );
203
204+
205+# #############################################################################
206+# Issue 1315130
207+# Failed to detect child tables in other schema, and falsely identified
208+# child tables in own schema
209+# #############################################################################
210+
211+$sb->load_file('master', "$sample/bug-1315130_cleanup.sql");
212+$sb->load_file('master', "$sample/bug-1315130.sql");
213+
214+$output = output(
215+ sub { pt_online_schema_change::main(@args, "$master_dsn,D=bug_1315130_a,t=parent_table",
216+ '--dry-run',
217+ '--alter', "add column c varchar(16)",
218+ '--alter-foreign-keys-method', 'auto'),
219+ },
220+);
221+
222+ like(
223+ $output,
224+ qr/Child tables:\s*`bug_1315130_a`\.`child_table_in_same_schema` \(approx\. 1 rows\)\s*`bug_1315130_b`\.`child_table_in_second_schema` \(approx\. 1 rows\)[^`]*?Will/s,
225+ "Correctly identify child tables from other schemas and ignores tables from same schema referencig same named parent in other schema.",
226+ );
227+# clear databases with their foreign keys
228+$sb->load_file('master', "$sample/bug-1315130_cleanup.sql");
229+
230+
231+# #############################################################################
232+# Issue 1340728
233+# fails when no index is returned in EXPLAIN, even though --nocheck-plan is set
234+# (happens on HASH indexes)
235+# #############################################################################
236+
237+$sb->load_file('master', "$sample/bug-1340728_cleanup.sql");
238+$sb->load_file('master', "$sample/bug-1340728.sql");
239+
240+# insert a few thousand rows (else test isn't valid)
241+my $rows = 5000;
242+for (my $i = 0; $i < $rows; $i++) {
243+ $master_dbh->do("INSERT INTO bug_1340728.test VALUES (NULL, 'xx')");
244+}
245+
246+
247+$output = output(
248+ sub { pt_online_schema_change::main(@args, "$master_dsn,D=bug_1340728,t=test",
249+ '--execute',
250+ '--alter', "ADD COLUMN c INT",
251+ '--nocheck-plan',
252+ ),
253+ },
254+);
255+
256+ like(
257+ $output,
258+ qr/Successfully altered/s,
259+ "--nocheck-plan ignores plans without index",
260+ );
261+# clear databases
262+$sb->load_file('master', "$sample/bug-1340728_cleanup.sql");
263+
264 # #############################################################################
265 # Done.
266 # #############################################################################
267
268=== added file 't/pt-online-schema-change/samples/bug-1340728.sql'
269--- t/pt-online-schema-change/samples/bug-1340728.sql 1970-01-01 00:00:00 +0000
270+++ t/pt-online-schema-change/samples/bug-1340728.sql 2014-08-05 15:51:35 +0000
271@@ -0,0 +1,10 @@
272+drop database if exists bug_1340728;
273+create database bug_1340728;
274+use bug_1340728;
275+
276+CREATE TABLE `test` (
277+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
278+ `name` char(2) NOT NULL,
279+ PRIMARY KEY (`id`) USING HASH
280+) ENGINE=MEMORY DEFAULT CHARSET=latin1;
281+
282
283=== added file 't/pt-online-schema-change/samples/bug-1340728_cleanup.sql'
284--- t/pt-online-schema-change/samples/bug-1340728_cleanup.sql 1970-01-01 00:00:00 +0000
285+++ t/pt-online-schema-change/samples/bug-1340728_cleanup.sql 2014-08-05 15:51:35 +0000
286@@ -0,0 +1,2 @@
287+drop database if exists bug_1340728;
288+

Subscribers

People subscribed via source and target branches

to all changes: