Merge lp:~percona-toolkit-dev/percona-toolkit/partial-fix-1063912-ptc-pxc-slaves into lp:~percona-toolkit-dev/percona-toolkit/2.1.5-release

Proposed by Daniel Nichter
Status: Merged
Merged at revision: 398
Proposed branch: lp:~percona-toolkit-dev/percona-toolkit/partial-fix-1063912-ptc-pxc-slaves
Merge into: lp:~percona-toolkit-dev/percona-toolkit/2.1.5-release
Diff against target: 905 lines (+586/-33)
11 files modified
bin/pt-query-digest (+208/-6)
bin/pt-stalk (+113/-4)
bin/pt-table-checksum (+30/-7)
lib/Cxn.pm (+3/-1)
lib/RowChecksum.pm (+5/-0)
t/lib/Pingback.t (+67/-7)
t/lib/RowChecksum.t (+45/-4)
t/pt-stalk/plugin.t (+74/-0)
t/pt-stalk/samples/plugin001.sh (+21/-0)
t/pt-table-checksum/bugs.t (+16/-0)
t/pt-table-checksum/run_time.t (+4/-4)
To merge this branch: bzr merge lp:~percona-toolkit-dev/percona-toolkit/partial-fix-1063912-ptc-pxc-slaves
Reviewer Review Type Date Requested Status
Daniel Nichter Approve
Review via email: mp+128566@code.launchpad.net
To post a comment you must log in.
405. By Daniel Nichter

Add note to PXC limiations that complex repl setups aren't supported.

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-query-digest'
2--- bin/pt-query-digest 2012-09-24 19:24:36 +0000
3+++ bin/pt-query-digest 2012-10-08 18:50:28 +0000
4@@ -15160,8 +15160,10 @@
5 may actually include different kinds of attributes (for example, you may have a
6 server with the Percona patches).
7
8-For a full list of attributes, see
9-L<http://code.google.com/p/maatkit/wiki/EventAttributes>.
10+See L<"ATTRIBUTES REFERENCE"> near the end of this documentation for a list
11+of common and L<"--type"> specific attributes. A familiarity with these
12+attributes is necessary for working with L<"--filter">,
13+L<"--ignore-attributes">, and other attribute-related options.
14
15 With creative use of L<"--filter">, you can create new attributes derived
16 from existing attributes. For example, to create an attribute called
17@@ -15189,8 +15191,8 @@
18 These attributes are no different from slow log attributes, so you can use them
19 with L<"--[no]report">, L<"--group-by">, in a L<"--filter">, etc.
20
21-These attributes and more are documented at
22-L<http://code.google.com/p/maatkit/wiki/EventAttributes>.
23+See the memcached section of L<"ATTRIBUTES REFERENCE"> for a list of
24+memcached-specific attributes.
25
26 =head1 OUTPUT
27
28@@ -15835,8 +15837,8 @@
29
30 It is permissible for the code to have side effects (to alter C<$event>).
31
32-You can find an explanation of the structure of $event at
33-L<http://code.google.com/p/maatkit/wiki/EventAttributes>.
34+See L<"ATTRIBUTES REFERENCE"> for a list of common and L<"--type"> specific
35+attributes.
36
37 Here are more examples of filter code:
38
39@@ -17069,6 +17071,206 @@
40
41 Replace C<TOOL> with the name of any tool.
42
43+=head1 ATTRIBUTES REFERENCE
44+
45+Events may have the following attributes. If writing a L<"--filter">,
46+be sure to check that an attribute is defined in each event before
47+using it, else the filter code may crash the tool with a
48+"use of uninitialized value" error.
49+
50+You can dump event attributes for any input like:
51+
52+ $ pt-query-digest \
53+ slowlog \
54+ --filter 'print Dumper $event' \
55+ --no-report \
56+ --sample 1
57+
58+That will produce a lot of output with "attribute => value" pairs like:
59+
60+ $VAR1 = {
61+ Query_time => '0.033384',
62+ Rows_examined => '0',
63+ Rows_sent => '0',
64+ Thread_id => '10',
65+ Tmp_table => 'No',
66+ Tmp_table_on_disk => 'No',
67+ arg => 'SELECT col FROM tbl WHERE id=5',
68+ bytes => 103,
69+ cmd => 'Query',
70+ db => 'db1',
71+ fingerprint => 'select col from tbl where id=?',
72+ host => '',
73+ pos_in_log => 1334,
74+ ts => '071218 11:48:27',
75+ user => '[SQL_SLAVE]'
76+ };
77+
78+=head2 COMMON
79+
80+These attribute are common to all input L<"--type"> and L<"--processlist">,
81+except where noted.
82+
83+=over
84+
85+=item arg
86+
87+The query text, or the command for admin commands like C<Ping>.
88+
89+=item bytes
90+
91+The byte length of the C<arg>.
92+
93+=item cmd
94+
95+"Query" or "Admin" for all except memcached. For memcached it's
96+the memcached command: get, set, etc.
97+
98+=item db
99+
100+The current database, except for memcached. The value comes from USE
101+database statements. By default, C<Schema> is an alias which is automatically
102+changed to C<db>; see L<"--attribute-aliases">.
103+
104+=item fingerprint
105+
106+An abstracted form of the query. See L<"FINGERPRINTS">.
107+
108+=item host
109+
110+Client host which executed the query.
111+
112+=item pos_in_log
113+
114+The byte offset of the event in the log or tcpdump,
115+except for L<"--processlist">.
116+
117+=item Query_time
118+
119+The total time the query took, including lock time.
120+
121+=item ts
122+
123+The timestamp of when the query ended.
124+
125+=back
126+
127+=head2 SLOW, GENERAL, AND BINARY LOGS
128+
129+Events have all available attributes from the log file. Therefore, you only
130+need to look at the log file to see which events are available, but remember:
131+not all events have the same attributes.
132+
133+Percona Server adds many attributes to the slow log; see
134+http://www.percona.com/doc/percona-server/5.1/diagnostics/slow_extended.html#changes-to-the-log-format
135+for more information.
136+
137+=head2 TCPDUMP
138+
139+These attributes are available when parsing L<"--type"> tcpdump.
140+
141+=over
142+
143+=item Error_no
144+
145+The MySQL error number if the query caused an error.
146+
147+=item ip
148+
149+The client's IP address. Certain log files may also contain this attribute.
150+
151+=item No_good_index_used
152+
153+Yes or No if no good index existed for the query (flag set by server).
154+
155+=item No_index_used
156+
157+Yes or No if the query did not use any index (flag set by server).
158+
159+=item port
160+
161+The client's port number.
162+
163+=item Warning_count
164+
165+The number of warnings, as otherwise shown by C<SHOW WARNINGS>.
166+
167+=back
168+
169+=head2 PROCESSLIST
170+
171+If using L<"--processlist">, an C<id> attribute is available for
172+the process ID, in addition to the common attributes.
173+
174+=head2 MEMCACHED
175+
176+These attributes are available when parsing L<"--type"> memcached.
177+
178+=over
179+
180+=item exptime
181+
182+Expiration time.
183+
184+=item key
185+
186+The key used by cmd.
187+
188+=item key_print
189+
190+An abstracted form of the key.
191+
192+=item Memc_add
193+
194+Yes/No if the command is add.
195+
196+=item Memc_append
197+
198+Yes/No if the command is append.
199+
200+=item Memc_cas
201+
202+Yes/No if the command is cas.
203+
204+=item Memc_error
205+
206+Yes/No if command caused an error. Currently, the only error is when
207+a retrieval command is interrupted.
208+
209+=item Memc_get
210+
211+Yes/No if the command is get.
212+
213+=item Memc_gets
214+
215+Yes/No if the command is gets.
216+
217+=item Memc_miss
218+
219+Yes/No if the command tried to access a nonexistent key.
220+
221+=item Memc_prepend
222+
223+Yes/No if the command is prepend.
224+
225+=item Memc_replace
226+
227+Yes/No if the command is replace.
228+
229+=item Memc_set
230+
231+Yes/No if the command is set.
232+
233+=item res
234+
235+Result of cmd.
236+
237+=item val
238+
239+The return value of cmd, if any.
240+
241+=back
242+
243 =head1 AUTHORS
244
245 Baron Schwartz and Daniel Nichter
246
247=== modified file 'bin/pt-stalk'
248--- bin/pt-stalk 2012-09-20 13:59:16 +0000
249+++ bin/pt-stalk 2012-10-08 18:50:28 +0000
250@@ -933,6 +933,30 @@
251 ITER=1
252
253 # ###########################################################################
254+# Plugin hooks
255+# ###########################################################################
256+
257+before_stalk() {
258+ :
259+}
260+
261+before_collect() {
262+ :
263+}
264+
265+after_collect() {
266+ :
267+}
268+
269+after_collect_sleep() {
270+ :
271+}
272+
273+after_stalk() {
274+ :
275+}
276+
277+# ###########################################################################
278 # Subroutines
279 # ###########################################################################
280
281@@ -1016,12 +1040,12 @@
282
283 oktorun() {
284 if [ $OKTORUN -eq 0 ]; then
285- EXIT_REASON="OKTORUN is false"
286+ [ -z "$EXIT_REASON" ] && EXIT_REASON="OKTORUN is false"
287 return 1 # stop running
288 fi
289
290 if [ -n "$OPT_ITERATIONS" ] && [ $ITER -gt $OPT_ITERATIONS ]; then
291- EXIT_REASON="no more iterations"
292+ [ -z "$EXIT_REASON" ] && EXIT_REASON="no more iterations"
293 return 1 # stop running
294 fi
295
296@@ -1136,6 +1160,9 @@
297 log "pt-stalk ran with $RAN_WITH" >> "$OPT_DEST/$prefix-trigger"
298 last_prefix="$prefix"
299
300+ # Plugin hook:
301+ before_collect
302+
303 # Fork and background the collect subroutine which will
304 # run for --run-time seconds. We (the parent) sleep
305 # while its collecting (hopefully --sleep is longer than
306@@ -1143,7 +1170,11 @@
307 (
308 collect "$OPT_DEST" "$prefix"
309 ) >> "$OPT_DEST/$prefix-output" 2>&1 &
310- log "Collector PID $!"
311+ local collector_pid=$!
312+ log "Collector PID $collector_pid"
313+
314+ # Plugin hook:
315+ after_collect $collector_pid
316 else
317 # There will not be enough disk space, so do not collect.
318 warn "Collect canceled because there will not be enough disk space after collecting another $margin MB"
319@@ -1156,6 +1187,9 @@
320 ITER=$((ITER + 1))
321 cycles_true=0
322 sleep_ok "$OPT_SLEEP" "Sleeping $OPT_SLEEP seconds after collect"
323+
324+ # Plugin hook:
325+ after_collect_sleep
326 else
327 # Trigger/check/value is ok, sleep until next check.
328 sleep_ok "$OPT_INTERVAL"
329@@ -1178,7 +1212,7 @@
330 # Note: $$ is the parent's PID, but we're a child proc.
331 # Bash 4 has $BASHPID but we can't rely on that. Consequently,
332 # we don't know our own PID. See the usage of $! below.
333- RAN_WITH="--function=$OPT_FUNCTION --variable=$OPT_VARIABLE --threshold=$OPT_THRESHOLD --match=$OPT_MATCH --cycles=$OPT_CYCLES --interval=$OPT_INTERVAL --iterations=$OPT_ITERATIONS --run-time=$OPT_RUN_TIME --sleep=$OPT_SLEEP --dest=$OPT_DEST --prefix=$OPT_PREFIX --notify-by-email=$OPT_NOTIFY_BY_EMAIL --log=$OPT_LOG --pid=$OPT_PID"
334+ RAN_WITH="--function=$OPT_FUNCTION --variable=$OPT_VARIABLE --threshold=$OPT_THRESHOLD --match=$OPT_MATCH --cycles=$OPT_CYCLES --interval=$OPT_INTERVAL --iterations=$OPT_ITERATIONS --run-time=$OPT_RUN_TIME --sleep=$OPT_SLEEP --dest=$OPT_DEST --prefix=$OPT_PREFIX --notify-by-email=$OPT_NOTIFY_BY_EMAIL --log=$OPT_LOG --pid=$OPT_PID --plugin=$OPT_PLUGIN"
335
336 log "Starting $0 $RAN_WITH"
337
338@@ -1190,9 +1224,15 @@
339 # Make a secure tmpdir.
340 mk_tmpdir
341
342+ # Plugin hook:
343+ before_stalk
344+
345 # Stalk while oktorun.
346 stalk
347
348+ # Plugin hook:
349+ after_stalk
350+
351 # Clean up.
352 rm_tmpdir
353 remove_pid_file "$OPT_PID"
354@@ -1217,6 +1257,15 @@
355 option_error "Invalid --function value: $OPT_FUNCTION"
356 fi
357
358+ # Verify and source the --plugin.
359+ if [ "$OPT_PLUGIN" ]; then
360+ if [ -f "$OPT_PLUGIN" ]; then
361+ . "$OPT_PLUGIN"
362+ else
363+ option_error "Invalid --plugin value: $OPT_PLUGIN is not a file"
364+ fi
365+ fi
366+
367 if [ -z "$OPT_STALK" -a "$OPT_COLLECT" ]; then
368 # Not stalking; do immediate collect once.
369 OPT_ITERATIONS=1
370@@ -1611,6 +1660,66 @@
371
372 Create a PID file when daemonized.
373
374+=item --plugin
375+
376+type: string
377+
378+Load a plugin to hook into the tool and extend is functionality.
379+The specified file does not need to be executable, nor does its first line
380+need to be shebang line. It only needs to define one or more of these
381+Bash functions:
382+
383+=over
384+
385+=item before_stalk
386+
387+Called before stalking.
388+
389+=item before_collect
390+
391+Called when the stalk condition is triggered, before running a collector
392+process as a backgrounded subshell.
393+
394+=item after_collect
395+
396+Called after running a collector process. The PID of the collector process
397+is passed as the first argument. This hook is called before
398+C<after_collect_sleep>.
399+
400+=item after_collect_sleep
401+
402+Called after sleeping L<"--sleep"> seconds for the collector process to finish.
403+This hook is called after C<after_collect>.
404+
405+=item after_stalk
406+
407+Called after stalking. Since pt-stalk stalks forever by default,
408+this hook is only called if L<"--iterations"> is specified.
409+
410+=back
411+
412+For example, a very simple plugin that touches a file when a collector
413+process is triggered:
414+
415+ before_colllect() {
416+ touch /tmp/foo
417+ }
418+
419+Since the plugin is completely sourced (imported) into the tool's namespace,
420+be careful not to define other functions or global variables that already
421+exist in the tool. You should prefix all plugin-specific functions and
422+global variables with C<plugin_> or C<PLUGIN_>.
423+
424+Plugins have access to all command line options but they should not modify
425+them. Each option is a global variable like C<$OPT_DEST> which corresponds
426+to L<"--dest">. Therefore, the global variable for each command line option
427+is C<OPT_> plus the option name in all caps with hyphens replaced by
428+underscores.
429+
430+Plugins can stop the tool by setting the global variable C<OKTORUN>
431+to C<1>. In this case, the global variable C<EXIT_REASON> should also
432+be set to indicate why the tool was stopped.
433+
434 =item --prefix
435
436 type: string
437
438=== modified file 'bin/pt-table-checksum'
439--- bin/pt-table-checksum 2012-10-05 22:28:45 +0000
440+++ bin/pt-table-checksum 2012-10-08 18:50:28 +0000
441@@ -3320,7 +3320,9 @@
442 PTDEBUG && _d($sql);
443 my $row = $self->{dbh}->selectrow_arrayref($sql);
444 PTDEBUG && _d(defined $row ? @$row : 'undef');
445- $self->{is_cluster_node} = $row && $row->[0] ? 1 : 0;
446+ $self->{is_cluster_node} = $row && $row->[1]
447+ ? ($row->[1] eq 'ON' || $row->[1] eq '1')
448+ : 0;
449
450 return $self->{is_cluster_node};
451 }
452@@ -5146,6 +5148,9 @@
453 my $func = $args{func} || uc($o->get('function'));
454 my $cols = $self->get_checksum_columns(%args);
455
456+ die "all columns are excluded by --columns or --ignore-columns"
457+ unless @{$cols->{select}};
458+
459 my $query;
460 if ( !$args{no_cols} ) {
461 $query = join(', ',
462@@ -9340,11 +9345,20 @@
463 # Make a nibble iterator for this table. This should only fail
464 # if the table has no indexes and is too large to checksum in
465 # one chunk.
466- my $checksum_cols = $rc->make_chunk_checksum(
467- dbh => $master_cxn->dbh(),
468- tbl => $tbl,
469- %crc_args
470- );
471+ my $checksum_cols = eval {
472+ $rc->make_chunk_checksum(
473+ dbh => $master_cxn->dbh(),
474+ tbl => $tbl,
475+ %crc_args
476+ );
477+ };
478+
479+ if ( $EVAL_ERROR ) {
480+ warn ts("Skipping table $tbl->{db}.$tbl->{tbl} because "
481+ . "$EVAL_ERROR\n");
482+ return;
483+ }
484+
485 my $nibble_iter;
486 eval {
487 $nibble_iter = new OobNibbleIterator(
488@@ -10664,7 +10678,8 @@
489
490 short form: -c; type: array; group: Filter
491
492-Checksum only this comma-separated list of columns.
493+Checksum only this comma-separated list of columns. If a table doesn't have
494+any of the specified columns it will be skipped.
495
496 =item --config
497
498@@ -10780,6 +10795,8 @@
499 type: Hash; group: Filter
500
501 Ignore this comma-separated list of columns when calculating the checksum.
502+If a table has all of its columns filtered by --ignore-columns, it will
503+be skipped.
504
505 =item --ignore-databases
506
507@@ -11313,6 +11330,12 @@
508 cannot be detected automatically. The lag check (see L<"REPLICA CHECKS">)
509 is not performed for cluster nodes.
510
511+Mixed replication setups are not currently supported. For example, the tool
512+does not work completely if the master host is replicating to a cluster,
513+or if the cluster is replicating to another cluster. In short, the only
514+supported setup is a single cluster with nodes optionally having traditional
515+replication slaves.
516+
517 =back
518
519 =head1 BUGS
520
521=== modified file 'lib/Cxn.pm'
522--- lib/Cxn.pm 2012-08-29 22:35:17 +0000
523+++ lib/Cxn.pm 2012-10-08 18:50:28 +0000
524@@ -203,7 +203,9 @@
525 PTDEBUG && _d($sql);
526 my $row = $self->{dbh}->selectrow_arrayref($sql);
527 PTDEBUG && _d(defined $row ? @$row : 'undef');
528- $self->{is_cluster_node} = $row && $row->[0] ? 1 : 0;
529+ $self->{is_cluster_node} = $row && $row->[1]
530+ ? ($row->[1] eq 'ON' || $row->[1] eq '1')
531+ : 0;
532
533 return $self->{is_cluster_node};
534 }
535
536=== modified file 'lib/RowChecksum.pm'
537--- lib/RowChecksum.pm 2012-06-07 03:36:07 +0000
538+++ lib/RowChecksum.pm 2012-10-08 18:50:28 +0000
539@@ -67,6 +67,11 @@
540 my $func = $args{func} || uc($o->get('function'));
541 my $cols = $self->get_checksum_columns(%args);
542
543+ # Skip tables that have all their columns skipped; See
544+ # https://bugs.launchpad.net/percona-toolkit/+bug/1016131
545+ die "all columns are excluded by --columns or --ignore-columns"
546+ unless @{$cols->{select}};
547+
548 # Prepend columns to query, resulting in "col1, col2, FUNC(..col1, col2...)",
549 # unless caller says not to. The only caller that says not to is
550 # make_chunk_checksum() which uses this row checksum as part of a larger
551
552=== modified file 't/lib/Pingback.t'
553--- t/lib/Pingback.t 2012-09-13 13:39:04 +0000
554+++ t/lib/Pingback.t 2012-10-08 18:50:28 +0000
555@@ -126,9 +126,19 @@
556 );
557 }
558
559+ my $expect_post;
560+ if ( $args{post} ) {
561+ $expect_post = join("\n",
562+ map { "$_->{id};$_->{item};$_->{val}" }
563+ sort {
564+ $a->{item} cmp $b->{item} ||
565+ $a->{id} cmp $b->{id}
566+ } @{$args{post}});
567+ $expect_post .= "\n";
568+ }
569 is(
570 $post ? ($post->{content} || '') : '',
571- $args{post},
572+ $expect_post || '',
573 "$args{name} client response"
574 );
575
576@@ -152,7 +162,18 @@
577 }
578 ],
579 # client should POST this
580- post => "$general_id;Data::Dumper;$dd_ver\n$general_id;Perl;$perl_ver\n",
581+ post => [
582+ {
583+ item => 'Data::Dumper',
584+ id => $general_id,
585+ val => $dd_ver,
586+ },
587+ {
588+ item => 'Perl',
589+ id => $general_id,
590+ val => $perl_ver,
591+ },
592+ ],
593 # Server should return these suggetions after the client posts
594 sug => [
595 'Data::Printer is nicer.',
596@@ -174,7 +195,18 @@
597 content => "",
598 }
599 ],
600- post => "$general_id;Data::Dumper;$dd_ver\n$general_id;Perl;$perl_ver\n",
601+ post => [
602+ {
603+ item => 'Data::Dumper',
604+ id => $general_id,
605+ val => $dd_ver,
606+ },
607+ {
608+ item => 'Perl',
609+ id => $general_id,
610+ val => $perl_ver,
611+ },
612+ ],
613 sug => undef,
614 );
615
616@@ -184,7 +216,7 @@
617 name => "No response to GET",
618 response => [],
619 no_response => 1,
620- post => "",
621+ post => undef,
622 sug => undef,
623 );
624
625@@ -199,7 +231,18 @@
626 content => "Perl;perl_version;PERL_VERSION\nData::Dumper;perl_module_version\n",
627 },
628 ],
629- post => "$general_id;Data::Dumper;$dd_ver\n$general_id;Perl;$perl_ver\n",
630+ post => [
631+ {
632+ id => $general_id,
633+ item => 'Data::Dumper',
634+ val => $dd_ver,
635+ },
636+ {
637+ id => $general_id,
638+ item => 'Perl',
639+ val => $perl_ver,
640+ },
641+ ],
642 sug => undef,
643 );
644
645@@ -223,7 +266,13 @@
646 }
647 ],
648 # client should POST this
649- post => "$master_id;MySQL;$mysql_ver $mysql_distro\n",
650+ post => [
651+ {
652+ id => $master_id,
653+ item => 'MySQL',
654+ val => "$mysql_ver $mysql_distro",
655+ }
656+ ],
657 # Server should return these suggetions after the client posts
658 sug => ['Percona Server is fast.'],
659 );
660@@ -440,7 +489,18 @@
661 }
662 ],
663 # client should POST this
664- post => "$slave1_id;MySQL;$mysql_ver $mysql_distro\n$master_id;MySQL;$mysql_ver $mysql_distro\n",
665+ post => [
666+ {
667+ id => $slave1_id,
668+ item => 'MySQL',
669+ val => "$mysql_ver $mysql_distro",
670+ },
671+ {
672+ id => $master_id,
673+ item => 'MySQL',
674+ val => "$mysql_ver $mysql_distro",
675+ }
676+ ],
677 # Server should return these suggetions after the client posts
678 sug => [
679 'Percona Server is fast.',
680
681=== modified file 't/lib/RowChecksum.t'
682--- t/lib/RowChecksum.t 2012-06-03 17:54:32 +0000
683+++ t/lib/RowChecksum.t 2012-10-08 18:50:28 +0000
684@@ -26,9 +26,6 @@
685 if ( !$dbh ) {
686 plan skip_all => "Cannot connect to sandbox master";
687 }
688-else {
689- plan tests => 29;
690-}
691
692 $sb->create_dbs($dbh, ['test']);
693
694@@ -421,9 +418,53 @@
695 'Ignores specified columns'
696 );
697
698+# #############################################################################
699+# crash with --columns if none match / --ignore-columns if everything is ignored
700+# https://bugs.launchpad.net/percona-toolkit/+bug/1016131
701+# #############################################################################
702+# Re-using the $tbl from the previous test!
703+local @ARGV = ('--ignore-columns', 'a,b,c');
704+$o->get_opts();
705+local $EVAL_ERROR;
706+eval {
707+ $c->make_row_checksum(
708+ tbl => $tbl,
709+ func => 'CRC32',
710+ );
711+};
712+
713+like(
714+ $EVAL_ERROR,
715+ qr/all columns are excluded by --columns or --ignore-columns/,
716+ "Dies if all columns are ignored by --ignore-columns"
717+);
718+
719+
720+$tbl = {
721+ db => 'mysql',
722+ tbl => 'user',
723+ tbl_struct => $tp->parse($tp->get_create_table($dbh, 'mysql', 'user')),
724+};
725+local @ARGV = qw(--columns some_column_that_doesnt_exist);
726+$o->get_opts();
727+local $EVAL_ERROR;
728+eval {
729+ $c->make_row_checksum(
730+ tbl => $tbl,
731+ func => 'SHA1',
732+ );
733+};
734+
735+like(
736+ $EVAL_ERROR,
737+ qr/all columns are excluded by --columns or --ignore-columns/,
738+ 'Dies if all columns are ignored by --columns'
739+);
740+
741 # ############################################################################
742 # Done.
743 # ############################################################################
744 $sb->wipe_clean($dbh);
745 ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
746-exit;
747+
748+done_testing;
749
750=== added file 't/pt-stalk/plugin.t'
751--- t/pt-stalk/plugin.t 1970-01-01 00:00:00 +0000
752+++ t/pt-stalk/plugin.t 2012-10-08 18:50:28 +0000
753@@ -0,0 +1,74 @@
754+#!/usr/bin/env perl
755+
756+BEGIN {
757+ die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n"
758+ unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH};
759+ unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib";
760+};
761+
762+use strict;
763+use warnings FATAL => 'all';
764+use English qw(-no_match_vars);
765+use Test::More;
766+use Time::HiRes qw(sleep);
767+
768+use PerconaTest;
769+use DSNParser;
770+use Sandbox;
771+
772+my $dp = new DSNParser(opts=>$dsn_opts);
773+my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
774+my $dbh = $sb->get_dbh_for('master');
775+
776+if ( !$dbh ) {
777+ plan skip_all => 'Cannot connect to sandbox master';
778+}
779+
780+my $cnf = "/tmp/12345/my.sandbox.cnf";
781+my $pid_file = "/tmp/pt-stalk.pid.$PID";
782+my $log_file = "/tmp/pt-stalk.log.$PID";
783+my $dest = "/tmp/pt-stalk.collect.$PID";
784+my $output;
785+my $retval;
786+my $pid;
787+
788+diag(`rm $pid_file 2>/dev/null`);
789+diag(`rm $log_file 2>/dev/null`);
790+diag(`mkdir $dest`);
791+
792+# We'll have to watch Uptime since it's the only status var that's going
793+# to be predictable.
794+my (undef, $uptime) = $dbh->selectrow_array("SHOW STATUS LIKE 'Uptime'");
795+my $threshold = $uptime + 2;
796+
797+$retval = system("$trunk/bin/pt-stalk --iterations 1 --dest $dest --variable Uptime --threshold $threshold --cycles 1 --run-time 2 --pid $pid_file --plugin $trunk/t/pt-stalk/samples/plugin001.sh -- --defaults-file=$cnf >$log_file 2>&1");
798+
799+PerconaTest::wait_until(sub { !-f $pid_file });
800+
801+is(
802+ $retval >> 8,
803+ 0,
804+ "Exit 0"
805+);
806+
807+foreach my $hook (qw(
808+ before_stalk
809+ before_collect
810+ after_collect
811+ after_collect_sleep
812+ after_stalk
813+)) {
814+ ok(
815+ -f "$dest/$hook",
816+ "$hook hook called"
817+ );
818+}
819+
820+# #############################################################################
821+# Done.
822+# #############################################################################
823+diag(`rm $pid_file 2>/dev/null`);
824+diag(`rm $log_file 2>/dev/null`);
825+diag(`rm -rf $dest 2>/dev/null`);
826+ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
827+done_testing;
828
829=== added file 't/pt-stalk/samples/plugin001.sh'
830--- t/pt-stalk/samples/plugin001.sh 1970-01-01 00:00:00 +0000
831+++ t/pt-stalk/samples/plugin001.sh 2012-10-08 18:50:28 +0000
832@@ -0,0 +1,21 @@
833+#!/bin/sh
834+
835+before_stalk() {
836+ date >> "$OPT_DEST/before_stalk"
837+}
838+
839+before_collect() {
840+ date >> "$OPT_DEST/before_collect"
841+}
842+
843+after_collect() {
844+ date >> "$OPT_DEST/after_collect"
845+}
846+
847+after_collect_sleep() {
848+ date >> "$OPT_DEST/after_collect_sleep"
849+}
850+
851+after_stalk() {
852+ date >> "$OPT_DEST/after_stalk"
853+}
854
855=== modified file 't/pt-table-checksum/bugs.t'
856--- t/pt-table-checksum/bugs.t 2012-07-27 17:52:24 +0000
857+++ t/pt-table-checksum/bugs.t 2012-10-08 18:50:28 +0000
858@@ -176,6 +176,22 @@
859 );
860
861 # #############################################################################
862+# pt-table-checksum can crash with --columns if none match
863+# https://bugs.launchpad.net/percona-toolkit/+bug/1016131
864+# #############################################################################
865+
866+($output) = full_output(
867+ sub { pt_table_checksum::main(@args, '--tables', 'mysql.user,mysql.host',
868+ '--columns', 'some_fale_column') },
869+);
870+
871+like(
872+ $output,
873+ qr/\QSkipping table mysql.user because all columns are excluded by --columns or --ignore-columns/,
874+ "Bug 1016131: ptc should skip tables where all columns are excluded"
875+);
876+
877+# #############################################################################
878 # Done.
879 # #############################################################################
880 $sb->wipe_clean($master_dbh);
881
882=== modified file 't/pt-table-checksum/run_time.t'
883--- t/pt-table-checksum/run_time.t 2012-07-18 16:07:27 +0000
884+++ t/pt-table-checksum/run_time.t 2012-10-08 18:50:28 +0000
885@@ -38,16 +38,16 @@
886 my $output;
887 my $exit_status;
888
889-# On my 2.4 GHz with SSD this takes a little more than 3s,
890+# On my 2.4 GHz with SSD this takes a little more than 5s,
891 # so no test servers should be faster, hopefully.
892 my $t0 = time;
893 $exit_status = pt_table_checksum::main(@args,
894- qw(--quiet --quiet -d sakila --chunk-size 100 --run-time 1));
895+ qw(--quiet --quiet -d sakila --chunk-size 50 --run-time 1));
896 my $t = time - $t0;
897
898 ok(
899- $t >= 1.5 && $t <= 2.0,
900- "Run in roughly --run-time 1 second"
901+ $t >= 1.5 && $t <= 2.5,
902+ "Ran in roughly --run-time 1 second"
903 ) or diag("Actual run time: $t");
904
905 my $rows = $master_dbh->selectall_arrayref("SELECT DISTINCT CONCAT(db, '.', tbl) FROM percona.checksums ORDER by db, tbl");

Subscribers

People subscribed via source and target branches

to all changes: