Merge lp:~percona-toolkit-dev/percona-toolkit/release-2.2.13 into lp:percona-toolkit/2.2

Proposed by Tomislav Plavcic
Status: Merged
Merged at revision: 613
Proposed branch: lp:~percona-toolkit-dev/percona-toolkit/release-2.2.13
Merge into: lp:percona-toolkit/2.2
Diff against target: 3499 lines (+1288/-259)
61 files modified
Changelog (+18/-0)
Makefile.PL (+1/-1)
bin/pt-align (+2/-2)
bin/pt-archiver (+13/-6)
bin/pt-config-diff (+44/-13)
bin/pt-deadlock-logger (+44/-13)
bin/pt-diskstats (+13/-6)
bin/pt-duplicate-key-checker (+13/-6)
bin/pt-fifo-split (+2/-2)
bin/pt-find (+13/-6)
bin/pt-fingerprint (+2/-2)
bin/pt-fk-error-logger (+44/-13)
bin/pt-heartbeat (+13/-6)
bin/pt-index-usage (+13/-6)
bin/pt-ioprofile (+6/-3)
bin/pt-kill (+66/-14)
bin/pt-mext (+6/-3)
bin/pt-mysql-summary (+7/-4)
bin/pt-online-schema-change (+208/-17)
bin/pt-pmp (+6/-3)
bin/pt-query-digest (+13/-6)
bin/pt-show-grants (+2/-2)
bin/pt-sift (+6/-3)
bin/pt-slave-delay (+13/-6)
bin/pt-slave-find (+2/-2)
bin/pt-slave-restart (+13/-6)
bin/pt-stalk (+6/-3)
bin/pt-summary (+6/-3)
bin/pt-table-checksum (+70/-24)
bin/pt-table-sync (+13/-6)
bin/pt-table-usage (+2/-2)
bin/pt-upgrade (+44/-13)
bin/pt-variable-advisor (+13/-6)
bin/pt-visual-explain (+2/-2)
config/deb/changelog (+18/-0)
docs/percona-toolkit.pod (+2/-2)
docs/release_notes.rst (+46/-0)
lib/Cxn.pm (+34/-10)
lib/HTTP/Micro.pm (+2/-1)
lib/Percona/Toolkit.pm (+1/-1)
lib/Percona/XtraDB/Cluster.pm (+1/-7)
lib/RowChecksum.pm (+3/-3)
lib/VersionCheck.pm (+12/-5)
lib/bash/parse_options.sh (+5/-1)
sandbox/sakila.sql (+3/-2)
sandbox/servers/5.7/my.sandbox.cnf (+29/-0)
sandbox/servers/5.7/system_idb_tables.sql (+149/-0)
sandbox/servers/pxc/5.6/my.sandbox.cnf (+42/-0)
t/lib/NibbleIterator.t (+23/-5)
t/lib/RowChecksum.t (+4/-4)
t/lib/bash/parse_options.sh (+14/-1)
t/pt-kill/match.t (+11/-1)
t/pt-slave-restart/gtid_parallelreplication.t (+1/-1)
t/pt-table-checksum/basics.t (+19/-0)
t/pt-table-checksum/bugs.t (+25/-0)
t/pt-table-checksum/pxc.t (+20/-2)
t/pt-table-checksum/samples/chunkidx004.txt (+1/-1)
t/pt-table-checksum/samples/chunkidx005.txt (+1/-1)
t/pt-table-checksum/samples/default-results-5.7.txt (+41/-0)
t/pt-table-checksum/samples/n-chunk-index-cols.txt (+1/-1)
t/pt-table-checksum/samples/static-chunk-size-results-5.7.txt (+41/-0)
To merge this branch: bzr merge lp:~percona-toolkit-dev/percona-toolkit/release-2.2.13
Reviewer Review Type Date Requested Status
Daniel Nichter Pending
Review via email: mp+247705@code.launchpad.net

Description of the change

Release branch for version 2.2.13

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Changelog'
2--- Changelog 2014-11-11 13:28:27 +0000
3+++ Changelog 2015-01-27 13:07:53 +0000
4@@ -1,5 +1,23 @@
5 Changelog for Percona Toolkit
6
7+v2.2.13 released 2015-01-26
8+
9+
10+ * Feature 1391240: pt-kill added query fingerprint hash to output
11+ * Fixed bug 1402668: pt-mysql-summary fails on cluster in Donor/Desynced status
12+ * Fixed bug 1396870: pt-online-schema-change CTRL+C leaves terminal in inconsistent state
13+ * Fixed bug 1396868: pt-online-schema-change --ask-pass option error
14+ * Fixed bug 1266869: pt-stalk fails to start if $HOME environment variable is not set
15+ * Fixed bug 1019479: pt-table-checksum does not work with sql_mode ONLY_FULL_GROUP_BY
16+ * Fixed bug 1394934: pt-table-checksum error in debug mode
17+ * Fixed bug 1321297: pt-table-checksum reports diffs on timestamp columns in 5.5 vs 5.6
18+ * Fixed bug 1399789: pt-table-checksum fails to find pxc nodes when wsrep_node_incoming_address is set to AUTO
19+ * Fixed bug 1388870: pt-table-checksum has some errors with different time zones
20+ * Fixed bug 1408375: vulnerable to MITM attack which would allow exfiltration of MySQL configuration information via --version-check
21+ * Fixed bug 1404298: missing MySQL5.7 test files for pt-table-checksum
22+ * Fixed bug 1403900: added sandbox and fixed sakila test db for 5.7
23+
24+
25 v2.2.12 released 2014-11-14
26
27
28
29=== modified file 'Makefile.PL'
30--- Makefile.PL 2014-11-11 13:28:27 +0000
31+++ Makefile.PL 2015-01-27 13:07:53 +0000
32@@ -2,7 +2,7 @@
33
34 WriteMakefile(
35 NAME => 'percona-toolkit',
36- VERSION => '2.2.12',
37+ VERSION => '2.2.13',
38 EXE_FILES => [ <bin/*> ],
39 MAN1PODS => {
40 'docs/percona-toolkit.pod' => 'blib/man1/percona-toolkit.1p',
41
42=== modified file 'bin/pt-align'
43--- bin/pt-align 2014-11-11 13:28:27 +0000
44+++ bin/pt-align 2015-01-27 13:07:53 +0000
45@@ -1312,7 +1312,7 @@
46
47 =head1 COPYRIGHT, LICENSE, AND WARRANTY
48
49-This program is copyright 2011-2014 Percona LLC and/or its affiliates,
50+This program is copyright 2011-2015 Percona LLC and/or its affiliates,
51 2010-2011 Baron Schwartz.
52
53 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
54@@ -1331,6 +1331,6 @@
55
56 =head1 VERSION
57
58-pt-align 2.2.12
59+pt-align 2.2.13
60
61 =cut
62
63=== modified file 'bin/pt-archiver'
64--- bin/pt-archiver 2014-11-11 13:28:27 +0000
65+++ bin/pt-archiver 2015-01-27 13:07:53 +0000
66@@ -43,7 +43,7 @@
67 {
68 package Percona::Toolkit;
69
70-our $VERSION = '2.2.12';
71+our $VERSION = '2.2.13';
72
73 use strict;
74 use warnings FATAL => 'all';
75@@ -4421,7 +4421,8 @@
76 ref($self->{fh}) eq 'IO::Socket::SSL'
77 or die(qq/SSL connection failed for $host\n/);
78 if ( $self->{fh}->can("verify_hostname") ) {
79- $self->{fh}->verify_hostname( $host, $ssl_verify_args );
80+ $self->{fh}->verify_hostname( $host, $ssl_verify_args )
81+ or die(qq/SSL certificate not valid for $host\n/);
82 }
83 else {
84 my $fh = $self->{fh};
85@@ -4943,11 +4944,12 @@
86 PTDEBUG && _d(scalar @$instances_to_check, 'instances to check');
87 return unless @$instances_to_check;
88
89- my $protocol = 'https'; # optimistic, but...
90+ my $protocol = 'https';
91 eval { require IO::Socket::SSL; };
92 if ( $EVAL_ERROR ) {
93 PTDEBUG && _d($EVAL_ERROR);
94- $protocol = 'http';
95+ PTDEBUG && _d("SSL not available, won't run version_check");
96+ return;
97 }
98 PTDEBUG && _d('Using', $protocol);
99
100@@ -5384,6 +5386,11 @@
101 return;
102 }
103
104+ if ($item->{item} eq 'MySQL' && $item->{type} eq 'mysql_variable') {
105+ $item->{vars} = ['version_comment', 'version'];
106+ }
107+
108+
109 my @versions;
110 my %version_for;
111 foreach my $instance ( @$instances ) {
112@@ -7884,7 +7891,7 @@
113
114 =head1 COPYRIGHT, LICENSE, AND WARRANTY
115
116-This program is copyright 2011-2014 Percona LLC and/or its affiliates,
117+This program is copyright 2011-2015 Percona LLC and/or its affiliates,
118 2007-2011 Baron Schwartz.
119
120 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
121@@ -7903,6 +7910,6 @@
122
123 =head1 VERSION
124
125-pt-archiver 2.2.12
126+pt-archiver 2.2.13
127
128 =cut
129
130=== modified file 'bin/pt-config-diff'
131--- bin/pt-config-diff 2014-11-11 13:28:27 +0000
132+++ bin/pt-config-diff 2015-01-27 13:07:53 +0000
133@@ -43,7 +43,7 @@
134 {
135 package Percona::Toolkit;
136
137-our $VERSION = '2.2.12';
138+our $VERSION = '2.2.13';
139
140 use strict;
141 use warnings FATAL => 'all';
142@@ -2295,7 +2295,7 @@
143 set => $args{set},
144 NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1,
145 dbh_set => 0,
146- ask_pass => $args{ask_pass},
147+ ask_pass => $o->get('ask-pass'),
148 DSNParser => $dp,
149 is_cluster_node => undef,
150 parent => $args{parent},
151@@ -2311,7 +2311,7 @@
152
153 my $dbh = $self->{dbh};
154 if ( !$dbh || !$dbh->ping() ) {
155- if ( $self->{ask_pass} && !$self->{asked_for_pass} ) {
156+ if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p} ) {
157 $dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
158 $self->{asked_for_pass} = 1;
159 }
160@@ -2393,13 +2393,40 @@
161 return $self->{hostname} || $self->{dsn_name} || 'unknown host';
162 }
163
164+sub get_id {
165+ my ($self, $cxn) = @_;
166+
167+ $cxn ||= $self;
168+
169+ my $unique_id;
170+ if ($cxn->is_cluster_node()) { # for cluster we concatenate various variables to maximize id 'uniqueness' across versions
171+ my $sql = q{SHOW STATUS LIKE 'wsrep\_local\_index'};
172+ my (undef, $wsrep_local_index) = $cxn->dbh->selectrow_array($sql);
173+ PTDEBUG && _d("Got cluster wsrep_local_index: ",$wsrep_local_index);
174+ $unique_id = $wsrep_local_index."|";
175+ foreach my $val ('server\_id', 'wsrep\_sst\_receive\_address', 'wsrep\_node\_name', 'wsrep\_node\_address') {
176+ my $sql = "SHOW VARIABLES LIKE '$val'";
177+ PTDEBUG && _d($cxn->name, $sql);
178+ my (undef, $val) = $cxn->dbh->selectrow_array($sql);
179+ $unique_id .= "|$val";
180+ }
181+ } else {
182+ my $sql = 'SELECT @@SERVER_ID';
183+ PTDEBUG && _d($sql);
184+ $unique_id = $cxn->dbh->selectrow_array($sql);
185+ }
186+ PTDEBUG && _d("Generated unique id for cluster:", $unique_id);
187+ return $unique_id;
188+}
189+
190+
191 sub is_cluster_node {
192 my ($self, $cxn) = @_;
193
194+ $cxn ||= $self;
195 my $sql = "SHOW VARIABLES LIKE 'wsrep\_on'";
196 PTDEBUG && _d($cxn->name, $sql);
197 my $row = $cxn->dbh->selectrow_arrayref($sql);
198- PTDEBUG && _d(Dumper($row));
199 return $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1') ? 1 : 0;
200
201 }
202@@ -2412,11 +2439,8 @@
203 my @trimmed_cxns;
204
205 for my $cxn ( @cxns ) {
206- my $dbh = $cxn->dbh();
207
208- my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id};
209- PTDEBUG && _d($sql);
210- my ($id) = $dbh->selectrow_array($sql);
211+ my $id = $cxn->get_id();
212 PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id);
213
214 if ( ! $seen_ids->{$id}++ ) {
215@@ -4169,7 +4193,8 @@
216 ref($self->{fh}) eq 'IO::Socket::SSL'
217 or die(qq/SSL connection failed for $host\n/);
218 if ( $self->{fh}->can("verify_hostname") ) {
219- $self->{fh}->verify_hostname( $host, $ssl_verify_args );
220+ $self->{fh}->verify_hostname( $host, $ssl_verify_args )
221+ or die(qq/SSL certificate not valid for $host\n/);
222 }
223 else {
224 my $fh = $self->{fh};
225@@ -4691,11 +4716,12 @@
226 PTDEBUG && _d(scalar @$instances_to_check, 'instances to check');
227 return unless @$instances_to_check;
228
229- my $protocol = 'https'; # optimistic, but...
230+ my $protocol = 'https';
231 eval { require IO::Socket::SSL; };
232 if ( $EVAL_ERROR ) {
233 PTDEBUG && _d($EVAL_ERROR);
234- $protocol = 'http';
235+ PTDEBUG && _d("SSL not available, won't run version_check");
236+ return;
237 }
238 PTDEBUG && _d('Using', $protocol);
239
240@@ -5132,6 +5158,11 @@
241 return;
242 }
243
244+ if ($item->{item} eq 'MySQL' && $item->{type} eq 'mysql_variable') {
245+ $item->{vars} = ['version_comment', 'version'];
246+ }
247+
248+
249 my @versions;
250 my %version_for;
251 foreach my $instance ( @$instances ) {
252@@ -5734,7 +5765,7 @@
253
254 =head1 COPYRIGHT, LICENSE, AND WARRANTY
255
256-This program is copyright 2011-2014 Percona LLC and/or its affiliates.
257+This program is copyright 2011-2015 Percona LLC and/or its affiliates.
258
259 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
260 WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
261@@ -5752,6 +5783,6 @@
262
263 =head1 VERSION
264
265-pt-config-diff 2.2.12
266+pt-config-diff 2.2.13
267
268 =cut
269
270=== modified file 'bin/pt-deadlock-logger'
271--- bin/pt-deadlock-logger 2014-11-11 13:28:27 +0000
272+++ bin/pt-deadlock-logger 2015-01-27 13:07:53 +0000
273@@ -42,7 +42,7 @@
274 {
275 package Percona::Toolkit;
276
277-our $VERSION = '2.2.12';
278+our $VERSION = '2.2.13';
279
280 use strict;
281 use warnings FATAL => 'all';
282@@ -2639,7 +2639,7 @@
283 set => $args{set},
284 NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1,
285 dbh_set => 0,
286- ask_pass => $args{ask_pass},
287+ ask_pass => $o->get('ask-pass'),
288 DSNParser => $dp,
289 is_cluster_node => undef,
290 parent => $args{parent},
291@@ -2655,7 +2655,7 @@
292
293 my $dbh = $self->{dbh};
294 if ( !$dbh || !$dbh->ping() ) {
295- if ( $self->{ask_pass} && !$self->{asked_for_pass} ) {
296+ if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p} ) {
297 $dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
298 $self->{asked_for_pass} = 1;
299 }
300@@ -2737,13 +2737,40 @@
301 return $self->{hostname} || $self->{dsn_name} || 'unknown host';
302 }
303
304+sub get_id {
305+ my ($self, $cxn) = @_;
306+
307+ $cxn ||= $self;
308+
309+ my $unique_id;
310+ if ($cxn->is_cluster_node()) { # for cluster we concatenate various variables to maximize id 'uniqueness' across versions
311+ my $sql = q{SHOW STATUS LIKE 'wsrep\_local\_index'};
312+ my (undef, $wsrep_local_index) = $cxn->dbh->selectrow_array($sql);
313+ PTDEBUG && _d("Got cluster wsrep_local_index: ",$wsrep_local_index);
314+ $unique_id = $wsrep_local_index."|";
315+ foreach my $val ('server\_id', 'wsrep\_sst\_receive\_address', 'wsrep\_node\_name', 'wsrep\_node\_address') {
316+ my $sql = "SHOW VARIABLES LIKE '$val'";
317+ PTDEBUG && _d($cxn->name, $sql);
318+ my (undef, $val) = $cxn->dbh->selectrow_array($sql);
319+ $unique_id .= "|$val";
320+ }
321+ } else {
322+ my $sql = 'SELECT @@SERVER_ID';
323+ PTDEBUG && _d($sql);
324+ $unique_id = $cxn->dbh->selectrow_array($sql);
325+ }
326+ PTDEBUG && _d("Generated unique id for cluster:", $unique_id);
327+ return $unique_id;
328+}
329+
330+
331 sub is_cluster_node {
332 my ($self, $cxn) = @_;
333
334+ $cxn ||= $self;
335 my $sql = "SHOW VARIABLES LIKE 'wsrep\_on'";
336 PTDEBUG && _d($cxn->name, $sql);
337 my $row = $cxn->dbh->selectrow_arrayref($sql);
338- PTDEBUG && _d(Dumper($row));
339 return $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1') ? 1 : 0;
340
341 }
342@@ -2756,11 +2783,8 @@
343 my @trimmed_cxns;
344
345 for my $cxn ( @cxns ) {
346- my $dbh = $cxn->dbh();
347
348- my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id};
349- PTDEBUG && _d($sql);
350- my ($id) = $dbh->selectrow_array($sql);
351+ my $id = $cxn->get_id();
352 PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id);
353
354 if ( ! $seen_ids->{$id}++ ) {
355@@ -3234,7 +3258,8 @@
356 ref($self->{fh}) eq 'IO::Socket::SSL'
357 or die(qq/SSL connection failed for $host\n/);
358 if ( $self->{fh}->can("verify_hostname") ) {
359- $self->{fh}->verify_hostname( $host, $ssl_verify_args );
360+ $self->{fh}->verify_hostname( $host, $ssl_verify_args )
361+ or die(qq/SSL certificate not valid for $host\n/);
362 }
363 else {
364 my $fh = $self->{fh};
365@@ -3756,11 +3781,12 @@
366 PTDEBUG && _d(scalar @$instances_to_check, 'instances to check');
367 return unless @$instances_to_check;
368
369- my $protocol = 'https'; # optimistic, but...
370+ my $protocol = 'https';
371 eval { require IO::Socket::SSL; };
372 if ( $EVAL_ERROR ) {
373 PTDEBUG && _d($EVAL_ERROR);
374- $protocol = 'http';
375+ PTDEBUG && _d("SSL not available, won't run version_check");
376+ return;
377 }
378 PTDEBUG && _d('Using', $protocol);
379
380@@ -4197,6 +4223,11 @@
381 return;
382 }
383
384+ if ($item->{item} eq 'MySQL' && $item->{type} eq 'mysql_variable') {
385+ $item->{vars} = ['version_comment', 'version'];
386+ }
387+
388+
389 my @versions;
390 my %version_for;
391 foreach my $instance ( @$instances ) {
392@@ -5523,7 +5554,7 @@
393
394 =head1 COPYRIGHT, LICENSE, AND WARRANTY
395
396-This program is copyright 2011-2014 Percona LLC and/or its affiliates,
397+This program is copyright 2011-2015 Percona LLC and/or its affiliates,
398 2007-2011 Baron Schwartz.
399
400 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
401@@ -5542,6 +5573,6 @@
402
403 =head1 VERSION
404
405-pt-deadlock-logger 2.2.12
406+pt-deadlock-logger 2.2.13
407
408 =cut
409
410=== modified file 'bin/pt-diskstats'
411--- bin/pt-diskstats 2014-11-11 13:28:27 +0000
412+++ bin/pt-diskstats 2015-01-27 13:07:53 +0000
413@@ -38,7 +38,7 @@
414 {
415 package Percona::Toolkit;
416
417-our $VERSION = '2.2.12';
418+our $VERSION = '2.2.13';
419
420 use strict;
421 use warnings FATAL => 'all';
422@@ -3828,7 +3828,8 @@
423 ref($self->{fh}) eq 'IO::Socket::SSL'
424 or die(qq/SSL connection failed for $host\n/);
425 if ( $self->{fh}->can("verify_hostname") ) {
426- $self->{fh}->verify_hostname( $host, $ssl_verify_args );
427+ $self->{fh}->verify_hostname( $host, $ssl_verify_args )
428+ or die(qq/SSL certificate not valid for $host\n/);
429 }
430 else {
431 my $fh = $self->{fh};
432@@ -4350,11 +4351,12 @@
433 PTDEBUG && _d(scalar @$instances_to_check, 'instances to check');
434 return unless @$instances_to_check;
435
436- my $protocol = 'https'; # optimistic, but...
437+ my $protocol = 'https';
438 eval { require IO::Socket::SSL; };
439 if ( $EVAL_ERROR ) {
440 PTDEBUG && _d($EVAL_ERROR);
441- $protocol = 'http';
442+ PTDEBUG && _d("SSL not available, won't run version_check");
443+ return;
444 }
445 PTDEBUG && _d('Using', $protocol);
446
447@@ -4791,6 +4793,11 @@
448 return;
449 }
450
451+ if ($item->{item} eq 'MySQL' && $item->{type} eq 'mysql_variable') {
452+ $item->{vars} = ['version_comment', 'version'];
453+ }
454+
455+
456 my @versions;
457 my %version_for;
458 foreach my $instance ( @$instances ) {
459@@ -5560,7 +5567,7 @@
460
461 =head1 COPYRIGHT, LICENSE, AND WARRANTY
462
463-This program is copyright 2011-2014 Percona LLC and/or its affiliates,
464+This program is copyright 2011-2015 Percona LLC and/or its affiliates,
465 2010-2011 Baron Schwartz.
466
467 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
468@@ -5579,6 +5586,6 @@
469
470 =head1 VERSION
471
472-pt-diskstats 2.2.12
473+pt-diskstats 2.2.13
474
475 =cut
476
477=== modified file 'bin/pt-duplicate-key-checker'
478--- bin/pt-duplicate-key-checker 2014-11-11 13:28:27 +0000
479+++ bin/pt-duplicate-key-checker 2015-01-27 13:07:53 +0000
480@@ -39,7 +39,7 @@
481 {
482 package Percona::Toolkit;
483
484-our $VERSION = '2.2.12';
485+our $VERSION = '2.2.13';
486
487 use strict;
488 use warnings FATAL => 'all';
489@@ -3845,7 +3845,8 @@
490 ref($self->{fh}) eq 'IO::Socket::SSL'
491 or die(qq/SSL connection failed for $host\n/);
492 if ( $self->{fh}->can("verify_hostname") ) {
493- $self->{fh}->verify_hostname( $host, $ssl_verify_args );
494+ $self->{fh}->verify_hostname( $host, $ssl_verify_args )
495+ or die(qq/SSL certificate not valid for $host\n/);
496 }
497 else {
498 my $fh = $self->{fh};
499@@ -4367,11 +4368,12 @@
500 PTDEBUG && _d(scalar @$instances_to_check, 'instances to check');
501 return unless @$instances_to_check;
502
503- my $protocol = 'https'; # optimistic, but...
504+ my $protocol = 'https';
505 eval { require IO::Socket::SSL; };
506 if ( $EVAL_ERROR ) {
507 PTDEBUG && _d($EVAL_ERROR);
508- $protocol = 'http';
509+ PTDEBUG && _d("SSL not available, won't run version_check");
510+ return;
511 }
512 PTDEBUG && _d('Using', $protocol);
513
514@@ -4808,6 +4810,11 @@
515 return;
516 }
517
518+ if ($item->{item} eq 'MySQL' && $item->{type} eq 'mysql_variable') {
519+ $item->{vars} = ['version_comment', 'version'];
520+ }
521+
522+
523 my @versions;
524 my %version_for;
525 foreach my $instance ( @$instances ) {
526@@ -5581,7 +5588,7 @@
527
528 =head1 COPYRIGHT, LICENSE, AND WARRANTY
529
530-This program is copyright 2011-2014 Percona LLC and/or its affiliates,
531+This program is copyright 2011-2015 Percona LLC and/or its affiliates,
532 2007-2011 Baron Schwartz.
533
534 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
535@@ -5600,6 +5607,6 @@
536
537 =head1 VERSION
538
539-pt-duplicate-key-checker 2.2.12
540+pt-duplicate-key-checker 2.2.13
541
542 =cut
543
544=== modified file 'bin/pt-fifo-split'
545--- bin/pt-fifo-split 2014-11-11 13:28:27 +0000
546+++ bin/pt-fifo-split 2015-01-27 13:07:53 +0000
547@@ -1601,7 +1601,7 @@
548
549 =head1 COPYRIGHT, LICENSE, AND WARRANTY
550
551-This program is copyright 2011-2014 Percona LLC and/or its affiliates,
552+This program is copyright 2011-2015 Percona LLC and/or its affiliates,
553 2007-2011 Baron Schwartz.
554
555 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
556@@ -1620,6 +1620,6 @@
557
558 =head1 VERSION
559
560-pt-fifo-split 2.2.12
561+pt-fifo-split 2.2.13
562
563 =cut
564
565=== modified file 'bin/pt-find'
566--- bin/pt-find 2014-11-11 13:28:27 +0000
567+++ bin/pt-find 2015-01-27 13:07:53 +0000
568@@ -35,7 +35,7 @@
569 {
570 package Percona::Toolkit;
571
572-our $VERSION = '2.2.12';
573+our $VERSION = '2.2.13';
574
575 use strict;
576 use warnings FATAL => 'all';
577@@ -2572,7 +2572,8 @@
578 ref($self->{fh}) eq 'IO::Socket::SSL'
579 or die(qq/SSL connection failed for $host\n/);
580 if ( $self->{fh}->can("verify_hostname") ) {
581- $self->{fh}->verify_hostname( $host, $ssl_verify_args );
582+ $self->{fh}->verify_hostname( $host, $ssl_verify_args )
583+ or die(qq/SSL certificate not valid for $host\n/);
584 }
585 else {
586 my $fh = $self->{fh};
587@@ -3094,11 +3095,12 @@
588 PTDEBUG && _d(scalar @$instances_to_check, 'instances to check');
589 return unless @$instances_to_check;
590
591- my $protocol = 'https'; # optimistic, but...
592+ my $protocol = 'https';
593 eval { require IO::Socket::SSL; };
594 if ( $EVAL_ERROR ) {
595 PTDEBUG && _d($EVAL_ERROR);
596- $protocol = 'http';
597+ PTDEBUG && _d("SSL not available, won't run version_check");
598+ return;
599 }
600 PTDEBUG && _d('Using', $protocol);
601
602@@ -3535,6 +3537,11 @@
603 return;
604 }
605
606+ if ($item->{item} eq 'MySQL' && $item->{type} eq 'mysql_variable') {
607+ $item->{vars} = ['version_comment', 'version'];
608+ }
609+
610+
611 my @versions;
612 my %version_for;
613 foreach my $instance ( @$instances ) {
614@@ -4965,7 +4972,7 @@
615
616 =head1 COPYRIGHT, LICENSE, AND WARRANTY
617
618-This program is copyright 2011-2014 Percona LLC and/or its affiliates,
619+This program is copyright 2011-2015 Percona LLC and/or its affiliates,
620 2007-2011 Baron Schwartz.
621
622 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
623@@ -4984,6 +4991,6 @@
624
625 =head1 VERSION
626
627-pt-find 2.2.12
628+pt-find 2.2.13
629
630 =cut
631
632=== modified file 'bin/pt-fingerprint'
633--- bin/pt-fingerprint 2014-11-11 13:28:27 +0000
634+++ bin/pt-fingerprint 2015-01-27 13:07:53 +0000
635@@ -2193,7 +2193,7 @@
636
637 =head1 COPYRIGHT, LICENSE, AND WARRANTY
638
639-This program is copyright 2011-2014 Percona LLC and/or its affiliates.
640+This program is copyright 2011-2015 Percona LLC and/or its affiliates.
641
642 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
643 WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
644@@ -2211,6 +2211,6 @@
645
646 =head1 VERSION
647
648-pt-fingerprint 2.2.12
649+pt-fingerprint 2.2.13
650
651 =cut
652
653=== modified file 'bin/pt-fk-error-logger'
654--- bin/pt-fk-error-logger 2014-11-11 13:28:27 +0000
655+++ bin/pt-fk-error-logger 2015-01-27 13:07:53 +0000
656@@ -37,7 +37,7 @@
657 {
658 package Percona::Toolkit;
659
660-our $VERSION = '2.2.12';
661+our $VERSION = '2.2.13';
662
663 use strict;
664 use warnings FATAL => 'all';
665@@ -1791,7 +1791,7 @@
666 set => $args{set},
667 NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1,
668 dbh_set => 0,
669- ask_pass => $args{ask_pass},
670+ ask_pass => $o->get('ask-pass'),
671 DSNParser => $dp,
672 is_cluster_node => undef,
673 parent => $args{parent},
674@@ -1807,7 +1807,7 @@
675
676 my $dbh = $self->{dbh};
677 if ( !$dbh || !$dbh->ping() ) {
678- if ( $self->{ask_pass} && !$self->{asked_for_pass} ) {
679+ if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p} ) {
680 $dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
681 $self->{asked_for_pass} = 1;
682 }
683@@ -1889,13 +1889,40 @@
684 return $self->{hostname} || $self->{dsn_name} || 'unknown host';
685 }
686
687+sub get_id {
688+ my ($self, $cxn) = @_;
689+
690+ $cxn ||= $self;
691+
692+ my $unique_id;
693+ if ($cxn->is_cluster_node()) { # for cluster we concatenate various variables to maximize id 'uniqueness' across versions
694+ my $sql = q{SHOW STATUS LIKE 'wsrep\_local\_index'};
695+ my (undef, $wsrep_local_index) = $cxn->dbh->selectrow_array($sql);
696+ PTDEBUG && _d("Got cluster wsrep_local_index: ",$wsrep_local_index);
697+ $unique_id = $wsrep_local_index."|";
698+ foreach my $val ('server\_id', 'wsrep\_sst\_receive\_address', 'wsrep\_node\_name', 'wsrep\_node\_address') {
699+ my $sql = "SHOW VARIABLES LIKE '$val'";
700+ PTDEBUG && _d($cxn->name, $sql);
701+ my (undef, $val) = $cxn->dbh->selectrow_array($sql);
702+ $unique_id .= "|$val";
703+ }
704+ } else {
705+ my $sql = 'SELECT @@SERVER_ID';
706+ PTDEBUG && _d($sql);
707+ $unique_id = $cxn->dbh->selectrow_array($sql);
708+ }
709+ PTDEBUG && _d("Generated unique id for cluster:", $unique_id);
710+ return $unique_id;
711+}
712+
713+
714 sub is_cluster_node {
715 my ($self, $cxn) = @_;
716
717+ $cxn ||= $self;
718 my $sql = "SHOW VARIABLES LIKE 'wsrep\_on'";
719 PTDEBUG && _d($cxn->name, $sql);
720 my $row = $cxn->dbh->selectrow_arrayref($sql);
721- PTDEBUG && _d(Dumper($row));
722 return $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1') ? 1 : 0;
723
724 }
725@@ -1908,11 +1935,8 @@
726 my @trimmed_cxns;
727
728 for my $cxn ( @cxns ) {
729- my $dbh = $cxn->dbh();
730
731- my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id};
732- PTDEBUG && _d($sql);
733- my ($id) = $dbh->selectrow_array($sql);
734+ my $id = $cxn->get_id();
735 PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id);
736
737 if ( ! $seen_ids->{$id}++ ) {
738@@ -2739,7 +2763,8 @@
739 ref($self->{fh}) eq 'IO::Socket::SSL'
740 or die(qq/SSL connection failed for $host\n/);
741 if ( $self->{fh}->can("verify_hostname") ) {
742- $self->{fh}->verify_hostname( $host, $ssl_verify_args );
743+ $self->{fh}->verify_hostname( $host, $ssl_verify_args )
744+ or die(qq/SSL certificate not valid for $host\n/);
745 }
746 else {
747 my $fh = $self->{fh};
748@@ -3261,11 +3286,12 @@
749 PTDEBUG && _d(scalar @$instances_to_check, 'instances to check');
750 return unless @$instances_to_check;
751
752- my $protocol = 'https'; # optimistic, but...
753+ my $protocol = 'https';
754 eval { require IO::Socket::SSL; };
755 if ( $EVAL_ERROR ) {
756 PTDEBUG && _d($EVAL_ERROR);
757- $protocol = 'http';
758+ PTDEBUG && _d("SSL not available, won't run version_check");
759+ return;
760 }
761 PTDEBUG && _d('Using', $protocol);
762
763@@ -3702,6 +3728,11 @@
764 return;
765 }
766
767+ if ($item->{item} eq 'MySQL' && $item->{type} eq 'mysql_variable') {
768+ $item->{vars} = ['version_comment', 'version'];
769+ }
770+
771+
772 my @versions;
773 my %version_for;
774 foreach my $instance ( @$instances ) {
775@@ -4510,7 +4541,7 @@
776
777 =head1 COPYRIGHT, LICENSE, AND WARRANTY
778
779-This program is copyright 2011-2014 Percona LLC and/or its affiliates.
780+This program is copyright 2011-2015 Percona LLC and/or its affiliates.
781
782 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
783 WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
784@@ -4528,6 +4559,6 @@
785
786 =head1 VERSION
787
788-pt-fk-error-logger 2.2.12
789+pt-fk-error-logger 2.2.13
790
791 =cut
792
793=== modified file 'bin/pt-heartbeat'
794--- bin/pt-heartbeat 2014-11-11 13:28:27 +0000
795+++ bin/pt-heartbeat 2015-01-27 13:07:53 +0000
796@@ -38,7 +38,7 @@
797 {
798 package Percona::Toolkit;
799
800-our $VERSION = '2.2.12';
801+our $VERSION = '2.2.13';
802
803 use strict;
804 use warnings FATAL => 'all';
805@@ -3744,7 +3744,8 @@
806 ref($self->{fh}) eq 'IO::Socket::SSL'
807 or die(qq/SSL connection failed for $host\n/);
808 if ( $self->{fh}->can("verify_hostname") ) {
809- $self->{fh}->verify_hostname( $host, $ssl_verify_args );
810+ $self->{fh}->verify_hostname( $host, $ssl_verify_args )
811+ or die(qq/SSL certificate not valid for $host\n/);
812 }
813 else {
814 my $fh = $self->{fh};
815@@ -4266,11 +4267,12 @@
816 PTDEBUG && _d(scalar @$instances_to_check, 'instances to check');
817 return unless @$instances_to_check;
818
819- my $protocol = 'https'; # optimistic, but...
820+ my $protocol = 'https';
821 eval { require IO::Socket::SSL; };
822 if ( $EVAL_ERROR ) {
823 PTDEBUG && _d($EVAL_ERROR);
824- $protocol = 'http';
825+ PTDEBUG && _d("SSL not available, won't run version_check");
826+ return;
827 }
828 PTDEBUG && _d('Using', $protocol);
829
830@@ -4707,6 +4709,11 @@
831 return;
832 }
833
834+ if ($item->{item} eq 'MySQL' && $item->{type} eq 'mysql_variable') {
835+ $item->{vars} = ['version_comment', 'version'];
836+ }
837+
838+
839 my @versions;
840 my %version_for;
841 foreach my $instance ( @$instances ) {
842@@ -6197,7 +6204,7 @@
843
844 =head1 COPYRIGHT, LICENSE, AND WARRANTY
845
846-This program is copyright 2007-2014 Percona LLC and/or its affiliates,
847+This program is copyright 2007-2015 Percona LLC and/or its affiliates,
848 2006 Proven Scaling LLC and Six Apart Ltd.
849
850 Feedback and improvements are welcome.
851@@ -6218,6 +6225,6 @@
852
853 =head1 VERSION
854
855-pt-heartbeat 2.2.12
856+pt-heartbeat 2.2.13
857
858 =cut
859
860=== modified file 'bin/pt-index-usage'
861--- bin/pt-index-usage 2014-11-11 13:28:27 +0000
862+++ bin/pt-index-usage 2015-01-27 13:07:53 +0000
863@@ -45,7 +45,7 @@
864 {
865 package Percona::Toolkit;
866
867-our $VERSION = '2.2.12';
868+our $VERSION = '2.2.13';
869
870 use strict;
871 use warnings FATAL => 'all';
872@@ -5249,7 +5249,8 @@
873 ref($self->{fh}) eq 'IO::Socket::SSL'
874 or die(qq/SSL connection failed for $host\n/);
875 if ( $self->{fh}->can("verify_hostname") ) {
876- $self->{fh}->verify_hostname( $host, $ssl_verify_args );
877+ $self->{fh}->verify_hostname( $host, $ssl_verify_args )
878+ or die(qq/SSL certificate not valid for $host\n/);
879 }
880 else {
881 my $fh = $self->{fh};
882@@ -5771,11 +5772,12 @@
883 PTDEBUG && _d(scalar @$instances_to_check, 'instances to check');
884 return unless @$instances_to_check;
885
886- my $protocol = 'https'; # optimistic, but...
887+ my $protocol = 'https';
888 eval { require IO::Socket::SSL; };
889 if ( $EVAL_ERROR ) {
890 PTDEBUG && _d($EVAL_ERROR);
891- $protocol = 'http';
892+ PTDEBUG && _d("SSL not available, won't run version_check");
893+ return;
894 }
895 PTDEBUG && _d('Using', $protocol);
896
897@@ -6212,6 +6214,11 @@
898 return;
899 }
900
901+ if ($item->{item} eq 'MySQL' && $item->{type} eq 'mysql_variable') {
902+ $item->{vars} = ['version_comment', 'version'];
903+ }
904+
905+
906 my @versions;
907 my %version_for;
908 foreach my $instance ( @$instances ) {
909@@ -7529,7 +7536,7 @@
910
911 =head1 COPYRIGHT, LICENSE, AND WARRANTY
912
913-This program is copyright 2011-2014 Percona LLC and/or its affiliates,
914+This program is copyright 2011-2015 Percona LLC and/or its affiliates,
915 2010-2011 Baron Schwartz.
916
917 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
918@@ -7548,6 +7555,6 @@
919
920 =head1 VERSION
921
922-pt-index-usage 2.2.12
923+pt-index-usage 2.2.13
924
925 =cut
926
927=== modified file 'bin/pt-ioprofile'
928--- bin/pt-ioprofile 2014-11-11 13:28:27 +0000
929+++ bin/pt-ioprofile 2015-01-27 13:07:53 +0000
930@@ -201,7 +201,10 @@
931 _parse_config_files "$user_config_file"
932 done
933 else
934- _parse_config_files "/etc/percona-toolkit/percona-toolkit.conf" "/etc/percona-toolkit/$TOOL.conf" "$HOME/.percona-toolkit.conf" "$HOME/.$TOOL.conf"
935+ _parse_config_files "/etc/percona-toolkit/percona-toolkit.conf" "/etc/percona-toolkit/$TOOL.conf"
936+ if [ "${HOME:-}" ]; then
937+ _parse_config_files "$HOME/.percona-toolkit.conf" "$HOME/.$TOOL.conf"
938+ fi
939 fi
940
941 _parse_command_line "${@:-""}"
942@@ -1103,7 +1106,7 @@
943
944 =head1 COPYRIGHT, LICENSE, AND WARRANTY
945
946-This program is copyright 2011-2014 Percona LLC and/or its affiliates,
947+This program is copyright 2011-2015 Percona LLC and/or its affiliates,
948 2010-2011 Baron Schwartz.
949
950 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
951@@ -1122,7 +1125,7 @@
952
953 =head1 VERSION
954
955-pt-ioprofile 2.2.12
956+pt-ioprofile 2.2.13
957
958 =cut
959
960
961=== modified file 'bin/pt-kill'
962--- bin/pt-kill 2014-11-11 13:28:27 +0000
963+++ bin/pt-kill 2015-01-27 13:07:53 +0000
964@@ -47,7 +47,7 @@
965 {
966 package Percona::Toolkit;
967
968-our $VERSION = '2.2.12';
969+our $VERSION = '2.2.13';
970
971 use strict;
972 use warnings FATAL => 'all';
973@@ -4007,7 +4007,7 @@
974 die "You do not have the PROCESS privilege";
975 }
976
977- $sql = 'SHOW PROCESSLIST';
978+ $sql = 'SHOW FULL PROCESSLIST';
979 PTDEBUG && _d($dbh, $sql);
980 grep { $_->{command} =~ m/Binlog Dump/i }
981 map { # Lowercase the column names
982@@ -5158,7 +5158,7 @@
983 set => $args{set},
984 NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1,
985 dbh_set => 0,
986- ask_pass => $args{ask_pass},
987+ ask_pass => $o->get('ask-pass'),
988 DSNParser => $dp,
989 is_cluster_node => undef,
990 parent => $args{parent},
991@@ -5174,7 +5174,7 @@
992
993 my $dbh = $self->{dbh};
994 if ( !$dbh || !$dbh->ping() ) {
995- if ( $self->{ask_pass} && !$self->{asked_for_pass} ) {
996+ if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p} ) {
997 $dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
998 $self->{asked_for_pass} = 1;
999 }
1000@@ -5256,13 +5256,40 @@
1001 return $self->{hostname} || $self->{dsn_name} || 'unknown host';
1002 }
1003
1004+sub get_id {
1005+ my ($self, $cxn) = @_;
1006+
1007+ $cxn ||= $self;
1008+
1009+ my $unique_id;
1010+ if ($cxn->is_cluster_node()) { # for cluster we concatenate various variables to maximize id 'uniqueness' across versions
1011+ my $sql = q{SHOW STATUS LIKE 'wsrep\_local\_index'};
1012+ my (undef, $wsrep_local_index) = $cxn->dbh->selectrow_array($sql);
1013+ PTDEBUG && _d("Got cluster wsrep_local_index: ",$wsrep_local_index);
1014+ $unique_id = $wsrep_local_index."|";
1015+ foreach my $val ('server\_id', 'wsrep\_sst\_receive\_address', 'wsrep\_node\_name', 'wsrep\_node\_address') {
1016+ my $sql = "SHOW VARIABLES LIKE '$val'";
1017+ PTDEBUG && _d($cxn->name, $sql);
1018+ my (undef, $val) = $cxn->dbh->selectrow_array($sql);
1019+ $unique_id .= "|$val";
1020+ }
1021+ } else {
1022+ my $sql = 'SELECT @@SERVER_ID';
1023+ PTDEBUG && _d($sql);
1024+ $unique_id = $cxn->dbh->selectrow_array($sql);
1025+ }
1026+ PTDEBUG && _d("Generated unique id for cluster:", $unique_id);
1027+ return $unique_id;
1028+}
1029+
1030+
1031 sub is_cluster_node {
1032 my ($self, $cxn) = @_;
1033
1034+ $cxn ||= $self;
1035 my $sql = "SHOW VARIABLES LIKE 'wsrep\_on'";
1036 PTDEBUG && _d($cxn->name, $sql);
1037 my $row = $cxn->dbh->selectrow_arrayref($sql);
1038- PTDEBUG && _d(Dumper($row));
1039 return $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1') ? 1 : 0;
1040
1041 }
1042@@ -5275,11 +5302,8 @@
1043 my @trimmed_cxns;
1044
1045 for my $cxn ( @cxns ) {
1046- my $dbh = $cxn->dbh();
1047
1048- my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id};
1049- PTDEBUG && _d($sql);
1050- my ($id) = $dbh->selectrow_array($sql);
1051+ my $id = $cxn->get_id();
1052 PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id);
1053
1054 if ( ! $seen_ids->{$id}++ ) {
1055@@ -5551,7 +5575,8 @@
1056 ref($self->{fh}) eq 'IO::Socket::SSL'
1057 or die(qq/SSL connection failed for $host\n/);
1058 if ( $self->{fh}->can("verify_hostname") ) {
1059- $self->{fh}->verify_hostname( $host, $ssl_verify_args );
1060+ $self->{fh}->verify_hostname( $host, $ssl_verify_args )
1061+ or die(qq/SSL certificate not valid for $host\n/);
1062 }
1063 else {
1064 my $fh = $self->{fh};
1065@@ -6073,11 +6098,12 @@
1066 PTDEBUG && _d(scalar @$instances_to_check, 'instances to check');
1067 return unless @$instances_to_check;
1068
1069- my $protocol = 'https'; # optimistic, but...
1070+ my $protocol = 'https';
1071 eval { require IO::Socket::SSL; };
1072 if ( $EVAL_ERROR ) {
1073 PTDEBUG && _d($EVAL_ERROR);
1074- $protocol = 'http';
1075+ PTDEBUG && _d("SSL not available, won't run version_check");
1076+ return;
1077 }
1078 PTDEBUG && _d('Using', $protocol);
1079
1080@@ -6514,6 +6540,11 @@
1081 return;
1082 }
1083
1084+ if ($item->{item} eq 'MySQL' && $item->{type} eq 'mysql_variable') {
1085+ $item->{vars} = ['version_comment', 'version'];
1086+ }
1087+
1088+
1089 my @versions;
1090 my %version_for;
1091 foreach my $instance ( @$instances ) {
1092@@ -6567,6 +6598,7 @@
1093 use English qw(-no_match_vars);
1094 use POSIX qw(setsid);
1095 use List::Util qw(max);
1096+use Digest::MD5 qw(md5_hex);
1097
1098 use Data::Dumper;
1099 $Data::Dumper::Indent = 1;
1100@@ -7101,6 +7133,11 @@
1101 $query->{Id}, ($query->{Command} || 'NULL'), $query->{Time},
1102 ($query->{Info} || 'NULL');
1103 }
1104+ if ( $o->get('query-id') ) {
1105+ my $fp = $qr->fingerprint($query->{'Info'});
1106+ my $chksm = Transformers::make_checksum($fp);
1107+ print "Query ID: 0x$chksm\n";
1108+ }
1109 if ( $o->get('execute-command') ) {
1110 exec_cmd($o->get('execute-command'));
1111 msg('Executed ' . $o->get('execute-command'));
1112@@ -7487,6 +7524,7 @@
1113
1114 It is permissible for the code to have side effects (to alter C<$event>).
1115
1116+
1117 =item --group-by
1118
1119 type: string
1120@@ -7590,6 +7628,20 @@
1121
1122 Port number to use for connection.
1123
1124+=item --query-id
1125+
1126+Prints an ID of the query that was just killed. This is
1127+equivalent to the "ID" output of pt-query-digest. This allows
1128+cross-referencing the output of both tools.
1129+
1130+Example:
1131+
1132+ Query ID 0xE9800998ECF8427E
1133+
1134+Note that this is a digest (or hash) of the query's "fingerprint",
1135+so queries of the same form but with different values will have the same ID.
1136+See pt-query-digest for more information.
1137+
1138 =item --run-time
1139
1140 type: time
1141@@ -8183,7 +8235,7 @@
1142
1143 =head1 COPYRIGHT, LICENSE, AND WARRANTY
1144
1145-This program is copyright 2011-2014 Percona LLC and/or its affiliates,
1146+This program is copyright 2011-2015 Percona LLC and/or its affiliates,
1147 2009-2011 Baron Schwartz.
1148
1149 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
1150@@ -8202,6 +8254,6 @@
1151
1152 =head1 VERSION
1153
1154-pt-kill 2.2.12
1155+pt-kill 2.2.13
1156
1157 =cut
1158
1159=== modified file 'bin/pt-mext'
1160--- bin/pt-mext 2014-11-11 13:28:27 +0000
1161+++ bin/pt-mext 2015-01-27 13:07:53 +0000
1162@@ -242,7 +242,10 @@
1163 _parse_config_files "$user_config_file"
1164 done
1165 else
1166- _parse_config_files "/etc/percona-toolkit/percona-toolkit.conf" "/etc/percona-toolkit/$TOOL.conf" "$HOME/.percona-toolkit.conf" "$HOME/.$TOOL.conf"
1167+ _parse_config_files "/etc/percona-toolkit/percona-toolkit.conf" "/etc/percona-toolkit/$TOOL.conf"
1168+ if [ "${HOME:-}" ]; then
1169+ _parse_config_files "$HOME/.percona-toolkit.conf" "$HOME/.$TOOL.conf"
1170+ fi
1171 fi
1172
1173 _parse_command_line "${@:-""}"
1174@@ -779,7 +782,7 @@
1175
1176 =head1 COPYRIGHT, LICENSE, AND WARRANTY
1177
1178-This program is copyright 2011-2014 Percona LLC and/or its affiliates,
1179+This program is copyright 2011-2015 Percona LLC and/or its affiliates,
1180 2010 Baron Schwartz.
1181
1182 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
1183@@ -798,7 +801,7 @@
1184
1185 =head1 VERSION
1186
1187-pt-mext 2.2.12
1188+pt-mext 2.2.13
1189
1190 =cut
1191
1192
1193=== modified file 'bin/pt-mysql-summary'
1194--- bin/pt-mysql-summary 2014-11-11 13:28:27 +0000
1195+++ bin/pt-mysql-summary 2015-01-27 13:07:53 +0000
1196@@ -203,7 +203,10 @@
1197 _parse_config_files "$user_config_file"
1198 done
1199 else
1200- _parse_config_files "/etc/percona-toolkit/percona-toolkit.conf" "/etc/percona-toolkit/$TOOL.conf" "$HOME/.percona-toolkit.conf" "$HOME/.$TOOL.conf"
1201+ _parse_config_files "/etc/percona-toolkit/percona-toolkit.conf" "/etc/percona-toolkit/$TOOL.conf"
1202+ if [ "${HOME:-}" ]; then
1203+ _parse_config_files "$HOME/.percona-toolkit.conf" "$HOME/.$TOOL.conf"
1204+ fi
1205 fi
1206
1207 _parse_command_line "${@:-""}"
1208@@ -2397,7 +2400,7 @@
1209
1210 # Now that we have the cmd line opts, check that we can actually
1211 # connect to MySQL.
1212- [ -n "$(mysql $EXT_ARGV -e 'SELECT 1')" ] \
1213+ [ -n "$(mysql $EXT_ARGV -e 'SHOW STATUS')" ] \
1214 || die "Cannot connect to MySQL. Check that MySQL is running and that the options after -- are correct."
1215
1216 }
1217@@ -3066,7 +3069,7 @@
1218
1219 =head1 COPYRIGHT, LICENSE, AND WARRANTY
1220
1221-This program is copyright 2011-2014 Percona LLC and/or its affiliates,
1222+This program is copyright 2011-2015 Percona LLC and/or its affiliates,
1223 2010-2011 Baron Schwartz.
1224
1225 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
1226@@ -3085,7 +3088,7 @@
1227
1228 =head1 VERSION
1229
1230-pt-mysql-summary 2.2.12
1231+pt-mysql-summary 2.2.13
1232
1233 =cut
1234
1235
1236=== modified file 'bin/pt-online-schema-change'
1237--- bin/pt-online-schema-change 2014-11-11 13:28:27 +0000
1238+++ bin/pt-online-schema-change 2015-01-27 13:07:53 +0000
1239@@ -40,6 +40,7 @@
1240 HTTP::Micro
1241 VersionCheck
1242 Percona::XtraDB::Cluster
1243+ ReadKeyMini
1244 ));
1245 }
1246
1247@@ -54,7 +55,7 @@
1248 {
1249 package Percona::Toolkit;
1250
1251-our $VERSION = '2.2.12';
1252+our $VERSION = '2.2.13';
1253
1254 use strict;
1255 use warnings FATAL => 'all';
1256@@ -3755,7 +3756,7 @@
1257 set => $args{set},
1258 NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1,
1259 dbh_set => 0,
1260- ask_pass => $args{ask_pass},
1261+ ask_pass => $o->get('ask-pass'),
1262 DSNParser => $dp,
1263 is_cluster_node => undef,
1264 parent => $args{parent},
1265@@ -3771,7 +3772,7 @@
1266
1267 my $dbh = $self->{dbh};
1268 if ( !$dbh || !$dbh->ping() ) {
1269- if ( $self->{ask_pass} && !$self->{asked_for_pass} ) {
1270+ if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p} ) {
1271 $dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
1272 $self->{asked_for_pass} = 1;
1273 }
1274@@ -3853,13 +3854,40 @@
1275 return $self->{hostname} || $self->{dsn_name} || 'unknown host';
1276 }
1277
1278+sub get_id {
1279+ my ($self, $cxn) = @_;
1280+
1281+ $cxn ||= $self;
1282+
1283+ my $unique_id;
1284+ if ($cxn->is_cluster_node()) { # for cluster we concatenate various variables to maximize id 'uniqueness' across versions
1285+ my $sql = q{SHOW STATUS LIKE 'wsrep\_local\_index'};
1286+ my (undef, $wsrep_local_index) = $cxn->dbh->selectrow_array($sql);
1287+ PTDEBUG && _d("Got cluster wsrep_local_index: ",$wsrep_local_index);
1288+ $unique_id = $wsrep_local_index."|";
1289+ foreach my $val ('server\_id', 'wsrep\_sst\_receive\_address', 'wsrep\_node\_name', 'wsrep\_node\_address') {
1290+ my $sql = "SHOW VARIABLES LIKE '$val'";
1291+ PTDEBUG && _d($cxn->name, $sql);
1292+ my (undef, $val) = $cxn->dbh->selectrow_array($sql);
1293+ $unique_id .= "|$val";
1294+ }
1295+ } else {
1296+ my $sql = 'SELECT @@SERVER_ID';
1297+ PTDEBUG && _d($sql);
1298+ $unique_id = $cxn->dbh->selectrow_array($sql);
1299+ }
1300+ PTDEBUG && _d("Generated unique id for cluster:", $unique_id);
1301+ return $unique_id;
1302+}
1303+
1304+
1305 sub is_cluster_node {
1306 my ($self, $cxn) = @_;
1307
1308+ $cxn ||= $self;
1309 my $sql = "SHOW VARIABLES LIKE 'wsrep\_on'";
1310 PTDEBUG && _d($cxn->name, $sql);
1311 my $row = $cxn->dbh->selectrow_arrayref($sql);
1312- PTDEBUG && _d(Dumper($row));
1313 return $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1') ? 1 : 0;
1314
1315 }
1316@@ -3872,11 +3900,8 @@
1317 my @trimmed_cxns;
1318
1319 for my $cxn ( @cxns ) {
1320- my $dbh = $cxn->dbh();
1321
1322- my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id};
1323- PTDEBUG && _d($sql);
1324- my ($id) = $dbh->selectrow_array($sql);
1325+ my $id = $cxn->get_id();
1326 PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id);
1327
1328 if ( ! $seen_ids->{$id}++ ) {
1329@@ -6552,7 +6577,8 @@
1330 ref($self->{fh}) eq 'IO::Socket::SSL'
1331 or die(qq/SSL connection failed for $host\n/);
1332 if ( $self->{fh}->can("verify_hostname") ) {
1333- $self->{fh}->verify_hostname( $host, $ssl_verify_args );
1334+ $self->{fh}->verify_hostname( $host, $ssl_verify_args )
1335+ or die(qq/SSL certificate not valid for $host\n/);
1336 }
1337 else {
1338 my $fh = $self->{fh};
1339@@ -7074,11 +7100,12 @@
1340 PTDEBUG && _d(scalar @$instances_to_check, 'instances to check');
1341 return unless @$instances_to_check;
1342
1343- my $protocol = 'https'; # optimistic, but...
1344+ my $protocol = 'https';
1345 eval { require IO::Socket::SSL; };
1346 if ( $EVAL_ERROR ) {
1347 PTDEBUG && _d($EVAL_ERROR);
1348- $protocol = 'http';
1349+ PTDEBUG && _d("SSL not available, won't run version_check");
1350+ return;
1351 }
1352 PTDEBUG && _d('Using', $protocol);
1353
1354@@ -7515,6 +7542,11 @@
1355 return;
1356 }
1357
1358+ if ($item->{item} eq 'MySQL' && $item->{type} eq 'mysql_variable') {
1359+ $item->{vars} = ['version_comment', 'version'];
1360+ }
1361+
1362+
1363 my @versions;
1364 my %version_for;
1365 foreach my $instance ( @$instances ) {
1366@@ -7662,10 +7694,7 @@
1367 my @trimmed_cxns;
1368
1369 for my $cxn ( @cxns ) {
1370- my $dbh = $cxn->dbh();
1371- my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id};
1372- PTDEBUG && _d($sql);
1373- my ($id) = $dbh->selectrow_array($sql);
1374+ my $id = $cxn->get_id();
1375 PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id);
1376
1377 if ( ! $seen_ids->{$id}++ ) {
1378@@ -7758,6 +7787,162 @@
1379 # ###########################################################################
1380
1381 # ###########################################################################
1382+# ReadKeyMini package
1383+# This package is a copy without comments from the original. The original
1384+# with comments and its test file can be found in the Bazaar repository at,
1385+# lib/ReadKeyMini.pm
1386+# t/lib/ReadKeyMini.t
1387+# See https://launchpad.net/percona-toolkit for more information.
1388+# ###########################################################################
1389+{
1390+
1391+BEGIN {
1392+
1393+package ReadKeyMini;
1394+BEGIN { $INC{"ReadKeyMini.pm"} ||= 1 }
1395+
1396+use warnings;
1397+use strict;
1398+use English qw(-no_match_vars);
1399+use constant PTDEBUG => $ENV{PTDEBUG} || 0;
1400+
1401+use POSIX qw( :termios_h );
1402+use Fcntl qw( F_SETFL F_GETFL );
1403+
1404+use base qw( Exporter );
1405+
1406+BEGIN {
1407+ our @EXPORT_OK = qw( GetTerminalSize ReadMode );
1408+ *ReadMode = *Term::ReadKey::ReadMode = \&_ReadMode;
1409+ *GetTerminalSize = *Term::ReadKey::GetTerminalSize = \&_GetTerminalSize;
1410+}
1411+
1412+my %modes = (
1413+ original => 0,
1414+ restore => 0,
1415+ normal => 1,
1416+ noecho => 2,
1417+ cbreak => 3,
1418+ raw => 4,
1419+ 'ultra-raw' => 5,
1420+);
1421+
1422+{
1423+ my $fd_stdin = fileno(STDIN);
1424+ my $flags;
1425+ unless ( $PerconaTest::DONT_RESTORE_STDIN ) {
1426+ $flags = fcntl(STDIN, F_GETFL, 0)
1427+ or warn "Error getting STDIN flags with fcntl: $OS_ERROR";
1428+ }
1429+ my $term = POSIX::Termios->new();
1430+ $term->getattr($fd_stdin);
1431+ my $oterm = $term->getlflag();
1432+ my $echo = ECHO | ECHOK | ICANON;
1433+ my $noecho = $oterm & ~$echo;
1434+
1435+ sub _ReadMode {
1436+ my $mode = $modes{ $_[0] };
1437+ if ( $mode == $modes{normal} ) {
1438+ cooked();
1439+ }
1440+ elsif ( $mode == $modes{cbreak} || $mode == $modes{noecho} ) {
1441+ cbreak( $mode == $modes{noecho} ? $noecho : $oterm );
1442+ }
1443+ else {
1444+ die("ReadMore('$_[0]') not supported");
1445+ }
1446+ }
1447+
1448+ sub cbreak {
1449+ my ($lflag) = $_[0] || $noecho;
1450+ $term->setlflag($lflag);
1451+ $term->setcc( VTIME, 1 );
1452+ $term->setattr( $fd_stdin, TCSANOW );
1453+ }
1454+
1455+ sub cooked {
1456+ $term->setlflag($oterm);
1457+ $term->setcc( VTIME, 0 );
1458+ $term->setattr( $fd_stdin, TCSANOW );
1459+ if ( !$PerconaTest::DONT_RESTORE_STDIN ) {
1460+ fcntl(STDIN, F_SETFL, int($flags))
1461+ or warn "Error restoring STDIN flags with fcntl: $OS_ERROR";
1462+ }
1463+ }
1464+
1465+ END { cooked() }
1466+}
1467+
1468+sub readkey {
1469+ my $key = '';
1470+ cbreak();
1471+ sysread(STDIN, $key, 1);
1472+ my $timeout = 0.1;
1473+ if ( $key eq "\033" ) {
1474+ my $x = '';
1475+ STDIN->blocking(0);
1476+ sysread(STDIN, $x, 2);
1477+ STDIN->blocking(1);
1478+ $key .= $x;
1479+ redo if $key =~ /\[[0-2](?:[0-9];)?$/
1480+ }
1481+ cooked();
1482+ return $key;
1483+}
1484+
1485+
1486+BEGIN {
1487+ eval { no warnings; local $^W; require 'sys/ioctl.ph' };
1488+ if ( !defined &TIOCGWINSZ ) {
1489+ *TIOCGWINSZ = sub () {
1490+ $^O eq 'linux' ? 0x005413
1491+ : $^O eq 'solaris' ? 0x005468
1492+ : 0x40087468;
1493+ };
1494+ }
1495+}
1496+
1497+sub _GetTerminalSize {
1498+ if ( @_ ) {
1499+ die "My::Term::ReadKey doesn't implement GetTerminalSize with arguments";
1500+ }
1501+
1502+ my $cols = $ENV{COLUMNS} || 80;
1503+ my $rows = $ENV{LINES} || 24;
1504+
1505+ if ( open( TTY, "+<", "/dev/tty" ) ) { # Got a tty
1506+ my $winsize = '';
1507+ if ( ioctl( TTY, &TIOCGWINSZ, $winsize ) ) {
1508+ ( $rows, $cols, my ( $xpixel, $ypixel ) ) = unpack( 'S4', $winsize );
1509+ return ( $cols, $rows, $xpixel, $ypixel );
1510+ }
1511+ }
1512+
1513+ if ( $rows = `tput lines 2>/dev/null` ) {
1514+ chomp($rows);
1515+ chomp($cols = `tput cols`);
1516+ }
1517+ elsif ( my $stty = `stty -a 2>/dev/null` ) {
1518+ ($rows, $cols) = $stty =~ /([0-9]+) rows; ([0-9]+) columns;/;
1519+ }
1520+ else {
1521+ ($cols, $rows) = @ENV{qw( COLUMNS LINES )};
1522+ $cols ||= 80;
1523+ $rows ||= 24;
1524+ }
1525+
1526+ return ( $cols, $rows );
1527+}
1528+
1529+}
1530+
1531+1;
1532+}
1533+# ###########################################################################
1534+# End ReadKeyMini package
1535+# ###########################################################################
1536+
1537+# ###########################################################################
1538 # This is a combination of modules and programs in one -- a runnable module.
1539 # http://www.perl.com/pub/a/2006/07/13/lightning-articles.html?page=last
1540 # Or, look it up in the Camel book on pages 642 and 643 in the 3rd edition.
1541@@ -10484,6 +10669,12 @@
1542 my ( $signal ) = @_;
1543 $oktorun = 0; # flag for cleanup tasks
1544 print STDERR "# Exiting on SIG$signal.\n";
1545+ # restore terminal to normal state in case CTL+C issued while
1546+ # asking for password
1547+ # https://bugs.launchpad.net/percona-toolkit/+bug/1396870
1548+ # note: just including ReadKeyMini seems to solve the bug,
1549+ # but lets use it explicitly so we don't forget why we need it
1550+ ReadKeyMini::ReadMode 0;
1551 exit 1;
1552 }
1553
1554@@ -11598,7 +11789,7 @@
1555
1556 =head1 COPYRIGHT, LICENSE, AND WARRANTY
1557
1558-This program is copyright 2011-2014 Percona LLC and/or its affiliates.
1559+This program is copyright 2011-2015 Percona LLC and/or its affiliates.
1560
1561 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
1562 WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
1563@@ -11616,6 +11807,6 @@
1564
1565 =head1 VERSION
1566
1567-pt-online-schema-change 2.2.12
1568+pt-online-schema-change 2.2.13
1569
1570 =cut
1571
1572=== modified file 'bin/pt-pmp'
1573--- bin/pt-pmp 2014-11-11 13:28:27 +0000
1574+++ bin/pt-pmp 2015-01-27 13:07:53 +0000
1575@@ -244,7 +244,10 @@
1576 _parse_config_files "$user_config_file"
1577 done
1578 else
1579- _parse_config_files "/etc/percona-toolkit/percona-toolkit.conf" "/etc/percona-toolkit/$TOOL.conf" "$HOME/.percona-toolkit.conf" "$HOME/.$TOOL.conf"
1580+ _parse_config_files "/etc/percona-toolkit/percona-toolkit.conf" "/etc/percona-toolkit/$TOOL.conf"
1581+ if [ "${HOME:-}" ]; then
1582+ _parse_config_files "$HOME/.percona-toolkit.conf" "$HOME/.$TOOL.conf"
1583+ fi
1584 fi
1585
1586 _parse_command_line "${@:-""}"
1587@@ -873,7 +876,7 @@
1588
1589 =head1 COPYRIGHT, LICENSE, AND WARRANTY
1590
1591-This program is copyright 2011-2014 Percona LLC and/or its affiliates,
1592+This program is copyright 2011-2015 Percona LLC and/or its affiliates,
1593 2010-2011 Baron Schwartz.
1594
1595 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
1596@@ -892,7 +895,7 @@
1597
1598 =head1 VERSION
1599
1600-pt-pmp 2.2.12
1601+pt-pmp 2.2.13
1602
1603 =cut
1604
1605
1606=== modified file 'bin/pt-query-digest'
1607--- bin/pt-query-digest 2014-11-11 13:28:27 +0000
1608+++ bin/pt-query-digest 2015-01-27 13:07:53 +0000
1609@@ -64,7 +64,7 @@
1610 {
1611 package Percona::Toolkit;
1612
1613-our $VERSION = '2.2.12';
1614+our $VERSION = '2.2.13';
1615
1616 use strict;
1617 use warnings FATAL => 'all';
1618@@ -11833,7 +11833,8 @@
1619 ref($self->{fh}) eq 'IO::Socket::SSL'
1620 or die(qq/SSL connection failed for $host\n/);
1621 if ( $self->{fh}->can("verify_hostname") ) {
1622- $self->{fh}->verify_hostname( $host, $ssl_verify_args );
1623+ $self->{fh}->verify_hostname( $host, $ssl_verify_args )
1624+ or die(qq/SSL certificate not valid for $host\n/);
1625 }
1626 else {
1627 my $fh = $self->{fh};
1628@@ -12355,11 +12356,12 @@
1629 PTDEBUG && _d(scalar @$instances_to_check, 'instances to check');
1630 return unless @$instances_to_check;
1631
1632- my $protocol = 'https'; # optimistic, but...
1633+ my $protocol = 'https';
1634 eval { require IO::Socket::SSL; };
1635 if ( $EVAL_ERROR ) {
1636 PTDEBUG && _d($EVAL_ERROR);
1637- $protocol = 'http';
1638+ PTDEBUG && _d("SSL not available, won't run version_check");
1639+ return;
1640 }
1641 PTDEBUG && _d('Using', $protocol);
1642
1643@@ -12796,6 +12798,11 @@
1644 return;
1645 }
1646
1647+ if ($item->{item} eq 'MySQL' && $item->{type} eq 'mysql_variable') {
1648+ $item->{vars} = ['version_comment', 'version'];
1649+ }
1650+
1651+
1652 my @versions;
1653 my %version_for;
1654 foreach my $instance ( @$instances ) {
1655@@ -16599,7 +16606,7 @@
1656
1657 =head1 COPYRIGHT, LICENSE, AND WARRANTY
1658
1659-This program is copyright 2008-2014 Percona LLC and/or its affiliates.
1660+This program is copyright 2008-2015 Percona LLC and/or its affiliates.
1661
1662 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
1663 WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
1664@@ -16617,6 +16624,6 @@
1665
1666 =head1 VERSION
1667
1668-pt-query-digest 2.2.12
1669+pt-query-digest 2.2.13
1670
1671 =cut
1672
1673=== modified file 'bin/pt-show-grants'
1674--- bin/pt-show-grants 2014-11-11 13:28:27 +0000
1675+++ bin/pt-show-grants 2015-01-27 13:07:53 +0000
1676@@ -2395,7 +2395,7 @@
1677
1678 =head1 COPYRIGHT, LICENSE, AND WARRANTY
1679
1680-This program is copyright 2011-2014 Percona LLC and/or its affiliates,
1681+This program is copyright 2011-2015 Percona LLC and/or its affiliates,
1682 2007-2011 Baron Schwartz.
1683
1684 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
1685@@ -2414,6 +2414,6 @@
1686
1687 =head1 VERSION
1688
1689-pt-show-grants 2.2.12
1690+pt-show-grants 2.2.13
1691
1692 =cut
1693
1694=== modified file 'bin/pt-sift'
1695--- bin/pt-sift 2014-11-11 13:28:27 +0000
1696+++ bin/pt-sift 2015-01-27 13:07:53 +0000
1697@@ -242,7 +242,10 @@
1698 _parse_config_files "$user_config_file"
1699 done
1700 else
1701- _parse_config_files "/etc/percona-toolkit/percona-toolkit.conf" "/etc/percona-toolkit/$TOOL.conf" "$HOME/.percona-toolkit.conf" "$HOME/.$TOOL.conf"
1702+ _parse_config_files "/etc/percona-toolkit/percona-toolkit.conf" "/etc/percona-toolkit/$TOOL.conf"
1703+ if [ "${HOME:-}" ]; then
1704+ _parse_config_files "$HOME/.percona-toolkit.conf" "$HOME/.$TOOL.conf"
1705+ fi
1706 fi
1707
1708 _parse_command_line "${@:-""}"
1709@@ -1221,7 +1224,7 @@
1710
1711 =head1 COPYRIGHT, LICENSE, AND WARRANTY
1712
1713-This program is copyright 2011-2014 Percona LLC and/or its affiliates,
1714+This program is copyright 2011-2015 Percona LLC and/or its affiliates,
1715 2010-2011 Baron Schwartz.
1716
1717 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
1718@@ -1240,7 +1243,7 @@
1719
1720 =head1 VERSION
1721
1722-pt-sift 2.2.12
1723+pt-sift 2.2.13
1724
1725 =cut
1726
1727
1728=== modified file 'bin/pt-slave-delay'
1729--- bin/pt-slave-delay 2014-11-11 13:28:27 +0000
1730+++ bin/pt-slave-delay 2015-01-27 13:07:53 +0000
1731@@ -40,7 +40,7 @@
1732 {
1733 package Percona::Toolkit;
1734
1735-our $VERSION = '2.2.12';
1736+our $VERSION = '2.2.13';
1737
1738 use strict;
1739 use warnings FATAL => 'all';
1740@@ -3097,7 +3097,8 @@
1741 ref($self->{fh}) eq 'IO::Socket::SSL'
1742 or die(qq/SSL connection failed for $host\n/);
1743 if ( $self->{fh}->can("verify_hostname") ) {
1744- $self->{fh}->verify_hostname( $host, $ssl_verify_args );
1745+ $self->{fh}->verify_hostname( $host, $ssl_verify_args )
1746+ or die(qq/SSL certificate not valid for $host\n/);
1747 }
1748 else {
1749 my $fh = $self->{fh};
1750@@ -3619,11 +3620,12 @@
1751 PTDEBUG && _d(scalar @$instances_to_check, 'instances to check');
1752 return unless @$instances_to_check;
1753
1754- my $protocol = 'https'; # optimistic, but...
1755+ my $protocol = 'https';
1756 eval { require IO::Socket::SSL; };
1757 if ( $EVAL_ERROR ) {
1758 PTDEBUG && _d($EVAL_ERROR);
1759- $protocol = 'http';
1760+ PTDEBUG && _d("SSL not available, won't run version_check");
1761+ return;
1762 }
1763 PTDEBUG && _d('Using', $protocol);
1764
1765@@ -4060,6 +4062,11 @@
1766 return;
1767 }
1768
1769+ if ($item->{item} eq 'MySQL' && $item->{type} eq 'mysql_variable') {
1770+ $item->{vars} = ['version_comment', 'version'];
1771+ }
1772+
1773+
1774 my @versions;
1775 my %version_for;
1776 foreach my $instance ( @$instances ) {
1777@@ -4850,7 +4857,7 @@
1778
1779 =head1 COPYRIGHT, LICENSE, AND WARRANTY
1780
1781-This program is copyright 2011-2014 Percona LLC and/or its affiliates,
1782+This program is copyright 2011-2015 Percona LLC and/or its affiliates,
1783 2007-2011 Sergey Zhuravle and Baron Schwartz.
1784
1785 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
1786@@ -4869,6 +4876,6 @@
1787
1788 =head1 VERSION
1789
1790-pt-slave-delay 2.2.12
1791+pt-slave-delay 2.2.13
1792
1793 =cut
1794
1795=== modified file 'bin/pt-slave-find'
1796--- bin/pt-slave-find 2014-11-11 13:28:27 +0000
1797+++ bin/pt-slave-find 2015-01-27 13:07:53 +0000
1798@@ -4323,7 +4323,7 @@
1799
1800 =head1 COPYRIGHT, LICENSE, AND WARRANTY
1801
1802-This program is copyright 2011-2014 Percona LLC and/or its affiliates,
1803+This program is copyright 2011-2015 Percona LLC and/or its affiliates,
1804 2007-2011 Baron Schwartz.
1805
1806 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
1807@@ -4342,6 +4342,6 @@
1808
1809 =head1 VERSION
1810
1811-pt-slave-find 2.2.12
1812+pt-slave-find 2.2.13
1813
1814 =cut
1815
1816=== modified file 'bin/pt-slave-restart'
1817--- bin/pt-slave-restart 2014-11-11 13:28:27 +0000
1818+++ bin/pt-slave-restart 2015-01-27 13:07:53 +0000
1819@@ -41,7 +41,7 @@
1820 {
1821 package Percona::Toolkit;
1822
1823-our $VERSION = '2.2.12';
1824+our $VERSION = '2.2.13';
1825
1826 use strict;
1827 use warnings FATAL => 'all';
1828@@ -3746,7 +3746,8 @@
1829 ref($self->{fh}) eq 'IO::Socket::SSL'
1830 or die(qq/SSL connection failed for $host\n/);
1831 if ( $self->{fh}->can("verify_hostname") ) {
1832- $self->{fh}->verify_hostname( $host, $ssl_verify_args );
1833+ $self->{fh}->verify_hostname( $host, $ssl_verify_args )
1834+ or die(qq/SSL certificate not valid for $host\n/);
1835 }
1836 else {
1837 my $fh = $self->{fh};
1838@@ -4268,11 +4269,12 @@
1839 PTDEBUG && _d(scalar @$instances_to_check, 'instances to check');
1840 return unless @$instances_to_check;
1841
1842- my $protocol = 'https'; # optimistic, but...
1843+ my $protocol = 'https';
1844 eval { require IO::Socket::SSL; };
1845 if ( $EVAL_ERROR ) {
1846 PTDEBUG && _d($EVAL_ERROR);
1847- $protocol = 'http';
1848+ PTDEBUG && _d("SSL not available, won't run version_check");
1849+ return;
1850 }
1851 PTDEBUG && _d('Using', $protocol);
1852
1853@@ -4709,6 +4711,11 @@
1854 return;
1855 }
1856
1857+ if ($item->{item} eq 'MySQL' && $item->{type} eq 'mysql_variable') {
1858+ $item->{vars} = ['version_comment', 'version'];
1859+ }
1860+
1861+
1862 my @versions;
1863 my %version_for;
1864 foreach my $instance ( @$instances ) {
1865@@ -5918,7 +5925,7 @@
1866
1867 =head1 COPYRIGHT, LICENSE, AND WARRANTY
1868
1869-This program is copyright 2011-2014 Percona LLC and/or its affiliates,
1870+This program is copyright 2011-2015 Percona LLC and/or its affiliates,
1871 2007-2011 Baron Schwartz.
1872
1873 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
1874@@ -5937,6 +5944,6 @@
1875
1876 =head1 VERSION
1877
1878-pt-slave-restart 2.2.12
1879+pt-slave-restart 2.2.13
1880
1881 =cut
1882
1883=== modified file 'bin/pt-stalk'
1884--- bin/pt-stalk 2014-11-11 13:28:27 +0000
1885+++ bin/pt-stalk 2015-01-27 13:07:53 +0000
1886@@ -255,7 +255,10 @@
1887 _parse_config_files "$user_config_file"
1888 done
1889 else
1890- _parse_config_files "/etc/percona-toolkit/percona-toolkit.conf" "/etc/percona-toolkit/$TOOL.conf" "$HOME/.percona-toolkit.conf" "$HOME/.$TOOL.conf"
1891+ _parse_config_files "/etc/percona-toolkit/percona-toolkit.conf" "/etc/percona-toolkit/$TOOL.conf"
1892+ if [ "${HOME:-}" ]; then
1893+ _parse_config_files "$HOME/.percona-toolkit.conf" "$HOME/.$TOOL.conf"
1894+ fi
1895 fi
1896
1897 _parse_command_line "${@:-""}"
1898@@ -2219,7 +2222,7 @@
1899
1900 =head1 COPYRIGHT, LICENSE, AND WARRANTY
1901
1902-This program is copyright 2011-2014 Percona LLC and/or its affiliates,
1903+This program is copyright 2011-2015 Percona LLC and/or its affiliates,
1904 2010-2011 Baron Schwartz.
1905
1906 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
1907@@ -2238,7 +2241,7 @@
1908
1909 =head1 VERSION
1910
1911-pt-stalk 2.2.12
1912+pt-stalk 2.2.13
1913
1914 =cut
1915
1916
1917=== modified file 'bin/pt-summary'
1918--- bin/pt-summary 2014-11-11 13:28:27 +0000
1919+++ bin/pt-summary 2015-01-27 13:07:53 +0000
1920@@ -210,7 +210,10 @@
1921 _parse_config_files "$user_config_file"
1922 done
1923 else
1924- _parse_config_files "/etc/percona-toolkit/percona-toolkit.conf" "/etc/percona-toolkit/$TOOL.conf" "$HOME/.percona-toolkit.conf" "$HOME/.$TOOL.conf"
1925+ _parse_config_files "/etc/percona-toolkit/percona-toolkit.conf" "/etc/percona-toolkit/$TOOL.conf"
1926+ if [ "${HOME:-}" ]; then
1927+ _parse_config_files "$HOME/.percona-toolkit.conf" "$HOME/.$TOOL.conf"
1928+ fi
1929 fi
1930
1931 _parse_command_line "${@:-""}"
1932@@ -2674,7 +2677,7 @@
1933
1934 =head1 COPYRIGHT, LICENSE, AND WARRANTY
1935
1936-This program is copyright 2011-2014 Percona LLC and/or its affiliates,
1937+This program is copyright 2011-2015 Percona LLC and/or its affiliates,
1938 2010-2011 Baron Schwartz.
1939
1940 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
1941@@ -2693,7 +2696,7 @@
1942
1943 =head1 VERSION
1944
1945-pt-summary 2.2.12
1946+pt-summary 2.2.13
1947
1948 =cut
1949
1950
1951=== modified file 'bin/pt-table-checksum'
1952--- bin/pt-table-checksum 2014-11-11 13:28:27 +0000
1953+++ bin/pt-table-checksum 2015-01-27 13:07:53 +0000
1954@@ -57,7 +57,7 @@
1955 {
1956 package Percona::Toolkit;
1957
1958-our $VERSION = '2.2.12';
1959+our $VERSION = '2.2.13';
1960
1961 use strict;
1962 use warnings FATAL => 'all';
1963@@ -332,7 +332,8 @@
1964 ref($self->{fh}) eq 'IO::Socket::SSL'
1965 or die(qq/SSL connection failed for $host\n/);
1966 if ( $self->{fh}->can("verify_hostname") ) {
1967- $self->{fh}->verify_hostname( $host, $ssl_verify_args );
1968+ $self->{fh}->verify_hostname( $host, $ssl_verify_args )
1969+ or die(qq/SSL certificate not valid for $host\n/);
1970 }
1971 else {
1972 my $fh = $self->{fh};
1973@@ -854,11 +855,12 @@
1974 PTDEBUG && _d(scalar @$instances_to_check, 'instances to check');
1975 return unless @$instances_to_check;
1976
1977- my $protocol = 'https'; # optimistic, but...
1978+ my $protocol = 'https';
1979 eval { require IO::Socket::SSL; };
1980 if ( $EVAL_ERROR ) {
1981 PTDEBUG && _d($EVAL_ERROR);
1982- $protocol = 'http';
1983+ PTDEBUG && _d("SSL not available, won't run version_check");
1984+ return;
1985 }
1986 PTDEBUG && _d('Using', $protocol);
1987
1988@@ -1295,6 +1297,11 @@
1989 return;
1990 }
1991
1992+ if ($item->{item} eq 'MySQL' && $item->{type} eq 'mysql_variable') {
1993+ $item->{vars} = ['version_comment', 'version'];
1994+ }
1995+
1996+
1997 my @versions;
1998 my %version_for;
1999 foreach my $instance ( @$instances ) {
2000@@ -3533,7 +3540,7 @@
2001 set => $args{set},
2002 NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1,
2003 dbh_set => 0,
2004- ask_pass => $args{ask_pass},
2005+ ask_pass => $o->get('ask-pass'),
2006 DSNParser => $dp,
2007 is_cluster_node => undef,
2008 parent => $args{parent},
2009@@ -3549,7 +3556,7 @@
2010
2011 my $dbh = $self->{dbh};
2012 if ( !$dbh || !$dbh->ping() ) {
2013- if ( $self->{ask_pass} && !$self->{asked_for_pass} ) {
2014+ if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p} ) {
2015 $dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
2016 $self->{asked_for_pass} = 1;
2017 }
2018@@ -3631,13 +3638,40 @@
2019 return $self->{hostname} || $self->{dsn_name} || 'unknown host';
2020 }
2021
2022+sub get_id {
2023+ my ($self, $cxn) = @_;
2024+
2025+ $cxn ||= $self;
2026+
2027+ my $unique_id;
2028+ if ($cxn->is_cluster_node()) { # for cluster we concatenate various variables to maximize id 'uniqueness' across versions
2029+ my $sql = q{SHOW STATUS LIKE 'wsrep\_local\_index'};
2030+ my (undef, $wsrep_local_index) = $cxn->dbh->selectrow_array($sql);
2031+ PTDEBUG && _d("Got cluster wsrep_local_index: ",$wsrep_local_index);
2032+ $unique_id = $wsrep_local_index."|";
2033+ foreach my $val ('server\_id', 'wsrep\_sst\_receive\_address', 'wsrep\_node\_name', 'wsrep\_node\_address') {
2034+ my $sql = "SHOW VARIABLES LIKE '$val'";
2035+ PTDEBUG && _d($cxn->name, $sql);
2036+ my (undef, $val) = $cxn->dbh->selectrow_array($sql);
2037+ $unique_id .= "|$val";
2038+ }
2039+ } else {
2040+ my $sql = 'SELECT @@SERVER_ID';
2041+ PTDEBUG && _d($sql);
2042+ $unique_id = $cxn->dbh->selectrow_array($sql);
2043+ }
2044+ PTDEBUG && _d("Generated unique id for cluster:", $unique_id);
2045+ return $unique_id;
2046+}
2047+
2048+
2049 sub is_cluster_node {
2050 my ($self, $cxn) = @_;
2051
2052+ $cxn ||= $self;
2053 my $sql = "SHOW VARIABLES LIKE 'wsrep\_on'";
2054 PTDEBUG && _d($cxn->name, $sql);
2055 my $row = $cxn->dbh->selectrow_arrayref($sql);
2056- PTDEBUG && _d(Dumper($row));
2057 return $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1') ? 1 : 0;
2058
2059 }
2060@@ -3650,11 +3684,8 @@
2061 my @trimmed_cxns;
2062
2063 for my $cxn ( @cxns ) {
2064- my $dbh = $cxn->dbh();
2065
2066- my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id};
2067- PTDEBUG && _d($sql);
2068- my ($id) = $dbh->selectrow_array($sql);
2069+ my $id = $cxn->get_id();
2070 PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id);
2071
2072 if ( ! $seen_ids->{$id}++ ) {
2073@@ -3812,10 +3843,7 @@
2074 my @trimmed_cxns;
2075
2076 for my $cxn ( @cxns ) {
2077- my $dbh = $cxn->dbh();
2078- my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id};
2079- PTDEBUG && _d($sql);
2080- my ($id) = $dbh->selectrow_array($sql);
2081+ my $id = $cxn->get_id();
2082 PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id);
2083
2084 if ( ! $seen_ids->{$id}++ ) {
2085@@ -5714,8 +5742,8 @@
2086 $query = join(', ',
2087 map {
2088 my $col = $_;
2089- if ( $col =~ m/\+ 0/ ) {
2090- my ($real_col) = /^(\S+)/;
2091+ if ( $col =~ m/UNIX_TIMESTAMP/ ) {
2092+ my ($real_col) = /^UNIX_TIMESTAMP\((.+?)\)/;
2093 $col .= " AS $real_col";
2094 }
2095 elsif ( $col =~ m/TRIM/ ) {
2096@@ -5815,7 +5843,7 @@
2097 my $type = $tbl_struct->{type_for}->{$_};
2098 my $result = $q->quote($_);
2099 if ( $type eq 'timestamp' ) {
2100- $result .= ' + 0';
2101+ $result = "UNIX_TIMESTAMP($result)";
2102 }
2103 elsif ( $float_precision && $type =~ m/float|double/ ) {
2104 $result = "ROUND($result, $float_precision)";
2105@@ -9131,6 +9159,26 @@
2106 return if $o->get('explain');
2107 my $sql;
2108
2109+ # https://bugs.launchpad.net/percona-toolkit/+bug/1019479
2110+ # sql_mode ONLY_FULL_GROUP_BY often raises error even when query is
2111+ # safe and deterministic. It's best to turn it off for the session
2112+ # at this point.
2113+ $sql = 'SELECT @@SQL_MODE';
2114+ PTDEBUG && _d($dbh, $sql);
2115+ my ($sql_mode) = eval { $dbh->selectrow_array($sql) };
2116+ if ( $EVAL_ERROR ) {
2117+ die "Error getting the current SQL_MODE: $EVAL_ERROR";
2118+ }
2119+ $sql_mode =~ s/ONLY_FULL_GROUP_BY//i;
2120+ $sql = qq[SET SQL_MODE='$sql_mode'];
2121+ PTDEBUG && _d($dbh, $sql);
2122+ eval { $dbh->do($sql) };
2123+ if ( $EVAL_ERROR ) {
2124+ die "Error setting SQL_MODE"
2125+ . ": $EVAL_ERROR";
2126+ }
2127+
2128+
2129 # https://bugs.launchpad.net/percona-toolkit/+bug/919352
2130 # The tool shouldn't blindly attempt to change binlog_format;
2131 # instead, it should check if it's already set to STATEMENT.
2132@@ -9323,10 +9371,8 @@
2133 my %seen_ids;
2134 for my $cxn ($master_cxn, @$slaves) {
2135 my $dbh = $cxn->dbh();
2136- # if it's a cluster node we use its incoming address as id ( see https://bugs.launchpad.net/percona-toolkit/+bug/1217466 )
2137- my $sql = $cluster->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id};
2138- PTDEBUG && _d($cxn, $dbh, $sql);
2139- my ($id) = $dbh->selectrow_array($sql);
2140+ # get server/node unique id ( https://bugs.launchpad.net/percona-toolkit/+bug/1217466 )
2141+ my $id = $cxn->get_id();
2142 $seen_ids{$id}++;
2143 }
2144
2145@@ -12723,7 +12769,7 @@
2146
2147 =head1 COPYRIGHT, LICENSE, AND WARRANTY
2148
2149-This program is copyright 2011-2014 Percona LLC and/or its affiliates,
2150+This program is copyright 2011-2015 Percona LLC and/or its affiliates,
2151 2007-2011 Baron Schwartz.
2152
2153 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
2154@@ -12742,6 +12788,6 @@
2155
2156 =head1 VERSION
2157
2158-pt-table-checksum 2.2.12
2159+pt-table-checksum 2.2.13
2160
2161 =cut
2162
2163=== modified file 'bin/pt-table-sync'
2164--- bin/pt-table-sync 2014-11-11 13:28:27 +0000
2165+++ bin/pt-table-sync 2015-01-27 13:07:53 +0000
2166@@ -55,7 +55,7 @@
2167 {
2168 package Percona::Toolkit;
2169
2170-our $VERSION = '2.2.12';
2171+our $VERSION = '2.2.13';
2172
2173 use strict;
2174 use warnings FATAL => 'all';
2175@@ -8605,7 +8605,8 @@
2176 ref($self->{fh}) eq 'IO::Socket::SSL'
2177 or die(qq/SSL connection failed for $host\n/);
2178 if ( $self->{fh}->can("verify_hostname") ) {
2179- $self->{fh}->verify_hostname( $host, $ssl_verify_args );
2180+ $self->{fh}->verify_hostname( $host, $ssl_verify_args )
2181+ or die(qq/SSL certificate not valid for $host\n/);
2182 }
2183 else {
2184 my $fh = $self->{fh};
2185@@ -9127,11 +9128,12 @@
2186 PTDEBUG && _d(scalar @$instances_to_check, 'instances to check');
2187 return unless @$instances_to_check;
2188
2189- my $protocol = 'https'; # optimistic, but...
2190+ my $protocol = 'https';
2191 eval { require IO::Socket::SSL; };
2192 if ( $EVAL_ERROR ) {
2193 PTDEBUG && _d($EVAL_ERROR);
2194- $protocol = 'http';
2195+ PTDEBUG && _d("SSL not available, won't run version_check");
2196+ return;
2197 }
2198 PTDEBUG && _d('Using', $protocol);
2199
2200@@ -9568,6 +9570,11 @@
2201 return;
2202 }
2203
2204+ if ($item->{item} eq 'MySQL' && $item->{type} eq 'mysql_variable') {
2205+ $item->{vars} = ['version_comment', 'version'];
2206+ }
2207+
2208+
2209 my @versions;
2210 my %version_for;
2211 foreach my $instance ( @$instances ) {
2212@@ -12749,7 +12756,7 @@
2213
2214 =head1 COPYRIGHT, LICENSE, AND WARRANTY
2215
2216-This program is copyright 2011-2014 Percona LLC and/or its affiliates,
2217+This program is copyright 2011-2015 Percona LLC and/or its affiliates,
2218 2007-2011 Baron Schwartz.
2219
2220 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
2221@@ -12768,6 +12775,6 @@
2222
2223 =head1 VERSION
2224
2225-pt-table-sync 2.2.12
2226+pt-table-sync 2.2.13
2227
2228 =cut
2229
2230=== modified file 'bin/pt-table-usage'
2231--- bin/pt-table-usage 2014-11-11 13:28:27 +0000
2232+++ bin/pt-table-usage 2015-01-27 13:07:53 +0000
2233@@ -7553,7 +7553,7 @@
2234
2235 =head1 COPYRIGHT, LICENSE, AND WARRANTY
2236
2237-This program is copyright 2012-2014 Percona LLC and/or its affiliates.
2238+This program is copyright 2012-2015 Percona LLC and/or its affiliates.
2239
2240 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
2241 WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
2242@@ -7571,6 +7571,6 @@
2243
2244 =head1 VERSION
2245
2246-pt-table-usage 2.2.12
2247+pt-table-usage 2.2.13
2248
2249 =cut
2250
2251=== modified file 'bin/pt-upgrade'
2252--- bin/pt-upgrade 2014-11-11 13:28:27 +0000
2253+++ bin/pt-upgrade 2015-01-27 13:07:53 +0000
2254@@ -61,7 +61,7 @@
2255 {
2256 package Percona::Toolkit;
2257
2258-our $VERSION = '2.2.12';
2259+our $VERSION = '2.2.13';
2260
2261 use strict;
2262 use warnings FATAL => 'all';
2263@@ -2464,7 +2464,7 @@
2264 set => $args{set},
2265 NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1,
2266 dbh_set => 0,
2267- ask_pass => $args{ask_pass},
2268+ ask_pass => $o->get('ask-pass'),
2269 DSNParser => $dp,
2270 is_cluster_node => undef,
2271 parent => $args{parent},
2272@@ -2480,7 +2480,7 @@
2273
2274 my $dbh = $self->{dbh};
2275 if ( !$dbh || !$dbh->ping() ) {
2276- if ( $self->{ask_pass} && !$self->{asked_for_pass} ) {
2277+ if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p} ) {
2278 $dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
2279 $self->{asked_for_pass} = 1;
2280 }
2281@@ -2562,13 +2562,40 @@
2282 return $self->{hostname} || $self->{dsn_name} || 'unknown host';
2283 }
2284
2285+sub get_id {
2286+ my ($self, $cxn) = @_;
2287+
2288+ $cxn ||= $self;
2289+
2290+ my $unique_id;
2291+ if ($cxn->is_cluster_node()) { # for cluster we concatenate various variables to maximize id 'uniqueness' across versions
2292+ my $sql = q{SHOW STATUS LIKE 'wsrep\_local\_index'};
2293+ my (undef, $wsrep_local_index) = $cxn->dbh->selectrow_array($sql);
2294+ PTDEBUG && _d("Got cluster wsrep_local_index: ",$wsrep_local_index);
2295+ $unique_id = $wsrep_local_index."|";
2296+ foreach my $val ('server\_id', 'wsrep\_sst\_receive\_address', 'wsrep\_node\_name', 'wsrep\_node\_address') {
2297+ my $sql = "SHOW VARIABLES LIKE '$val'";
2298+ PTDEBUG && _d($cxn->name, $sql);
2299+ my (undef, $val) = $cxn->dbh->selectrow_array($sql);
2300+ $unique_id .= "|$val";
2301+ }
2302+ } else {
2303+ my $sql = 'SELECT @@SERVER_ID';
2304+ PTDEBUG && _d($sql);
2305+ $unique_id = $cxn->dbh->selectrow_array($sql);
2306+ }
2307+ PTDEBUG && _d("Generated unique id for cluster:", $unique_id);
2308+ return $unique_id;
2309+}
2310+
2311+
2312 sub is_cluster_node {
2313 my ($self, $cxn) = @_;
2314
2315+ $cxn ||= $self;
2316 my $sql = "SHOW VARIABLES LIKE 'wsrep\_on'";
2317 PTDEBUG && _d($cxn->name, $sql);
2318 my $row = $cxn->dbh->selectrow_arrayref($sql);
2319- PTDEBUG && _d(Dumper($row));
2320 return $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1') ? 1 : 0;
2321
2322 }
2323@@ -2581,11 +2608,8 @@
2324 my @trimmed_cxns;
2325
2326 for my $cxn ( @cxns ) {
2327- my $dbh = $cxn->dbh();
2328
2329- my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id};
2330- PTDEBUG && _d($sql);
2331- my ($id) = $dbh->selectrow_array($sql);
2332+ my $id = $cxn->get_id();
2333 PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id);
2334
2335 if ( ! $seen_ids->{$id}++ ) {
2336@@ -3545,7 +3569,8 @@
2337 ref($self->{fh}) eq 'IO::Socket::SSL'
2338 or die(qq/SSL connection failed for $host\n/);
2339 if ( $self->{fh}->can("verify_hostname") ) {
2340- $self->{fh}->verify_hostname( $host, $ssl_verify_args );
2341+ $self->{fh}->verify_hostname( $host, $ssl_verify_args )
2342+ or die(qq/SSL certificate not valid for $host\n/);
2343 }
2344 else {
2345 my $fh = $self->{fh};
2346@@ -4067,11 +4092,12 @@
2347 PTDEBUG && _d(scalar @$instances_to_check, 'instances to check');
2348 return unless @$instances_to_check;
2349
2350- my $protocol = 'https'; # optimistic, but...
2351+ my $protocol = 'https';
2352 eval { require IO::Socket::SSL; };
2353 if ( $EVAL_ERROR ) {
2354 PTDEBUG && _d($EVAL_ERROR);
2355- $protocol = 'http';
2356+ PTDEBUG && _d("SSL not available, won't run version_check");
2357+ return;
2358 }
2359 PTDEBUG && _d('Using', $protocol);
2360
2361@@ -4508,6 +4534,11 @@
2362 return;
2363 }
2364
2365+ if ($item->{item} eq 'MySQL' && $item->{type} eq 'mysql_variable') {
2366+ $item->{vars} = ['version_comment', 'version'];
2367+ }
2368+
2369+
2370 my @versions;
2371 my %version_for;
2372 foreach my $instance ( @$instances ) {
2373@@ -11240,7 +11271,7 @@
2374
2375 =head1 COPYRIGHT, LICENSE, AND WARRANTY
2376
2377-This program is copyright 2009-2014 Percona LLC and/or its affiliates.
2378+This program is copyright 2009-2015 Percona LLC and/or its affiliates.
2379 Feedback and improvements are welcome.
2380
2381 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
2382@@ -11259,6 +11290,6 @@
2383
2384 =head1 VERSION
2385
2386-pt-upgrade 2.2.12
2387+pt-upgrade 2.2.13
2388
2389 =cut
2390
2391=== modified file 'bin/pt-variable-advisor'
2392--- bin/pt-variable-advisor 2014-11-11 13:28:27 +0000
2393+++ bin/pt-variable-advisor 2015-01-27 13:07:53 +0000
2394@@ -44,7 +44,7 @@
2395 {
2396 package Percona::Toolkit;
2397
2398-our $VERSION = '2.2.12';
2399+our $VERSION = '2.2.13';
2400
2401 use strict;
2402 use warnings FATAL => 'all';
2403@@ -4004,7 +4004,8 @@
2404 ref($self->{fh}) eq 'IO::Socket::SSL'
2405 or die(qq/SSL connection failed for $host\n/);
2406 if ( $self->{fh}->can("verify_hostname") ) {
2407- $self->{fh}->verify_hostname( $host, $ssl_verify_args );
2408+ $self->{fh}->verify_hostname( $host, $ssl_verify_args )
2409+ or die(qq/SSL certificate not valid for $host\n/);
2410 }
2411 else {
2412 my $fh = $self->{fh};
2413@@ -4526,11 +4527,12 @@
2414 PTDEBUG && _d(scalar @$instances_to_check, 'instances to check');
2415 return unless @$instances_to_check;
2416
2417- my $protocol = 'https'; # optimistic, but...
2418+ my $protocol = 'https';
2419 eval { require IO::Socket::SSL; };
2420 if ( $EVAL_ERROR ) {
2421 PTDEBUG && _d($EVAL_ERROR);
2422- $protocol = 'http';
2423+ PTDEBUG && _d("SSL not available, won't run version_check");
2424+ return;
2425 }
2426 PTDEBUG && _d('Using', $protocol);
2427
2428@@ -4967,6 +4969,11 @@
2429 return;
2430 }
2431
2432+ if ($item->{item} eq 'MySQL' && $item->{type} eq 'mysql_variable') {
2433+ $item->{vars} = ['version_comment', 'version'];
2434+ }
2435+
2436+
2437 my @versions;
2438 my %version_for;
2439 foreach my $instance ( @$instances ) {
2440@@ -6120,7 +6127,7 @@
2441
2442 =head1 COPYRIGHT, LICENSE, AND WARRANTY
2443
2444-This program is copyright 2010-2014 Percona LLC and/or its affiliates.
2445+This program is copyright 2010-2015 Percona LLC and/or its affiliates.
2446
2447 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
2448 WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
2449@@ -6138,6 +6145,6 @@
2450
2451 =head1 VERSION
2452
2453-pt-variable-advisor 2.2.12
2454+pt-variable-advisor 2.2.13
2455
2456 =cut
2457
2458=== modified file 'bin/pt-visual-explain'
2459--- bin/pt-visual-explain 2014-11-11 13:28:27 +0000
2460+++ bin/pt-visual-explain 2015-01-27 13:07:53 +0000
2461@@ -3232,7 +3232,7 @@
2462
2463 =head1 COPYRIGHT, LICENSE, AND WARRANTY
2464
2465-This program is copyright 2011-2014 Percona LLC and/or its affiliates,
2466+This program is copyright 2011-2015 Percona LLC and/or its affiliates,
2467 2007-2011 Baron Schwartz.
2468
2469 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
2470@@ -3251,6 +3251,6 @@
2471
2472 =head1 VERSION
2473
2474-pt-visual-explain 2.2.12
2475+pt-visual-explain 2.2.13
2476
2477 =cut
2478
2479=== modified file 'config/deb/changelog'
2480--- config/deb/changelog 2014-11-11 13:28:27 +0000
2481+++ config/deb/changelog 2015-01-27 13:07:53 +0000
2482@@ -1,3 +1,21 @@
2483+percona-toolkit (2.2.13) unstable; urgency=low
2484+
2485+ * Feature 1391240: pt-kill added query fingerprint hash to output
2486+ * Fixed bug 1402668: pt-mysql-summary fails on cluster in Donor/Desynced status
2487+ * Fixed bug 1396870: pt-online-schema-change CTRL+C leaves terminal in inconsistent state
2488+ * Fixed bug 1396868: pt-online-schema-change --ask-pass option error
2489+ * Fixed bug 1266869: pt-stalk fails to start if $HOME environment variable is not set
2490+ * Fixed bug 1019479: pt-table-checksum does not work with sql_mode ONLY_FULL_GROUP_BY
2491+ * Fixed bug 1394934: pt-table-checksum error in debug mode
2492+ * Fixed bug 1321297: pt-table-checksum reports diffs on timestamp columns in 5.5 vs 5.6
2493+ * Fixed bug 1399789: pt-table-checksum fails to find pxc nodes when wsrep_node_incoming_address is set to AUTO
2494+ * Fixed bug 1388870: pt-table-checksum has some errors with different time zones
2495+ * Fixed bug 1408375: vulnerable to MITM attack which would allow exfiltration of MySQL configuration information via --version-check
2496+ * Fixed bug 1404298: missing MySQL5.7 test files for pt-table-checksum
2497+ * Fixed bug 1403900: added sandbox and fixed sakila test db for 5.7
2498+
2499+ -- Percona Toolkit Developers <toolkit-dev@percona.com> Fri, 23 Jan 2015 10:08:15 +0000
2500+
2501 percona-toolkit (2.2.12) unstable; urgency=low
2502
2503 * Fixed bug 1376561: pt-archiver is not able to archive all the rows when a table has a hash partition
2504
2505=== modified file 'config/sphinx-build/conf.py'
2506=== modified file 'docs/percona-toolkit.pod'
2507--- docs/percona-toolkit.pod 2014-11-11 13:28:27 +0000
2508+++ docs/percona-toolkit.pod 2015-01-27 13:07:53 +0000
2509@@ -538,7 +538,7 @@
2510
2511 =head1 COPYRIGHT, LICENSE, AND WARRANTY
2512
2513-Percona Toolkit is copyright 2011-2014 Percona LLC and/or its affiliates, et al.
2514+Percona Toolkit is copyright 2011-2015 Percona LLC and/or its affiliates, et al.
2515 See each program's documentation for complete copyright notices.
2516
2517 THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
2518@@ -557,6 +557,6 @@
2519
2520 =head1 VERSION
2521
2522-Percona Toolkit v2.2.12 released 2014-11-11
2523+Percona Toolkit v2.2.13 released 2015-01-23
2524
2525 =cut
2526
2527=== modified file 'docs/release_notes.rst'
2528--- docs/release_notes.rst 2014-11-11 13:28:27 +0000
2529+++ docs/release_notes.rst 2015-01-27 13:07:53 +0000
2530@@ -1,6 +1,52 @@
2531 Release Notes
2532 *************
2533
2534+v2.2.13 released 2015-01-26
2535+===========================
2536+
2537+Percona Toolkit 2.2.13 has been released. This release contains one new feature and twelve bug fixes.
2538+
2539+New Features:
2540+
2541+* pt-kill now supports new ``--query-id`` option. This option can be used to print a query fingerprint hash after killing a query to enable the cross-referencing with the pt-query-digest output. This option can be used along with ``--print`` option as well.
2542+
2543+Bugs Fixed:
2544+
2545+* Fixed bug 1019479: pt-table-checksum now works with ``ONLY_FULL_GROUP_BY`` sql_mode.
2546+
2547+* Fixed bug 1394934: running pt-table-checksum in debug mode would cause an error.
2548+
2549+* Fixed bug 1396868: regression introduced in Percona Toolkit 2.2.12 caused pt-online-schema-change not to honor ``--ask-pass`` option.
2550+
2551+* Fixed bug 1399789: pt-table-checksum would fail to find Percona XtraDB Cluster nodes when variable ``wsrep_node_incoming_address`` was set to ``AUTO``.
2552+
2553+* Fixed bug 1408375: Percona Toolkit was vulnerable to MITM attack which could allow exfiltration of MySQL configuration information via ``--version-check`` option. This vulnerability was logged as `CVE 2015-1027 <http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2015-1027>_`
2554+
2555+* Fixed bug 1321297: pt-table-checksum was reporting differences on timestamp columns with replication from 5.5 to 5.6 server version, although the data was identical.
2556+
2557+* Fixed bug 1388870: pt-table-checksum was showing differences if the master and slave were in different time zone.
2558+
2559+* Fixed bug 1402668: pt-mysql-summary would exit if Percona XtraDB Cluster was in ``Donor/Desynced`` state.
2560+
2561+* Fixed bug 1266869: pt-stalk would fail to start if ``$HOME`` environment variable was not set.
2562+
2563+Changelog
2564+---------
2565+
2566+* Feature 1391240: pt-kill added query fingerprint hash to output
2567+* Fixed bug 1402668: pt-mysql-summary fails on cluster in Donor/Desynced status
2568+* Fixed bug 1396870: pt-online-schema-change CTRL+C leaves terminal in inconsistent state
2569+* Fixed bug 1396868: pt-online-schema-change --ask-pass option error
2570+* Fixed bug 1266869: pt-stalk fails to start if $HOME environment variable is not set
2571+* Fixed bug 1019479: pt-table-checksum does not work with sql_mode ONLY_FULL_GROUP_BY
2572+* Fixed bug 1394934: pt-table-checksum error in debug mode
2573+* Fixed bug 1321297: pt-table-checksum reports diffs on timestamp columns in 5.5 vs 5.6
2574+* Fixed bug 1399789: pt-table-checksum fails to find pxc nodes when wsrep_node_incoming_address is set to AUTO
2575+* Fixed bug 1388870: pt-table-checksum has some errors with different time zones
2576+* Fixed bug 1408375: vulnerable to MITM attack which would allow exfiltration of MySQL configuration information via --version-check
2577+* Fixed bug 1404298: missing MySQL5.7 test files for pt-table-checksum
2578+* Fixed bug 1403900: added sandbox and fixed sakila test db for 5.7
2579+
2580 v2.2.12 released 2014-11-14
2581 ===========================
2582
2583
2584=== modified file 'lib/Cxn.pm'
2585--- lib/Cxn.pm 2014-11-05 22:21:51 +0000
2586+++ lib/Cxn.pm 2015-01-27 13:07:53 +0000
2587@@ -108,7 +108,7 @@
2588 set => $args{set},
2589 NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1,
2590 dbh_set => 0,
2591- ask_pass => $args{ask_pass},
2592+ ask_pass => $o->get('ask-pass'),
2593 DSNParser => $dp,
2594 is_cluster_node => undef,
2595 parent => $args{parent},
2596@@ -125,7 +125,7 @@
2597 my $dbh = $self->{dbh};
2598 if ( !$dbh || !$dbh->ping() ) {
2599 # Ask for password once.
2600- if ( $self->{ask_pass} && !$self->{asked_for_pass} ) {
2601+ if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p} ) {
2602 $dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
2603 $self->{asked_for_pass} = 1;
2604 }
2605@@ -226,15 +226,45 @@
2606 return $self->{hostname} || $self->{dsn_name} || 'unknown host';
2607 }
2608
2609+# This returns the server_id.
2610+# For cluster nodes, since server_id is unreliable, we use a combination of
2611+# variables to create an id string that is unique.
2612+sub get_id {
2613+ my ($self, $cxn) = @_;
2614+
2615+ $cxn ||= $self;
2616+
2617+ my $unique_id;
2618+ if ($cxn->is_cluster_node()) { # for cluster we concatenate various variables to maximize id 'uniqueness' across versions
2619+ my $sql = q{SHOW STATUS LIKE 'wsrep\_local\_index'};
2620+ my (undef, $wsrep_local_index) = $cxn->dbh->selectrow_array($sql);
2621+ PTDEBUG && _d("Got cluster wsrep_local_index: ",$wsrep_local_index);
2622+ $unique_id = $wsrep_local_index."|";
2623+ foreach my $val ('server\_id', 'wsrep\_sst\_receive\_address', 'wsrep\_node\_name', 'wsrep\_node\_address') {
2624+ my $sql = "SHOW VARIABLES LIKE '$val'";
2625+ PTDEBUG && _d($cxn->name, $sql);
2626+ my (undef, $val) = $cxn->dbh->selectrow_array($sql);
2627+ $unique_id .= "|$val";
2628+ }
2629+ } else {
2630+ my $sql = 'SELECT @@SERVER_ID';
2631+ PTDEBUG && _d($sql);
2632+ $unique_id = $cxn->dbh->selectrow_array($sql);
2633+ }
2634+ PTDEBUG && _d("Generated unique id for cluster:", $unique_id);
2635+ return $unique_id;
2636+}
2637+
2638+
2639 # This is used to help remove_duplicate_cxns detect cluster nodes
2640 # (which often have unreliable server_id's)
2641 sub is_cluster_node {
2642 my ($self, $cxn) = @_;
2643
2644+ $cxn ||= $self;
2645 my $sql = "SHOW VARIABLES LIKE 'wsrep\_on'";
2646 PTDEBUG && _d($cxn->name, $sql);
2647 my $row = $cxn->dbh->selectrow_arrayref($sql);
2648- PTDEBUG && _d(Dumper($row));
2649 return $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1') ? 1 : 0;
2650
2651 }
2652@@ -257,14 +287,8 @@
2653 my @trimmed_cxns;
2654
2655 for my $cxn ( @cxns ) {
2656- my $dbh = $cxn->dbh();
2657
2658- # Very often cluster nodes are configured with matching server_id's
2659- # So in that case we'll use its incoming address as its unique identifier
2660- # Note: this relies on "seen_ids" being populated using the same strategy
2661- my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id};
2662- PTDEBUG && _d($sql);
2663- my ($id) = $dbh->selectrow_array($sql);
2664+ my $id = $cxn->get_id();
2665 PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id);
2666
2667 if ( ! $seen_ids->{$id}++ ) {
2668
2669=== modified file 'lib/HTTP/Micro.pm'
2670--- lib/HTTP/Micro.pm 2013-08-03 18:50:52 +0000
2671+++ lib/HTTP/Micro.pm 2015-01-27 13:07:53 +0000
2672@@ -237,7 +237,8 @@
2673 ref($self->{fh}) eq 'IO::Socket::SSL'
2674 or die(qq/SSL connection failed for $host\n/);
2675 if ( $self->{fh}->can("verify_hostname") ) {
2676- $self->{fh}->verify_hostname( $host, $ssl_verify_args );
2677+ $self->{fh}->verify_hostname( $host, $ssl_verify_args )
2678+ or die(qq/SSL certificate not valid for $host\n/);
2679 }
2680 else {
2681 # Can't use $self->{fh}->verify_hostname because the IO::Socket::SSL
2682
2683=== modified file 'lib/Percona/Toolkit.pm'
2684--- lib/Percona/Toolkit.pm 2014-11-07 16:55:56 +0000
2685+++ lib/Percona/Toolkit.pm 2015-01-27 13:07:53 +0000
2686@@ -18,7 +18,7 @@
2687 # ###########################################################################
2688 package Percona::Toolkit;
2689
2690-our $VERSION = '2.2.12';
2691+our $VERSION = '2.2.13';
2692
2693 use strict;
2694 use warnings FATAL => 'all';
2695
2696=== modified file 'lib/Percona/XtraDB/Cluster.pm'
2697--- lib/Percona/XtraDB/Cluster.pm 2014-10-23 17:32:34 +0000
2698+++ lib/Percona/XtraDB/Cluster.pm 2015-01-27 13:07:53 +0000
2699@@ -137,13 +137,7 @@
2700 my @trimmed_cxns;
2701
2702 for my $cxn ( @cxns ) {
2703- my $dbh = $cxn->dbh();
2704- # Very often cluster nodes are configured with matching server_id's
2705- # So in that case we'll use its incoming address as its unique identifier
2706- # Note: This relies on "seen_ids" being populated using the same strategy
2707- my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id};
2708- PTDEBUG && _d($sql);
2709- my ($id) = $dbh->selectrow_array($sql);
2710+ my $id = $cxn->get_id();
2711 PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id);
2712
2713 if ( ! $seen_ids->{$id}++ ) {
2714
2715=== modified file 'lib/RowChecksum.pm'
2716--- lib/RowChecksum.pm 2014-08-05 14:21:32 +0000
2717+++ lib/RowChecksum.pm 2015-01-27 13:07:53 +0000
2718@@ -82,10 +82,10 @@
2719 $query = join(', ',
2720 map {
2721 my $col = $_;
2722- if ( $col =~ m/\+ 0/ ) {
2723+ if ( $col =~ m/UNIX_TIMESTAMP/ ) {
2724 # Alias col name back to itself else its name becomes
2725 # "col + 0" instead of just "col".
2726- my ($real_col) = /^(\S+)/;
2727+ my ($real_col) = /^UNIX_TIMESTAMP\((.+?)\)/;
2728 $col .= " AS $real_col";
2729 }
2730 elsif ( $col =~ m/TRIM/ ) {
2731@@ -216,7 +216,7 @@
2732 my $type = $tbl_struct->{type_for}->{$_};
2733 my $result = $q->quote($_);
2734 if ( $type eq 'timestamp' ) {
2735- $result .= ' + 0';
2736+ $result = "UNIX_TIMESTAMP($result)";
2737 }
2738 elsif ( $float_precision && $type =~ m/float|double/ ) {
2739 $result = "ROUND($result, $float_precision)";
2740
2741=== modified file 'lib/VersionCheck.pm'
2742--- lib/VersionCheck.pm 2014-02-20 03:00:02 +0000
2743+++ lib/VersionCheck.pm 2015-01-27 13:07:53 +0000
2744@@ -138,17 +138,17 @@
2745 PTDEBUG && _d(scalar @$instances_to_check, 'instances to check');
2746 return unless @$instances_to_check;
2747
2748- # Get the list of program to check from Percona. Try using
2749- # https first; fallback to http if that fails (probably because
2750- # IO::Socket::SSL isn't installed).
2751- my $protocol = 'https'; # optimistic, but...
2752+ # Skip Version Check altogether if SSL not available
2753+ my $protocol = 'https';
2754 eval { require IO::Socket::SSL; };
2755 if ( $EVAL_ERROR ) {
2756 PTDEBUG && _d($EVAL_ERROR);
2757- $protocol = 'http';
2758+ PTDEBUG && _d("SSL not available, won't run version_check");
2759+ return;
2760 }
2761 PTDEBUG && _d('Using', $protocol);
2762
2763+ # Get list of programs to check from Percona.
2764 my $advice = pingback(
2765 instances => $instances_to_check,
2766 protocol => $protocol,
2767@@ -644,6 +644,13 @@
2768 return;
2769 }
2770
2771+ # Only allow version variables to be reported
2772+ # So in case of MITM attack, we don't report sensitive data
2773+ if ($item->{item} eq 'MySQL' && $item->{type} eq 'mysql_variable') {
2774+ @{$item->{vars}} = grep { $_ eq 'version' || $_ eq 'version_comment' } @{$item->{vars}};
2775+ }
2776+
2777+
2778 my @versions;
2779 my %version_for;
2780 foreach my $instance ( @$instances ) {
2781
2782=== modified file 'lib/bash/parse_options.sh'
2783--- lib/bash/parse_options.sh 2014-10-06 21:04:49 +0000
2784+++ lib/bash/parse_options.sh 2015-01-27 13:07:53 +0000
2785@@ -213,7 +213,11 @@
2786 _parse_config_files "$user_config_file"
2787 done
2788 else
2789- _parse_config_files "/etc/percona-toolkit/percona-toolkit.conf" "/etc/percona-toolkit/$TOOL.conf" "$HOME/.percona-toolkit.conf" "$HOME/.$TOOL.conf"
2790+ _parse_config_files "/etc/percona-toolkit/percona-toolkit.conf" "/etc/percona-toolkit/$TOOL.conf"
2791+ # conditional in case $HOME isn't set; e.g. tool launched from init
2792+ if [ "${HOME:-}" ]; then
2793+ _parse_config_files "$HOME/.percona-toolkit.conf" "$HOME/.$TOOL.conf"
2794+ fi
2795 fi
2796
2797 # Finally, parse the command line.
2798
2799=== modified file 'sandbox/sakila.sql'
2800--- sandbox/sakila.sql 2012-12-05 22:05:41 +0000
2801+++ sandbox/sakila.sql 2015-01-27 13:07:53 +0000
2802@@ -6,6 +6,7 @@
2803 SET UNIQUE_CHECKS=0;
2804 SET FOREIGN_KEY_CHECKS=0;
2805
2806+
2807 CREATE TABLE `actor` (
2808 `actor_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
2809 `first_name` varchar(45) NOT NULL,
2810@@ -370,7 +371,7 @@
2811 FROM category LEFT JOIN film_category ON category.category_id = film_category.category_id LEFT JOIN film ON film_category.film_id = film.film_id
2812 JOIN film_actor ON film.film_id = film_actor.film_id
2813 JOIN actor ON film_actor.actor_id = actor.actor_id
2814-GROUP BY film.film_id;
2815+GROUP BY film.film_id, category.name;
2816
2817 CREATE VIEW nicer_but_slower_film_list
2818 AS
2819@@ -381,7 +382,7 @@
2820 FROM category LEFT JOIN film_category ON category.category_id = film_category.category_id LEFT JOIN film ON film_category.film_id = film.film_id
2821 JOIN film_actor ON film.film_id = film_actor.film_id
2822 JOIN actor ON film_actor.actor_id = actor.actor_id
2823-GROUP BY film.film_id;
2824+GROUP BY film.film_id, category.name;
2825
2826 CREATE VIEW staff_list
2827 AS
2828
2829=== added directory 'sandbox/servers/5.7'
2830=== added file 'sandbox/servers/5.7/data.tar.gz'
2831Binary files sandbox/servers/5.7/data.tar.gz 1970-01-01 00:00:00 +0000 and sandbox/servers/5.7/data.tar.gz 2015-01-27 13:07:53 +0000 differ
2832=== added file 'sandbox/servers/5.7/my.sandbox.cnf'
2833--- sandbox/servers/5.7/my.sandbox.cnf 1970-01-01 00:00:00 +0000
2834+++ sandbox/servers/5.7/my.sandbox.cnf 2015-01-27 13:07:53 +0000
2835@@ -0,0 +1,29 @@
2836+[client]
2837+user = msandbox
2838+password = msandbox
2839+port = PORT
2840+socket = /tmp/PORT/mysql_sandboxPORT.sock
2841+
2842+[mysqld]
2843+port = PORT
2844+socket = /tmp/PORT/mysql_sandboxPORT.sock
2845+pid-file = /tmp/PORT/data/mysql_sandboxPORT.pid
2846+basedir = PERCONA_TOOLKIT_SANDBOX
2847+datadir = /tmp/PORT/data
2848+key_buffer_size = 16M
2849+innodb_buffer_pool_size = 16M
2850+innodb_data_home_dir = /tmp/PORT/data
2851+innodb_log_group_home_dir = /tmp/PORT/data
2852+innodb_data_file_path = ibdata1:10M:autoextend
2853+innodb_log_file_size = 5M
2854+log-bin = mysql-bin
2855+relay_log = mysql-relay-bin
2856+log_slave_updates
2857+server-id = PORT
2858+report-host = 127.0.0.1
2859+report-port = PORT
2860+log-error = /tmp/PORT/data/mysqld.log
2861+innodb_lock_wait_timeout = 3
2862+general_log
2863+general_log_file = genlog
2864+lower_case_table_names = 0
2865
2866=== added file 'sandbox/servers/5.7/system_idb_tables.sql'
2867--- sandbox/servers/5.7/system_idb_tables.sql 1970-01-01 00:00:00 +0000
2868+++ sandbox/servers/5.7/system_idb_tables.sql 2015-01-27 13:07:53 +0000
2869@@ -0,0 +1,149 @@
2870+USE `mysql`;
2871+
2872+CREATE TABLE IF NOT EXISTS `innodb_index_stats` (
2873+ `database_name` varchar(64) COLLATE utf8_bin NOT NULL,
2874+ `table_name` varchar(64) COLLATE utf8_bin NOT NULL,
2875+ `index_name` varchar(64) COLLATE utf8_bin NOT NULL,
2876+ `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
2877+ `stat_name` varchar(64) COLLATE utf8_bin NOT NULL,
2878+ `stat_value` bigint(20) unsigned NOT NULL,
2879+ `sample_size` bigint(20) unsigned DEFAULT NULL,
2880+ `stat_description` varchar(1024) COLLATE utf8_bin NOT NULL,
2881+ PRIMARY KEY (`database_name`,`table_name`,`index_name`,`stat_name`)
2882+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin STATS_PERSISTENT=0;
2883+
2884+CREATE TABLE IF NOT EXISTS `innodb_table_stats` (
2885+ `database_name` varchar(64) COLLATE utf8_bin NOT NULL,
2886+ `table_name` varchar(64) COLLATE utf8_bin NOT NULL,
2887+ `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
2888+ `n_rows` bigint(20) unsigned NOT NULL,
2889+ `clustered_index_size` bigint(20) unsigned NOT NULL,
2890+ `sum_of_other_index_sizes` bigint(20) unsigned NOT NULL,
2891+ PRIMARY KEY (`database_name`,`table_name`)
2892+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin STATS_PERSISTENT=0;
2893+
2894+CREATE TABLE IF NOT EXISTS `slave_master_info` (
2895+ `Number_of_lines` int(10) unsigned NOT NULL COMMENT 'Number of lines in the file.',
2896+ `Master_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'The name of the master binary log currently being read from the master.',
2897+ `Master_log_pos` bigint(20) unsigned NOT NULL COMMENT 'The master log position of the last read event.',
2898+ `Host` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'The host name of the master.',
2899+ `User_name` text CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The user name used to connect to the master.',
2900+ `User_password` text CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The password used to connect to the master.',
2901+ `Port` int(10) unsigned NOT NULL COMMENT 'The network port used to connect to the master.',
2902+ `Connect_retry` int(10) unsigned NOT NULL COMMENT 'The period (in seconds) that the slave will wait before trying to reconnect to the master.',
2903+ `Enabled_ssl` tinyint(1) NOT NULL COMMENT 'Indicates whether the server supports SSL connections.',
2904+ `Ssl_ca` text CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The file used for the Certificate Authority (CA) certificate.',
2905+ `Ssl_capath` text CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The path to the Certificate Authority (CA) certificates.',
2906+ `Ssl_cert` text CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The name of the SSL certificate file.',
2907+ `Ssl_cipher` text CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The name of the cipher in use for the SSL connection.',
2908+ `Ssl_key` text CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The name of the SSL key file.',
2909+ `Ssl_verify_server_cert` tinyint(1) NOT NULL COMMENT 'Whether to verify the server certificate.',
2910+ `Heartbeat` float NOT NULL,
2911+ `Bind` text CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'Displays which interface is employed when connecting to the MySQL server',
2912+ `Ignored_server_ids` text CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The number of server IDs to be ignored, followed by the actual server IDs',
2913+ `Uuid` text CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The master server uuid.',
2914+ `Retry_count` bigint(20) unsigned NOT NULL COMMENT 'Number of reconnect attempts, to the master, before giving up.',
2915+ `Ssl_crl` text CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The file used for the Certificate Revocation List (CRL)',
2916+ `Ssl_crlpath` text CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The path used for Certificate Revocation List (CRL) files',
2917+ `Enabled_auto_position` tinyint(1) NOT NULL COMMENT 'Indicates whether GTIDs will be used to retrieve events from the master.',
2918+ PRIMARY KEY (`Host`,`Port`)
2919+) ENGINE=InnoDB DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT='Master Information';
2920+
2921+CREATE TABLE IF NOT EXISTS `slave_relay_log_info` (
2922+ `Number_of_lines` int(10) unsigned NOT NULL COMMENT 'Number of lines in the file or rows in the table. Used to version table definitions.',
2923+ `Relay_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'The name of the current relay log file.',
2924+ `Relay_log_pos` bigint(20) unsigned NOT NULL COMMENT 'The relay log position of the last executed event.',
2925+ `Master_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'The name of the master binary log file from which the events in the relay log file were read.',
2926+ `Master_log_pos` bigint(20) unsigned NOT NULL COMMENT 'The master log position of the last executed event.',
2927+ `Sql_delay` int(11) NOT NULL COMMENT 'The number of seconds that the slave must lag behind the master.',
2928+ `Number_of_workers` int(10) unsigned NOT NULL,
2929+ `Id` int(10) unsigned NOT NULL COMMENT 'Internal Id that uniquely identifies this record.',
2930+ PRIMARY KEY (`Id`)
2931+) ENGINE=InnoDB DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT='Relay Log Information';
2932+
2933+
2934+CREATE TABLE IF NOT EXISTS `slave_worker_info` (
2935+ `Id` int(10) unsigned NOT NULL,
2936+ `Relay_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
2937+ `Relay_log_pos` bigint(20) unsigned NOT NULL,
2938+ `Master_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
2939+ `Master_log_pos` bigint(20) unsigned NOT NULL,
2940+ `Checkpoint_relay_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
2941+ `Checkpoint_relay_log_pos` bigint(20) unsigned NOT NULL,
2942+ `Checkpoint_master_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
2943+ `Checkpoint_master_log_pos` bigint(20) unsigned NOT NULL,
2944+ `Checkpoint_seqno` int(10) unsigned NOT NULL,
2945+ `Checkpoint_group_size` int(10) unsigned NOT NULL,
2946+ `Checkpoint_group_bitmap` blob NOT NULL,
2947+ PRIMARY KEY (`Id`)
2948+) ENGINE=InnoDB DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT='Worker Information';
2949+
2950+
2951+CREATE TABLE IF NOT EXISTS `help_category` (
2952+ `help_category_id` smallint(5) unsigned NOT NULL,
2953+ `name` char(64) NOT NULL,
2954+ `parent_category_id` smallint(5) unsigned DEFAULT NULL,
2955+ `url` text NOT NULL,
2956+ PRIMARY KEY (`help_category_id`),
2957+ UNIQUE KEY `name` (`name`)
2958+) ENGINE=InnoDB DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT='help categories';
2959+
2960+CREATE TABLE IF NOT EXISTS `help_keyword` (
2961+ `help_keyword_id` int(10) unsigned NOT NULL,
2962+ `name` char(64) NOT NULL,
2963+ PRIMARY KEY (`help_keyword_id`),
2964+ UNIQUE KEY `name` (`name`)
2965+) ENGINE=InnoDB DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT='help keywords';
2966+
2967+CREATE TABLE IF NOT EXISTS `help_relation` (
2968+ `help_topic_id` int(10) unsigned NOT NULL,
2969+ `help_keyword_id` int(10) unsigned NOT NULL,
2970+ PRIMARY KEY (`help_keyword_id`,`help_topic_id`)
2971+) ENGINE=InnoDB DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT='keyword-topic relation';
2972+
2973+CREATE TABLE IF NOT EXISTS `help_topic` (
2974+ `help_topic_id` int(10) unsigned NOT NULL,
2975+ `name` char(64) NOT NULL,
2976+ `help_category_id` smallint(5) unsigned NOT NULL,
2977+ `description` text NOT NULL,
2978+ `example` text NOT NULL,
2979+ `url` text NOT NULL,
2980+ PRIMARY KEY (`help_topic_id`),
2981+ UNIQUE KEY `name` (`name`)
2982+) ENGINE=InnoDB DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT='help topics';
2983+
2984+CREATE TABLE IF NOT EXISTS `time_zone` (
2985+ `Time_zone_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
2986+ `Use_leap_seconds` enum('Y','N') NOT NULL DEFAULT 'N',
2987+ PRIMARY KEY (`Time_zone_id`)
2988+) ENGINE=InnoDB DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT='Time zones';
2989+
2990+CREATE TABLE IF NOT EXISTS `time_zone_leap_second` (
2991+ `Transition_time` bigint(20) NOT NULL,
2992+ `Correction` int(11) NOT NULL,
2993+ PRIMARY KEY (`Transition_time`)
2994+) ENGINE=InnoDB DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT='Leap seconds information for time zones';
2995+
2996+CREATE TABLE IF NOT EXISTS `time_zone_name` (
2997+ `Name` char(64) NOT NULL,
2998+ `Time_zone_id` int(10) unsigned NOT NULL,
2999+ PRIMARY KEY (`Name`)
3000+) ENGINE=InnoDB DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT='Time zone names';
3001+
3002+CREATE TABLE IF NOT EXISTS `time_zone_transition` (
3003+ `Time_zone_id` int(10) unsigned NOT NULL,
3004+ `Transition_time` bigint(20) NOT NULL,
3005+ `Transition_type_id` int(10) unsigned NOT NULL,
3006+ PRIMARY KEY (`Time_zone_id`,`Transition_time`)
3007+) ENGINE=InnoDB DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT='Time zone transitions';
3008+
3009+CREATE TABLE IF NOT EXISTS `time_zone_transition_type` (
3010+ `Time_zone_id` int(10) unsigned NOT NULL,
3011+ `Transition_type_id` int(10) unsigned NOT NULL,
3012+ `Offset` int(11) NOT NULL DEFAULT '0',
3013+ `Is_DST` tinyint(3) unsigned NOT NULL DEFAULT '0',
3014+ `Abbreviation` char(8) NOT NULL DEFAULT '',
3015+ PRIMARY KEY (`Time_zone_id`,`Transition_type_id`)
3016+) ENGINE=InnoDB DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT='Time zone transition types';
3017+
3018+
3019
3020=== added directory 'sandbox/servers/pxc/5.6'
3021=== added file 'sandbox/servers/pxc/5.6/my.sandbox.cnf'
3022--- sandbox/servers/pxc/5.6/my.sandbox.cnf 1970-01-01 00:00:00 +0000
3023+++ sandbox/servers/pxc/5.6/my.sandbox.cnf 2015-01-27 13:07:53 +0000
3024@@ -0,0 +1,42 @@
3025+[client]
3026+user = msandbox
3027+password = msandbox
3028+port = PORT
3029+socket = /tmp/PORT/mysql_sandboxPORT.sock
3030+
3031+[mysqld]
3032+port = PORT
3033+socket = /tmp/PORT/mysql_sandboxPORT.sock
3034+pid-file = /tmp/PORT/data/mysql_sandboxPORT.pid
3035+basedir = PERCONA_TOOLKIT_SANDBOX
3036+datadir = /tmp/PORT/data
3037+key_buffer_size = 16M
3038+innodb_buffer_pool_size = 16M
3039+innodb_data_home_dir = /tmp/PORT/data
3040+innodb_log_group_home_dir = /tmp/PORT/data
3041+innodb_data_file_path = ibdata1:10M:autoextend
3042+innodb_log_file_size = 5M
3043+log-bin = mysql-bin
3044+relay_log = mysql-relay-bin
3045+log_slave_updates
3046+server-id = PORT
3047+report-host = 127.0.0.1
3048+report-port = PORT
3049+log-error = /tmp/PORT/data/mysqld.log
3050+innodb_lock_wait_timeout = 3
3051+general_log
3052+general_log_file = genlog
3053+
3054+binlog_format = ROW
3055+wsrep_provider = LIBGALERA
3056+wsrep_cluster_address = CLUSTER_AD
3057+wsrep_sst_receive_address = ADDR:RECEIVE_PRT
3058+wsrep_node_incoming_address= ADDR:PORT
3059+wsrep_slave_threads = 2
3060+wsrep_cluster_name = CLUSTER_NAME
3061+wsrep_provider_options = "gmcast.listen_addr=tcp://ADDR:LISTEN_PRT;"
3062+wsrep_sst_method = rsync
3063+wsrep_node_name = PORT
3064+innodb_locks_unsafe_for_binlog = 1
3065+innodb_autoinc_lock_mode = 2
3066+wsrep-replicate-myisam
3067
3068=== modified file 't/lib/NibbleIterator.t'
3069--- t/lib/NibbleIterator.t 2013-07-10 17:23:28 +0000
3070+++ t/lib/NibbleIterator.t 2015-01-27 13:07:53 +0000
3071@@ -389,41 +389,59 @@
3072 select => $chunk_checksum,
3073 );
3074
3075+# The following tests need a trick to make the timestamp column consistent
3076+# across different test servers.
3077+# Sakila uses '2006-02-15 11:44:00' for this column, which is converted to
3078+# a different epoch vaule in different timezones, resulting in different
3079+# checksum values according to the tz of the server where sakila was created.
3080+
3081+# save original value, just in case
3082+my ($orig_datetime) = $dbh->selectrow_array("SELECT last_update FROM sakila.country LIMIT 1");
3083+# get locat datetime for UTC 2006-02-15 11:44:00
3084+my ($local_datetime_for_fixed_timestamp) = $dbh->selectrow_array("SELECT FROM_UNIXTIME(1140003840)");
3085+$dbh->do("UPDATE sakila.country SET last_update = '$local_datetime_for_fixed_timestamp'");
3086+
3087+# now the following checksums are fixed, no matter the test server timezone
3088+# where the sakila database was created
3089 my $row = $ni->next();
3090 is_deeply(
3091 $row,
3092- [25, 'd9c52498'],
3093+ [25, 'a947cb12'],
3094 "SELECT chunk checksum 1 FROM sakila.country"
3095 ) or diag(Dumper($row));
3096
3097 $row = $ni->next();
3098 is_deeply(
3099 $row,
3100- [25, 'ebdc982c'],
3101+ [25, 'c32790b9'],
3102 "SELECT chunk checksum 2 FROM sakila.country"
3103 ) or diag(Dumper($row));
3104
3105 $row = $ni->next();
3106 is_deeply(
3107 $row,
3108- [25, 'e8d9438d'],
3109+ [25, 'ea52549f'],
3110 "SELECT chunk checksum 3 FROM sakila.country"
3111 ) or diag(Dumper($row));
3112
3113 $row = $ni->next();
3114 is_deeply(
3115 $row,
3116- [25, '2e3b895d'],
3117+ [25, 'e78a7363'],
3118 "SELECT chunk checksum 4 FROM sakila.country"
3119 ) or diag(Dumper($row));
3120
3121 $row = $ni->next();
3122 is_deeply(
3123 $row,
3124- [9, 'bd08fd55'],
3125+ [9, 'd97ccb0d'],
3126 "SELECT chunk checksum 5 FROM sakila.country"
3127 ) or diag(Dumper($row));
3128
3129+# revert timestamp to original value, in case other tests use it
3130+$dbh->do("UPDATE sakila.country SET last_update = '$orig_datetime'");
3131+
3132+
3133 # #########################################################################
3134 # exec_nibble callback and explain_sth
3135 # #########################################################################
3136
3137=== modified file 't/lib/RowChecksum.t'
3138--- t/lib/RowChecksum.t 2012-10-30 15:38:31 +0000
3139+++ t/lib/RowChecksum.t 2015-01-27 13:07:53 +0000
3140@@ -126,11 +126,11 @@
3141 tbl => $tbl,
3142 func => 'SHA1',
3143 ),
3144- q{`film_id`, `title`, `description`, `release_year`, `language_id`, `original_language_id`, `rental_duration`, `rental_rate`, `length`, `replacement_cost`, `rating`, `special_features`, `last_update` + 0 AS `last_update`, }
3145+ q{`film_id`, `title`, `description`, `release_year`, `language_id`, `original_language_id`, `rental_duration`, `rental_rate`, `length`, `replacement_cost`, `rating`, `special_features`, UNIX_TIMESTAMP(`last_update`) AS `last_update`, }
3146 . q{SHA1(CONCAT_WS('#', }
3147 . q{`film_id`, `title`, `description`, `release_year`, `language_id`, }
3148 . q{`original_language_id`, `rental_duration`, `rental_rate`, `length`, }
3149- . q{`replacement_cost`, `rating`, `special_features`, `last_update` + 0, }
3150+ . q{`replacement_cost`, `rating`, `special_features`, UNIX_TIMESTAMP(`last_update`), }
3151 . q{CONCAT(ISNULL(`description`), ISNULL(`release_year`), }
3152 . q{ISNULL(`original_language_id`), ISNULL(`length`), }
3153 . q{ISNULL(`rating`), ISNULL(`special_features`))))},
3154@@ -142,11 +142,11 @@
3155 tbl => $tbl,
3156 func => 'FNV_64',
3157 ),
3158- q{`film_id`, `title`, `description`, `release_year`, `language_id`, `original_language_id`, `rental_duration`, `rental_rate`, `length`, `replacement_cost`, `rating`, `special_features`, `last_update` + 0 AS `last_update`, }
3159+ q{`film_id`, `title`, `description`, `release_year`, `language_id`, `original_language_id`, `rental_duration`, `rental_rate`, `length`, `replacement_cost`, `rating`, `special_features`, UNIX_TIMESTAMP(`last_update`) AS `last_update`, }
3160 . q{FNV_64(}
3161 . q{`film_id`, `title`, `description`, `release_year`, `language_id`, }
3162 . q{`original_language_id`, `rental_duration`, `rental_rate`, `length`, }
3163- . q{`replacement_cost`, `rating`, `special_features`, `last_update` + 0)},
3164+ . q{`replacement_cost`, `rating`, `special_features`, UNIX_TIMESTAMP(`last_update`))},
3165 'FNV_64 query for sakila.film',
3166 );
3167
3168
3169=== modified file 't/lib/bash/parse_options.sh'
3170--- t/lib/bash/parse_options.sh 2012-08-20 22:22:31 +0000
3171+++ t/lib/bash/parse_options.sh 2015-01-27 13:07:53 +0000
3172@@ -1,6 +1,6 @@
3173 #!/usr/bin/env bash
3174
3175-plan 83
3176+plan 84
3177
3178 TMPFILE="$TEST_PT_TMPDIR/parse-opts-output"
3179 TOOL="pt-stalk"
3180@@ -259,5 +259,18 @@
3181 is "$OPT_NOTIFY_BY_EMAIL" "foo@bar.com" "Bug 1038995: ...but gets set without errors if specified"
3182
3183 # ############################################################################
3184+# Bug 1266869: fails when $HOME unset
3185+# https://bugs.launchpad.net/percona-toolkit/+bug/1266869
3186+# ############################################################################
3187+
3188+TMP_HOME="$HOME"
3189+unset HOME
3190+OUTPUT=`parse_options $T_LIB_DIR/samples/bash/po001.sh 2>&1`
3191+echo "$OUTPUT" > "$TMPFILE"
3192+cmd_ok "grep -q -v unbound $TMPFILE" "No error when \$HOME is not set"
3193+HOME="$TMP_HOME" # just in case further tests below need it
3194+
3195+
3196+# ############################################################################
3197 # Done
3198 # ############################################################################
3199
3200=== modified file 't/pt-kill/match.t'
3201--- t/pt-kill/match.t 2012-06-03 19:14:30 +0000
3202+++ t/pt-kill/match.t 2015-01-27 13:07:53 +0000
3203@@ -9,7 +9,7 @@
3204 use strict;
3205 use warnings FATAL => 'all';
3206 use English qw(-no_match_vars);
3207-use Test::More tests => 15;
3208+use Test::More tests => 16;
3209
3210 use PerconaTest;
3211 use Sandbox;
3212@@ -137,6 +137,16 @@
3213 "--match-all"
3214 );
3215
3216+# --query-id option
3217+$output = output(
3218+ sub { pt_kill::main(@args, "$trunk/t/lib/samples/pl/recset011.txt", qw(--match-all --print --query-id)); }
3219+);
3220+like(
3221+ $output,
3222+ qr/0x69962191E64980E6/,
3223+ '--query-id'
3224+);
3225+
3226 # #############################################################################
3227 # Live tests.
3228 # #############################################################################
3229
3230=== modified file 't/pt-slave-restart/gtid_parallelreplication.t'
3231--- t/pt-slave-restart/gtid_parallelreplication.t 2014-04-30 14:53:04 +0000
3232+++ t/pt-slave-restart/gtid_parallelreplication.t 2015-01-27 13:07:53 +0000
3233@@ -49,7 +49,7 @@
3234
3235 like(
3236 $output,
3237- qr/It is impossible to skip transactions properly./,
3238+ qr/Cannot skip transactions properly.*slave_parallel_workers/,
3239 "pt-slave-restart exits with multiple replication threads"
3240 );
3241
3242
3243=== modified file 't/pt-table-checksum/basics.t'
3244--- t/pt-table-checksum/basics.t 2014-08-05 19:51:34 +0000
3245+++ t/pt-table-checksum/basics.t 2015-01-27 13:07:53 +0000
3246@@ -56,6 +56,7 @@
3247 $master_dbh->do("use $repl_db");
3248 }
3249
3250+
3251 # ############################################################################
3252 # Default checksum and results. The tool does not technically require any
3253 # options on well-configured systems (which the test env cannot be). With
3254@@ -509,6 +510,24 @@
3255 );
3256
3257 # #############################################################################
3258+# Bug 1019479: does not work with sql_mode ONLY_FULL_GROUP_BY
3259+# #############################################################################
3260+
3261+# add a couple more modes to test that commas don't affect setting
3262+$master_dbh->do("SET sql_mode = 'NO_ZERO_DATE,ONLY_FULL_GROUP_BY,STRICT_ALL_TABLES'");
3263+
3264+# force chunk-size because bug doesn't show up if table done in one chunk
3265+$exit_status = pt_table_checksum::main(@args,
3266+ qw(--quiet --quiet -t sakila.actor --chunk-size=50));
3267+
3268+is(
3269+ $exit_status,
3270+ 0,
3271+ "sql_mode ONLY_FULL_GROUP_BY is overidden"
3272+);
3273+
3274+
3275+# #############################################################################
3276 # Done.
3277 # #############################################################################
3278 $sb->wipe_clean($master_dbh);
3279
3280=== modified file 't/pt-table-checksum/bugs.t'
3281--- t/pt-table-checksum/bugs.t 2013-10-02 18:26:11 +0000
3282+++ t/pt-table-checksum/bugs.t 2015-01-27 13:07:53 +0000
3283@@ -295,6 +295,31 @@
3284 );
3285
3286 # #############################################################################
3287+# pt-table-checksum has errors when slaves have different system_time_zone
3288+# https://bugs.launchpad.net/percona-toolkit/+bug/1388870
3289+# #############################################################################
3290+
3291+# make slave set diferent system_time_zone by changing env var TZ.
3292+diag(`/tmp/12346/stop >/dev/null`);
3293+diag(`export TZ='HST';/tmp/12346/start >/dev/null`);
3294+
3295+$output = output(
3296+ sub { pt_table_checksum::main(@args, qw(-t sakila.payment)) },
3297+);
3298+
3299+
3300+is(
3301+ PerconaTest::count_checksum_results($output, 'diffs'),
3302+ 0,
3303+ "Bug 1388870 - No false positive reported when system_tz differ on slave"
3304+);
3305+
3306+# restore slave to original system_tz
3307+diag(`/tmp/12346/stop >/dev/null`);
3308+diag(`/tmp/12346/start >/dev/null`);
3309+
3310+
3311+# #############################################################################
3312 # Done.
3313 # #############################################################################
3314 $sb->wipe_clean($master_dbh);
3315
3316=== modified file 't/pt-table-checksum/pxc.t'
3317--- t/pt-table-checksum/pxc.t 2014-11-07 20:14:54 +0000
3318+++ t/pt-table-checksum/pxc.t 2015-01-27 13:07:53 +0000
3319@@ -88,8 +88,8 @@
3320 );
3321
3322 ok (
3323- $output =~ qr/WARNING/i && !$exit_status,
3324- "Warns but doesn't die if --recursion-method=none - issue #1373937"
3325+ $output !~ qr/no other nodes or regular replicas were found/i && !$exit_status,
3326+ "checksums even if --recursion-method=none - issue 1373937"
3327 );
3328
3329 for my $args (
3330@@ -159,6 +159,7 @@
3331 my $same_ids = shift;
3332
3333 my ($orig_id_1, $orig_id_2, $orig_id_3);
3334+ my ($orig_ia_1, $orig_ia_2, $orig_ia_3);
3335
3336 if ($same_ids) {
3337 # save original values
3338@@ -171,6 +172,19 @@
3339 $node1->do($sql);
3340 $node2->do($sql);
3341 $node3->do($sql);
3342+
3343+ # since we're testing server id issues, set wsrep_node_incoming_address=AUTO ( https://bugs.launchpad.net/percona-toolkit/+bug/1399789 )
3344+ # save original values
3345+ $sql = 'SELECT @@wsrep_node_incoming_address';
3346+ ($orig_ia_1) = $node1->selectrow_array($sql);
3347+ ($orig_ia_2) = $node2->selectrow_array($sql);
3348+ ($orig_ia_3) = $node3->selectrow_array($sql);
3349+ # set wsrep_node_incoming_address value to AUTO on all nodes
3350+ $sql = 'SET GLOBAL wsrep_node_incoming_address = AUTO';
3351+ $node1->do($sql);
3352+ $node2->do($sql);
3353+ $node3->do($sql);
3354+
3355 }
3356
3357 for my $args (
3358@@ -227,6 +241,10 @@
3359 $node1->do("SET GLOBAL server_id = $orig_id_1");
3360 $node2->do("SET GLOBAL server_id = $orig_id_2");
3361 $node3->do("SET GLOBAL server_id = $orig_id_3");
3362+ # reset node wsrep_node_incoming_address to original values
3363+ $node1->do("SET GLOBAL wsrep_node_incoming_address = '$orig_ia_1'");
3364+ $node2->do("SET GLOBAL wsrep_node_incoming_address = '$orig_ia_2'");
3365+ $node3->do("SET GLOBAL wsrep_node_incoming_address = '$orig_ia_3'");
3366 }
3367
3368 }
3369
3370=== modified file 't/pt-table-checksum/samples/chunkidx004.txt'
3371--- t/pt-table-checksum/samples/chunkidx004.txt 2011-12-27 18:12:40 +0000
3372+++ t/pt-table-checksum/samples/chunkidx004.txt 2015-01-27 13:07:53 +0000
3373@@ -2,7 +2,7 @@
3374 -- sakila.city
3375 --
3376
3377-REPLACE INTO `percona`.`checksums` (db, tbl, chunk, chunk_index, lower_boundary, upper_boundary, this_cnt, this_crc) SELECT ?, ?, ?, ?, ?, ?, COUNT(*) AS cnt, COALESCE(LOWER(CONV(BIT_XOR(CAST(CRC32(CONCAT_WS('#', `city_id`, `city`, `country_id`, `last_update` + 0)) AS UNSIGNED)), 10, 16)), 0) AS crc FROM `sakila`.`city` FORCE INDEX(`idx_fk_country_id`) WHERE ((`country_id` >= ?)) AND ((`country_id` <= ?)) AND (country_id > 100) /*checksum chunk*/
3378+REPLACE INTO `percona`.`checksums` (db, tbl, chunk, chunk_index, lower_boundary, upper_boundary, this_cnt, this_crc) SELECT ?, ?, ?, ?, ?, ?, COUNT(*) AS cnt, COALESCE(LOWER(CONV(BIT_XOR(CAST(CRC32(CONCAT_WS('#', `city_id`, `city`, `country_id`, UNIX_TIMESTAMP(`last_update`))) AS UNSIGNED)), 10, 16)), 0) AS crc FROM `sakila`.`city` FORCE INDEX(`idx_fk_country_id`) WHERE ((`country_id` >= ?)) AND ((`country_id` <= ?)) AND (country_id > 100) /*checksum chunk*/
3379
3380 REPLACE INTO `percona`.`checksums` (db, tbl, chunk, chunk_index, lower_boundary, upper_boundary, this_cnt, this_crc) SELECT ?, ?, ?, ?, ?, ?, COUNT(*), '0' FROM `sakila`.`city` FORCE INDEX(`idx_fk_country_id`) WHERE ((`country_id` < ?)) AND (country_id > 100) ORDER BY `country_id` /*past lower chunk*/
3381
3382
3383=== modified file 't/pt-table-checksum/samples/chunkidx005.txt'
3384--- t/pt-table-checksum/samples/chunkidx005.txt 2011-12-27 18:12:40 +0000
3385+++ t/pt-table-checksum/samples/chunkidx005.txt 2015-01-27 13:07:53 +0000
3386@@ -2,7 +2,7 @@
3387 -- sakila.city
3388 --
3389
3390-REPLACE INTO `percona`.`checksums` (db, tbl, chunk, chunk_index, lower_boundary, upper_boundary, this_cnt, this_crc) SELECT ?, ?, ?, ?, ?, ?, COUNT(*) AS cnt, COALESCE(LOWER(CONV(BIT_XOR(CAST(CRC32(CONCAT_WS('#', `city_id`, `city`, `country_id`, `last_update` + 0)) AS UNSIGNED)), 10, 16)), 0) AS crc FROM `sakila`.`city` FORCE INDEX(`PRIMARY`) WHERE ((`city_id` >= ?)) AND ((`city_id` <= ?)) AND (country_id > 100) /*checksum chunk*/
3391+REPLACE INTO `percona`.`checksums` (db, tbl, chunk, chunk_index, lower_boundary, upper_boundary, this_cnt, this_crc) SELECT ?, ?, ?, ?, ?, ?, COUNT(*) AS cnt, COALESCE(LOWER(CONV(BIT_XOR(CAST(CRC32(CONCAT_WS('#', `city_id`, `city`, `country_id`, UNIX_TIMESTAMP(`last_update`))) AS UNSIGNED)), 10, 16)), 0) AS crc FROM `sakila`.`city` FORCE INDEX(`PRIMARY`) WHERE ((`city_id` >= ?)) AND ((`city_id` <= ?)) AND (country_id > 100) /*checksum chunk*/
3392
3393 REPLACE INTO `percona`.`checksums` (db, tbl, chunk, chunk_index, lower_boundary, upper_boundary, this_cnt, this_crc) SELECT ?, ?, ?, ?, ?, ?, COUNT(*), '0' FROM `sakila`.`city` FORCE INDEX(`PRIMARY`) WHERE ((`city_id` < ?)) AND (country_id > 100) ORDER BY `city_id` /*past lower chunk*/
3394
3395
3396=== added file 't/pt-table-checksum/samples/default-results-5.7.txt'
3397--- t/pt-table-checksum/samples/default-results-5.7.txt 1970-01-01 00:00:00 +0000
3398+++ t/pt-table-checksum/samples/default-results-5.7.txt 2015-01-27 13:07:53 +0000
3399@@ -0,0 +1,41 @@
3400+ERRORS DIFFS ROWS SKIPPED TABLE
3401+0 0 0 0 mysql.columns_priv
3402+0 0 0 0 mysql.db
3403+0 0 0 0 mysql.event
3404+0 0 0 0 mysql.func
3405+0 0 0 0 mysql.help_category
3406+0 0 0 0 mysql.help_keyword
3407+0 0 0 0 mysql.help_relation
3408+0 0 0 0 mysql.help_topic
3409+0 0 0 0 mysql.ndb_binlog_index
3410+0 0 0 0 mysql.plugin
3411+0 0 0 0 mysql.proc
3412+0 0 0 0 mysql.procs_priv
3413+0 0 1 0 mysql.proxies_priv
3414+0 0 0 0 mysql.servers
3415+0 0 0 0 mysql.tables_priv
3416+0 0 0 0 mysql.time_zone
3417+0 0 0 0 mysql.time_zone_leap_second
3418+0 0 0 0 mysql.time_zone_name
3419+0 0 0 0 mysql.time_zone_transition
3420+0 0 0 0 mysql.time_zone_transition_type
3421+0 0 8 0 mysql.user
3422+0 0 18 0 percona_test.checksums
3423+0 0 1 0 percona_test.load_data
3424+0 0 1 0 percona_test.sentinel
3425+0 0 200 0 sakila.actor
3426+0 0 603 0 sakila.address
3427+0 0 16 0 sakila.category
3428+0 0 600 0 sakila.city
3429+0 0 109 0 sakila.country
3430+0 0 599 0 sakila.customer
3431+0 0 1000 0 sakila.film
3432+0 0 5462 0 sakila.film_actor
3433+0 0 1000 0 sakila.film_category
3434+0 0 1000 0 sakila.film_text
3435+0 0 4581 0 sakila.inventory
3436+0 0 6 0 sakila.language
3437+0 0 16049 0 sakila.payment
3438+0 0 16044 0 sakila.rental
3439+0 0 2 0 sakila.staff
3440+0 0 2 0 sakila.store
3441
3442=== modified file 't/pt-table-checksum/samples/n-chunk-index-cols.txt'
3443--- t/pt-table-checksum/samples/n-chunk-index-cols.txt 2012-06-10 14:43:42 +0000
3444+++ t/pt-table-checksum/samples/n-chunk-index-cols.txt 2015-01-27 13:07:53 +0000
3445@@ -2,7 +2,7 @@
3446 -- sakila.rental
3447 --
3448
3449-REPLACE INTO `percona`.`checksums` (db, tbl, chunk, chunk_index, lower_boundary, upper_boundary, this_cnt, this_crc) SELECT ?, ?, ?, ?, ?, ?, COUNT(*) AS cnt, COALESCE(LOWER(CONV(BIT_XOR(CAST(CRC32(CONCAT_WS('#', `rental_id`, `rental_date`, `inventory_id`, `customer_id`, `return_date`, `staff_id`, `last_update` + 0, CONCAT(ISNULL(`return_date`)))) AS UNSIGNED)), 10, 16)), 0) AS crc FROM `sakila`.`rental` FORCE INDEX(`rental_date`) WHERE ((`rental_date` > ?) OR (`rental_date` = ? AND `inventory_id` >= ?)) AND ((`rental_date` < ?) OR (`rental_date` = ? AND `inventory_id` <= ?)) /*checksum chunk*/
3450+REPLACE INTO `percona`.`checksums` (db, tbl, chunk, chunk_index, lower_boundary, upper_boundary, this_cnt, this_crc) SELECT ?, ?, ?, ?, ?, ?, COUNT(*) AS cnt, COALESCE(LOWER(CONV(BIT_XOR(CAST(CRC32(CONCAT_WS('#', `rental_id`, `rental_date`, `inventory_id`, `customer_id`, `return_date`, `staff_id`, UNIX_TIMESTAMP(`last_update`), CONCAT(ISNULL(`return_date`)))) AS UNSIGNED)), 10, 16)), 0) AS crc FROM `sakila`.`rental` FORCE INDEX(`rental_date`) WHERE ((`rental_date` > ?) OR (`rental_date` = ? AND `inventory_id` >= ?)) AND ((`rental_date` < ?) OR (`rental_date` = ? AND `inventory_id` <= ?)) /*checksum chunk*/
3451
3452 REPLACE INTO `percona`.`checksums` (db, tbl, chunk, chunk_index, lower_boundary, upper_boundary, this_cnt, this_crc) SELECT ?, ?, ?, ?, ?, ?, COUNT(*), '0' FROM `sakila`.`rental` FORCE INDEX(`rental_date`) WHERE ((`rental_date` < ?) OR (`rental_date` = ? AND `inventory_id` < ?)) ORDER BY `rental_date`, `inventory_id`, `customer_id` /*past lower chunk*/
3453
3454
3455=== added file 't/pt-table-checksum/samples/static-chunk-size-results-5.7.txt'
3456--- t/pt-table-checksum/samples/static-chunk-size-results-5.7.txt 1970-01-01 00:00:00 +0000
3457+++ t/pt-table-checksum/samples/static-chunk-size-results-5.7.txt 2015-01-27 13:07:53 +0000
3458@@ -0,0 +1,41 @@
3459+ERRORS DIFFS ROWS CHUNKS SKIPPED TABLE
3460+0 0 0 1 0 mysql.columns_priv
3461+0 0 0 1 0 mysql.db
3462+0 0 0 1 0 mysql.event
3463+0 0 0 1 0 mysql.func
3464+0 0 0 1 0 mysql.help_category
3465+0 0 0 1 0 mysql.help_keyword
3466+0 0 0 1 0 mysql.help_relation
3467+0 0 0 1 0 mysql.help_topic
3468+0 0 0 1 0 mysql.ndb_binlog_index
3469+0 0 0 1 0 mysql.plugin
3470+0 0 0 1 0 mysql.proc
3471+0 0 0 1 0 mysql.procs_priv
3472+0 0 1 1 0 mysql.proxies_priv
3473+0 0 0 1 0 mysql.servers
3474+0 0 0 1 0 mysql.tables_priv
3475+0 0 0 1 0 mysql.time_zone
3476+0 0 0 1 0 mysql.time_zone_leap_second
3477+0 0 0 1 0 mysql.time_zone_name
3478+0 0 0 1 0 mysql.time_zone_transition
3479+0 0 0 1 0 mysql.time_zone_transition_type
3480+0 0 8 1 0 mysql.user
3481+0 0 18 1 0 percona_test.checksums
3482+0 0 1 1 0 percona_test.load_data
3483+0 0 1 1 0 percona_test.sentinel
3484+0 0 200 1 0 sakila.actor
3485+0 0 603 1 0 sakila.address
3486+0 0 16 1 0 sakila.category
3487+0 0 600 1 0 sakila.city
3488+0 0 109 1 0 sakila.country
3489+0 0 599 1 0 sakila.customer
3490+0 0 1000 1 0 sakila.film
3491+0 0 5462 8 0 sakila.film_actor
3492+0 0 1000 1 0 sakila.film_category
3493+0 0 1000 1 0 sakila.film_text
3494+0 0 4581 7 0 sakila.inventory
3495+0 0 6 1 0 sakila.language
3496+0 0 16049 19 0 sakila.payment
3497+0 0 16044 19 0 sakila.rental
3498+0 0 2 1 0 sakila.staff
3499+0 0 2 1 0 sakila.store

Subscribers

People subscribed via source and target branches