Merge lp:~percona-toolkit-dev/percona-toolkit/partial-fix-1063912-ptc-pxc-slaves into lp:~percona-toolkit-dev/percona-toolkit/2.1.5-release
- partial-fix-1063912-ptc-pxc-slaves
- Merge into 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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Daniel Nichter | Approve | ||
Review via email: mp+128566@code.launchpad.net |
Commit message
Description of the change
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"); |