Merge lp:~gryp/percona-toolkit/pt-slave-restart-gtid-support into lp:~percona-toolkit-dev/percona-toolkit/release-2.2.8

Proposed by Kenny Gryp
Status: Merged
Approved by: Daniel Nichter
Approved revision: 604
Merged at revision: 601
Proposed branch: lp:~gryp/percona-toolkit/pt-slave-restart-gtid-support
Merge into: lp:~percona-toolkit-dev/percona-toolkit/release-2.2.8
Diff against target: 533 lines (+419/-13)
7 files modified
bin/pt-slave-restart (+132/-6)
lib/Sandbox.pm (+1/-0)
sandbox/start-sandbox (+8/-0)
sandbox/test-env (+10/-7)
t/pt-slave-restart/gtid.t (+203/-0)
t/pt-slave-restart/gtid_parallelreplication.t (+64/-0)
util/checksum-test-dataset (+1/-0)
To merge this branch: bzr merge lp:~gryp/percona-toolkit/pt-slave-restart-gtid-support
Reviewer Review Type Date Requested Status
Daniel Nichter Approve
Review via email: mp+217776@code.launchpad.net

Commit message

Added GTID support for pt-slave-restart.

Description of the change

Basic support for GTID's.

Documentation:

GLOBAL TRANSACTION IDS
       pt-slave-restart supports Global Transaction IDs, which has been
       introduced in MySQL in 5.6.5.

       It's important to keep in mind that:

       o pt-slave-restart will not skip transactions when multiple
           replication threads are being used (slave_parallel_workers>0).
           pt-slave-restart does not know what the GTID event is of the
           failed
           transaction of a specific slave thread.

       o The default behavior is to skip the next transaction from the
           slave's master. Writes can originate on different servers,each
           with their own unique UUID.

           See "--skip-gtid-uuid".

       --skip-gtid-uuid
           type: string; default: master

           When using GTID, an empty transaction should be created in
           order to
           skip it. If writes are coming from different nodes in the
           replication tree above, it is not possible to know which event
           from which UUID to skip.

           By default, the UUID from the slave's master is being used to
           skip.
           ("SHOW GLOBAL STATUS Master_UUID" column).

           Example: Master -> Slave1 -> Slave2. When skipping events from
           'Slave2', and writes originated from 'Master', --skip-gtid-uuid
           should be specified with the 'Master' it's UUID.

           See "GLOBAL TRANSACTION IDS".

To post a comment you must log in.
604. By Kenny Gryp

merge branch daniel

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-slave-restart'
2--- bin/pt-slave-restart 2014-02-20 08:10:16 +0000
3+++ bin/pt-slave-restart 2014-05-28 22:19:33 +0000
4@@ -4766,6 +4766,12 @@
5 use Percona::Toolkit;
6 use constant PTDEBUG => $ENV{PTDEBUG} || 0;
7
8+use Data::Dumper;
9+
10+local $Data::Dumper::Indent = 1;
11+local $Data::Dumper::Sortkeys = 1;
12+local $Data::Dumper::Quotekeys = 0;
13+
14 $OUTPUT_AUTOFLUSH = 1;
15
16 my $o;
17@@ -4976,10 +4982,36 @@
18 $start_sql .= " UNTIL RELAY_LOG_FILE = '$file', RELAY_LOG_POS = $pos";
19 }
20
21- my $set_skip = $dbh->prepare("SET GLOBAL SQL_SLAVE_SKIP_COUNTER = "
22- . $o->get('skip-count'));
23- my $start = $dbh->prepare($start_sql);
24- my $stop = $dbh->prepare('STOP SLAVE');
25+ my $start = $dbh->prepare($start_sql);
26+ my $stop = $dbh->prepare('STOP SLAVE');
27+
28+ # ########################################################################
29+ # Detect if GTID is enabled. Skipping an event is done differently.
30+ # ########################################################################
31+ # When MySQL 5.6.5 or higher is used and gtid is enabled, skipping a
32+ # transaction is not possible with SQL_SLAVE_SKIP_COUNTER
33+ my $skip_event;
34+ my $have_gtid = 0;
35+ if ( VersionParser->new($dbh) >= '5.6.5' ) {
36+ my $row = $dbh->selectrow_arrayref('SELECT @@GLOBAL.gtid_mode');
37+ PTDEBUG && _d('@@GLOBAL.gtid_mode:', $row->[0]);
38+ if ( $row && $row->[0] eq 'ON' ) {
39+ $have_gtid = 1;
40+ }
41+ }
42+ PTDEBUG && _d('Have GTID:', $have_gtid);
43+
44+ # If GTID is enabled, slave_parallel_workers should be == 0.
45+ # It's currently not possible to know what GTID event the failed trx is.
46+ if ( $have_gtid ) {
47+ my $threads = $dbh->selectrow_hashref(
48+ 'SELECT @@GLOBAL.slave_parallel_workers AS threads');
49+ if ( $threads->{threads} > 0 ) {
50+ die "Cannot skip transactions properly because GTID is enabled "
51+ . "and slave_parallel_workers > 0. See 'GLOBAL TRANSACTION IDS' "
52+ . "in the tool's documentation.\n";
53+ }
54+ }
55
56 # ########################################################################
57 # Lookup tables of things to do when a problem is detected.
58@@ -4989,7 +5021,7 @@
59 [ qr/Could not parse relay log event entry/ => 'refetch_relay_log' ],
60 [ qr/Incorrect key file for table/ => 'repair_table' ],
61 # This must be the last one. It's a catch-all rule: skip and restart.
62- [ qr/./ => 'skip' ],
63+ [ qr/./ => ($have_gtid ? 'skip_gtid' : 'skip') ],
64 );
65
66 # ########################################################################
67@@ -5012,9 +5044,61 @@
68 },
69 skip => sub {
70 my ( $stat, $dbh ) = @_;
71- PTDEBUG && _d('Found non-relay-log error');
72+ my $set_skip = $dbh->prepare("SET GLOBAL SQL_SLAVE_SKIP_COUNTER = "
73+ . $o->get('skip-count'));
74 $set_skip->execute();
75 },
76+ skip_gtid => sub {
77+ my ( $stat, $dbh ) = @_;
78+
79+ # Get master_uuid from SHOW SLAVE STATUS if a UUID is not specified
80+ # with --master-uuid.
81+ my $gtid_uuid = $o->get('master-uuid');
82+ if ( !$gtid_uuid ) {
83+ $gtid_uuid = $stat->{master_uuid};
84+ die "No master_uuid" unless $gtid_uuid; # shouldn't happen
85+ }
86+
87+ # We need the highest transaction in the executed_gtid_set.
88+ # and then we need to increase it by 1 (the one we want to skip)
89+ # Notes:
90+ # - does not work with parallel replication
91+ # - it skips the next transaction from the master_uuid
92+ # (when a slaveB is replicating from slaveA,
93+ # the master_uuid is it's own master, slaveA)
94+ my ($gtid_exec_ids) = ($stat->{executed_gtid_set} || '') =~ m/$gtid_uuid([0-9-:]*)/;
95+ $gtid_exec_ids =~ s/:[0-9]-/:/g;
96+ die "No executed GTIDs" unless $gtid_exec_ids;
97+
98+ my @gtid_exec_ranges = split(/:/, $gtid_exec_ids);
99+ delete $gtid_exec_ranges[0]; # undef the first value, it's always empty
100+
101+ # Get the highest id by sorting the array, removing the undef value.
102+ my @gtid_exec_sorted = sort { $a <=> $b }
103+ grep { defined($_) } @gtid_exec_ranges;
104+ my $gtid_exec_last = $gtid_exec_sorted[-1];
105+
106+ PTDEBUG && _d("\n",
107+ "GTID: master_uuid:", $gtid_uuid, "\n",
108+ "GTID: executed_gtid_set:", $gtid_exec_ids, "\n",
109+ "GTID: max for master_uuid:", $gtid_exec_sorted[-1], "\n",
110+ "GTID: last executed gtid:", $gtid_uuid, ":", $gtid_exec_last);
111+
112+ # Set the sessions next gtid, write an empty transaction
113+ my $skipped = 0;
114+ while ( $skipped++ < $o->get('skip-count') ) {
115+ my $gtid_next = $gtid_exec_last + $skipped;
116+ my $sql = "SET GTID_NEXT='$gtid_uuid:$gtid_next'";
117+ PTDEBUG && _d($sql);
118+ my $sth = $dbh->prepare($sql);
119+ $sth->execute();
120+ $dbh->begin_work();
121+ $dbh->commit();
122+ }
123+
124+ # Set the session back to the automatically generated GTID_NEXT.
125+ $dbh->do("SET GTID_NEXT='AUTOMATIC'");
126+ },
127 repair_table => sub {
128 my ( $stat, $dbh ) = @_;
129 PTDEBUG && _d('Found corrupt table');
130@@ -5301,6 +5385,28 @@
131
132 =back
133
134+=head1 GLOBAL TRANSACTION IDS
135+
136+As of Percona Toolkit 2.2.8, pt-slave-restart supports Global Transaction IDs
137+introduced in MySQL 5.6.5. It's important to keep in mind that:
138+
139+=over
140+
141+=item *
142+
143+pt-slave-restart will not skip transactions when multiple replication threads
144+are being used (slave_parallel_workers > 0). pt-slave-restart does not know
145+what the GTID event is of the failed transaction of a specific slave thread.
146+
147+=item *
148+
149+The default behavior is to skip the next transaction from the slave's master.
150+Writes can originate on different servers, each with their own UUID.
151+
152+See L<"--master-uuid">.
153+
154+=back
155+
156 =head1 EXIT STATUS
157
158 An exit status of 0 (sometimes also called a return value or return code)
159@@ -5555,6 +5661,26 @@
160
161 Number of statements to skip when restarting the slave.
162
163+=item --master-uuid
164+
165+type: string
166+
167+When using GTID, an empty transaction should be created in order to skip it.
168+If writes are coming from different nodes in the replication tree above, it is
169+not possible to know which event from which UUID to skip.
170+
171+By default, transactions from the slave's master (C<'Master_UUID'> from
172+C<SHOW SLAVE STATUS>) are skipped.
173+
174+For example, with
175+
176+ master1 -> slave1 -> slave2
177+
178+When skipping events on slave2 that were written to master1, you must specify
179+the UUID of master1, else the tool will use the UUID of slave1 by default.
180+
181+See L<"GLOBAL TRANSACTION IDS">.
182+
183 =item --sleep
184
185 type: int; default: 1
186
187=== modified file 'lib/Sandbox.pm'
188--- lib/Sandbox.pm 2013-08-12 21:19:57 +0000
189+++ lib/Sandbox.pm 2014-05-28 22:19:33 +0000
190@@ -379,6 +379,7 @@
191 # Diff the two sets of checksums: host to master (ref).
192 my @diffs;
193 foreach my $c ( @checksums ) {
194+ next unless $c->{checksum};
195 if ( $c->{checksum} ne $ref->{$c->{table}}->{checksum} ) {
196 push @diffs, $c->{table};
197 }
198
199=== modified file 'sandbox/start-sandbox'
200--- sandbox/start-sandbox 2013-06-26 01:18:29 +0000
201+++ sandbox/start-sandbox 2014-05-28 22:19:33 +0000
202@@ -113,6 +113,14 @@
203 echo "query_cache_size=$QUERY_CACHE_SIZE" >> /tmp/$port/my.sandbox.cnf
204 fi
205
206+ if [ -n "$GTID" ]; then
207+ echo "gtid_mode=on" >> /tmp/$port/my.sandbox.cnf
208+ echo "enforce_gtid_consistency" >> /tmp/$port/my.sandbox.cnf
209+ fi
210+ if [ -n "$REPLICATION_THREADS" ]; then
211+ echo "slave_parallel_workers=$REPLICATION_THREADS" >> /tmp/$port/my.sandbox.cnf
212+ fi
213+
214 if [ -n "$EXTRA_DEFAULTS_FILE" ]; then
215 cat "$EXTRA_DEFAULTS_FILE" >> /tmp/$port/my.sandbox.cnf
216 fi
217
218=== modified file 'sandbox/test-env'
219--- sandbox/test-env 2013-03-07 21:17:01 +0000
220+++ sandbox/test-env 2014-05-28 22:19:33 +0000
221@@ -315,13 +315,16 @@
222 fi
223
224 if [ $? -eq 0 -a "$MYSQL_VERSION" '>' "4.1" ]; then
225- echo -n "Loading sakila database... "
226- ./load-sakila-db 12345 "${2:-""}"
227- exit_status=$((exit_status | $?))
228- if [ $exit_status -ne 0 ]; then
229- echo "FAILED"
230- else
231- echo "OK"
232+ SAKILA=${SAKILA:-1}
233+ if [ $SAKILA -eq 1 ]; then
234+ echo -n "Loading sakila database... "
235+ ./load-sakila-db 12345 "${2:-""}"
236+ exit_status=$((exit_status | $?))
237+ if [ $exit_status -ne 0 ]; then
238+ echo "FAILED"
239+ else
240+ echo "OK"
241+ fi
242 fi
243
244 # Create percona_test db and checksum all the tables.
245
246=== added file 't/pt-slave-restart/gtid.t'
247--- t/pt-slave-restart/gtid.t 1970-01-01 00:00:00 +0000
248+++ t/pt-slave-restart/gtid.t 2014-05-28 22:19:33 +0000
249@@ -0,0 +1,203 @@
250+#!/usr/bin/env perl
251+
252+BEGIN {
253+ die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n"
254+ unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH};
255+ unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib";
256+};
257+
258+use strict;
259+use warnings FATAL => 'all';
260+use English qw(-no_match_vars);
261+use Test::More;
262+
263+use PerconaTest;
264+use Sandbox;
265+require "$trunk/bin/pt-slave-restart";
266+
267+if ( $sandbox_version lt '5.6' ) {
268+ plan skip_all => "Requires MySQL 5.6";
269+}
270+
271+diag(`SAKILA=0 GTID=1 $trunk/sandbox/test-env restart`);
272+
273+my $dp = new DSNParser(opts=>$dsn_opts);
274+my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
275+my $master_dbh = $sb->get_dbh_for('master');
276+my $slave1_dbh = $sb->get_dbh_for('slave1');
277+my $slave2_dbh = $sb->get_dbh_for('slave2');
278+
279+if ( !$master_dbh ) {
280+ plan skip_all => 'Cannot connect to sandbox master';
281+}
282+elsif ( !$slave1_dbh ) {
283+ plan skip_all => 'Cannot connect to sandbox slave1';
284+}
285+elsif ( !$slave2_dbh ) {
286+ plan skip_all => 'Cannot connect to sandbox slave2';
287+}
288+
289+my $slave1_dsn = $sb->dsn_for("slave1");
290+my $slave2_dsn = $sb->dsn_for("slave2");
291+
292+my $pid_file = "/tmp/pt-slave-restart-test-$PID.pid";
293+my $log_file = "/tmp/pt-slave-restart-test-$PID.log";
294+my $cmd = "$trunk/bin/pt-slave-restart --daemonize --run-time 5 --max-sleep .25 --pid $pid_file --log $log_file";
295+
296+sub start {
297+ my ( $extra ) = @_;
298+ stop() or return;
299+ system "$cmd $extra";
300+ PerconaTest::wait_for_files($pid_file);
301+}
302+
303+sub stop() {
304+ return 1 if !is_running();
305+ diag(`$trunk/bin/pt-slave-restart --stop -q >/dev/null 2>&1 &`);
306+ wait_until(sub { !-f $pid_file }, 0.3, 2);
307+ diag(`rm -f /tmp/pt-slave-restart-sentinel`);
308+ return is_running() ? 0 : 1;
309+}
310+
311+sub is_running {
312+ chomp(my $running = `ps -eaf | grep -v grep | grep '$cmd'`);
313+ if (!-f $pid_file && !$running) {
314+ return 0;
315+ } elsif (-f $pid_file && !$running) {
316+ diag(`rm -f $pid_file`);
317+ return 0;
318+ }
319+ return 1;
320+}
321+
322+sub wait_repl_broke {
323+ my $dbh = shift;
324+ return wait_until(
325+ sub {
326+ my $row = $dbh->selectrow_hashref('show slave status');
327+ return $row->{last_sql_errno};
328+ }
329+ );
330+}
331+
332+sub wait_repl_ok {
333+ my $dbh = shift;
334+ wait_until(
335+ sub {
336+ my $row = $dbh->selectrow_hashref('show slave status');
337+ return $row->{last_sql_errno} == 0;
338+ },
339+ 0.30,
340+ 5,
341+ );
342+}
343+
344+# #############################################################################
345+# Basic test to see if restart works with GTID.
346+# #############################################################################
347+
348+$master_dbh->do('DROP DATABASE IF EXISTS test');
349+$master_dbh->do('CREATE DATABASE test');
350+$master_dbh->do('CREATE TABLE test.t (a INT)');
351+$sb->wait_for_slaves;
352+
353+# Bust replication
354+$slave1_dbh->do('DROP TABLE test.t');
355+$master_dbh->do('INSERT INTO test.t SELECT 1');
356+wait_repl_broke($slave1_dbh) or die "Failed to break replication";
357+
358+my $r = $slave1_dbh->selectrow_hashref('show slave status');
359+like($r->{last_error}, qr/Table 'test.t' doesn't exist'/, 'slave: Replication broke');
360+
361+# Start pt-slave-restart and wait up to 5s for it to fix replication
362+# (it should take < 1s but tests can be really slow sometimes).
363+start("$slave1_dsn") or die "Failed to start pt-slave-restart";
364+wait_repl_ok($slave1_dbh);
365+
366+# Check if replication is fixed.
367+$r = $slave1_dbh->selectrow_hashref('show slave status');
368+like(
369+ $r->{last_errno},
370+ qr/^0$/,
371+ 'Event is skipped',
372+) or BAIL_OUT("Replication is broken");
373+
374+# Stop pt-slave-restart.
375+stop() or die "Failed to stop pt-slave-restart";
376+
377+# #############################################################################
378+# Test the slave of the master.
379+# #############################################################################
380+
381+$master_dbh->do('DROP DATABASE IF EXISTS test');
382+$master_dbh->do('CREATE DATABASE test');
383+$master_dbh->do('CREATE TABLE test.t (a INT)');
384+$sb->wait_for_slaves;
385+
386+# Bust replication
387+$slave2_dbh->do('DROP TABLE test.t');
388+$master_dbh->do('INSERT INTO test.t SELECT 1');
389+wait_repl_broke($slave2_dbh) or die "Failed to break replication";
390+
391+# fetch the master uuid, which is the machine we need to skip an event from
392+$r = $master_dbh->selectrow_hashref('select @@GLOBAL.server_uuid as uuid');
393+my $uuid = $r->{uuid};
394+
395+$r = $slave2_dbh->selectrow_hashref('show slave status');
396+like($r->{last_error}, qr/Table 'test.t' doesn't exist'/, 'slaveofslave: Replication broke');
397+
398+# Start an instance
399+start("--master-uuid=$uuid $slave2_dsn") or die;
400+wait_repl_ok($slave2_dbh);
401+
402+$r = $slave2_dbh->selectrow_hashref('show slave status');
403+like(
404+ $r->{last_errno},
405+ qr/^0$/,
406+ 'Skips event from master on slave2'
407+) or BAIL_OUT("Replication is broken");
408+
409+stop() or die "Failed to stop pt-slave-restart";
410+
411+# #############################################################################
412+# Test skipping 2 events in a row.
413+# #############################################################################
414+
415+$master_dbh->do('DROP DATABASE IF EXISTS test');
416+$master_dbh->do('CREATE DATABASE test');
417+$master_dbh->do('CREATE TABLE test.t (a INT)');
418+$sb->wait_for_slaves;
419+
420+# Bust replication
421+$slave2_dbh->do('DROP TABLE test.t');
422+$master_dbh->do('INSERT INTO test.t SELECT 1');
423+$master_dbh->do('INSERT INTO test.t SELECT 1');
424+wait_repl_broke($slave2_dbh) or die "Failed to break replication";
425+
426+# fetch the master uuid, which is the machine we need to skip an event from
427+$r = $master_dbh->selectrow_hashref('select @@GLOBAL.server_uuid as uuid');
428+$uuid = $r->{uuid};
429+
430+$r = $slave2_dbh->selectrow_hashref('show slave status');
431+like($r->{last_error}, qr/Table 'test.t' doesn't exist'/, 'slaveofslaveskip2: Replication broke');
432+
433+# Start an instance
434+start("--skip-count=2 --master-uuid=$uuid $slave2_dsn") or die;
435+wait_repl_ok($slave2_dbh);
436+
437+$r = $slave2_dbh->selectrow_hashref('show slave status');
438+like(
439+ $r->{last_errno},
440+ qr/^0$/,
441+ 'Skips multiple events'
442+) or BAIL_OUT("Replication is broken");
443+
444+stop() or die "Failed to stop pt-slave-restart";
445+
446+# #############################################################################
447+# Done.
448+# #############################################################################
449+diag(`rm -f $pid_file $log_file >/dev/null`);
450+diag(`$trunk/sandbox/test-env restart`);
451+ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
452+done_testing;
453
454=== added file 't/pt-slave-restart/gtid_parallelreplication.t'
455--- t/pt-slave-restart/gtid_parallelreplication.t 1970-01-01 00:00:00 +0000
456+++ t/pt-slave-restart/gtid_parallelreplication.t 2014-05-28 22:19:33 +0000
457@@ -0,0 +1,64 @@
458+#!/usr/bin/env perl
459+
460+BEGIN {
461+ die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n"
462+ unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH};
463+ unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib";
464+};
465+
466+use strict;
467+use warnings FATAL => 'all';
468+use English qw(-no_match_vars);
469+use Test::More;
470+
471+use PerconaTest;
472+use Sandbox;
473+require "$trunk/bin/pt-slave-restart";
474+
475+if ( $sandbox_version lt '5.6' ) {
476+ plan skip_all => 'MySQL Version ' . $sandbox_version
477+ . ' < 5.6, GTID is not available, skipping tests';
478+}
479+
480+diag("Stopping/reconfiguring/restarting sandboxes 12345, 12346 and 12347");
481+
482+diag(`$trunk/sandbox/test-env stop >/dev/null`);
483+diag(`REPLICATION_THREADS=2 GTID=1 $trunk/sandbox/test-env start >/dev/null`);
484+
485+my $dp = new DSNParser(opts=>$dsn_opts);
486+my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
487+my $master_dbh = $sb->get_dbh_for('master');
488+my $slave_dbh = $sb->get_dbh_for('slave1');
489+my $slave2_dbh = $sb->get_dbh_for('slave2');
490+
491+if ( !$master_dbh ) {
492+ plan skip_all => 'Cannot connect to sandbox master';
493+}
494+elsif ( !$slave_dbh ) {
495+ plan skip_all => 'Cannot connect to sandbox slave1';
496+}
497+elsif ( !$slave2_dbh ) {
498+ plan skip_all => 'Cannot connect to sandbox slave2';
499+}
500+
501+# #############################################################################
502+# pt-slave-restart should exit!
503+# #############################################################################
504+# Start an instance
505+my $output=`$trunk/bin/pt-slave-restart --run-time=1s -h 127.0.0.1 -P 12346 -u msandbox -p msandbox 2>&1`;
506+
507+like(
508+ $output,
509+ qr/It is impossible to skip transactions properly./,
510+ "pt-slave-restart exits with multiple replication threads"
511+);
512+
513+# #############################################################################
514+# Done.
515+# #############################################################################
516+diag(`rm -f /tmp/pt-slave-re*`);
517+diag(`$trunk/sandbox/test-env stop >/dev/null`);
518+diag(`$trunk/sandbox/test-env start >/dev/null`);
519+
520+ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
521+done_testing;
522
523=== modified file 'util/checksum-test-dataset'
524--- util/checksum-test-dataset 2013-02-19 00:28:12 +0000
525+++ util/checksum-test-dataset 2014-05-28 22:19:33 +0000
526@@ -61,6 +61,7 @@
527 . join(", ", map { "sakila.$_" } @tables_in_sakila);
528 my @checksums = @{$dbh->selectall_arrayref($sql, {Slice => {} })};
529 foreach my $c ( @checksums ) {
530+ next unless $c->{Checksum};
531 $dbh->do("INSERT INTO percona_test.checksums(db_tbl, checksum)
532 VALUES('$c->{Table}', $c->{Checksum})");
533 }

Subscribers

People subscribed via source and target branches