Merge lp:~percona-toolkit-dev/percona-toolkit/fix-pt-osc-prefix-bug-1215608 into lp:~percona-toolkit-dev/percona-toolkit/release-2.2.5

Proposed by Daniel Nichter
Status: Merged
Approved by: Daniel Nichter
Approved revision: 630
Merged at revision: 627
Proposed branch: lp:~percona-toolkit-dev/percona-toolkit/fix-pt-osc-prefix-bug-1215608
Merge into: lp:~percona-toolkit-dev/percona-toolkit/release-2.2.5
Diff against target: 198 lines (+75/-29)
2 files modified
bin/pt-online-schema-change (+46/-28)
t/pt-online-schema-change/basics.t (+29/-1)
To merge this branch: bzr merge lp:~percona-toolkit-dev/percona-toolkit/fix-pt-osc-prefix-bug-1215608
Reviewer Review Type Date Requested Status
Daniel Nichter Approve
Review via email: mp+190286@code.launchpad.net
To post a comment you must log in.
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 2013-10-09 20:23:10 +0000
3+++ bin/pt-online-schema-change 2013-10-10 02:14:57 +0000
4@@ -8430,19 +8430,27 @@
5 # Step 1: Create the new table.
6 # #####################################################################
7
8+ my $new_table_name = $o->get('new-table-name');
9+ my $new_table_prefix = $o->got('new-table-name') ? undef : '_';
10+
11 # --plugin hook
12- if ( $plugin && $plugin->can('before_create_new_table') ) {
13- $plugin->before_create_new_table();
14+ if ( $plugin && $plugin->can('before_create_new_table') ) {
15+ $plugin->before_create_new_table(
16+ new_table_name => $new_table_name,
17+ new_table_prefix => $new_table_prefix,
18+ );
19 }
20
21 my $new_tbl;
22 eval {
23 $new_tbl = create_new_table(
24- orig_tbl => $orig_tbl,
25- Cxn => $cxn,
26- Quoter => $q,
27- OptionParser => $o,
28- TableParser => $tp,
29+ new_table_name => $new_table_name,
30+ new_table_prefix => $new_table_prefix,
31+ orig_tbl => $orig_tbl,
32+ Cxn => $cxn,
33+ Quoter => $q,
34+ OptionParser => $o,
35+ TableParser => $tp,
36 );
37 };
38 if ( $EVAL_ERROR ) {
39@@ -9528,11 +9536,12 @@
40
41 sub create_new_table {
42 my (%args) = @_;
43- my @required_args = qw(orig_tbl Cxn Quoter OptionParser TableParser);
44+ my @required_args = qw(new_table_name orig_tbl Cxn Quoter OptionParser TableParser);
45 foreach my $arg ( @required_args ) {
46 die "I need a $arg argument" unless $args{$arg};
47 }
48- my ($orig_tbl, $cxn, $q, $o, $tp) = @args{@required_args};
49+ my ($new_table_name, $orig_tbl, $cxn, $q, $o, $tp) = @args{@required_args};
50+ my $new_table_prefix = $args{new_table_prefix};
51
52 # Get the original table struct.
53 my $ddl = $tp->get_create_table(
54@@ -9541,25 +9550,23 @@
55 $orig_tbl->{tbl},
56 );
57
58- my $tries = $args{tries} || 10; # don't try forever
59- my $prefix = $args{prefix} || '_';
60- my $suffix = '_new';
61- my $table_name = $orig_tbl->{tbl} . $suffix;
62+ $new_table_name =~ s/%T/$orig_tbl->{tbl}/;
63
64 print "Creating new table...\n";
65+ my $tries = $new_table_prefix ? 10 : 1;
66 my $tryno = 1;
67 my @old_tables;
68- while ( $tryno++ < $tries ) {
69- $table_name = $prefix . $table_name;
70+ while ( $tryno++ <= $tries ) {
71+ if ( $new_table_prefix ) {
72+ $new_table_name = $new_table_prefix . $new_table_name;
73+ }
74
75- if ( length($table_name) > 64 ) {
76- my $truncated_table_name = substr($table_name, 0, 60) . $suffix;
77- PTDEBUG && _d($table_name, 'is over 64 characters long, truncating to',
78- $truncated_table_name);
79- $table_name = $truncated_table_name;
80+ if ( length($new_table_name) > 64 ) {
81+ my $truncated_table_name = substr($new_table_name, 0, 64);
82+ PTDEBUG && _d($new_table_name, 'is over 64 characters long, '
83+ . 'truncating to', $truncated_table_name);
84+ $new_table_name = $truncated_table_name;
85 }
86-
87- my $quoted = $q->quote($orig_tbl->{db}, $table_name);
88
89 # Generate SQL to create the new table. We do not use CREATE TABLE LIKE
90 # because it doesn't preserve foreign key constraints. Here we need to
91@@ -9572,6 +9579,7 @@
92 # or another table, we can still have a collision. But if there are
93 # multiple FKs on this table, it's hard to know which one is causing the
94 # trouble. Should we generate random/UUID FK names or something instead?
95+ my $quoted = $q->quote($orig_tbl->{db}, $new_table_name);
96 my $sql = $ddl;
97 $sql =~ s/\ACREATE TABLE .*?\($/CREATE TABLE $quoted (/m;
98 $sql =~ s/^ CONSTRAINT `/ CONSTRAINT `_/gm;
99@@ -9590,7 +9598,7 @@
100 # to have a similarly named table created by the user for other
101 # purposes.
102 if ( $EVAL_ERROR =~ m/table.+?already exists/i ) {
103- push @old_tables, $q->quote($orig_tbl->{db}, $table_name);
104+ push @old_tables, $q->quote($orig_tbl->{db}, $new_table_name);
105 next;
106 }
107
108@@ -9598,11 +9606,11 @@
109 die $EVAL_ERROR;
110 }
111 print $sql, "\n" if $o->get('print'); # the sql that work
112- print "Created new table $orig_tbl->{db}.$table_name OK.\n";
113+ print "Created new table $orig_tbl->{db}.$new_table_name OK.\n";
114 return { # success
115 db => $orig_tbl->{db},
116- tbl => $table_name,
117- name => $q->quote($orig_tbl->{db}, $table_name),
118+ tbl => $new_table_name,
119+ name => $q->quote($orig_tbl->{db}, $new_table_name),
120 };
121 }
122
123@@ -10943,8 +10951,8 @@
124 Drop the new table if copying the original table fails.
125
126 Specifying C<--no-drop-new-table> and C<--no-swap-tables> leaves the new,
127-altered copy of the table without modifying the original table. The new
128-table name is like C<_TBL_new> where C<TBL> is the table name.
129+altered copy of the table without modifying the original table. See
130+L<"--new-table-name">.
131
132 L<--no-drop-new-table> does not work with
133 C<alter-foreign-keys-method drop_swap>.
134@@ -11038,6 +11046,16 @@
135 however; it will only give the server a chance to recover from the queueing. If
136 you notice queueing, it is best to decrease the chunk time.
137
138+=item --new-table-name
139+
140+type: string; default: %T_new
141+
142+New table name before it is swapped. C<%T> is replaced with the original
143+table name. When the default is used, the tool prefixes the name with up
144+to 10 C<_> (underscore) to find a unique table name. If a table name is
145+specified, the tool does not prefix it with C<_>, so the table must not
146+exist.
147+
148 =item --password
149
150 short form: -p; type: string
151
152=== modified file 't/pt-online-schema-change/basics.t'
153--- t/pt-online-schema-change/basics.t 2013-10-09 20:23:10 +0000
154+++ t/pt-online-schema-change/basics.t 2013-10-10 02:14:57 +0000
155@@ -134,7 +134,7 @@
156 # should still exist, but not yet, so add it to the list so
157 # is_deeply() against $new_tbls passes. This only works for
158 # single-table tests.
159- my $new_tbl = "_${tbl}_new";
160+ my $new_tbl = $args{new_table} || "_${tbl}_new";
161 if ( grep { $_ eq '--no-drop-new-table' } @$cmds ) {
162 unshift @$orig_tbls, [$new_tbl];
163 }
164@@ -739,6 +739,34 @@
165 }
166
167 # #############################################################################
168+# --new-table-name
169+# #############################################################################
170+
171+test_alter_table(
172+ name => "--new-table-name %T_foo",
173+ table => "pt_osc.t",
174+ file => "basic_no_fks_innodb.sql",
175+ max_id => 20,
176+ test_type => "add_col",
177+ new_col => "foo",
178+ cmds => [
179+ qw(--execute --new-table-name %T_foo), '--alter', 'ADD COLUMN foo INT'
180+ ],
181+);
182+
183+test_alter_table(
184+ name => "--new-table-name static_new",
185+ table => "pt_osc.t",
186+ max_id => 20,
187+ test_type => "drop_col",
188+ drop_col => "foo",
189+ new_table => 'static_new',
190+ cmds => [
191+ qw(--execute --new-table-name static_new), '--alter', 'DROP COLUMN foo'
192+ ],
193+);
194+
195+# #############################################################################
196 # Done.
197 # #############################################################################
198 $sb->wipe_clean($master_dbh);

Subscribers

People subscribed via source and target branches

to all changes: