Merge lp:~percona-toolkit-dev/percona-toolkit/fix-950294-ptc-if-not-exists into lp:percona-toolkit/2.1

Proposed by Brian Fraser
Status: Merged
Approved by: Daniel Nichter
Approved revision: 333
Merged at revision: 335
Proposed branch: lp:~percona-toolkit-dev/percona-toolkit/fix-950294-ptc-if-not-exists
Merge into: lp:percona-toolkit/2.1
Diff against target: 242 lines (+143/-18) (has conflicts)
2 files modified
bin/pt-table-checksum (+63/-15)
t/pt-table-checksum/privs.t (+80/-3)
Text conflict in bin/pt-table-checksum
Text conflict in t/pt-table-checksum/privs.t
To merge this branch: bzr merge lp:~percona-toolkit-dev/percona-toolkit/fix-950294-ptc-if-not-exists
Reviewer Review Type Date Requested Status
Daniel Nichter Approve
Review via email: mp+117303@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Daniel Nichter (daniel-nichter) wrote :

1) "--no-create-replicate-table was passed in." -> ""--no-create-replicate-table was specified."

2)

29 + print STDERR "CREATE DATABASE IF NOT EXISTS $db failed, but the "
30 + . "db already exists. This is harmless unless the "
31 + . "slaves don't have the database. $EVAL_ERROR"; # kb link?

I think we need to make this fatal because we must avoid breaking replication. So:

die "Error executing $sql: $EVAL_ERROR\nThe database exists on the master, but replication will break if it does not also exist on all replicas. If the --replicate database and table already exist on the master and all replicas, or if you create them manually, then specify --no-create-replicate-table to avoid this error."

How does that ^ sound? Better to force the user to think/do a little manual work than break their replication.

3) 49 +<<<<<<< TREE -- why is there a merge conflict?

4) 63 + . "--no-create-replicate-table was passed in. " -- "passed id" -> "specified"

5) 73 + print STDERR "CREATE TABLE IF NOT EXISTS $args{repl_table} " -- Same as above with the db: make fatal, change error message, etc.

6) 142 +isnt($exit_status, 0, "");

i) Let's never use isnt() because 1) it amounts to "yes we have no bananas" ("yes, $got is not $bar") and 2) it's dangerously close to isn't() which is just crazy.

ii) Test has no name.

review: Needs Fixing
333. By Brian Fraser <email address hidden>

Resolved a pending merge conflict.

The fix for https://bugs.launchpad.net/percona-toolkit/+bug/916168
was affecting the same code as this fix.
This commit mimicks that fix, and removes the privs checks.

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-table-checksum'
2--- bin/pt-table-checksum 2012-07-30 14:30:05 +0000
3+++ bin/pt-table-checksum 2012-07-31 15:30:27 +0000
4@@ -8152,17 +8152,38 @@
5 my $sql = "SHOW DATABASES LIKE '$db'";
6 PTDEBUG && _d($sql);
7 my @db_exists = $dbh->selectrow_array($sql);
8- if ( !@db_exists && $o->get('create-replicate-table') ) {
9- $sql = "CREATE DATABASE " . $q->quote($db) . " /* pt-table-checksum */";
10+ if ( !@db_exists && !$o->get('create-replicate-table') ) {
11+ die "--replicate database $db does not exist and "
12+ . "--no-create-replicate-table was specified. You need "
13+ . "to create the database.\n";
14+ }
15+
16+ if ( $o->get('create-replicate-table') ) {
17+ $sql = "CREATE DATABASE IF NOT EXISTS "
18+ . $q->quote($db)
19+ . " /* pt-table-checksum */";
20+ local $@;
21+ PTDEBUG && _d($sql);
22 eval {
23 $dbh->do($sql);
24 };
25 if ( $EVAL_ERROR ) {
26- die "--replicate database $db does not exist and it cannot be "
27- . "created automatically. You need to create the database.\n";
28+ if ( @db_exists ) {
29+ die "Error executing $sql: $EVAL_ERROR\n"
30+ . "The database exists on the master, but replication will "
31+ . "break if it does not also exist on all replicas. If the "
32+ . "--replicate database and table already exist on the master "
33+ . "and all replicas, or if you created them manually, then "
34+ . "specify --no-create-replicate-table to avoid this error."
35+ }
36+ else {
37+ die "--replicate database $db does not exist and it cannot be "
38+ . "created automatically. You need to create the database. "
39+ . $EVAL_ERROR;
40+ }
41 }
42 }
43-
44+
45 # USE the correct db (probably the repl db, but maybe --replicate-database).
46 use_repl_db(%args);
47
48@@ -8172,20 +8193,47 @@
49 db => $db,
50 tbl => $tbl,
51 );
52+
53+ # Always create the table, unless --no-create-replicate-table
54+ # was passed in; see https://bugs.launchpad.net/percona-toolkit/+bug/950294
55 if ( !$tbl_exists ) {
56- if ( $o->get('create-replicate-table') ) {
57- create_repl_table(%args)
58- }
59- else {
60- die "--replicate table $repl_table does not exist; "
61- . "read the documentation or use --create-replicate-table "
62- . "to create it.\n";
63+ if ( !$o->get('create-replicate-table') ) {
64+ die "--replicate table $repl_table does not exist and "
65+ . "--no-create-replicate-table was specified. "
66+ . "You need to create the table.\n";
67 }
68 }
69 else {
70 PTDEBUG && _d('--replicate table', $repl_table, 'already exists');
71- # We used to check the table privs here, but:
72- # https://bugs.launchpad.net/percona-toolkit/+bug/916168
73+<<<<<<< TREE
74+ # We used to check the table privs here, but:
75+ # https://bugs.launchpad.net/percona-toolkit/+bug/916168
76+=======
77+ # We used to check the table privs here, but:
78+ # https://bugs.launchpad.net/percona-toolkit/+bug/916168
79+ }
80+
81+ if ( $o->get('create-replicate-table') ) {
82+ local $@;
83+ eval {
84+ create_repl_table(%args);
85+ };
86+ if ( $EVAL_ERROR ) {
87+ if ( $tbl_exists ) {
88+ die "Error executing $sql: $EVAL_ERROR\n"
89+ . "The table exists on the master, but replication will "
90+ . "break if it does not also exist on all replicas. If the "
91+ . "--replicate database and table already exist on the master "
92+ . "and all replicas, or if you created them manually, then "
93+ . "specify --no-create-replicate-table to avoid this error."
94+ }
95+ else {
96+ die "--replicate table $tbl does not exist and it cannot be "
97+ . "created automatically. You need to create the table. "
98+ . $EVAL_ERROR;
99+ }
100+ }
101+>>>>>>> MERGE-SOURCE
102 }
103
104 # Check and wait for the repl table to appear on all slaves.
105@@ -8327,7 +8375,7 @@
106 my ($dbh, $repl_table, $o) = @args{@required_args};
107 PTDEBUG && _d('Creating --replicate table', $repl_table);
108 my $sql = $o->read_para_after(__FILE__, qr/MAGIC_create_replicate/);
109- $sql =~ s/CREATE TABLE checksums/CREATE TABLE $repl_table/;
110+ $sql =~ s/CREATE TABLE checksums/CREATE TABLE IF NOT EXISTS $repl_table/;
111 $sql =~ s/;$//;
112 PTDEBUG && _d($dbh, $sql);
113 eval {
114
115=== modified file 't/pt-table-checksum/privs.t'
116--- t/pt-table-checksum/privs.t 2012-07-20 23:58:44 +0000
117+++ t/pt-table-checksum/privs.t 2012-07-31 15:30:27 +0000
118@@ -41,9 +41,12 @@
119 elsif ( !@{$master_dbh->selectall_arrayref("show databases like 'sakila'")} ) {
120 plan skip_all => 'sakila database is not loaded';
121 }
122+<<<<<<< TREE
123 else {
124 plan tests => 4;
125 }
126+=======
127+>>>>>>> MERGE-SOURCE
128
129 # The sandbox servers run with lock_wait_timeout=3 and it's not dynamic
130 # so we need to specify --lock-wait-timeout=3 else the tool will die.
131@@ -55,6 +58,53 @@
132 my $sample = "t/pt-table-checksum/samples/";
133
134 # ############################################################################
135+# Should always create schema and tables with IF NOT EXISTS
136+# https://bugs.launchpad.net/percona-toolkit/+bug/950294
137+# ############################################################################
138+
139+$sb->wipe_clean($master_dbh);
140+diag(`/tmp/12345/use -u root < $trunk/t/lib/samples/ro-checksum-user.sql 2>/dev/null`);
141+PerconaTest::wait_for_table($slave1_dbh, "mysql.tables_priv", "user='ro_checksum_user'");
142+
143+($output, $exit_status) = full_output(
144+ sub { pt_table_checksum::main(@args,
145+ "$master_dsn,u=ro_checksum_user,p=msandbox",
146+ qw(--recursion-method none)
147+ ) },
148+);
149+
150+ok(
151+ $exit_status,
152+ "Dies with an error status if it can't create the db/table"
153+);
154+
155+like($output,
156+ qr/\Q--replicate database percona does not exist and it cannot be created automatically/,
157+ "fails if the percona db doesn't exist and the user can't create it",
158+);
159+
160+($output, $exit_status) = full_output(
161+ sub { pt_table_checksum::main(@args,
162+ "$master_dsn,u=ro_checksum_user,p=msandbox",
163+ qw(--recursion-method none --no-create-replicate-table)
164+ ) },
165+);
166+
167+like($output,
168+ qr/\Q--replicate database percona does not exist and --no-create-replicate-table was/,
169+ "fails if the percona db doesn't exist and --no-create-replicate-table",
170+);
171+
172+diag(`/tmp/12345/use -u root -e "drop user 'ro_checksum_user'\@'%'"`);
173+wait_until(
174+ sub {
175+ my $rows=$slave2_dbh->selectall_arrayref("SELECT user FROM mysql.user");
176+ return !grep { ($_->[0] || '') ne 'ro_checksum_user' } @$rows;
177+ }
178+);
179+$sb->wipe_clean($master_dbh);
180+
181+# ############################################################################
182 # --recursion-method=none to avoid SHOW SLAVE HOSTS
183 # https://bugs.launchpad.net/percona-toolkit/+bug/987694
184 # ############################################################################
185@@ -64,7 +114,7 @@
186 "$master_dsn,u=msandbox,p=msandbox",
187 qw(-t sakila.country --quiet --quiet));
188
189-diag(`/tmp/12345/use -u root < $trunk/t/lib/samples/ro-checksum-user.sql`);
190+diag(`/tmp/12345/use -u root < $trunk/t/lib/samples/ro-checksum-user.sql 2>/dev/null`);
191 PerconaTest::wait_for_table($slave1_dbh, "mysql.tables_priv", "user='ro_checksum_user'");
192
193 $output = output(
194@@ -73,7 +123,7 @@
195 # Comment out this line and the tests fail because ro_checksum_user
196 # doesn't have privs to SHOW SLAVE HOSTS. This proves that
197 # --recursion-method none is working.
198- qw(--recursion-method none)
199+ qw(--recursion-method none --no-create-replicate-table)
200 ) },
201 stderr => 1,
202 );
203@@ -90,6 +140,32 @@
204 "Read-only user (bug 987694): checksummed rows"
205 );
206
207+($output) = full_output(
208+ sub { $exit_status = pt_table_checksum::main(@args,
209+ "$master_dsn,u=ro_checksum_user,p=msandbox",
210+ qw(--recursion-method none)
211+ ) }
212+);
213+
214+like($output,
215+ qr/\QThe database exists on the master, but replication will break/,
216+ "dies if the db exists on the master but it can't CREATE DATABASE and --no-create-replicate-table was not specified",
217+);
218+
219+diag(qx{/tmp/12345/use -u root -e 'DROP TABLE `percona`.`checksums`'});
220+
221+($output, $exit_status) = full_output(
222+ sub { pt_table_checksum::main(@args,
223+ "$master_dsn,u=ro_checksum_user,p=msandbox",
224+ qw(--recursion-method none --no-create-replicate-table)
225+ ) },
226+);
227+
228+like($output,
229+ qr/\Q--replicate table `percona`.`checksums` does not exist and --no/,
230+ "fails if the checksums db doesn't exist and --no-create-replicate-table"
231+);
232+
233 diag(`/tmp/12345/use -u root -e "drop user 'ro_checksum_user'\@'%'"`);
234 wait_until(
235 sub {
236@@ -127,4 +203,5 @@
237 # #############################################################################
238 $sb->wipe_clean($master_dbh);
239 ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
240-exit;
241+
242+done_testing;

Subscribers

People subscribed via source and target branches