Merge lp:~percona-toolkit-dev/percona-toolkit/fix-sync-index-bug-1003014 into lp:percona-toolkit/2.1

Proposed by Daniel Nichter
Status: Merged
Merged at revision: 261
Proposed branch: lp:~percona-toolkit-dev/percona-toolkit/fix-sync-index-bug-1003014
Merge into: lp:percona-toolkit/2.1
Diff against target: 236 lines (+209/-0)
3 files modified
bin/pt-table-sync (+18/-0)
t/pt-table-sync/bugs.t (+156/-0)
t/pt-table-sync/samples/wrong-tbl-struct-bug-1003014.sql (+35/-0)
To merge this branch: bzr merge lp:~percona-toolkit-dev/percona-toolkit/fix-sync-index-bug-1003014
Reviewer Review Type Date Requested Status
Daniel Nichter Approve
Review via email: mp+106866@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-table-sync'
2--- bin/pt-table-sync 2012-05-21 21:50:40 +0000
3+++ bin/pt-table-sync 2012-05-22 17:50:26 +0000
4@@ -8035,6 +8035,16 @@
5 lock_server(src => $src, dst => $dst, %args);
6
7 foreach my $diff ( @$diffs ) {
8+ # Clear the tbl_struct if this is a new table. The tbl_struct
9+ # is fetched and parsed in ok_to_sync() if not set. We only
10+ # need to set it once per table to avoid doing this for every
11+ # diff in the same table.
12+ # https://bugs.launchpad.net/percona-toolkit/+bug/1003014
13+ if ( ($src->{db} || '') ne $diff->{db}
14+ || ($src->{tbl} || '') ne $diff->{tbl} ) {
15+ PTDEBUG && _d('New table:', $diff->{db}, $diff->{tbl});
16+ $src->{tbl_struct} = undef;
17+ }
18 $src->{db} = $dst->{db} = $diff->{db};
19 $src->{tbl} = $dst->{tbl} = $diff->{tbl};
20
21@@ -8103,6 +8113,14 @@
22 lock_server(src => $src, dst => $dst, %args);
23
24 foreach my $diff ( @$diffs ) {
25+ # Clear the tbl_struct if this is a new table.
26+ # See the same code block above.
27+ if ( ($src->{db} || '') ne $diff->{db}
28+ || ($src->{tbl} || '') ne $diff->{tbl} ) {
29+ PTDEBUG && _d('New table:',
30+ $diff->{db}, $diff->{tbl});
31+ $src->{tbl_struct} = undef;
32+ }
33 $src->{db} = $dst->{db} = $diff->{db};
34 $src->{tbl} = $dst->{tbl} = $diff->{tbl};
35
36
37=== added file 't/pt-table-sync/bugs.t'
38--- t/pt-table-sync/bugs.t 1970-01-01 00:00:00 +0000
39+++ t/pt-table-sync/bugs.t 2012-05-22 17:50:26 +0000
40@@ -0,0 +1,156 @@
41+#!/usr/bin/env perl
42+
43+BEGIN {
44+ die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n"
45+ unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH};
46+ unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib";
47+};
48+
49+use strict;
50+use warnings FATAL => 'all';
51+use English qw(-no_match_vars);
52+use Test::More;
53+use Data::Dumper;
54+
55+use PerconaTest;
56+use Sandbox;
57+require "$trunk/bin/pt-table-sync";
58+
59+my $output;
60+my $dp = new DSNParser(opts=>$dsn_opts);
61+my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
62+my $master_dbh = $sb->get_dbh_for('master');
63+my $slave_dbh = $sb->get_dbh_for('slave1');
64+
65+if ( !$master_dbh ) {
66+ plan skip_all => 'Cannot connect to sandbox master';
67+}
68+elsif ( !$slave_dbh ) {
69+ plan skip_all => 'Cannot connect to sandbox slave';
70+}
71+else {
72+ plan tests => 8;
73+}
74+
75+my $sample = "t/pt-table-sync/samples";
76+my $master_dsn = "h=127.1,P=12345,u=msandbox,p=msandbox";
77+my $slave_dsn = "h=127.1,P=12346,u=msandbox,p=msandbox";
78+
79+# #############################################################################
80+#
81+# #############################################################################
82+
83+$sb->load_file('master', "$sample/wrong-tbl-struct-bug-1003014.sql");
84+PerconaTest::wait_for_table($slave_dbh, "test.zzz", "id=111");
85+
86+# Make a diff in each table.
87+$slave_dbh->do("DELETE FROM test.aaa WHERE STOP_ARCHIVE IN (5,6,7)");
88+$slave_dbh->do("UPDATE test.zzz SET c='x' WHERE id IN (44,45,46)");
89+
90+$output = `$trunk/bin/pt-table-checksum $master_dsn --lock-wait-timeout 3 --max-load '' -d test --chunk-size 10 2>&1`;
91+
92+is(
93+ PerconaTest::count_checksum_results($output, 'diffs'),
94+ 2,
95+ "Bug 1003014 (wrong tbl_struct): 2 diffs"
96+) or print STDERR $output;
97+
98+my $checksums = [
99+ [qw( test aaa 1 )],
100+ [qw( test zzz 1 )],
101+ [qw( test zzz 2 )],
102+ [qw( test zzz 3 )],
103+ [qw( test zzz 4 )],
104+ [qw( test zzz 5 )],
105+ [qw( test zzz 6 )],
106+ [qw( test zzz 7 )],
107+ [qw( test zzz 8 )],
108+ [qw( test zzz 9 )],
109+ [qw( test zzz 10 )],
110+ [qw( test zzz 11 )],
111+ [qw( test zzz 12 )],
112+ [qw( test zzz 13 )],
113+ [qw( test zzz 14 )],
114+];
115+
116+my $rows = $master_dbh->selectall_arrayref("SELECT db, tbl, chunk FROM percona.checksums ORDER BY db, tbl, chunk");
117+is_deeply(
118+ $rows,
119+ $checksums,
120+ "Bug 1003014 (wrong tbl_struct): checksums"
121+);
122+
123+my $exit_status;
124+$output = output(
125+ sub { $exit_status = pt_table_sync::main($slave_dsn,
126+ qw(--replicate percona.checksums --sync-to-master --print --execute),
127+ "--tables", "test.aaa,test.zzz") },
128+ stderr => 1,
129+);
130+
131+is(
132+ $exit_status,
133+ 2, # rows synced OK; 3=error (1) & rows synced (2)
134+ "Bug 1003014 (wrong tbl_struct): 0 exit"
135+) or diag($output);
136+
137+$rows = $slave_dbh->selectall_arrayref("SELECT c FROM test.zzz WHERE id IN (44,45,46)");
138+is_deeply(
139+ $rows,
140+ [ ['a'], ['a'], ['a'] ],
141+ "Bug 1003014 (wrong tbl_struct): synced rows"
142+);
143+
144+# #########################################################################
145+# Repeat the whole process without --sync-to-master so the second code path
146+# in sync_via_replication() is tested.
147+# #########################################################################
148+
149+$sb->wipe_clean($master_dbh);
150+
151+$sb->load_file('master', "$sample/wrong-tbl-struct-bug-1003014.sql");
152+PerconaTest::wait_for_table($slave_dbh, "test.zzz", "id=111");
153+
154+$slave_dbh->do("DELETE FROM test.aaa WHERE STOP_ARCHIVE IN (5,6,7)");
155+$slave_dbh->do("UPDATE test.zzz SET c='x' WHERE id IN (44,45,46)");
156+
157+$output = `$trunk/bin/pt-table-checksum $master_dsn --lock-wait-timeout 3 --max-load '' -d test --chunk-size 10 2>&1`;
158+
159+is(
160+ PerconaTest::count_checksum_results($output, 'diffs'),
161+ 2,
162+ "Bug 1003014 (wrong tbl_struct): 2 diffs (just replicate)"
163+) or print STDERR $output;
164+
165+$rows = $master_dbh->selectall_arrayref("SELECT db, tbl, chunk FROM percona.checksums ORDER BY db, tbl, chunk");
166+is_deeply(
167+ $rows,
168+ $checksums,
169+ "Bug 1003014 (wrong tbl_struct): checksums (just replicate)"
170+);
171+
172+$output = output(
173+ sub { $exit_status = pt_table_sync::main($master_dsn,
174+ qw(--replicate percona.checksums --print --execute),
175+ "--tables", "test.aaa,test.zzz") },
176+ stderr => 1,
177+);
178+
179+is(
180+ $exit_status,
181+ 2, # rows synced OK; 3=error (1) & rows synced (2)
182+ "Bug 1003014 (wrong tbl_struct): 0 exit (just replicate)"
183+) or diag($output);
184+
185+$rows = $slave_dbh->selectall_arrayref("SELECT c FROM test.zzz WHERE id IN (44,45,46)");
186+is_deeply(
187+ $rows,
188+ [ ['a'], ['a'], ['a'] ],
189+ "Bug 1003014 (wrong tbl_struct): synced rows (just replicate)"
190+);
191+
192+# #############################################################################
193+# Done.
194+# #############################################################################
195+$sb->wipe_clean($master_dbh);
196+exit;
197
198=== added file 't/pt-table-sync/samples/wrong-tbl-struct-bug-1003014.sql'
199--- t/pt-table-sync/samples/wrong-tbl-struct-bug-1003014.sql 1970-01-01 00:00:00 +0000
200+++ t/pt-table-sync/samples/wrong-tbl-struct-bug-1003014.sql 2012-05-22 17:50:26 +0000
201@@ -0,0 +1,35 @@
202+drop database if exists test;
203+create database test;
204+use test;
205+
206+--
207+-- Checksum aaa in one chunk, make it differ, sync it first.
208+--
209+create table aaa (
210+ `STOP_ARCHIVE` int(11) NOT NULL default '1',
211+ UNIQUE KEY `STOP_ARCHIVE` (`STOP_ARCHIVE`)
212+) ENGINE=MyISAM;
213+
214+insert into aaa values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
215+
216+--
217+-- Checksum zzz in chunks, make a chunk differ, sync it 2nd.
218+--
219+create table `zzz` (
220+ id int not null primary key,
221+ c varchar(16) not null
222+);
223+
224+insert into zzz values
225+ (1,'a'),(2,'a'),(3,'a'),(4,'a'),(5,'a'),(6,'a'),(7,'a'),(8,'a'),(9,'a'),(10,'a'),
226+ (11,'a'),(12,'a'),(13,'a'),(14,'a'),(15,'a'),(16,'a'),(17,'a'),(18,'a'),(19,'a'),(20,'a'),
227+ (21,'a'),(22,'a'),(23,'a'),(24,'a'),(25,'a'),(26,'a'),(27,'a'),(28,'a'),(29,'a'),(30,'a'),
228+ (31,'a'),(32,'a'),(33,'a'),(34,'a'),(35,'a'),(36,'a'),(37,'a'),(38,'a'),(39,'a'),(40,'a'),
229+ (41,'a'),(42,'a'),(43,'a'),(44,'a'),(45,'a'),(46,'a'),(47,'a'),(48,'a'),(49,'a'),(50,'a'),
230+ (51,'a'),(52,'a'),(53,'a'),(54,'a'),(55,'a'),(56,'a'),(57,'a'),(58,'a'),(59,'a'),(60,'a'),
231+ (61,'a'),(62,'a'),(63,'a'),(64,'a'),(65,'a'),(66,'a'),(67,'a'),(68,'a'),(69,'a'),(70,'a'),
232+ (71,'a'),(72,'a'),(73,'a'),(74,'a'),(75,'a'),(76,'a'),(77,'a'),(78,'a'),(79,'a'),(80,'a'),
233+ (81,'a'),(82,'a'),(83,'a'),(84,'a'),(85,'a'),(86,'a'),(87,'a'),(88,'a'),(89,'a'),(90,'a'),
234+ (91,'a'),(92,'a'),(93,'a'),(94,'a'),(95,'a'),(96,'a'),(97,'a'),(98,'a'),(99,'a'),(100,'a'),
235+ (101,'a'),(102,'a'),(103,'a'),(104,'a'),(105,'a'),(106,'a'),(107,'a'),(108,'a'),(109,'a'),(110,'a'),
236+ (111, 'a');

Subscribers

People subscribed via source and target branches