mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-11 21:51:21 +00:00
Compare commits
2 Commits
release-v3
...
v3.5.2
Author | SHA1 | Date | |
---|---|---|---|
![]() |
a85b7aa32c | ||
![]() |
642253ce52 |
33
Changelog
33
Changelog
@@ -1,5 +1,38 @@
|
|||||||
Changelog for Percona Toolkit
|
Changelog for Percona Toolkit
|
||||||
|
|
||||||
|
v3.5.2 release 2023-03-28
|
||||||
|
|
||||||
|
* Improvement PT-188: Use percona.checksums in examples
|
||||||
|
* Improvement PT-2141: Fix tests for pt-archiver
|
||||||
|
* Improvement PT-2149: Fix tests for pt-mext
|
||||||
|
* Improvement PT-2150: Fix tests for pt-mysql-summary
|
||||||
|
* Improvement PT-2152: Fix tests for pt-show-grants
|
||||||
|
* Improvement PT-2155: Fix tests for pt-upgrade
|
||||||
|
* Improvement PT-2156: Fix tests for lib
|
||||||
|
* Improvement PT-2159: Fix tests for pt-duplicate-key-checker
|
||||||
|
* Improvement PT-2160: Fix tests for pt-online-schema-change
|
||||||
|
* Improvement PT-2161: Fix tests for pt-slave-restart
|
||||||
|
* Improvement PT-2164: pt-k8s-debug-collector does not have version flag
|
||||||
|
* Improvement PT-2165: Actual Version, GoVersion, and Build for Go tools
|
||||||
|
* Fixed bug PT-215: Documentation fix
|
||||||
|
* Fixed bug PT-1059: LP #1093972: Tools can't parse index names containing newlines
|
||||||
|
* Fixed bug PT-1389: LP #1637859: [pt-variable-advisor] Docs Typos
|
||||||
|
* Fixed bug PT-1594: Need correction in the Documentation - pt-mysql-summary
|
||||||
|
* Fixed bug PT-1595: percona toolkit docs still reference Maatkit
|
||||||
|
* Fixed bug PT-1642: Update PT docs to reference bug reporting location as Percona JIRA
|
||||||
|
* Fixed bug PT-1683: List of supported distributions in the docs is outdated
|
||||||
|
* Fixed bug PT-1700: pt-table-checksum REPLICATION_STOPPED exit status not documented
|
||||||
|
* Fixed bug PT-1927: pt-k8s-debug-collector requires mysql client
|
||||||
|
* Fixed bug PT-1930: pt-k8s-debug-collector should not attempt collecting PXC information when running against PSMDB
|
||||||
|
* Fixed bug PT-2084: Changes from PT-80 broke previous pt-stalk functionality (Thanks Agustín Gallego)
|
||||||
|
* Fixed bug PT-2102: pt-mysql-summary should support !include* in config files (Thanks Yoann La Cancellera)
|
||||||
|
* Fixed bug PT-2110: Incorrect PTDEBUG output with --ignore-engines option (Thanks Kazuya Yokogawa)
|
||||||
|
* Fixed bug PT-2114: Incorrect casting of BIT columns by pt-archiver
|
||||||
|
* Fixed bug PT-2116: pt-osc --null-to-not-null description is wrong (Thanks Yoann La Cancellera)
|
||||||
|
* Fixed bug PT-2120: pt-stalk with --system-only displaying "MYSQL_ONLY:" message on the screen
|
||||||
|
* Fixed bug PT-2123: pt-archiver gives error "Wide character in print at /usr/bin/pt-archiver line 6815" when using --bulk-insert while using character set alias
|
||||||
|
* Fixed bug PT-2187: CVEs reported in Percona Toolkit version 5.3.1 related to GO.
|
||||||
|
|
||||||
v3.5.1 release 2023-01-23
|
v3.5.1 release 2023-01-23
|
||||||
|
|
||||||
* Feature PT-2134: Add support for PostgreSQL and MySQL operators in pt-k8s-debug-collector
|
* Feature PT-2134: Add support for PostgreSQL and MySQL operators in pt-k8s-debug-collector
|
||||||
|
@@ -2,7 +2,7 @@ use ExtUtils::MakeMaker;
|
|||||||
|
|
||||||
WriteMakefile(
|
WriteMakefile(
|
||||||
NAME => 'Percona::Toolkit',
|
NAME => 'Percona::Toolkit',
|
||||||
VERSION => '3.5.1',
|
VERSION => '3.5.2',
|
||||||
EXE_FILES => [ <bin/*> ],
|
EXE_FILES => [ <bin/*> ],
|
||||||
MAN1PODS => {
|
MAN1PODS => {
|
||||||
'docs/percona-toolkit.pod' => 'blib/man1/percona-toolkit.1p',
|
'docs/percona-toolkit.pod' => 'blib/man1/percona-toolkit.1p',
|
||||||
|
@@ -1364,6 +1364,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-align 3.5.1
|
pt-align 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
@@ -45,7 +45,7 @@ BEGIN {
|
|||||||
{
|
{
|
||||||
package Percona::Toolkit;
|
package Percona::Toolkit;
|
||||||
|
|
||||||
our $VERSION = '3.5.1';
|
our $VERSION = '3.5.2';
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings FATAL => 'all';
|
use warnings FATAL => 'all';
|
||||||
@@ -2139,8 +2139,7 @@ sub get_keys {
|
|||||||
my $clustered_key = undef;
|
my $clustered_key = undef;
|
||||||
|
|
||||||
KEY:
|
KEY:
|
||||||
foreach my $key ( $ddl =~ m/^ ((?:[A-Z]+ )?KEY \(?`[\s\S]*?`\)[\s\S]*?,?)$/gm ) {
|
foreach my $key ( $ddl =~ m/^ ((?:[A-Z]+ )?KEY [\s\S]*?\),?.*)$/gm ) {
|
||||||
|
|
||||||
next KEY if $key =~ m/FOREIGN/;
|
next KEY if $key =~ m/FOREIGN/;
|
||||||
|
|
||||||
my $key_ddl = $key;
|
my $key_ddl = $key;
|
||||||
@@ -2150,7 +2149,7 @@ sub get_keys {
|
|||||||
$key =~ s/USING HASH/USING BTREE/;
|
$key =~ s/USING HASH/USING BTREE/;
|
||||||
}
|
}
|
||||||
|
|
||||||
my ( $type, $cols ) = $key =~ m/(?:USING (\w+))? \(([\s\S]+?)\)/;
|
my ( $type, $cols ) = $key =~ m/(?:USING (\w+))? \(([\s\S]+)\)/;
|
||||||
my ( $special ) = $key =~ m/(FULLTEXT|SPATIAL)/;
|
my ( $special ) = $key =~ m/(FULLTEXT|SPATIAL)/;
|
||||||
$type = $type || $special || 'BTREE';
|
$type = $type || $special || 'BTREE';
|
||||||
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
|
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
|
||||||
@@ -3221,7 +3220,7 @@ sub generate_cmp_where {
|
|||||||
push @clause, "($val IS NULL OR $quo $type $val)";
|
push @clause, "($val IS NULL OR $quo $type $val)";
|
||||||
}
|
}
|
||||||
elsif ( $type =~ m/>/ ) {
|
elsif ( $type =~ m/>/ ) {
|
||||||
push @clause, "($val IS NULL AND $quo IS NOT NULL) OR ($quo $cmp $val)";
|
push @clause, "(($val IS NULL AND $quo IS NOT NULL) OR ($quo $cmp $val))";
|
||||||
}
|
}
|
||||||
else { # If $type =~ m/</ ) {
|
else { # If $type =~ m/</ ) {
|
||||||
push @clauses, "(($val IS NOT NULL AND $quo IS NULL) OR ($quo $cmp $val))";
|
push @clauses, "(($val IS NOT NULL AND $quo IS NULL) OR ($quo $cmp $val))";
|
||||||
@@ -4601,7 +4600,7 @@ sub connect {
|
|||||||
my $dp = $self->{DSNParser};
|
my $dp = $self->{DSNParser};
|
||||||
|
|
||||||
my $dbh = $self->{dbh};
|
my $dbh = $self->{dbh};
|
||||||
if ( !$dbh || !$dbh->ping() ) {
|
if ( !$dbh || ( $dbh && $self->{dbh_set} && !$self->_ping($dbh) ) ) {
|
||||||
if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p} ) {
|
if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p} ) {
|
||||||
$dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
|
$dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
|
||||||
$self->{asked_for_pass} = 1;
|
$self->{asked_for_pass} = 1;
|
||||||
@@ -4630,19 +4629,20 @@ sub connect {
|
|||||||
sub set_dbh {
|
sub set_dbh {
|
||||||
my ($self, $dbh) = @_;
|
my ($self, $dbh) = @_;
|
||||||
|
|
||||||
if ( $self->{dbh} && $self->{dbh} == $dbh && $self->{dbh_set} ) {
|
|
||||||
PTDEBUG && _d($dbh, 'Already set dbh');
|
|
||||||
return $dbh;
|
|
||||||
}
|
|
||||||
|
|
||||||
PTDEBUG && _d($dbh, 'Setting dbh');
|
PTDEBUG && _d($dbh, 'Setting dbh');
|
||||||
|
|
||||||
$dbh->{FetchHashKeyName} = 'NAME_lc' if $self->{NAME_lc};
|
$dbh->{FetchHashKeyName} = 'NAME_lc' if $self->{NAME_lc};
|
||||||
|
|
||||||
my $sql = 'SELECT @@server_id /*!50038 , @@hostname*/';
|
my $sql = 'SELECT @@server_id /*!50038 , @@hostname*/, CONNECTION_ID() as connection_id';
|
||||||
PTDEBUG && _d($dbh, $sql);
|
PTDEBUG && _d($dbh, $sql);
|
||||||
my ($server_id, $hostname) = $dbh->selectrow_array($sql);
|
my ($server_id, $hostname, $connection_id) = $dbh->selectrow_array($sql);
|
||||||
PTDEBUG && _d($dbh, 'hostname:', $hostname, $server_id);
|
PTDEBUG && _d($dbh, 'hostname:', $hostname, $server_id);
|
||||||
|
|
||||||
|
if ( $self->{dbh} && $self->{dbh} == $dbh && $self->{dbh_set} && $self->{dbh_set} == $connection_id) {
|
||||||
|
PTDEBUG && _d($dbh, 'Already set dbh');
|
||||||
|
return $dbh;
|
||||||
|
}
|
||||||
|
|
||||||
if ( $hostname ) {
|
if ( $hostname ) {
|
||||||
$self->{hostname} = $hostname;
|
$self->{hostname} = $hostname;
|
||||||
}
|
}
|
||||||
@@ -4657,7 +4657,7 @@ sub set_dbh {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$self->{dbh} = $dbh;
|
$self->{dbh} = $dbh;
|
||||||
$self->{dbh_set} = 1;
|
$self->{dbh_set} = $connection_id;
|
||||||
return $dbh;
|
return $dbh;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4783,6 +4783,17 @@ sub DESTROY {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub _ping() {
|
||||||
|
my ( $self, $dbh ) = @_;
|
||||||
|
if (!$dbh->ping()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
my $sql = 'SELECT CONNECTION_ID() as connection_id';
|
||||||
|
PTDEBUG && _d($dbh, $sql);
|
||||||
|
my ($connection_id) = $dbh->selectrow_array($sql);
|
||||||
|
return $self->{dbh_set} == $connection_id;
|
||||||
|
}
|
||||||
|
|
||||||
sub _d {
|
sub _d {
|
||||||
my ($package, undef, $line) = caller 0;
|
my ($package, undef, $line) = caller 0;
|
||||||
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
|
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
|
||||||
@@ -8767,6 +8778,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-archiver 3.5.1
|
pt-archiver 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
@@ -43,7 +43,7 @@ BEGIN {
|
|||||||
{
|
{
|
||||||
package Percona::Toolkit;
|
package Percona::Toolkit;
|
||||||
|
|
||||||
our $VERSION = '3.5.1';
|
our $VERSION = '3.5.2';
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings FATAL => 'all';
|
use warnings FATAL => 'all';
|
||||||
@@ -2368,7 +2368,7 @@ sub connect {
|
|||||||
my $dp = $self->{DSNParser};
|
my $dp = $self->{DSNParser};
|
||||||
|
|
||||||
my $dbh = $self->{dbh};
|
my $dbh = $self->{dbh};
|
||||||
if ( !$dbh || !$dbh->ping() ) {
|
if ( !$dbh || ( $dbh && $self->{dbh_set} && !$self->_ping($dbh) ) ) {
|
||||||
if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p} ) {
|
if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p} ) {
|
||||||
$dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
|
$dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
|
||||||
$self->{asked_for_pass} = 1;
|
$self->{asked_for_pass} = 1;
|
||||||
@@ -2397,19 +2397,20 @@ sub connect {
|
|||||||
sub set_dbh {
|
sub set_dbh {
|
||||||
my ($self, $dbh) = @_;
|
my ($self, $dbh) = @_;
|
||||||
|
|
||||||
if ( $self->{dbh} && $self->{dbh} == $dbh && $self->{dbh_set} ) {
|
|
||||||
PTDEBUG && _d($dbh, 'Already set dbh');
|
|
||||||
return $dbh;
|
|
||||||
}
|
|
||||||
|
|
||||||
PTDEBUG && _d($dbh, 'Setting dbh');
|
PTDEBUG && _d($dbh, 'Setting dbh');
|
||||||
|
|
||||||
$dbh->{FetchHashKeyName} = 'NAME_lc' if $self->{NAME_lc};
|
$dbh->{FetchHashKeyName} = 'NAME_lc' if $self->{NAME_lc};
|
||||||
|
|
||||||
my $sql = 'SELECT @@server_id /*!50038 , @@hostname*/';
|
my $sql = 'SELECT @@server_id /*!50038 , @@hostname*/, CONNECTION_ID() as connection_id';
|
||||||
PTDEBUG && _d($dbh, $sql);
|
PTDEBUG && _d($dbh, $sql);
|
||||||
my ($server_id, $hostname) = $dbh->selectrow_array($sql);
|
my ($server_id, $hostname, $connection_id) = $dbh->selectrow_array($sql);
|
||||||
PTDEBUG && _d($dbh, 'hostname:', $hostname, $server_id);
|
PTDEBUG && _d($dbh, 'hostname:', $hostname, $server_id);
|
||||||
|
|
||||||
|
if ( $self->{dbh} && $self->{dbh} == $dbh && $self->{dbh_set} && $self->{dbh_set} == $connection_id) {
|
||||||
|
PTDEBUG && _d($dbh, 'Already set dbh');
|
||||||
|
return $dbh;
|
||||||
|
}
|
||||||
|
|
||||||
if ( $hostname ) {
|
if ( $hostname ) {
|
||||||
$self->{hostname} = $hostname;
|
$self->{hostname} = $hostname;
|
||||||
}
|
}
|
||||||
@@ -2424,7 +2425,7 @@ sub set_dbh {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$self->{dbh} = $dbh;
|
$self->{dbh} = $dbh;
|
||||||
$self->{dbh_set} = 1;
|
$self->{dbh_set} = $connection_id;
|
||||||
return $dbh;
|
return $dbh;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2550,6 +2551,17 @@ sub DESTROY {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub _ping() {
|
||||||
|
my ( $self, $dbh ) = @_;
|
||||||
|
if (!$dbh->ping()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
my $sql = 'SELECT CONNECTION_ID() as connection_id';
|
||||||
|
PTDEBUG && _d($dbh, $sql);
|
||||||
|
my ($connection_id) = $dbh->selectrow_array($sql);
|
||||||
|
return $self->{dbh_set} == $connection_id;
|
||||||
|
}
|
||||||
|
|
||||||
sub _d {
|
sub _d {
|
||||||
my ($package, undef, $line) = caller 0;
|
my ($package, undef, $line) = caller 0;
|
||||||
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
|
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
|
||||||
@@ -5999,6 +6011,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-config-diff 3.5.1
|
pt-config-diff 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
@@ -42,7 +42,7 @@ BEGIN {
|
|||||||
{
|
{
|
||||||
package Percona::Toolkit;
|
package Percona::Toolkit;
|
||||||
|
|
||||||
our $VERSION = '3.5.1';
|
our $VERSION = '3.5.2';
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings FATAL => 'all';
|
use warnings FATAL => 'all';
|
||||||
@@ -2712,7 +2712,7 @@ sub connect {
|
|||||||
my $dp = $self->{DSNParser};
|
my $dp = $self->{DSNParser};
|
||||||
|
|
||||||
my $dbh = $self->{dbh};
|
my $dbh = $self->{dbh};
|
||||||
if ( !$dbh || !$dbh->ping() ) {
|
if ( !$dbh || ( $dbh && $self->{dbh_set} && !$self->_ping($dbh) ) ) {
|
||||||
if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p} ) {
|
if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p} ) {
|
||||||
$dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
|
$dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
|
||||||
$self->{asked_for_pass} = 1;
|
$self->{asked_for_pass} = 1;
|
||||||
@@ -2741,19 +2741,20 @@ sub connect {
|
|||||||
sub set_dbh {
|
sub set_dbh {
|
||||||
my ($self, $dbh) = @_;
|
my ($self, $dbh) = @_;
|
||||||
|
|
||||||
if ( $self->{dbh} && $self->{dbh} == $dbh && $self->{dbh_set} ) {
|
|
||||||
PTDEBUG && _d($dbh, 'Already set dbh');
|
|
||||||
return $dbh;
|
|
||||||
}
|
|
||||||
|
|
||||||
PTDEBUG && _d($dbh, 'Setting dbh');
|
PTDEBUG && _d($dbh, 'Setting dbh');
|
||||||
|
|
||||||
$dbh->{FetchHashKeyName} = 'NAME_lc' if $self->{NAME_lc};
|
$dbh->{FetchHashKeyName} = 'NAME_lc' if $self->{NAME_lc};
|
||||||
|
|
||||||
my $sql = 'SELECT @@server_id /*!50038 , @@hostname*/';
|
my $sql = 'SELECT @@server_id /*!50038 , @@hostname*/, CONNECTION_ID() as connection_id';
|
||||||
PTDEBUG && _d($dbh, $sql);
|
PTDEBUG && _d($dbh, $sql);
|
||||||
my ($server_id, $hostname) = $dbh->selectrow_array($sql);
|
my ($server_id, $hostname, $connection_id) = $dbh->selectrow_array($sql);
|
||||||
PTDEBUG && _d($dbh, 'hostname:', $hostname, $server_id);
|
PTDEBUG && _d($dbh, 'hostname:', $hostname, $server_id);
|
||||||
|
|
||||||
|
if ( $self->{dbh} && $self->{dbh} == $dbh && $self->{dbh_set} && $self->{dbh_set} == $connection_id) {
|
||||||
|
PTDEBUG && _d($dbh, 'Already set dbh');
|
||||||
|
return $dbh;
|
||||||
|
}
|
||||||
|
|
||||||
if ( $hostname ) {
|
if ( $hostname ) {
|
||||||
$self->{hostname} = $hostname;
|
$self->{hostname} = $hostname;
|
||||||
}
|
}
|
||||||
@@ -2768,7 +2769,7 @@ sub set_dbh {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$self->{dbh} = $dbh;
|
$self->{dbh} = $dbh;
|
||||||
$self->{dbh_set} = 1;
|
$self->{dbh_set} = $connection_id;
|
||||||
return $dbh;
|
return $dbh;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2894,6 +2895,17 @@ sub DESTROY {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub _ping() {
|
||||||
|
my ( $self, $dbh ) = @_;
|
||||||
|
if (!$dbh->ping()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
my $sql = 'SELECT CONNECTION_ID() as connection_id';
|
||||||
|
PTDEBUG && _d($dbh, $sql);
|
||||||
|
my ($connection_id) = $dbh->selectrow_array($sql);
|
||||||
|
return $self->{dbh_set} == $connection_id;
|
||||||
|
}
|
||||||
|
|
||||||
sub _d {
|
sub _d {
|
||||||
my ($package, undef, $line) = caller 0;
|
my ($package, undef, $line) = caller 0;
|
||||||
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
|
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
|
||||||
@@ -5776,6 +5788,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-deadlock-logger 3.5.1
|
pt-deadlock-logger 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
@@ -38,7 +38,7 @@ BEGIN {
|
|||||||
{
|
{
|
||||||
package Percona::Toolkit;
|
package Percona::Toolkit;
|
||||||
|
|
||||||
our $VERSION = '3.5.1';
|
our $VERSION = '3.5.2';
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings FATAL => 'all';
|
use warnings FATAL => 'all';
|
||||||
@@ -5692,6 +5692,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-diskstats 3.5.1
|
pt-diskstats 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
@@ -39,7 +39,7 @@ BEGIN {
|
|||||||
{
|
{
|
||||||
package Percona::Toolkit;
|
package Percona::Toolkit;
|
||||||
|
|
||||||
our $VERSION = '3.5.1';
|
our $VERSION = '3.5.2';
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings FATAL => 'all';
|
use warnings FATAL => 'all';
|
||||||
@@ -345,7 +345,7 @@ sub parse {
|
|||||||
|
|
||||||
my $engine = $self->get_engine($ddl);
|
my $engine = $self->get_engine($ddl);
|
||||||
|
|
||||||
my @defs = $ddl =~ m/^(\s+`.*?),?$/gm;
|
my @defs = $ddl =~ m/(?:(?<=,\n)|(?<=\(\n))(\s+`(?:.|\n)+?`.+?),?\n/g;
|
||||||
my @cols = map { $_ =~ m/`([^`]+)`/ } @defs;
|
my @cols = map { $_ =~ m/`([^`]+)`/ } @defs;
|
||||||
PTDEBUG && _d('Table cols:', join(', ', map { "`$_`" } @cols));
|
PTDEBUG && _d('Table cols:', join(', ', map { "`$_`" } @cols));
|
||||||
|
|
||||||
@@ -526,8 +526,7 @@ sub get_keys {
|
|||||||
my $clustered_key = undef;
|
my $clustered_key = undef;
|
||||||
|
|
||||||
KEY:
|
KEY:
|
||||||
foreach my $key ( $ddl =~ m/^ ((?:[A-Z]+ )?KEY .*)$/gm ) {
|
foreach my $key ( $ddl =~ m/^ ((?:[A-Z]+ )?KEY [\s\S]*?\),?.*)$/gm ) {
|
||||||
|
|
||||||
next KEY if $key =~ m/FOREIGN/;
|
next KEY if $key =~ m/FOREIGN/;
|
||||||
|
|
||||||
my $key_ddl = $key;
|
my $key_ddl = $key;
|
||||||
@@ -537,7 +536,7 @@ sub get_keys {
|
|||||||
$key =~ s/USING HASH/USING BTREE/;
|
$key =~ s/USING HASH/USING BTREE/;
|
||||||
}
|
}
|
||||||
|
|
||||||
my ( $type, $cols ) = $key =~ m/(?:USING (\w+))? \((.+)\)/;
|
my ( $type, $cols ) = $key =~ m/(?:USING (\w+))? \(([\s\S]+)\)/;
|
||||||
my ( $special ) = $key =~ m/(FULLTEXT|SPATIAL)/;
|
my ( $special ) = $key =~ m/(FULLTEXT|SPATIAL)/;
|
||||||
$type = $type || $special || 'BTREE';
|
$type = $type || $special || 'BTREE';
|
||||||
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
|
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
|
||||||
@@ -5787,6 +5786,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-duplicate-key-checker 3.5.1
|
pt-duplicate-key-checker 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
@@ -1708,6 +1708,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-fifo-split 3.5.1
|
pt-fifo-split 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
11
bin/pt-find
11
bin/pt-find
@@ -35,7 +35,7 @@ BEGIN {
|
|||||||
{
|
{
|
||||||
package Percona::Toolkit;
|
package Percona::Toolkit;
|
||||||
|
|
||||||
our $VERSION = '3.5.1';
|
our $VERSION = '3.5.2';
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings FATAL => 'all';
|
use warnings FATAL => 'all';
|
||||||
@@ -1897,7 +1897,7 @@ sub parse {
|
|||||||
|
|
||||||
my $engine = $self->get_engine($ddl);
|
my $engine = $self->get_engine($ddl);
|
||||||
|
|
||||||
my @defs = $ddl =~ m/^(\s+`.*?),?$/gm;
|
my @defs = $ddl =~ m/(?:(?<=,\n)|(?<=\(\n))(\s+`(?:.|\n)+?`.+?),?\n/g;
|
||||||
my @cols = map { $_ =~ m/`([^`]+)`/ } @defs;
|
my @cols = map { $_ =~ m/`([^`]+)`/ } @defs;
|
||||||
PTDEBUG && _d('Table cols:', join(', ', map { "`$_`" } @cols));
|
PTDEBUG && _d('Table cols:', join(', ', map { "`$_`" } @cols));
|
||||||
|
|
||||||
@@ -2078,8 +2078,7 @@ sub get_keys {
|
|||||||
my $clustered_key = undef;
|
my $clustered_key = undef;
|
||||||
|
|
||||||
KEY:
|
KEY:
|
||||||
foreach my $key ( $ddl =~ m/^ ((?:[A-Z]+ )?KEY .*)$/gm ) {
|
foreach my $key ( $ddl =~ m/^ ((?:[A-Z]+ )?KEY [\s\S]*?\),?.*)$/gm ) {
|
||||||
|
|
||||||
next KEY if $key =~ m/FOREIGN/;
|
next KEY if $key =~ m/FOREIGN/;
|
||||||
|
|
||||||
my $key_ddl = $key;
|
my $key_ddl = $key;
|
||||||
@@ -2089,7 +2088,7 @@ sub get_keys {
|
|||||||
$key =~ s/USING HASH/USING BTREE/;
|
$key =~ s/USING HASH/USING BTREE/;
|
||||||
}
|
}
|
||||||
|
|
||||||
my ( $type, $cols ) = $key =~ m/(?:USING (\w+))? \((.+)\)/;
|
my ( $type, $cols ) = $key =~ m/(?:USING (\w+))? \(([\s\S]+)\)/;
|
||||||
my ( $special ) = $key =~ m/(FULLTEXT|SPATIAL)/;
|
my ( $special ) = $key =~ m/(FULLTEXT|SPATIAL)/;
|
||||||
$type = $type || $special || 'BTREE';
|
$type = $type || $special || 'BTREE';
|
||||||
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
|
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
|
||||||
@@ -5202,6 +5201,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-find 3.5.1
|
pt-find 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
@@ -2271,6 +2271,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-fingerprint 3.5.1
|
pt-fingerprint 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
@@ -37,7 +37,7 @@ BEGIN {
|
|||||||
{
|
{
|
||||||
package Percona::Toolkit;
|
package Percona::Toolkit;
|
||||||
|
|
||||||
our $VERSION = '3.5.1';
|
our $VERSION = '3.5.2';
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings FATAL => 'all';
|
use warnings FATAL => 'all';
|
||||||
@@ -1866,7 +1866,7 @@ sub connect {
|
|||||||
my $dp = $self->{DSNParser};
|
my $dp = $self->{DSNParser};
|
||||||
|
|
||||||
my $dbh = $self->{dbh};
|
my $dbh = $self->{dbh};
|
||||||
if ( !$dbh || !$dbh->ping() ) {
|
if ( !$dbh || ( $dbh && $self->{dbh_set} && !$self->_ping($dbh) ) ) {
|
||||||
if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p} ) {
|
if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p} ) {
|
||||||
$dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
|
$dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
|
||||||
$self->{asked_for_pass} = 1;
|
$self->{asked_for_pass} = 1;
|
||||||
@@ -1895,19 +1895,20 @@ sub connect {
|
|||||||
sub set_dbh {
|
sub set_dbh {
|
||||||
my ($self, $dbh) = @_;
|
my ($self, $dbh) = @_;
|
||||||
|
|
||||||
if ( $self->{dbh} && $self->{dbh} == $dbh && $self->{dbh_set} ) {
|
|
||||||
PTDEBUG && _d($dbh, 'Already set dbh');
|
|
||||||
return $dbh;
|
|
||||||
}
|
|
||||||
|
|
||||||
PTDEBUG && _d($dbh, 'Setting dbh');
|
PTDEBUG && _d($dbh, 'Setting dbh');
|
||||||
|
|
||||||
$dbh->{FetchHashKeyName} = 'NAME_lc' if $self->{NAME_lc};
|
$dbh->{FetchHashKeyName} = 'NAME_lc' if $self->{NAME_lc};
|
||||||
|
|
||||||
my $sql = 'SELECT @@server_id /*!50038 , @@hostname*/';
|
my $sql = 'SELECT @@server_id /*!50038 , @@hostname*/, CONNECTION_ID() as connection_id';
|
||||||
PTDEBUG && _d($dbh, $sql);
|
PTDEBUG && _d($dbh, $sql);
|
||||||
my ($server_id, $hostname) = $dbh->selectrow_array($sql);
|
my ($server_id, $hostname, $connection_id) = $dbh->selectrow_array($sql);
|
||||||
PTDEBUG && _d($dbh, 'hostname:', $hostname, $server_id);
|
PTDEBUG && _d($dbh, 'hostname:', $hostname, $server_id);
|
||||||
|
|
||||||
|
if ( $self->{dbh} && $self->{dbh} == $dbh && $self->{dbh_set} && $self->{dbh_set} == $connection_id) {
|
||||||
|
PTDEBUG && _d($dbh, 'Already set dbh');
|
||||||
|
return $dbh;
|
||||||
|
}
|
||||||
|
|
||||||
if ( $hostname ) {
|
if ( $hostname ) {
|
||||||
$self->{hostname} = $hostname;
|
$self->{hostname} = $hostname;
|
||||||
}
|
}
|
||||||
@@ -1922,7 +1923,7 @@ sub set_dbh {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$self->{dbh} = $dbh;
|
$self->{dbh} = $dbh;
|
||||||
$self->{dbh_set} = 1;
|
$self->{dbh_set} = $connection_id;
|
||||||
return $dbh;
|
return $dbh;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2048,6 +2049,17 @@ sub DESTROY {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub _ping() {
|
||||||
|
my ( $self, $dbh ) = @_;
|
||||||
|
if (!$dbh->ping()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
my $sql = 'SELECT CONNECTION_ID() as connection_id';
|
||||||
|
PTDEBUG && _d($dbh, $sql);
|
||||||
|
my ($connection_id) = $dbh->selectrow_array($sql);
|
||||||
|
return $self->{dbh_set} == $connection_id;
|
||||||
|
}
|
||||||
|
|
||||||
sub _d {
|
sub _d {
|
||||||
my ($package, undef, $line) = caller 0;
|
my ($package, undef, $line) = caller 0;
|
||||||
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
|
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
|
||||||
@@ -4763,6 +4775,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-fk-error-logger 3.5.1
|
pt-fk-error-logger 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
@@ -44,7 +44,7 @@ BEGIN {
|
|||||||
{
|
{
|
||||||
package Percona::Toolkit;
|
package Percona::Toolkit;
|
||||||
|
|
||||||
our $VERSION = '3.5.1';
|
our $VERSION = '3.5.2';
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings FATAL => 'all';
|
use warnings FATAL => 'all';
|
||||||
@@ -170,6 +170,7 @@ sub get_slaves {
|
|||||||
dsn => $dsn,
|
dsn => $dsn,
|
||||||
slave_user => $o->got('slave-user') ? $o->get('slave-user') : '',
|
slave_user => $o->got('slave-user') ? $o->get('slave-user') : '',
|
||||||
slave_password => $o->got('slave-password') ? $o->get('slave-password') : '',
|
slave_password => $o->got('slave-password') ? $o->get('slave-password') : '',
|
||||||
|
slaves => $args{slaves},
|
||||||
callback => sub {
|
callback => sub {
|
||||||
my ( $dsn, $dbh, $level, $parent ) = @_;
|
my ( $dsn, $dbh, $level, $parent ) = @_;
|
||||||
return unless $level;
|
return unless $level;
|
||||||
@@ -246,17 +247,30 @@ sub recurse_to_slaves {
|
|||||||
PTDEBUG && _d("Slave password set");
|
PTDEBUG && _d("Slave password set");
|
||||||
}
|
}
|
||||||
|
|
||||||
my $dbh;
|
my $dbh = $args->{dbh};
|
||||||
|
|
||||||
|
DBH: {
|
||||||
|
if ( !defined $dbh ) {
|
||||||
|
foreach my $known_slave ( @{$args->{slaves}} ) {
|
||||||
|
if ($known_slave->{dsn}->{h} eq $slave_dsn->{h} and
|
||||||
|
$known_slave->{dsn}->{P} eq $slave_dsn->{P} ) {
|
||||||
|
$dbh = $known_slave->{dbh};
|
||||||
|
last DBH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
eval {
|
eval {
|
||||||
$dbh = $args->{dbh} || $dp->get_dbh(
|
$dbh = $dp->get_dbh(
|
||||||
$dp->get_cxn_params($slave_dsn), { AutoCommit => 1 });
|
$dp->get_cxn_params($slave_dsn), { AutoCommit => 1 });
|
||||||
PTDEBUG && _d('Connected to', $dp->as_string($slave_dsn));
|
PTDEBUG && _d('Connected to', $dp->as_string($slave_dsn));
|
||||||
};
|
};
|
||||||
if ( $EVAL_ERROR ) {
|
if ( $EVAL_ERROR ) {
|
||||||
print STDERR "Cannot connect to ", $dp->as_string($slave_dsn), "\n"
|
print STDERR "Cannot connect to ", $dp->as_string($slave_dsn), ": ", $EVAL_ERROR, "\n"
|
||||||
or die "Cannot print: $OS_ERROR";
|
or die "Cannot print: $OS_ERROR";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
my $sql = 'SELECT @@SERVER_ID';
|
my $sql = 'SELECT @@SERVER_ID';
|
||||||
PTDEBUG && _d($sql);
|
PTDEBUG && _d($sql);
|
||||||
@@ -3624,7 +3638,7 @@ sub parse {
|
|||||||
|
|
||||||
my $engine = $self->get_engine($ddl);
|
my $engine = $self->get_engine($ddl);
|
||||||
|
|
||||||
my @defs = $ddl =~ m/^(\s+`.*?),?$/gm;
|
my @defs = $ddl =~ m/(?:(?<=,\n)|(?<=\(\n))(\s+`(?:.|\n)+?`.+?),?\n/g;
|
||||||
my @cols = map { $_ =~ m/`([^`]+)`/ } @defs;
|
my @cols = map { $_ =~ m/`([^`]+)`/ } @defs;
|
||||||
PTDEBUG && _d('Table cols:', join(', ', map { "`$_`" } @cols));
|
PTDEBUG && _d('Table cols:', join(', ', map { "`$_`" } @cols));
|
||||||
|
|
||||||
@@ -3805,8 +3819,7 @@ sub get_keys {
|
|||||||
my $clustered_key = undef;
|
my $clustered_key = undef;
|
||||||
|
|
||||||
KEY:
|
KEY:
|
||||||
foreach my $key ( $ddl =~ m/^ ((?:[A-Z]+ )?KEY .*)$/gm ) {
|
foreach my $key ( $ddl =~ m/^ ((?:[A-Z]+ )?KEY [\s\S]*?\),?.*)$/gm ) {
|
||||||
|
|
||||||
next KEY if $key =~ m/FOREIGN/;
|
next KEY if $key =~ m/FOREIGN/;
|
||||||
|
|
||||||
my $key_ddl = $key;
|
my $key_ddl = $key;
|
||||||
@@ -3816,7 +3829,7 @@ sub get_keys {
|
|||||||
$key =~ s/USING HASH/USING BTREE/;
|
$key =~ s/USING HASH/USING BTREE/;
|
||||||
}
|
}
|
||||||
|
|
||||||
my ( $type, $cols ) = $key =~ m/(?:USING (\w+))? \((.+)\)/;
|
my ( $type, $cols ) = $key =~ m/(?:USING (\w+))? \(([\s\S]+)\)/;
|
||||||
my ( $special ) = $key =~ m/(FULLTEXT|SPATIAL)/;
|
my ( $special ) = $key =~ m/(FULLTEXT|SPATIAL)/;
|
||||||
$type = $type || $special || 'BTREE';
|
$type = $type || $special || 'BTREE';
|
||||||
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
|
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
|
||||||
@@ -7460,6 +7473,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-heartbeat 3.5.1
|
pt-heartbeat 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
@@ -45,7 +45,7 @@ BEGIN {
|
|||||||
{
|
{
|
||||||
package Percona::Toolkit;
|
package Percona::Toolkit;
|
||||||
|
|
||||||
our $VERSION = '3.5.1';
|
our $VERSION = '3.5.2';
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings FATAL => 'all';
|
use warnings FATAL => 'all';
|
||||||
@@ -3149,7 +3149,7 @@ sub parse {
|
|||||||
|
|
||||||
my $engine = $self->get_engine($ddl);
|
my $engine = $self->get_engine($ddl);
|
||||||
|
|
||||||
my @defs = $ddl =~ m/^(\s+`.*?),?$/gm;
|
my @defs = $ddl =~ m/(?:(?<=,\n)|(?<=\(\n))(\s+`(?:.|\n)+?`.+?),?\n/g;
|
||||||
my @cols = map { $_ =~ m/`([^`]+)`/ } @defs;
|
my @cols = map { $_ =~ m/`([^`]+)`/ } @defs;
|
||||||
PTDEBUG && _d('Table cols:', join(', ', map { "`$_`" } @cols));
|
PTDEBUG && _d('Table cols:', join(', ', map { "`$_`" } @cols));
|
||||||
|
|
||||||
@@ -3330,8 +3330,7 @@ sub get_keys {
|
|||||||
my $clustered_key = undef;
|
my $clustered_key = undef;
|
||||||
|
|
||||||
KEY:
|
KEY:
|
||||||
foreach my $key ( $ddl =~ m/^ ((?:[A-Z]+ )?KEY .*)$/gm ) {
|
foreach my $key ( $ddl =~ m/^ ((?:[A-Z]+ )?KEY [\s\S]*?\),?.*)$/gm ) {
|
||||||
|
|
||||||
next KEY if $key =~ m/FOREIGN/;
|
next KEY if $key =~ m/FOREIGN/;
|
||||||
|
|
||||||
my $key_ddl = $key;
|
my $key_ddl = $key;
|
||||||
@@ -3341,7 +3340,7 @@ sub get_keys {
|
|||||||
$key =~ s/USING HASH/USING BTREE/;
|
$key =~ s/USING HASH/USING BTREE/;
|
||||||
}
|
}
|
||||||
|
|
||||||
my ( $type, $cols ) = $key =~ m/(?:USING (\w+))? \((.+)\)/;
|
my ( $type, $cols ) = $key =~ m/(?:USING (\w+))? \(([\s\S]+)\)/;
|
||||||
my ( $special ) = $key =~ m/(FULLTEXT|SPATIAL)/;
|
my ( $special ) = $key =~ m/(FULLTEXT|SPATIAL)/;
|
||||||
$type = $type || $special || 'BTREE';
|
$type = $type || $special || 'BTREE';
|
||||||
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
|
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
|
||||||
@@ -7732,6 +7731,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-index-usage 3.5.1
|
pt-index-usage 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
@@ -1132,7 +1132,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-ioprofile 3.5.1
|
pt-ioprofile 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
|
61
bin/pt-kill
61
bin/pt-kill
@@ -47,7 +47,7 @@ BEGIN {
|
|||||||
{
|
{
|
||||||
package Percona::Toolkit;
|
package Percona::Toolkit;
|
||||||
|
|
||||||
our $VERSION = '3.5.1';
|
our $VERSION = '3.5.2';
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings FATAL => 'all';
|
use warnings FATAL => 'all';
|
||||||
@@ -3012,7 +3012,7 @@ sub parse {
|
|||||||
|
|
||||||
my $engine = $self->get_engine($ddl);
|
my $engine = $self->get_engine($ddl);
|
||||||
|
|
||||||
my @defs = $ddl =~ m/^(\s+`.*?),?$/gm;
|
my @defs = $ddl =~ m/(?:(?<=,\n)|(?<=\(\n))(\s+`(?:.|\n)+?`.+?),?\n/g;
|
||||||
my @cols = map { $_ =~ m/`([^`]+)`/ } @defs;
|
my @cols = map { $_ =~ m/`([^`]+)`/ } @defs;
|
||||||
PTDEBUG && _d('Table cols:', join(', ', map { "`$_`" } @cols));
|
PTDEBUG && _d('Table cols:', join(', ', map { "`$_`" } @cols));
|
||||||
|
|
||||||
@@ -3193,8 +3193,7 @@ sub get_keys {
|
|||||||
my $clustered_key = undef;
|
my $clustered_key = undef;
|
||||||
|
|
||||||
KEY:
|
KEY:
|
||||||
foreach my $key ( $ddl =~ m/^ ((?:[A-Z]+ )?KEY .*)$/gm ) {
|
foreach my $key ( $ddl =~ m/^ ((?:[A-Z]+ )?KEY [\s\S]*?\),?.*)$/gm ) {
|
||||||
|
|
||||||
next KEY if $key =~ m/FOREIGN/;
|
next KEY if $key =~ m/FOREIGN/;
|
||||||
|
|
||||||
my $key_ddl = $key;
|
my $key_ddl = $key;
|
||||||
@@ -3204,7 +3203,7 @@ sub get_keys {
|
|||||||
$key =~ s/USING HASH/USING BTREE/;
|
$key =~ s/USING HASH/USING BTREE/;
|
||||||
}
|
}
|
||||||
|
|
||||||
my ( $type, $cols ) = $key =~ m/(?:USING (\w+))? \((.+)\)/;
|
my ( $type, $cols ) = $key =~ m/(?:USING (\w+))? \(([\s\S]+)\)/;
|
||||||
my ( $special ) = $key =~ m/(FULLTEXT|SPATIAL)/;
|
my ( $special ) = $key =~ m/(FULLTEXT|SPATIAL)/;
|
||||||
$type = $type || $special || 'BTREE';
|
$type = $type || $special || 'BTREE';
|
||||||
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
|
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
|
||||||
@@ -3951,6 +3950,7 @@ sub get_slaves {
|
|||||||
dsn => $dsn,
|
dsn => $dsn,
|
||||||
slave_user => $o->got('slave-user') ? $o->get('slave-user') : '',
|
slave_user => $o->got('slave-user') ? $o->get('slave-user') : '',
|
||||||
slave_password => $o->got('slave-password') ? $o->get('slave-password') : '',
|
slave_password => $o->got('slave-password') ? $o->get('slave-password') : '',
|
||||||
|
slaves => $args{slaves},
|
||||||
callback => sub {
|
callback => sub {
|
||||||
my ( $dsn, $dbh, $level, $parent ) = @_;
|
my ( $dsn, $dbh, $level, $parent ) = @_;
|
||||||
return unless $level;
|
return unless $level;
|
||||||
@@ -4027,17 +4027,30 @@ sub recurse_to_slaves {
|
|||||||
PTDEBUG && _d("Slave password set");
|
PTDEBUG && _d("Slave password set");
|
||||||
}
|
}
|
||||||
|
|
||||||
my $dbh;
|
my $dbh = $args->{dbh};
|
||||||
|
|
||||||
|
DBH: {
|
||||||
|
if ( !defined $dbh ) {
|
||||||
|
foreach my $known_slave ( @{$args->{slaves}} ) {
|
||||||
|
if ($known_slave->{dsn}->{h} eq $slave_dsn->{h} and
|
||||||
|
$known_slave->{dsn}->{P} eq $slave_dsn->{P} ) {
|
||||||
|
$dbh = $known_slave->{dbh};
|
||||||
|
last DBH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
eval {
|
eval {
|
||||||
$dbh = $args->{dbh} || $dp->get_dbh(
|
$dbh = $dp->get_dbh(
|
||||||
$dp->get_cxn_params($slave_dsn), { AutoCommit => 1 });
|
$dp->get_cxn_params($slave_dsn), { AutoCommit => 1 });
|
||||||
PTDEBUG && _d('Connected to', $dp->as_string($slave_dsn));
|
PTDEBUG && _d('Connected to', $dp->as_string($slave_dsn));
|
||||||
};
|
};
|
||||||
if ( $EVAL_ERROR ) {
|
if ( $EVAL_ERROR ) {
|
||||||
print STDERR "Cannot connect to ", $dp->as_string($slave_dsn), "\n"
|
print STDERR "Cannot connect to ", $dp->as_string($slave_dsn), ": ", $EVAL_ERROR, "\n"
|
||||||
or die "Cannot print: $OS_ERROR";
|
or die "Cannot print: $OS_ERROR";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
my $sql = 'SELECT @@SERVER_ID';
|
my $sql = 'SELECT @@SERVER_ID';
|
||||||
PTDEBUG && _d($sql);
|
PTDEBUG && _d($sql);
|
||||||
@@ -5402,7 +5415,7 @@ sub connect {
|
|||||||
my $dp = $self->{DSNParser};
|
my $dp = $self->{DSNParser};
|
||||||
|
|
||||||
my $dbh = $self->{dbh};
|
my $dbh = $self->{dbh};
|
||||||
if ( !$dbh || !$dbh->ping() ) {
|
if ( !$dbh || ( $dbh && $self->{dbh_set} && !$self->_ping($dbh) ) ) {
|
||||||
if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p} ) {
|
if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p} ) {
|
||||||
$dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
|
$dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
|
||||||
$self->{asked_for_pass} = 1;
|
$self->{asked_for_pass} = 1;
|
||||||
@@ -5431,19 +5444,20 @@ sub connect {
|
|||||||
sub set_dbh {
|
sub set_dbh {
|
||||||
my ($self, $dbh) = @_;
|
my ($self, $dbh) = @_;
|
||||||
|
|
||||||
if ( $self->{dbh} && $self->{dbh} == $dbh && $self->{dbh_set} ) {
|
|
||||||
PTDEBUG && _d($dbh, 'Already set dbh');
|
|
||||||
return $dbh;
|
|
||||||
}
|
|
||||||
|
|
||||||
PTDEBUG && _d($dbh, 'Setting dbh');
|
PTDEBUG && _d($dbh, 'Setting dbh');
|
||||||
|
|
||||||
$dbh->{FetchHashKeyName} = 'NAME_lc' if $self->{NAME_lc};
|
$dbh->{FetchHashKeyName} = 'NAME_lc' if $self->{NAME_lc};
|
||||||
|
|
||||||
my $sql = 'SELECT @@server_id /*!50038 , @@hostname*/';
|
my $sql = 'SELECT @@server_id /*!50038 , @@hostname*/, CONNECTION_ID() as connection_id';
|
||||||
PTDEBUG && _d($dbh, $sql);
|
PTDEBUG && _d($dbh, $sql);
|
||||||
my ($server_id, $hostname) = $dbh->selectrow_array($sql);
|
my ($server_id, $hostname, $connection_id) = $dbh->selectrow_array($sql);
|
||||||
PTDEBUG && _d($dbh, 'hostname:', $hostname, $server_id);
|
PTDEBUG && _d($dbh, 'hostname:', $hostname, $server_id);
|
||||||
|
|
||||||
|
if ( $self->{dbh} && $self->{dbh} == $dbh && $self->{dbh_set} && $self->{dbh_set} == $connection_id) {
|
||||||
|
PTDEBUG && _d($dbh, 'Already set dbh');
|
||||||
|
return $dbh;
|
||||||
|
}
|
||||||
|
|
||||||
if ( $hostname ) {
|
if ( $hostname ) {
|
||||||
$self->{hostname} = $hostname;
|
$self->{hostname} = $hostname;
|
||||||
}
|
}
|
||||||
@@ -5458,7 +5472,7 @@ sub set_dbh {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$self->{dbh} = $dbh;
|
$self->{dbh} = $dbh;
|
||||||
$self->{dbh_set} = 1;
|
$self->{dbh_set} = $connection_id;
|
||||||
return $dbh;
|
return $dbh;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5584,6 +5598,17 @@ sub DESTROY {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub _ping() {
|
||||||
|
my ( $self, $dbh ) = @_;
|
||||||
|
if (!$dbh->ping()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
my $sql = 'SELECT CONNECTION_ID() as connection_id';
|
||||||
|
PTDEBUG && _d($dbh, $sql);
|
||||||
|
my ($connection_id) = $dbh->selectrow_array($sql);
|
||||||
|
return $self->{dbh_set} == $connection_id;
|
||||||
|
}
|
||||||
|
|
||||||
sub _d {
|
sub _d {
|
||||||
my ($package, undef, $line) = caller 0;
|
my ($package, undef, $line) = caller 0;
|
||||||
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
|
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
|
||||||
@@ -8734,6 +8759,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-kill 3.5.1
|
pt-kill 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
@@ -808,7 +808,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-mext 3.5.1
|
pt-mext 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
|
@@ -3325,7 +3325,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-mysql-summary 3.5.1
|
pt-mysql-summary 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
|
@@ -56,7 +56,7 @@ BEGIN {
|
|||||||
{
|
{
|
||||||
package Percona::Toolkit;
|
package Percona::Toolkit;
|
||||||
|
|
||||||
our $VERSION = '3.5.1';
|
our $VERSION = '3.5.2';
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings FATAL => 'all';
|
use warnings FATAL => 'all';
|
||||||
@@ -3102,7 +3102,7 @@ sub generate_cmp_where {
|
|||||||
push @clause, "($val IS NULL OR $quo $type $val)";
|
push @clause, "($val IS NULL OR $quo $type $val)";
|
||||||
}
|
}
|
||||||
elsif ( $type =~ m/>/ ) {
|
elsif ( $type =~ m/>/ ) {
|
||||||
push @clause, "($val IS NULL AND $quo IS NOT NULL) OR ($quo $cmp $val)";
|
push @clause, "(($val IS NULL AND $quo IS NOT NULL) OR ($quo $cmp $val))";
|
||||||
}
|
}
|
||||||
else { # If $type =~ m/</ ) {
|
else { # If $type =~ m/</ ) {
|
||||||
push @clauses, "(($val IS NOT NULL AND $quo IS NULL) OR ($quo $cmp $val))";
|
push @clauses, "(($val IS NOT NULL AND $quo IS NULL) OR ($quo $cmp $val))";
|
||||||
@@ -3509,8 +3509,7 @@ sub get_keys {
|
|||||||
my $clustered_key = undef;
|
my $clustered_key = undef;
|
||||||
|
|
||||||
KEY:
|
KEY:
|
||||||
foreach my $key ( $ddl =~ m/^ ((?:[A-Z]+ )?KEY \(?`[\s\S]*?`\)[\s\S]*?,?)$/gm ) {
|
foreach my $key ( $ddl =~ m/^ ((?:[A-Z]+ )?KEY [\s\S]*?\),?.*)$/gm ) {
|
||||||
|
|
||||||
next KEY if $key =~ m/FOREIGN/;
|
next KEY if $key =~ m/FOREIGN/;
|
||||||
|
|
||||||
my $key_ddl = $key;
|
my $key_ddl = $key;
|
||||||
@@ -3520,7 +3519,7 @@ sub get_keys {
|
|||||||
$key =~ s/USING HASH/USING BTREE/;
|
$key =~ s/USING HASH/USING BTREE/;
|
||||||
}
|
}
|
||||||
|
|
||||||
my ( $type, $cols ) = $key =~ m/(?:USING (\w+))? \(([\s\S]+?)\)/;
|
my ( $type, $cols ) = $key =~ m/(?:USING (\w+))? \(([\s\S]+)\)/;
|
||||||
my ( $special ) = $key =~ m/(FULLTEXT|SPATIAL)/;
|
my ( $special ) = $key =~ m/(FULLTEXT|SPATIAL)/;
|
||||||
$type = $type || $special || 'BTREE';
|
$type = $type || $special || 'BTREE';
|
||||||
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
|
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
|
||||||
@@ -3955,7 +3954,7 @@ sub connect {
|
|||||||
my $dp = $self->{DSNParser};
|
my $dp = $self->{DSNParser};
|
||||||
|
|
||||||
my $dbh = $self->{dbh};
|
my $dbh = $self->{dbh};
|
||||||
if ( !$dbh || !$dbh->ping() ) {
|
if ( !$dbh || ( $dbh && $self->{dbh_set} && !$self->_ping($dbh) ) ) {
|
||||||
if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p} ) {
|
if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p} ) {
|
||||||
$dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
|
$dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
|
||||||
$self->{asked_for_pass} = 1;
|
$self->{asked_for_pass} = 1;
|
||||||
@@ -3984,19 +3983,20 @@ sub connect {
|
|||||||
sub set_dbh {
|
sub set_dbh {
|
||||||
my ($self, $dbh) = @_;
|
my ($self, $dbh) = @_;
|
||||||
|
|
||||||
if ( $self->{dbh} && $self->{dbh} == $dbh && $self->{dbh_set} ) {
|
|
||||||
PTDEBUG && _d($dbh, 'Already set dbh');
|
|
||||||
return $dbh;
|
|
||||||
}
|
|
||||||
|
|
||||||
PTDEBUG && _d($dbh, 'Setting dbh');
|
PTDEBUG && _d($dbh, 'Setting dbh');
|
||||||
|
|
||||||
$dbh->{FetchHashKeyName} = 'NAME_lc' if $self->{NAME_lc};
|
$dbh->{FetchHashKeyName} = 'NAME_lc' if $self->{NAME_lc};
|
||||||
|
|
||||||
my $sql = 'SELECT @@server_id /*!50038 , @@hostname*/';
|
my $sql = 'SELECT @@server_id /*!50038 , @@hostname*/, CONNECTION_ID() as connection_id';
|
||||||
PTDEBUG && _d($dbh, $sql);
|
PTDEBUG && _d($dbh, $sql);
|
||||||
my ($server_id, $hostname) = $dbh->selectrow_array($sql);
|
my ($server_id, $hostname, $connection_id) = $dbh->selectrow_array($sql);
|
||||||
PTDEBUG && _d($dbh, 'hostname:', $hostname, $server_id);
|
PTDEBUG && _d($dbh, 'hostname:', $hostname, $server_id);
|
||||||
|
|
||||||
|
if ( $self->{dbh} && $self->{dbh} == $dbh && $self->{dbh_set} && $self->{dbh_set} == $connection_id) {
|
||||||
|
PTDEBUG && _d($dbh, 'Already set dbh');
|
||||||
|
return $dbh;
|
||||||
|
}
|
||||||
|
|
||||||
if ( $hostname ) {
|
if ( $hostname ) {
|
||||||
$self->{hostname} = $hostname;
|
$self->{hostname} = $hostname;
|
||||||
}
|
}
|
||||||
@@ -4011,7 +4011,7 @@ sub set_dbh {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$self->{dbh} = $dbh;
|
$self->{dbh} = $dbh;
|
||||||
$self->{dbh_set} = 1;
|
$self->{dbh_set} = $connection_id;
|
||||||
return $dbh;
|
return $dbh;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4137,6 +4137,17 @@ sub DESTROY {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub _ping() {
|
||||||
|
my ( $self, $dbh ) = @_;
|
||||||
|
if (!$dbh->ping()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
my $sql = 'SELECT CONNECTION_ID() as connection_id';
|
||||||
|
PTDEBUG && _d($dbh, $sql);
|
||||||
|
my ($connection_id) = $dbh->selectrow_array($sql);
|
||||||
|
return $self->{dbh_set} == $connection_id;
|
||||||
|
}
|
||||||
|
|
||||||
sub _d {
|
sub _d {
|
||||||
my ($package, undef, $line) = caller 0;
|
my ($package, undef, $line) = caller 0;
|
||||||
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
|
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
|
||||||
@@ -13482,6 +13493,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-online-schema-change 3.5.1
|
pt-online-schema-change 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
@@ -901,7 +901,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-pmp 3.5.1
|
pt-pmp 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
|
@@ -64,7 +64,7 @@ BEGIN {
|
|||||||
{
|
{
|
||||||
package Percona::Toolkit;
|
package Percona::Toolkit;
|
||||||
|
|
||||||
our $VERSION = '3.5.1';
|
our $VERSION = '3.5.2';
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings FATAL => 'all';
|
use warnings FATAL => 'all';
|
||||||
@@ -8894,7 +8894,7 @@ sub parse {
|
|||||||
|
|
||||||
my $engine = $self->get_engine($ddl);
|
my $engine = $self->get_engine($ddl);
|
||||||
|
|
||||||
my @defs = $ddl =~ m/^(\s+`.*?),?$/gm;
|
my @defs = $ddl =~ m/(?:(?<=,\n)|(?<=\(\n))(\s+`(?:.|\n)+?`.+?),?\n/g;
|
||||||
my @cols = map { $_ =~ m/`([^`]+)`/ } @defs;
|
my @cols = map { $_ =~ m/`([^`]+)`/ } @defs;
|
||||||
PTDEBUG && _d('Table cols:', join(', ', map { "`$_`" } @cols));
|
PTDEBUG && _d('Table cols:', join(', ', map { "`$_`" } @cols));
|
||||||
|
|
||||||
@@ -9075,8 +9075,7 @@ sub get_keys {
|
|||||||
my $clustered_key = undef;
|
my $clustered_key = undef;
|
||||||
|
|
||||||
KEY:
|
KEY:
|
||||||
foreach my $key ( $ddl =~ m/^ ((?:[A-Z]+ )?KEY .*)$/gm ) {
|
foreach my $key ( $ddl =~ m/^ ((?:[A-Z]+ )?KEY [\s\S]*?\),?.*)$/gm ) {
|
||||||
|
|
||||||
next KEY if $key =~ m/FOREIGN/;
|
next KEY if $key =~ m/FOREIGN/;
|
||||||
|
|
||||||
my $key_ddl = $key;
|
my $key_ddl = $key;
|
||||||
@@ -9086,7 +9085,7 @@ sub get_keys {
|
|||||||
$key =~ s/USING HASH/USING BTREE/;
|
$key =~ s/USING HASH/USING BTREE/;
|
||||||
}
|
}
|
||||||
|
|
||||||
my ( $type, $cols ) = $key =~ m/(?:USING (\w+))? \((.+)\)/;
|
my ( $type, $cols ) = $key =~ m/(?:USING (\w+))? \(([\s\S]+)\)/;
|
||||||
my ( $special ) = $key =~ m/(FULLTEXT|SPATIAL)/;
|
my ( $special ) = $key =~ m/(FULLTEXT|SPATIAL)/;
|
||||||
$type = $type || $special || 'BTREE';
|
$type = $type || $special || 'BTREE';
|
||||||
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
|
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
|
||||||
@@ -10539,6 +10538,7 @@ sub get_slaves {
|
|||||||
dsn => $dsn,
|
dsn => $dsn,
|
||||||
slave_user => $o->got('slave-user') ? $o->get('slave-user') : '',
|
slave_user => $o->got('slave-user') ? $o->get('slave-user') : '',
|
||||||
slave_password => $o->got('slave-password') ? $o->get('slave-password') : '',
|
slave_password => $o->got('slave-password') ? $o->get('slave-password') : '',
|
||||||
|
slaves => $args{slaves},
|
||||||
callback => sub {
|
callback => sub {
|
||||||
my ( $dsn, $dbh, $level, $parent ) = @_;
|
my ( $dsn, $dbh, $level, $parent ) = @_;
|
||||||
return unless $level;
|
return unless $level;
|
||||||
@@ -10615,17 +10615,30 @@ sub recurse_to_slaves {
|
|||||||
PTDEBUG && _d("Slave password set");
|
PTDEBUG && _d("Slave password set");
|
||||||
}
|
}
|
||||||
|
|
||||||
my $dbh;
|
my $dbh = $args->{dbh};
|
||||||
|
|
||||||
|
DBH: {
|
||||||
|
if ( !defined $dbh ) {
|
||||||
|
foreach my $known_slave ( @{$args->{slaves}} ) {
|
||||||
|
if ($known_slave->{dsn}->{h} eq $slave_dsn->{h} and
|
||||||
|
$known_slave->{dsn}->{P} eq $slave_dsn->{P} ) {
|
||||||
|
$dbh = $known_slave->{dbh};
|
||||||
|
last DBH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
eval {
|
eval {
|
||||||
$dbh = $args->{dbh} || $dp->get_dbh(
|
$dbh = $dp->get_dbh(
|
||||||
$dp->get_cxn_params($slave_dsn), { AutoCommit => 1 });
|
$dp->get_cxn_params($slave_dsn), { AutoCommit => 1 });
|
||||||
PTDEBUG && _d('Connected to', $dp->as_string($slave_dsn));
|
PTDEBUG && _d('Connected to', $dp->as_string($slave_dsn));
|
||||||
};
|
};
|
||||||
if ( $EVAL_ERROR ) {
|
if ( $EVAL_ERROR ) {
|
||||||
print STDERR "Cannot connect to ", $dp->as_string($slave_dsn), "\n"
|
print STDERR "Cannot connect to ", $dp->as_string($slave_dsn), ": ", $EVAL_ERROR, "\n"
|
||||||
or die "Cannot print: $OS_ERROR";
|
or die "Cannot print: $OS_ERROR";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
my $sql = 'SELECT @@SERVER_ID';
|
my $sql = 'SELECT @@SERVER_ID';
|
||||||
PTDEBUG && _d($sql);
|
PTDEBUG && _d($sql);
|
||||||
@@ -16977,6 +16990,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-query-digest 3.5.1
|
pt-query-digest 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
@@ -2673,6 +2673,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-show-grants 3.5.1
|
pt-show-grants 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
@@ -1249,7 +1249,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-sift 3.5.1
|
pt-sift 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
|
@@ -40,7 +40,7 @@ BEGIN {
|
|||||||
{
|
{
|
||||||
package Percona::Toolkit;
|
package Percona::Toolkit;
|
||||||
|
|
||||||
our $VERSION = '3.5.1';
|
our $VERSION = '3.5.2';
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings FATAL => 'all';
|
use warnings FATAL => 'all';
|
||||||
@@ -5061,6 +5061,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-slave-delay 3.5.1
|
pt-slave-delay 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
@@ -2306,6 +2306,7 @@ sub get_slaves {
|
|||||||
dsn => $dsn,
|
dsn => $dsn,
|
||||||
slave_user => $o->got('slave-user') ? $o->get('slave-user') : '',
|
slave_user => $o->got('slave-user') ? $o->get('slave-user') : '',
|
||||||
slave_password => $o->got('slave-password') ? $o->get('slave-password') : '',
|
slave_password => $o->got('slave-password') ? $o->get('slave-password') : '',
|
||||||
|
slaves => $args{slaves},
|
||||||
callback => sub {
|
callback => sub {
|
||||||
my ( $dsn, $dbh, $level, $parent ) = @_;
|
my ( $dsn, $dbh, $level, $parent ) = @_;
|
||||||
return unless $level;
|
return unless $level;
|
||||||
@@ -2382,17 +2383,30 @@ sub recurse_to_slaves {
|
|||||||
PTDEBUG && _d("Slave password set");
|
PTDEBUG && _d("Slave password set");
|
||||||
}
|
}
|
||||||
|
|
||||||
my $dbh;
|
my $dbh = $args->{dbh};
|
||||||
|
|
||||||
|
DBH: {
|
||||||
|
if ( !defined $dbh ) {
|
||||||
|
foreach my $known_slave ( @{$args->{slaves}} ) {
|
||||||
|
if ($known_slave->{dsn}->{h} eq $slave_dsn->{h} and
|
||||||
|
$known_slave->{dsn}->{P} eq $slave_dsn->{P} ) {
|
||||||
|
$dbh = $known_slave->{dbh};
|
||||||
|
last DBH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
eval {
|
eval {
|
||||||
$dbh = $args->{dbh} || $dp->get_dbh(
|
$dbh = $dp->get_dbh(
|
||||||
$dp->get_cxn_params($slave_dsn), { AutoCommit => 1 });
|
$dp->get_cxn_params($slave_dsn), { AutoCommit => 1 });
|
||||||
PTDEBUG && _d('Connected to', $dp->as_string($slave_dsn));
|
PTDEBUG && _d('Connected to', $dp->as_string($slave_dsn));
|
||||||
};
|
};
|
||||||
if ( $EVAL_ERROR ) {
|
if ( $EVAL_ERROR ) {
|
||||||
print STDERR "Cannot connect to ", $dp->as_string($slave_dsn), "\n"
|
print STDERR "Cannot connect to ", $dp->as_string($slave_dsn), ": ", $EVAL_ERROR, "\n"
|
||||||
or die "Cannot print: $OS_ERROR";
|
or die "Cannot print: $OS_ERROR";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
my $sql = 'SELECT @@SERVER_ID';
|
my $sql = 'SELECT @@SERVER_ID';
|
||||||
PTDEBUG && _d($sql);
|
PTDEBUG && _d($sql);
|
||||||
@@ -4581,6 +4595,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-slave-find 3.5.1
|
pt-slave-find 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
@@ -41,7 +41,7 @@ BEGIN {
|
|||||||
{
|
{
|
||||||
package Percona::Toolkit;
|
package Percona::Toolkit;
|
||||||
|
|
||||||
our $VERSION = '3.5.1';
|
our $VERSION = '3.5.2';
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings FATAL => 'all';
|
use warnings FATAL => 'all';
|
||||||
@@ -2717,6 +2717,7 @@ sub get_slaves {
|
|||||||
dsn => $dsn,
|
dsn => $dsn,
|
||||||
slave_user => $o->got('slave-user') ? $o->get('slave-user') : '',
|
slave_user => $o->got('slave-user') ? $o->get('slave-user') : '',
|
||||||
slave_password => $o->got('slave-password') ? $o->get('slave-password') : '',
|
slave_password => $o->got('slave-password') ? $o->get('slave-password') : '',
|
||||||
|
slaves => $args{slaves},
|
||||||
callback => sub {
|
callback => sub {
|
||||||
my ( $dsn, $dbh, $level, $parent ) = @_;
|
my ( $dsn, $dbh, $level, $parent ) = @_;
|
||||||
return unless $level;
|
return unless $level;
|
||||||
@@ -2793,17 +2794,30 @@ sub recurse_to_slaves {
|
|||||||
PTDEBUG && _d("Slave password set");
|
PTDEBUG && _d("Slave password set");
|
||||||
}
|
}
|
||||||
|
|
||||||
my $dbh;
|
my $dbh = $args->{dbh};
|
||||||
|
|
||||||
|
DBH: {
|
||||||
|
if ( !defined $dbh ) {
|
||||||
|
foreach my $known_slave ( @{$args->{slaves}} ) {
|
||||||
|
if ($known_slave->{dsn}->{h} eq $slave_dsn->{h} and
|
||||||
|
$known_slave->{dsn}->{P} eq $slave_dsn->{P} ) {
|
||||||
|
$dbh = $known_slave->{dbh};
|
||||||
|
last DBH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
eval {
|
eval {
|
||||||
$dbh = $args->{dbh} || $dp->get_dbh(
|
$dbh = $dp->get_dbh(
|
||||||
$dp->get_cxn_params($slave_dsn), { AutoCommit => 1 });
|
$dp->get_cxn_params($slave_dsn), { AutoCommit => 1 });
|
||||||
PTDEBUG && _d('Connected to', $dp->as_string($slave_dsn));
|
PTDEBUG && _d('Connected to', $dp->as_string($slave_dsn));
|
||||||
};
|
};
|
||||||
if ( $EVAL_ERROR ) {
|
if ( $EVAL_ERROR ) {
|
||||||
print STDERR "Cannot connect to ", $dp->as_string($slave_dsn), "\n"
|
print STDERR "Cannot connect to ", $dp->as_string($slave_dsn), ": ", $EVAL_ERROR, "\n"
|
||||||
or die "Cannot print: $OS_ERROR";
|
or die "Cannot print: $OS_ERROR";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
my $sql = 'SELECT @@SERVER_ID';
|
my $sql = 'SELECT @@SERVER_ID';
|
||||||
PTDEBUG && _d($sql);
|
PTDEBUG && _d($sql);
|
||||||
@@ -6232,6 +6246,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-slave-restart 3.5.1
|
pt-slave-restart 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
@@ -2564,7 +2564,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-stalk 3.5.1
|
pt-stalk 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
|
@@ -2769,7 +2769,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-summary 3.5.1
|
pt-summary 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
|
@@ -58,7 +58,7 @@ BEGIN {
|
|||||||
{
|
{
|
||||||
package Percona::Toolkit;
|
package Percona::Toolkit;
|
||||||
|
|
||||||
our $VERSION = '3.5.1';
|
our $VERSION = '3.5.2';
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings FATAL => 'all';
|
use warnings FATAL => 'all';
|
||||||
@@ -3673,7 +3673,7 @@ sub connect {
|
|||||||
my $dp = $self->{DSNParser};
|
my $dp = $self->{DSNParser};
|
||||||
|
|
||||||
my $dbh = $self->{dbh};
|
my $dbh = $self->{dbh};
|
||||||
if ( !$dbh || !$dbh->ping() ) {
|
if ( !$dbh || ( $dbh && $self->{dbh_set} && !$self->_ping($dbh) ) ) {
|
||||||
if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p} ) {
|
if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p} ) {
|
||||||
$dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
|
$dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
|
||||||
$self->{asked_for_pass} = 1;
|
$self->{asked_for_pass} = 1;
|
||||||
@@ -3702,19 +3702,20 @@ sub connect {
|
|||||||
sub set_dbh {
|
sub set_dbh {
|
||||||
my ($self, $dbh) = @_;
|
my ($self, $dbh) = @_;
|
||||||
|
|
||||||
if ( $self->{dbh} && $self->{dbh} == $dbh && $self->{dbh_set} ) {
|
|
||||||
PTDEBUG && _d($dbh, 'Already set dbh');
|
|
||||||
return $dbh;
|
|
||||||
}
|
|
||||||
|
|
||||||
PTDEBUG && _d($dbh, 'Setting dbh');
|
PTDEBUG && _d($dbh, 'Setting dbh');
|
||||||
|
|
||||||
$dbh->{FetchHashKeyName} = 'NAME_lc' if $self->{NAME_lc};
|
$dbh->{FetchHashKeyName} = 'NAME_lc' if $self->{NAME_lc};
|
||||||
|
|
||||||
my $sql = 'SELECT @@server_id /*!50038 , @@hostname*/';
|
my $sql = 'SELECT @@server_id /*!50038 , @@hostname*/, CONNECTION_ID() as connection_id';
|
||||||
PTDEBUG && _d($dbh, $sql);
|
PTDEBUG && _d($dbh, $sql);
|
||||||
my ($server_id, $hostname) = $dbh->selectrow_array($sql);
|
my ($server_id, $hostname, $connection_id) = $dbh->selectrow_array($sql);
|
||||||
PTDEBUG && _d($dbh, 'hostname:', $hostname, $server_id);
|
PTDEBUG && _d($dbh, 'hostname:', $hostname, $server_id);
|
||||||
|
|
||||||
|
if ( $self->{dbh} && $self->{dbh} == $dbh && $self->{dbh_set} && $self->{dbh_set} == $connection_id) {
|
||||||
|
PTDEBUG && _d($dbh, 'Already set dbh');
|
||||||
|
return $dbh;
|
||||||
|
}
|
||||||
|
|
||||||
if ( $hostname ) {
|
if ( $hostname ) {
|
||||||
$self->{hostname} = $hostname;
|
$self->{hostname} = $hostname;
|
||||||
}
|
}
|
||||||
@@ -3729,7 +3730,7 @@ sub set_dbh {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$self->{dbh} = $dbh;
|
$self->{dbh} = $dbh;
|
||||||
$self->{dbh_set} = 1;
|
$self->{dbh_set} = $connection_id;
|
||||||
return $dbh;
|
return $dbh;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3855,6 +3856,17 @@ sub DESTROY {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub _ping() {
|
||||||
|
my ( $self, $dbh ) = @_;
|
||||||
|
if (!$dbh->ping()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
my $sql = 'SELECT CONNECTION_ID() as connection_id';
|
||||||
|
PTDEBUG && _d($dbh, $sql);
|
||||||
|
my ($connection_id) = $dbh->selectrow_array($sql);
|
||||||
|
return $self->{dbh_set} == $connection_id;
|
||||||
|
}
|
||||||
|
|
||||||
sub _d {
|
sub _d {
|
||||||
my ($package, undef, $line) = caller 0;
|
my ($package, undef, $line) = caller 0;
|
||||||
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
|
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
|
||||||
@@ -4697,8 +4709,7 @@ sub get_keys {
|
|||||||
my $clustered_key = undef;
|
my $clustered_key = undef;
|
||||||
|
|
||||||
KEY:
|
KEY:
|
||||||
foreach my $key ( $ddl =~ m/^ ((?:[A-Z]+ )?KEY \(?`[\s\S]*?`\),?)$/gm ) {
|
foreach my $key ( $ddl =~ m/^ ((?:[A-Z]+ )?KEY [\s\S]*?\),?.*)$/gm ) {
|
||||||
|
|
||||||
next KEY if $key =~ m/FOREIGN/;
|
next KEY if $key =~ m/FOREIGN/;
|
||||||
|
|
||||||
my $key_ddl = $key;
|
my $key_ddl = $key;
|
||||||
@@ -4708,7 +4719,7 @@ sub get_keys {
|
|||||||
$key =~ s/USING HASH/USING BTREE/;
|
$key =~ s/USING HASH/USING BTREE/;
|
||||||
}
|
}
|
||||||
|
|
||||||
my ( $type, $cols ) = $key =~ m/(?:USING (\w+))? \(([\s\S]+?)\)/;
|
my ( $type, $cols ) = $key =~ m/(?:USING (\w+))? \(([\s\S]+)\)/;
|
||||||
my ( $special ) = $key =~ m/(FULLTEXT|SPATIAL)/;
|
my ( $special ) = $key =~ m/(FULLTEXT|SPATIAL)/;
|
||||||
$type = $type || $special || 'BTREE';
|
$type = $type || $special || 'BTREE';
|
||||||
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
|
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
|
||||||
@@ -4989,7 +5000,7 @@ sub generate_cmp_where {
|
|||||||
push @clause, "($val IS NULL OR $quo $type $val)";
|
push @clause, "($val IS NULL OR $quo $type $val)";
|
||||||
}
|
}
|
||||||
elsif ( $type =~ m/>/ ) {
|
elsif ( $type =~ m/>/ ) {
|
||||||
push @clause, "($val IS NULL AND $quo IS NOT NULL) OR ($quo $cmp $val)";
|
push @clause, "(($val IS NULL AND $quo IS NOT NULL) OR ($quo $cmp $val))";
|
||||||
}
|
}
|
||||||
else { # If $type =~ m/</ ) {
|
else { # If $type =~ m/</ ) {
|
||||||
push @clauses, "(($val IS NOT NULL AND $quo IS NULL) OR ($quo $cmp $val))";
|
push @clauses, "(($val IS NOT NULL AND $quo IS NULL) OR ($quo $cmp $val))";
|
||||||
@@ -5188,6 +5199,7 @@ sub get_slaves {
|
|||||||
dsn => $dsn,
|
dsn => $dsn,
|
||||||
slave_user => $o->got('slave-user') ? $o->get('slave-user') : '',
|
slave_user => $o->got('slave-user') ? $o->get('slave-user') : '',
|
||||||
slave_password => $o->got('slave-password') ? $o->get('slave-password') : '',
|
slave_password => $o->got('slave-password') ? $o->get('slave-password') : '',
|
||||||
|
slaves => $args{slaves},
|
||||||
callback => sub {
|
callback => sub {
|
||||||
my ( $dsn, $dbh, $level, $parent ) = @_;
|
my ( $dsn, $dbh, $level, $parent ) = @_;
|
||||||
return unless $level;
|
return unless $level;
|
||||||
@@ -5264,17 +5276,30 @@ sub recurse_to_slaves {
|
|||||||
PTDEBUG && _d("Slave password set");
|
PTDEBUG && _d("Slave password set");
|
||||||
}
|
}
|
||||||
|
|
||||||
my $dbh;
|
my $dbh = $args->{dbh};
|
||||||
|
|
||||||
|
DBH: {
|
||||||
|
if ( !defined $dbh ) {
|
||||||
|
foreach my $known_slave ( @{$args->{slaves}} ) {
|
||||||
|
if ($known_slave->{dsn}->{h} eq $slave_dsn->{h} and
|
||||||
|
$known_slave->{dsn}->{P} eq $slave_dsn->{P} ) {
|
||||||
|
$dbh = $known_slave->{dbh};
|
||||||
|
last DBH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
eval {
|
eval {
|
||||||
$dbh = $args->{dbh} || $dp->get_dbh(
|
$dbh = $dp->get_dbh(
|
||||||
$dp->get_cxn_params($slave_dsn), { AutoCommit => 1 });
|
$dp->get_cxn_params($slave_dsn), { AutoCommit => 1 });
|
||||||
PTDEBUG && _d('Connected to', $dp->as_string($slave_dsn));
|
PTDEBUG && _d('Connected to', $dp->as_string($slave_dsn));
|
||||||
};
|
};
|
||||||
if ( $EVAL_ERROR ) {
|
if ( $EVAL_ERROR ) {
|
||||||
print STDERR "Cannot connect to ", $dp->as_string($slave_dsn), "\n"
|
print STDERR "Cannot connect to ", $dp->as_string($slave_dsn), ": ", $EVAL_ERROR, "\n"
|
||||||
or die "Cannot print: $OS_ERROR";
|
or die "Cannot print: $OS_ERROR";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
my $sql = 'SELECT @@SERVER_ID';
|
my $sql = 'SELECT @@SERVER_ID';
|
||||||
PTDEBUG && _d($sql);
|
PTDEBUG && _d($sql);
|
||||||
@@ -14130,6 +14155,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-table-checksum 3.5.1
|
pt-table-checksum 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
@@ -55,7 +55,7 @@ BEGIN {
|
|||||||
{
|
{
|
||||||
package Percona::Toolkit;
|
package Percona::Toolkit;
|
||||||
|
|
||||||
our $VERSION = '3.5.1';
|
our $VERSION = '3.5.2';
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings FATAL => 'all';
|
use warnings FATAL => 'all';
|
||||||
@@ -2877,7 +2877,7 @@ sub parse {
|
|||||||
|
|
||||||
my $engine = $self->get_engine($ddl);
|
my $engine = $self->get_engine($ddl);
|
||||||
|
|
||||||
my @defs = $ddl =~ m/^(\s+`.*?),?$/gm;
|
my @defs = $ddl =~ m/(?:(?<=,\n)|(?<=\(\n))(\s+`(?:.|\n)+?`.+?),?\n/g;
|
||||||
my @cols = map { $_ =~ m/`([^`]+)`/ } @defs;
|
my @cols = map { $_ =~ m/`([^`]+)`/ } @defs;
|
||||||
PTDEBUG && _d('Table cols:', join(', ', map { "`$_`" } @cols));
|
PTDEBUG && _d('Table cols:', join(', ', map { "`$_`" } @cols));
|
||||||
|
|
||||||
@@ -3058,8 +3058,7 @@ sub get_keys {
|
|||||||
my $clustered_key = undef;
|
my $clustered_key = undef;
|
||||||
|
|
||||||
KEY:
|
KEY:
|
||||||
foreach my $key ( $ddl =~ m/^ ((?:[A-Z]+ )?KEY .*)$/gm ) {
|
foreach my $key ( $ddl =~ m/^ ((?:[A-Z]+ )?KEY [\s\S]*?\),?.*)$/gm ) {
|
||||||
|
|
||||||
next KEY if $key =~ m/FOREIGN/;
|
next KEY if $key =~ m/FOREIGN/;
|
||||||
|
|
||||||
my $key_ddl = $key;
|
my $key_ddl = $key;
|
||||||
@@ -3069,7 +3068,7 @@ sub get_keys {
|
|||||||
$key =~ s/USING HASH/USING BTREE/;
|
$key =~ s/USING HASH/USING BTREE/;
|
||||||
}
|
}
|
||||||
|
|
||||||
my ( $type, $cols ) = $key =~ m/(?:USING (\w+))? \((.+)\)/;
|
my ( $type, $cols ) = $key =~ m/(?:USING (\w+))? \(([\s\S]+)\)/;
|
||||||
my ( $special ) = $key =~ m/(FULLTEXT|SPATIAL)/;
|
my ( $special ) = $key =~ m/(FULLTEXT|SPATIAL)/;
|
||||||
$type = $type || $special || 'BTREE';
|
$type = $type || $special || 'BTREE';
|
||||||
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
|
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
|
||||||
@@ -6517,7 +6516,7 @@ sub generate_cmp_where {
|
|||||||
push @clause, "($val IS NULL OR $quo $type $val)";
|
push @clause, "($val IS NULL OR $quo $type $val)";
|
||||||
}
|
}
|
||||||
elsif ( $type =~ m/>/ ) {
|
elsif ( $type =~ m/>/ ) {
|
||||||
push @clause, "($val IS NULL AND $quo IS NOT NULL) OR ($quo $cmp $val)";
|
push @clause, "(($val IS NULL AND $quo IS NOT NULL) OR ($quo $cmp $val))";
|
||||||
}
|
}
|
||||||
else { # If $type =~ m/</ ) {
|
else { # If $type =~ m/</ ) {
|
||||||
push @clauses, "(($val IS NOT NULL AND $quo IS NULL) OR ($quo $cmp $val))";
|
push @clauses, "(($val IS NOT NULL AND $quo IS NULL) OR ($quo $cmp $val))";
|
||||||
@@ -6716,6 +6715,7 @@ sub get_slaves {
|
|||||||
dsn => $dsn,
|
dsn => $dsn,
|
||||||
slave_user => $o->got('slave-user') ? $o->get('slave-user') : '',
|
slave_user => $o->got('slave-user') ? $o->get('slave-user') : '',
|
||||||
slave_password => $o->got('slave-password') ? $o->get('slave-password') : '',
|
slave_password => $o->got('slave-password') ? $o->get('slave-password') : '',
|
||||||
|
slaves => $args{slaves},
|
||||||
callback => sub {
|
callback => sub {
|
||||||
my ( $dsn, $dbh, $level, $parent ) = @_;
|
my ( $dsn, $dbh, $level, $parent ) = @_;
|
||||||
return unless $level;
|
return unless $level;
|
||||||
@@ -6792,17 +6792,30 @@ sub recurse_to_slaves {
|
|||||||
PTDEBUG && _d("Slave password set");
|
PTDEBUG && _d("Slave password set");
|
||||||
}
|
}
|
||||||
|
|
||||||
my $dbh;
|
my $dbh = $args->{dbh};
|
||||||
|
|
||||||
|
DBH: {
|
||||||
|
if ( !defined $dbh ) {
|
||||||
|
foreach my $known_slave ( @{$args->{slaves}} ) {
|
||||||
|
if ($known_slave->{dsn}->{h} eq $slave_dsn->{h} and
|
||||||
|
$known_slave->{dsn}->{P} eq $slave_dsn->{P} ) {
|
||||||
|
$dbh = $known_slave->{dbh};
|
||||||
|
last DBH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
eval {
|
eval {
|
||||||
$dbh = $args->{dbh} || $dp->get_dbh(
|
$dbh = $dp->get_dbh(
|
||||||
$dp->get_cxn_params($slave_dsn), { AutoCommit => 1 });
|
$dp->get_cxn_params($slave_dsn), { AutoCommit => 1 });
|
||||||
PTDEBUG && _d('Connected to', $dp->as_string($slave_dsn));
|
PTDEBUG && _d('Connected to', $dp->as_string($slave_dsn));
|
||||||
};
|
};
|
||||||
if ( $EVAL_ERROR ) {
|
if ( $EVAL_ERROR ) {
|
||||||
print STDERR "Cannot connect to ", $dp->as_string($slave_dsn), "\n"
|
print STDERR "Cannot connect to ", $dp->as_string($slave_dsn), ": ", $EVAL_ERROR, "\n"
|
||||||
or die "Cannot print: $OS_ERROR";
|
or die "Cannot print: $OS_ERROR";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
my $sql = 'SELECT @@SERVER_ID';
|
my $sql = 'SELECT @@SERVER_ID';
|
||||||
PTDEBUG && _d($sql);
|
PTDEBUG && _d($sql);
|
||||||
@@ -13165,6 +13178,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-table-sync 3.5.1
|
pt-table-sync 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
@@ -8519,6 +8519,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-table-usage 3.5.1
|
pt-table-usage 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
@@ -61,7 +61,7 @@ BEGIN {
|
|||||||
{
|
{
|
||||||
package Percona::Toolkit;
|
package Percona::Toolkit;
|
||||||
|
|
||||||
our $VERSION = '3.5.1';
|
our $VERSION = '3.5.2';
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings FATAL => 'all';
|
use warnings FATAL => 'all';
|
||||||
@@ -2539,7 +2539,7 @@ sub connect {
|
|||||||
my $dp = $self->{DSNParser};
|
my $dp = $self->{DSNParser};
|
||||||
|
|
||||||
my $dbh = $self->{dbh};
|
my $dbh = $self->{dbh};
|
||||||
if ( !$dbh || !$dbh->ping() ) {
|
if ( !$dbh || ( $dbh && $self->{dbh_set} && !$self->_ping($dbh) ) ) {
|
||||||
if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p} ) {
|
if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p} ) {
|
||||||
$dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
|
$dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
|
||||||
$self->{asked_for_pass} = 1;
|
$self->{asked_for_pass} = 1;
|
||||||
@@ -2568,19 +2568,20 @@ sub connect {
|
|||||||
sub set_dbh {
|
sub set_dbh {
|
||||||
my ($self, $dbh) = @_;
|
my ($self, $dbh) = @_;
|
||||||
|
|
||||||
if ( $self->{dbh} && $self->{dbh} == $dbh && $self->{dbh_set} ) {
|
|
||||||
PTDEBUG && _d($dbh, 'Already set dbh');
|
|
||||||
return $dbh;
|
|
||||||
}
|
|
||||||
|
|
||||||
PTDEBUG && _d($dbh, 'Setting dbh');
|
PTDEBUG && _d($dbh, 'Setting dbh');
|
||||||
|
|
||||||
$dbh->{FetchHashKeyName} = 'NAME_lc' if $self->{NAME_lc};
|
$dbh->{FetchHashKeyName} = 'NAME_lc' if $self->{NAME_lc};
|
||||||
|
|
||||||
my $sql = 'SELECT @@server_id /*!50038 , @@hostname*/';
|
my $sql = 'SELECT @@server_id /*!50038 , @@hostname*/, CONNECTION_ID() as connection_id';
|
||||||
PTDEBUG && _d($dbh, $sql);
|
PTDEBUG && _d($dbh, $sql);
|
||||||
my ($server_id, $hostname) = $dbh->selectrow_array($sql);
|
my ($server_id, $hostname, $connection_id) = $dbh->selectrow_array($sql);
|
||||||
PTDEBUG && _d($dbh, 'hostname:', $hostname, $server_id);
|
PTDEBUG && _d($dbh, 'hostname:', $hostname, $server_id);
|
||||||
|
|
||||||
|
if ( $self->{dbh} && $self->{dbh} == $dbh && $self->{dbh_set} && $self->{dbh_set} == $connection_id) {
|
||||||
|
PTDEBUG && _d($dbh, 'Already set dbh');
|
||||||
|
return $dbh;
|
||||||
|
}
|
||||||
|
|
||||||
if ( $hostname ) {
|
if ( $hostname ) {
|
||||||
$self->{hostname} = $hostname;
|
$self->{hostname} = $hostname;
|
||||||
}
|
}
|
||||||
@@ -2595,7 +2596,7 @@ sub set_dbh {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$self->{dbh} = $dbh;
|
$self->{dbh} = $dbh;
|
||||||
$self->{dbh_set} = 1;
|
$self->{dbh_set} = $connection_id;
|
||||||
return $dbh;
|
return $dbh;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2721,6 +2722,17 @@ sub DESTROY {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub _ping() {
|
||||||
|
my ( $self, $dbh ) = @_;
|
||||||
|
if (!$dbh->ping()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
my $sql = 'SELECT CONNECTION_ID() as connection_id';
|
||||||
|
PTDEBUG && _d($dbh, $sql);
|
||||||
|
my ($connection_id) = $dbh->selectrow_array($sql);
|
||||||
|
return $self->{dbh_set} == $connection_id;
|
||||||
|
}
|
||||||
|
|
||||||
sub _d {
|
sub _d {
|
||||||
my ($package, undef, $line) = caller 0;
|
my ($package, undef, $line) = caller 0;
|
||||||
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
|
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
|
||||||
@@ -11516,6 +11528,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-upgrade 3.5.1
|
pt-upgrade 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
@@ -44,7 +44,7 @@ BEGIN {
|
|||||||
{
|
{
|
||||||
package Percona::Toolkit;
|
package Percona::Toolkit;
|
||||||
|
|
||||||
our $VERSION = '3.5.1';
|
our $VERSION = '3.5.2';
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings FATAL => 'all';
|
use warnings FATAL => 'all';
|
||||||
@@ -6326,6 +6326,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-variable-advisor 3.5.1
|
pt-variable-advisor 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
@@ -3308,6 +3308,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
pt-visual-explain 3.5.1
|
pt-visual-explain 3.5.2
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
@@ -50,7 +50,7 @@ copyright = u'2023, Percona LLC and/or its affiliates'
|
|||||||
# The short X.Y version.
|
# The short X.Y version.
|
||||||
version = '3.5'
|
version = '3.5'
|
||||||
# The full version, including alpha/beta/rc tags.
|
# The full version, including alpha/beta/rc tags.
|
||||||
release = '3.5.1'
|
release = '3.5.2'
|
||||||
|
|
||||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
# for a list of supported languages.
|
# for a list of supported languages.
|
||||||
|
@@ -575,6 +575,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
Percona Toolkit v3.5.1 released 2023-01-23
|
Percona Toolkit v3.5.2 released 2023-03-28
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
@@ -1,6 +1,48 @@
|
|||||||
Percona Toolkit
|
Percona Toolkit
|
||||||
***************
|
***************
|
||||||
|
|
||||||
|
v3.5.2 released 2023-03-28
|
||||||
|
==============================
|
||||||
|
|
||||||
|
Improvements
|
||||||
|
------------------------------------------------------------
|
||||||
|
|
||||||
|
* :jirabug:`PT-188`: Use percona.checksums in examples
|
||||||
|
* :jirabug:`PT-2141`: Fix tests for pt-archiver
|
||||||
|
* :jirabug:`PT-2149`: Fix tests for pt-mext
|
||||||
|
* :jirabug:`PT-2150`: Fix tests for pt-mysql-summary
|
||||||
|
* :jirabug:`PT-2152`: Fix tests for pt-show-grants
|
||||||
|
* :jirabug:`PT-2155`: Fix tests for pt-upgrade
|
||||||
|
* :jirabug:`PT-2156`: Fix tests for lib
|
||||||
|
* :jirabug:`PT-2159`: Fix tests for pt-duplicate-key-checker
|
||||||
|
* :jirabug:`PT-2160`: Fix tests for pt-online-schema-change
|
||||||
|
* :jirabug:`PT-2161`: Fix tests for pt-slave-restart
|
||||||
|
* :jirabug:`PT-2164`: pt-k8s-debug-collector does not have version flag
|
||||||
|
* :jirabug:`PT-2165`: Actual Version, GoVersion, and Build for Go tools
|
||||||
|
|
||||||
|
Bugs Fixed
|
||||||
|
------------
|
||||||
|
|
||||||
|
* :jirabug:`PT-215`: Documentation fix
|
||||||
|
* :jirabug:`PT-1059`: LP #1093972: Tools can't parse index names containing newlines
|
||||||
|
* :jirabug:`PT-1389`: LP #1637859: [pt-variable-advisor] Docs Typos
|
||||||
|
* :jirabug:`PT-1594`: Need correction in the Documentation - pt-mysql-summary
|
||||||
|
* :jirabug:`PT-1595`: percona toolkit docs still reference Maatkit
|
||||||
|
* :jirabug:`PT-1642`: Update PT docs to reference bug reporting location as Percona JIRA
|
||||||
|
* :jirabug:`PT-1683`: List of supported distributions in the docs is outdated
|
||||||
|
* :jirabug:`PT-1700`: pt-table-checksum REPLICATION_STOPPED exit status not documented
|
||||||
|
* :jirabug:`PT-1927`: pt-k8s-debug-collector requires mysql client
|
||||||
|
* :jirabug:`PT-1930`: pt-k8s-debug-collector should not attempt collecting PXC information when running against PSMDB
|
||||||
|
* :jirabug:`PT-2084`: Changes from PT-80 broke previous pt-stalk functionality (Thanks to Agustín Gallego for reporting this issue)
|
||||||
|
* :jirabug:`PT-2102`: pt-mysql-summary should support !include* in config files (Thanks to Yoann La Cancellera for reporting this issue)
|
||||||
|
* :jirabug:`PT-2110`: Incorrect PTDEBUG output with --ignore-engines option (Thanks to Kazuya Yokogawa for reporting this issue)
|
||||||
|
* :jirabug:`PT-2114`: Incorrect casting of BIT columns by pt-archiver
|
||||||
|
* :jirabug:`PT-2116`: pt-osc --null-to-not-null description is wrong (Thanks to Yoann La Cancellera for reporting this issue)
|
||||||
|
* :jirabug:`PT-2120`: pt-stalk with --system-only displaying "MYSQL_ONLY:" message on the screen
|
||||||
|
* :jirabug:`PT-2123`: pt-archiver gives error "Wide character in print at /usr/bin/pt-archiver line 6815" when using --bulk-insert while using character set alias
|
||||||
|
* :jirabug:`PT-2187`: CVEs reported in Percona Toolkit version 5.3.1 related to GO
|
||||||
|
|
||||||
|
|
||||||
v3.5.1 released 2023-01-23
|
v3.5.1 released 2023-01-23
|
||||||
==============================
|
==============================
|
||||||
|
|
||||||
|
48
docs/rn.3-5-2.txt
Normal file
48
docs/rn.3-5-2.txt
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
.. _PT-3.5.2:
|
||||||
|
|
||||||
|
================================================================================
|
||||||
|
*Percona Toolkit* 3.5.2
|
||||||
|
================================================================================
|
||||||
|
|
||||||
|
:Date: March 28, 2023
|
||||||
|
:Installation: `Installing Percona Toolkit <https://www.percona.com/doc/percona-toolkit/LATEST/installation.html>`_
|
||||||
|
|
||||||
|
|
||||||
|
Improvements
|
||||||
|
================================================================================
|
||||||
|
|
||||||
|
* :jirabug:`PT-188`: Use percona.checksums in examples
|
||||||
|
* :jirabug:`PT-2141`: Fix tests for pt-archiver
|
||||||
|
* :jirabug:`PT-2149`: Fix tests for pt-mext
|
||||||
|
* :jirabug:`PT-2150`: Fix tests for pt-mysql-summary
|
||||||
|
* :jirabug:`PT-2152`: Fix tests for pt-show-grants
|
||||||
|
* :jirabug:`PT-2155`: Fix tests for pt-upgrade
|
||||||
|
* :jirabug:`PT-2156`: Fix tests for lib
|
||||||
|
* :jirabug:`PT-2159`: Fix tests for pt-duplicate-key-checker
|
||||||
|
* :jirabug:`PT-2160`: Fix tests for pt-online-schema-change
|
||||||
|
* :jirabug:`PT-2161`: Fix tests for pt-slave-restart
|
||||||
|
* :jirabug:`PT-2164`: pt-k8s-debug-collector does not have version flag
|
||||||
|
* :jirabug:`PT-2165`: Actual Version, GoVersion, and Build for Go tools
|
||||||
|
|
||||||
|
Bugs Fixed
|
||||||
|
================================================================================
|
||||||
|
|
||||||
|
* :jirabug:`PT-215`: Documentation fix
|
||||||
|
* :jirabug:`PT-1059`: LP #1093972: Tools can't parse index names containing newlines
|
||||||
|
* :jirabug:`PT-1389`: LP #1637859: [pt-variable-advisor] Docs Typos
|
||||||
|
* :jirabug:`PT-1594`: Need correction in the Documentation - pt-mysql-summary
|
||||||
|
* :jirabug:`PT-1595`: percona toolkit docs still reference Maatkit
|
||||||
|
* :jirabug:`PT-1642`: Update PT docs to reference bug reporting location as Percona JIRA
|
||||||
|
* :jirabug:`PT-1683`: List of supported distributions in the docs is outdated
|
||||||
|
* :jirabug:`PT-1700`: pt-table-checksum REPLICATION_STOPPED exit status not documented
|
||||||
|
* :jirabug:`PT-1927`: pt-k8s-debug-collector requires mysql client
|
||||||
|
* :jirabug:`PT-1930`: pt-k8s-debug-collector should not attempt collecting PXC information when running against PSMDB
|
||||||
|
* :jirabug:`PT-2084`: Changes from PT-80 broke previous pt-stalk functionality (Thanks Agustín Gallego)
|
||||||
|
* :jirabug:`PT-2102`: pt-mysql-summary should support !include* in config files (Thanks Yoann La Cancellera)
|
||||||
|
* :jirabug:`PT-2110`: Incorrect PTDEBUG output with --ignore-engines option (Thanks Kazuya Yokogawa)
|
||||||
|
* :jirabug:`PT-2114`: Incorrect casting of BIT columns by pt-archiver
|
||||||
|
* :jirabug:`PT-2116`: pt-osc --null-to-not-null description is wrong (Thanks Yoann La Cancellera)
|
||||||
|
* :jirabug:`PT-2120`: pt-stalk with --system-only displaying "MYSQL_ONLY:" message on the screen
|
||||||
|
* :jirabug:`PT-2123`: pt-archiver gives error "Wide character in print at /usr/bin/pt-archiver line 6815" when using --bulk-insert while using character set alias
|
||||||
|
* :jirabug:`PT-2187`: CVEs reported in Percona Toolkit version 5.3.1 related to GO
|
||||||
|
|
50
lib/Cxn.pm
50
lib/Cxn.pm
@@ -123,7 +123,8 @@ sub connect {
|
|||||||
my $dp = $self->{DSNParser};
|
my $dp = $self->{DSNParser};
|
||||||
|
|
||||||
my $dbh = $self->{dbh};
|
my $dbh = $self->{dbh};
|
||||||
if ( !$dbh || !$dbh->ping() ) {
|
# We cannot use $dbh->ping() here due to https://github.com/perl5-dbi/DBD-mysql/issues/306
|
||||||
|
if ( !$dbh || ( $dbh && $self->{dbh_set} && !$self->_ping($dbh) ) ) {
|
||||||
# Ask for password once.
|
# Ask for password once.
|
||||||
if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p} ) {
|
if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p} ) {
|
||||||
$dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
|
$dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
|
||||||
@@ -153,18 +154,6 @@ sub connect {
|
|||||||
sub set_dbh {
|
sub set_dbh {
|
||||||
my ($self, $dbh) = @_;
|
my ($self, $dbh) = @_;
|
||||||
|
|
||||||
# If we already have a dbh, and that dbh is the same as this dbh,
|
|
||||||
# and the dbh has already been set, then do not re-set the same
|
|
||||||
# dbh. dbh_set is required so that if this obj was created with
|
|
||||||
# a dbh, we set that dbh when connect() is called because whoever
|
|
||||||
# created the dbh probably didn't set what we set here. For example,
|
|
||||||
# MasterSlave makes dbhs when finding slaves, but it doesn't set
|
|
||||||
# anything.
|
|
||||||
if ( $self->{dbh} && $self->{dbh} == $dbh && $self->{dbh_set} ) {
|
|
||||||
PTDEBUG && _d($dbh, 'Already set dbh');
|
|
||||||
return $dbh;
|
|
||||||
}
|
|
||||||
|
|
||||||
PTDEBUG && _d($dbh, 'Setting dbh');
|
PTDEBUG && _d($dbh, 'Setting dbh');
|
||||||
|
|
||||||
# Set stuff for this dbh (i.e. initialize it).
|
# Set stuff for this dbh (i.e. initialize it).
|
||||||
@@ -172,10 +161,26 @@ sub set_dbh {
|
|||||||
|
|
||||||
# Update the cxn's name. Until we connect, the DSN parts
|
# Update the cxn's name. Until we connect, the DSN parts
|
||||||
# h and P are used. Once connected, use @@hostname.
|
# h and P are used. Once connected, use @@hostname.
|
||||||
my $sql = 'SELECT @@server_id /*!50038 , @@hostname*/';
|
my $sql = 'SELECT @@server_id /*!50038 , @@hostname*/, CONNECTION_ID() as connection_id';
|
||||||
PTDEBUG && _d($dbh, $sql);
|
PTDEBUG && _d($dbh, $sql);
|
||||||
my ($server_id, $hostname) = $dbh->selectrow_array($sql);
|
my ($server_id, $hostname, $connection_id) = $dbh->selectrow_array($sql);
|
||||||
PTDEBUG && _d($dbh, 'hostname:', $hostname, $server_id);
|
PTDEBUG && _d($dbh, 'hostname:', $hostname, $server_id);
|
||||||
|
|
||||||
|
# If we already have a dbh, and that dbh is the same as this dbh,
|
||||||
|
# and the dbh has already been set, then do not re-set the same
|
||||||
|
# dbh. dbh_set is required so that if this obj was created with
|
||||||
|
# a dbh, we set that dbh when connect() is called because whoever
|
||||||
|
# created the dbh probably didn't set what we set here. For example,
|
||||||
|
# MasterSlave makes dbhs when finding slaves, but it doesn't set
|
||||||
|
# anything.
|
||||||
|
# Due to https://github.com/perl5-dbi/DBD-mysql/issues/306 we assigning
|
||||||
|
# connection_id to $self->{dbh_set} and compare it with current connection_id.
|
||||||
|
# This is required to set variable values again after disconnect.
|
||||||
|
if ( $self->{dbh} && $self->{dbh} == $dbh && $self->{dbh_set} && $self->{dbh_set} == $connection_id) {
|
||||||
|
PTDEBUG && _d($dbh, 'Already set dbh');
|
||||||
|
return $dbh;
|
||||||
|
}
|
||||||
|
|
||||||
if ( $hostname ) {
|
if ( $hostname ) {
|
||||||
$self->{hostname} = $hostname;
|
$self->{hostname} = $hostname;
|
||||||
}
|
}
|
||||||
@@ -191,7 +196,7 @@ sub set_dbh {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$self->{dbh} = $dbh;
|
$self->{dbh} = $dbh;
|
||||||
$self->{dbh_set} = 1;
|
$self->{dbh_set} = $connection_id;
|
||||||
return $dbh;
|
return $dbh;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,6 +348,19 @@ sub DESTROY {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# We have to create a wrapper around $dbh->ping() here due to
|
||||||
|
# https://github.com/perl5-dbi/DBD-mysql/issues/306
|
||||||
|
sub _ping() {
|
||||||
|
my ( $self, $dbh ) = @_;
|
||||||
|
if (!$dbh->ping()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
my $sql = 'SELECT CONNECTION_ID() as connection_id';
|
||||||
|
PTDEBUG && _d($dbh, $sql);
|
||||||
|
my ($connection_id) = $dbh->selectrow_array($sql);
|
||||||
|
return $self->{dbh_set} == $connection_id;
|
||||||
|
}
|
||||||
|
|
||||||
sub _d {
|
sub _d {
|
||||||
my ($package, undef, $line) = caller 0;
|
my ($package, undef, $line) = caller 0;
|
||||||
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
|
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
|
||||||
|
@@ -18,7 +18,7 @@
|
|||||||
# ###########################################################################
|
# ###########################################################################
|
||||||
package Percona::Toolkit;
|
package Percona::Toolkit;
|
||||||
|
|
||||||
our $VERSION = '3.5.1';
|
our $VERSION = '3.5.2';
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings FATAL => 'all';
|
use warnings FATAL => 'all';
|
||||||
|
@@ -197,7 +197,7 @@ sub generate_cmp_where {
|
|||||||
push @clause, "($val IS NULL OR $quo $type $val)";
|
push @clause, "($val IS NULL OR $quo $type $val)";
|
||||||
}
|
}
|
||||||
elsif ( $type =~ m/>/ ) {
|
elsif ( $type =~ m/>/ ) {
|
||||||
push @clause, "($val IS NULL AND $quo IS NOT NULL) OR ($quo $cmp $val)";
|
push @clause, "(($val IS NULL AND $quo IS NOT NULL) OR ($quo $cmp $val))";
|
||||||
}
|
}
|
||||||
else { # If $type =~ m/</ ) {
|
else { # If $type =~ m/</ ) {
|
||||||
push @clauses, "(($val IS NOT NULL AND $quo IS NULL) OR ($quo $cmp $val))";
|
push @clauses, "(($val IS NOT NULL AND $quo IS NULL) OR ($quo $cmp $val))";
|
||||||
|
@@ -389,8 +389,7 @@ sub get_keys {
|
|||||||
my $clustered_key = undef;
|
my $clustered_key = undef;
|
||||||
|
|
||||||
KEY:
|
KEY:
|
||||||
foreach my $key ( $ddl =~ m/^ ((?:[A-Z]+ )?KEY \(`[\s\S]*?`\)[\s\S]*?,?)$/gm ) {
|
foreach my $key ( $ddl =~ m/^ ((?:[A-Z]+ )?KEY [\s\S]*?\),?.*)$/gm ) {
|
||||||
|
|
||||||
# If you want foreign keys, use get_fks() below.
|
# If you want foreign keys, use get_fks() below.
|
||||||
next KEY if $key =~ m/FOREIGN/;
|
next KEY if $key =~ m/FOREIGN/;
|
||||||
|
|
||||||
@@ -407,7 +406,7 @@ sub get_keys {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Determine index type
|
# Determine index type
|
||||||
my ( $type, $cols ) = $key =~ m/(?:USING (\w+))? \(([\s\S]+?)\)/;
|
my ( $type, $cols ) = $key =~ m/(?:USING (\w+))? \(([\s\S]+)\)/;
|
||||||
my ( $special ) = $key =~ m/(FULLTEXT|SPATIAL)/;
|
my ( $special ) = $key =~ m/(FULLTEXT|SPATIAL)/;
|
||||||
$type = $type || $special || 'BTREE';
|
$type = $type || $special || 'BTREE';
|
||||||
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
|
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
|
||||||
|
@@ -8,8 +8,8 @@ SET @@GLOBAL.GTID_MODE = ON;
|
|||||||
|
|
||||||
CHANGE MASTER TO master_host='127.0.0.1', master_port=12345, master_user='msandbox', master_password='msandbox', master_auto_position=1 FOR CHANNEL 'masterchan1';
|
CHANGE MASTER TO master_host='127.0.0.1', master_port=12345, master_user='msandbox', master_password='msandbox', master_auto_position=1 FOR CHANNEL 'masterchan1';
|
||||||
|
|
||||||
-- CHANGE MASTER TO master_host='127.0.0.1', master_port=12346, master_user='msandbox', master_password='msandbox', master_auto_position=1 FOR CHANNEL 'masterchan2';
|
CHANGE MASTER TO master_host='127.0.0.1', master_port=12346, master_user='msandbox', master_password='msandbox', master_auto_position=1 FOR CHANNEL 'masterchan2';
|
||||||
|
|
||||||
START SLAVE for channel 'masterchan1';
|
START SLAVE for channel 'masterchan1';
|
||||||
-- START SLAVE for channel 'masterchan2';
|
START SLAVE for channel 'masterchan2';
|
||||||
|
|
||||||
|
@@ -128,9 +128,9 @@ is(
|
|||||||
),
|
),
|
||||||
q{`film_id`, `title`, CRC32(`description`), `release_year`, `language_id`, `original_language_id`,}
|
q{`film_id`, `title`, CRC32(`description`), `release_year`, `language_id`, `original_language_id`,}
|
||||||
.q{ `rental_duration`, `rental_rate`, `length`, `replacement_cost`, `rating`, `special_features`,}
|
.q{ `rental_duration`, `rental_rate`, `length`, `replacement_cost`, `rating`, `special_features`,}
|
||||||
.q{ UNIX_TIMESTAMP(`last_update`) AS `last_update`, SHA1(CONCAT_WS('#', `film_id`, `title`,}
|
.q{ UNIX_TIMESTAMP(`last_update`) AS `last_update`, SHA1(CONCAT_WS('#', `film_id`, convert(`title` using utf8mb4),}
|
||||||
.q{ CRC32(`description`), `release_year`, `language_id`, `original_language_id`, `rental_duration`,}
|
.q{ CRC32(`description`), `release_year`, `language_id`, `original_language_id`, `rental_duration`,}
|
||||||
.q{ `rental_rate`, `length`, `replacement_cost`, `rating`, `special_features`, }
|
.q{ `rental_rate`, `length`, `replacement_cost`, convert(`rating` using utf8mb4), convert(`special_features` using utf8mb4), }
|
||||||
.q{UNIX_TIMESTAMP(`last_update`), CONCAT(ISNULL(`description`), ISNULL(`release_year`), }
|
.q{UNIX_TIMESTAMP(`last_update`), CONCAT(ISNULL(`description`), ISNULL(`release_year`), }
|
||||||
.q{ISNULL(`original_language_id`), ISNULL(`length`), ISNULL(`rating`), ISNULL(`special_features`))))},
|
.q{ISNULL(`original_language_id`), ISNULL(`length`), ISNULL(`rating`), ISNULL(`special_features`))))},
|
||||||
'SHA1 query for sakila.film',
|
'SHA1 query for sakila.film',
|
||||||
@@ -180,7 +180,7 @@ is(
|
|||||||
tbl => $tbl,
|
tbl => $tbl,
|
||||||
func => 'SHA1',
|
func => 'SHA1',
|
||||||
),
|
),
|
||||||
q{`film_id`, `title`, SHA1(CONCAT_WS('%', `film_id`, `title`))},
|
q{`film_id`, `title`, SHA1(CONCAT_WS('%', `film_id`, convert(`title` using utf8mb4)))},
|
||||||
'Separator',
|
'Separator',
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -191,7 +191,7 @@ is(
|
|||||||
tbl => $tbl,
|
tbl => $tbl,
|
||||||
func => 'SHA1',
|
func => 'SHA1',
|
||||||
),
|
),
|
||||||
q{`film_id`, `title`, SHA1(CONCAT_WS('%', `film_id`, `title`))},
|
q{`film_id`, `title`, SHA1(CONCAT_WS('%', `film_id`, convert(`title` using utf8mb4)))},
|
||||||
'Bad separator',
|
'Bad separator',
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -204,7 +204,7 @@ is(
|
|||||||
cols => [qw(film_id title)],
|
cols => [qw(film_id title)],
|
||||||
sep => "'''",
|
sep => "'''",
|
||||||
),
|
),
|
||||||
q{`film_id`, `title`, SHA1(CONCAT_WS('#', `film_id`, `title`))},
|
q{`film_id`, `title`, SHA1(CONCAT_WS('#', `film_id`, convert(`title` using utf8mb4)))},
|
||||||
'Really bad separator',
|
'Really bad separator',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@@ -229,9 +229,9 @@ is (
|
|||||||
function => 'SHA1',
|
function => 'SHA1',
|
||||||
tbl_struct => $t,
|
tbl_struct => $t,
|
||||||
),
|
),
|
||||||
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`, }
|
q{`film_id`, `title`, CRC32(`description`) AS `description`, `release_year`, `language_id`, `original_language_id`, `rental_duration`, `rental_rate`, `length`, `replacement_cost`, `rating`, `special_features`, `last_update` + 0 AS `last_update`, }
|
||||||
. q{SHA1(CONCAT_WS('#', }
|
. q{SHA1(CONCAT_WS('#', }
|
||||||
. q{`film_id`, `title`, `description`, `release_year`, `language_id`, }
|
. q{`film_id`, `title`, CRC32(`description`), `release_year`, `language_id`, }
|
||||||
. q{`original_language_id`, `rental_duration`, `rental_rate`, `length`, }
|
. q{`original_language_id`, `rental_duration`, `rental_rate`, `length`, }
|
||||||
. q{`replacement_cost`, `rating`, `special_features`, `last_update` + 0, }
|
. q{`replacement_cost`, `rating`, `special_features`, `last_update` + 0, }
|
||||||
. q{CONCAT(ISNULL(`description`), ISNULL(`release_year`), }
|
. q{CONCAT(ISNULL(`description`), ISNULL(`release_year`), }
|
||||||
@@ -245,9 +245,9 @@ is (
|
|||||||
function => 'FNV_64',
|
function => 'FNV_64',
|
||||||
tbl_struct => $t,
|
tbl_struct => $t,
|
||||||
),
|
),
|
||||||
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`, }
|
q{`film_id`, `title`, CRC32(`description`) AS `description`, `release_year`, `language_id`, `original_language_id`, `rental_duration`, `rental_rate`, `length`, `replacement_cost`, `rating`, `special_features`, `last_update` + 0 AS `last_update`, }
|
||||||
. q{FNV_64(}
|
. q{FNV_64(}
|
||||||
. q{`film_id`, `title`, `description`, `release_year`, `language_id`, }
|
. q{`film_id`, `title`, CRC32(`description`), `release_year`, `language_id`, }
|
||||||
. q{`original_language_id`, `rental_duration`, `rental_rate`, `length`, }
|
. q{`original_language_id`, `rental_duration`, `rental_rate`, `length`, }
|
||||||
. q{`replacement_cost`, `rating`, `special_features`, `last_update` + 0)},
|
. q{`replacement_cost`, `rating`, `special_features`, `last_update` + 0)},
|
||||||
'FNV_64 query for sakila.film',
|
'FNV_64 query for sakila.film',
|
||||||
@@ -490,7 +490,7 @@ is (
|
|||||||
q{SELECT /*PROGRESS_COMMENT*//*CHUNK_NUM*/ COUNT(*) AS cnt, }
|
q{SELECT /*PROGRESS_COMMENT*//*CHUNK_NUM*/ COUNT(*) AS cnt, }
|
||||||
. q{COALESCE(RIGHT(MAX(@crc := CONCAT(LPAD(@cnt := @cnt + 1, 16, '0'), }
|
. q{COALESCE(RIGHT(MAX(@crc := CONCAT(LPAD(@cnt := @cnt + 1, 16, '0'), }
|
||||||
. q{SHA1(CONCAT(@crc, SHA1(CONCAT_WS('#', }
|
. q{SHA1(CONCAT(@crc, SHA1(CONCAT_WS('#', }
|
||||||
. q{`film_id`, `title`, `description`, `release_year`, `language_id`, }
|
. q{`film_id`, `title`, CRC32(`description`), `release_year`, `language_id`, }
|
||||||
. q{`original_language_id`, `rental_duration`, `rental_rate`, `length`, }
|
. q{`original_language_id`, `rental_duration`, `rental_rate`, `length`, }
|
||||||
. q{`replacement_cost`, `rating`, `special_features`, `last_update` + 0, }
|
. q{`replacement_cost`, `rating`, `special_features`, `last_update` + 0, }
|
||||||
. q{CONCAT(ISNULL(`description`), ISNULL(`release_year`), }
|
. q{CONCAT(ISNULL(`description`), ISNULL(`release_year`), }
|
||||||
@@ -514,7 +514,7 @@ is (
|
|||||||
q{SELECT /*PROGRESS_COMMENT*//*CHUNK_NUM*/ COUNT(*) AS cnt, }
|
q{SELECT /*PROGRESS_COMMENT*//*CHUNK_NUM*/ COUNT(*) AS cnt, }
|
||||||
. q{COALESCE(RIGHT(MAX(@crc := CONCAT(LPAD(@cnt := @cnt + 1, 16, '0'), }
|
. q{COALESCE(RIGHT(MAX(@crc := CONCAT(LPAD(@cnt := @cnt + 1, 16, '0'), }
|
||||||
. q{CONV(CAST(FNV_64(CONCAT(@crc, FNV_64(}
|
. q{CONV(CAST(FNV_64(CONCAT(@crc, FNV_64(}
|
||||||
. q{`film_id`, `title`, `description`, `release_year`, `language_id`, }
|
. q{`film_id`, `title`, CRC32(`description`), `release_year`, `language_id`, }
|
||||||
. q{`original_language_id`, `rental_duration`, `rental_rate`, `length`, }
|
. q{`original_language_id`, `rental_duration`, `rental_rate`, `length`, }
|
||||||
. q{`replacement_cost`, `rating`, `special_features`, `last_update` + 0}
|
. q{`replacement_cost`, `rating`, `special_features`, `last_update` + 0}
|
||||||
. q{))) AS UNSIGNED), 10, 16))), 16), 0) AS crc }
|
. q{))) AS UNSIGNED), 10, 16))), 16), 0) AS crc }
|
||||||
@@ -559,7 +559,7 @@ is (
|
|||||||
. q{SELECT ?, ?, /*CHUNK_NUM*/ ?, COUNT(*) AS cnt, }
|
. q{SELECT ?, ?, /*CHUNK_NUM*/ ?, COUNT(*) AS cnt, }
|
||||||
. q{COALESCE(RIGHT(MAX(@crc := CONCAT(LPAD(@cnt := @cnt + 1, 16, '0'), }
|
. q{COALESCE(RIGHT(MAX(@crc := CONCAT(LPAD(@cnt := @cnt + 1, 16, '0'), }
|
||||||
. q{SHA1(CONCAT(@crc, SHA1(CONCAT_WS('#', }
|
. q{SHA1(CONCAT(@crc, SHA1(CONCAT_WS('#', }
|
||||||
. q{`film_id`, `title`, `description`, `release_year`, `language_id`, }
|
. q{`film_id`, `title`, CRC32(`description`), `release_year`, `language_id`, }
|
||||||
. q{`original_language_id`, `rental_duration`, `rental_rate`, `length`, }
|
. q{`original_language_id`, `rental_duration`, `rental_rate`, `length`, }
|
||||||
. q{`replacement_cost`, `rating`, `special_features`, `last_update` + 0, }
|
. q{`replacement_cost`, `rating`, `special_features`, `last_update` + 0, }
|
||||||
. q{CONCAT(ISNULL(`description`), ISNULL(`release_year`), }
|
. q{CONCAT(ISNULL(`description`), ISNULL(`release_year`), }
|
||||||
|
@@ -419,7 +419,7 @@ is_deeply(
|
|||||||
. '= ? AND (? IS NULL OR `customer_id` >= ?)))',
|
. '= ? AND (? IS NULL OR `customer_id` >= ?)))',
|
||||||
'>' => '((`rental_date` > ?) OR (`rental_date` = ? AND `inventory_id` > ?) OR '
|
'>' => '((`rental_date` > ?) OR (`rental_date` = ? AND `inventory_id` > ?) OR '
|
||||||
. '(`rental_date` = ? AND `inventory_id` = ? AND ((? IS NULL AND `customer_id` IS NOT NULL) '
|
. '(`rental_date` = ? AND `inventory_id` = ? AND ((? IS NULL AND `customer_id` IS NOT NULL) '
|
||||||
. 'OR (`customer_id` > ?)))',
|
. 'OR (`customer_id` > ?))))',
|
||||||
# '((`rental_date` > ?) OR (`rental_date` = ? AND '
|
# '((`rental_date` > ?) OR (`rental_date` = ? AND '
|
||||||
#. '`inventory_id` > ?) OR (`rental_date` = ? AND `inventory_id` '
|
#. '`inventory_id` > ?) OR (`rental_date` = ? AND `inventory_id` '
|
||||||
# . '= ? AND ((? IS NULL AND `customer_id` IS NOT NULL) '
|
# . '= ? AND ((? IS NULL AND `customer_id` IS NOT NULL) '
|
||||||
@@ -469,7 +469,7 @@ is_deeply(
|
|||||||
index => 'rental_date',
|
index => 'rental_date',
|
||||||
where => '((`rental_date` > ?) OR (`rental_date` = ? AND `inventory_id` > ?) OR '
|
where => '((`rental_date` > ?) OR (`rental_date` = ? AND `inventory_id` > ?) OR '
|
||||||
. '(`rental_date` = ? AND `inventory_id` = ? AND ((? IS NULL AND `customer_id` IS NOT NULL) '
|
. '(`rental_date` = ? AND `inventory_id` = ? AND ((? IS NULL AND `customer_id` IS NOT NULL) '
|
||||||
. 'OR (`customer_id` > ?)))',
|
. 'OR (`customer_id` > ?))))',
|
||||||
# '((`rental_date` > ?) OR (`rental_date` = ? AND `inventory_id` > ?)'
|
# '((`rental_date` > ?) OR (`rental_date` = ? AND `inventory_id` > ?)'
|
||||||
#. ' OR (`rental_date` = ? AND `inventory_id` = ? AND '
|
#. ' OR (`rental_date` = ? AND `inventory_id` = ? AND '
|
||||||
#. '((? IS NULL AND `customer_id` IS NOT NULL) OR (`customer_id` > ?))))',
|
#. '((? IS NULL AND `customer_id` IS NOT NULL) OR (`customer_id` > ?))))',
|
||||||
@@ -481,7 +481,7 @@ is_deeply(
|
|||||||
. '= ? AND (? IS NULL OR `customer_id` >= ?)))',
|
. '= ? AND (? IS NULL OR `customer_id` >= ?)))',
|
||||||
'>' => '((`rental_date` > ?) OR (`rental_date` = ? AND `inventory_id` > ?) OR '
|
'>' => '((`rental_date` > ?) OR (`rental_date` = ? AND `inventory_id` > ?) OR '
|
||||||
. '(`rental_date` = ? AND `inventory_id` = ? AND ((? IS NULL AND `customer_id` IS NOT NULL) OR '
|
. '(`rental_date` = ? AND `inventory_id` = ? AND ((? IS NULL AND `customer_id` IS NOT NULL) OR '
|
||||||
. '(`customer_id` > ?)))',
|
. '(`customer_id` > ?))))',
|
||||||
# '((`rental_date` > ?) OR (`rental_date` = ? AND '
|
# '((`rental_date` > ?) OR (`rental_date` = ? AND '
|
||||||
#. '`inventory_id` > ?) OR (`rental_date` = ? AND `inventory_id` '
|
#. '`inventory_id` > ?) OR (`rental_date` = ? AND `inventory_id` '
|
||||||
#. '= ? AND ((? IS NULL AND `customer_id` IS NOT NULL) '
|
#. '= ? AND ((? IS NULL AND `customer_id` IS NOT NULL) '
|
||||||
@@ -517,7 +517,7 @@ is_deeply(
|
|||||||
return_date staff_id last_update)],
|
return_date staff_id last_update)],
|
||||||
index => 'rental_date',
|
index => 'rental_date',
|
||||||
where => '((`rental_date` > ?) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NOT NULL)'
|
where => '((`rental_date` > ?) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NOT NULL)'
|
||||||
. ' OR (`inventory_id` > ?)) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NULL) OR '
|
. ' OR (`inventory_id` > ?))) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NULL) OR '
|
||||||
. '(`inventory_id` = ?)) AND `customer_id` >= ?))',
|
. '(`inventory_id` = ?)) AND `customer_id` >= ?))',
|
||||||
# '((`rental_date` > ?) OR '
|
# '((`rental_date` > ?) OR '
|
||||||
#. '(`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NOT NULL) OR (`inventory_id` > ?)))'
|
#. '(`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NOT NULL) OR (`inventory_id` > ?)))'
|
||||||
@@ -528,14 +528,14 @@ is_deeply(
|
|||||||
rental_date inventory_id inventory_id customer_id)],
|
rental_date inventory_id inventory_id customer_id)],
|
||||||
boundaries => {
|
boundaries => {
|
||||||
'>=' => '((`rental_date` > ?) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NOT NULL) OR '
|
'>=' => '((`rental_date` > ?) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NOT NULL) OR '
|
||||||
. '(`inventory_id` > ?)) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NULL) OR '
|
. '(`inventory_id` > ?))) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NULL) OR '
|
||||||
. '(`inventory_id` = ?)) AND `customer_id` >= ?))',
|
. '(`inventory_id` = ?)) AND `customer_id` >= ?))',
|
||||||
# '((`rental_date` > ?) OR (`rental_date` = ? AND '
|
# '((`rental_date` > ?) OR (`rental_date` = ? AND '
|
||||||
#. '((? IS NULL AND `inventory_id` IS NOT NULL) OR (`inventory_id` '
|
#. '((? IS NULL AND `inventory_id` IS NOT NULL) OR (`inventory_id` '
|
||||||
#. '> ?))) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` '
|
#. '> ?))) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` '
|
||||||
#. 'IS NULL) OR (`inventory_id` = ?)) AND `customer_id` >= ?))',
|
#. 'IS NULL) OR (`inventory_id` = ?)) AND `customer_id` >= ?))',
|
||||||
'>' => '((`rental_date` > ?) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NOT NULL) OR '
|
'>' => '((`rental_date` > ?) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NOT NULL) OR '
|
||||||
. '(`inventory_id` > ?)) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NULL) OR '
|
. '(`inventory_id` > ?))) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NULL) OR '
|
||||||
. '(`inventory_id` = ?)) AND `customer_id` > ?))',
|
. '(`inventory_id` = ?)) AND `customer_id` > ?))',
|
||||||
# '((`rental_date` > ?) OR (`rental_date` = ? AND ((? IS NULL '
|
# '((`rental_date` > ?) OR (`rental_date` = ? AND ((? IS NULL '
|
||||||
#. 'AND `inventory_id` IS NOT NULL) OR (`inventory_id` > ?))) OR '
|
#. 'AND `inventory_id` IS NOT NULL) OR (`inventory_id` > ?))) OR '
|
||||||
@@ -572,7 +572,7 @@ is_deeply(
|
|||||||
return_date staff_id last_update)],
|
return_date staff_id last_update)],
|
||||||
index => 'rental_date',
|
index => 'rental_date',
|
||||||
where => '((`rental_date` > ?) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NOT NULL) OR '
|
where => '((`rental_date` > ?) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NOT NULL) OR '
|
||||||
. '(`inventory_id` > ?)) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NULL) OR '
|
. '(`inventory_id` > ?))) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NULL) OR '
|
||||||
. '(`inventory_id` = ?)) AND `customer_id` > ?))',
|
. '(`inventory_id` = ?)) AND `customer_id` > ?))',
|
||||||
# '((`rental_date` > ?) OR '
|
# '((`rental_date` > ?) OR '
|
||||||
#. '(`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NOT NULL) OR (`inventory_id` > ?)))'
|
#. '(`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NOT NULL) OR (`inventory_id` > ?)))'
|
||||||
@@ -583,14 +583,14 @@ is_deeply(
|
|||||||
rental_date inventory_id inventory_id customer_id)],
|
rental_date inventory_id inventory_id customer_id)],
|
||||||
boundaries => {
|
boundaries => {
|
||||||
'>=' => '((`rental_date` > ?) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NOT NULL) OR '
|
'>=' => '((`rental_date` > ?) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NOT NULL) OR '
|
||||||
. '(`inventory_id` > ?)) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NULL) OR '
|
. '(`inventory_id` > ?))) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NULL) OR '
|
||||||
. '(`inventory_id` = ?)) AND `customer_id` >= ?))',
|
. '(`inventory_id` = ?)) AND `customer_id` >= ?))',
|
||||||
# '((`rental_date` > ?) OR (`rental_date` = ? AND '
|
# '((`rental_date` > ?) OR (`rental_date` = ? AND '
|
||||||
#. '((? IS NULL AND `inventory_id` IS NOT NULL) OR (`inventory_id` '
|
#. '((? IS NULL AND `inventory_id` IS NOT NULL) OR (`inventory_id` '
|
||||||
#. '> ?))) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` '
|
#. '> ?))) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` '
|
||||||
#. 'IS NULL) OR (`inventory_id` = ?)) AND `customer_id` >= ?))',
|
#. 'IS NULL) OR (`inventory_id` = ?)) AND `customer_id` >= ?))',
|
||||||
'>' => '((`rental_date` > ?) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NOT NULL) OR '
|
'>' => '((`rental_date` > ?) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NOT NULL) OR '
|
||||||
. '(`inventory_id` > ?)) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NULL) OR '
|
. '(`inventory_id` > ?))) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NULL) OR '
|
||||||
. '(`inventory_id` = ?)) AND `customer_id` > ?))',
|
. '(`inventory_id` = ?)) AND `customer_id` > ?))',
|
||||||
# '((`rental_date` > ?) OR (`rental_date` = ? AND ((? IS NULL '
|
# '((`rental_date` > ?) OR (`rental_date` = ? AND ((? IS NULL '
|
||||||
#. 'AND `inventory_id` IS NOT NULL) OR (`inventory_id` > ?))) OR '
|
#. 'AND `inventory_id` IS NOT NULL) OR (`inventory_id` > ?))) OR '
|
||||||
|
@@ -28,6 +28,18 @@ my $tp = new TableParser(Quoter=>$q);
|
|||||||
my $tbl;
|
my $tbl;
|
||||||
my $sample = "t/lib/samples/tables/";
|
my $sample = "t/lib/samples/tables/";
|
||||||
|
|
||||||
|
my $transform_int = undef;
|
||||||
|
# In version 8.0 integer display width is deprecated and not shown in the outputs.
|
||||||
|
# So we need to transform our samples.
|
||||||
|
if ($sandbox_version ge '8.0') {
|
||||||
|
$transform_int = sub {
|
||||||
|
my $txt = slurp_file(shift);
|
||||||
|
$txt =~ s/int\(\d{1,2}\)/int/g;
|
||||||
|
$txt =~ s/utf8/utf8mb3/g;
|
||||||
|
print $txt;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
SKIP: {
|
SKIP: {
|
||||||
skip "Cannot connect to sandbox master", 2 unless $dbh;
|
skip "Cannot connect to sandbox master", 2 unless $dbh;
|
||||||
skip 'Sandbox master does not have the sakila database', 2
|
skip 'Sandbox master does not have the sakila database', 2
|
||||||
@@ -44,12 +56,14 @@ SKIP: {
|
|||||||
$ddl = $tp->ansi_to_legacy($ddl);
|
$ddl = $tp->ansi_to_legacy($ddl);
|
||||||
$ddl = "$ddl ENGINE=InnoDB AUTO_INCREMENT=201 DEFAULT CHARSET=utf8";
|
$ddl = "$ddl ENGINE=InnoDB AUTO_INCREMENT=201 DEFAULT CHARSET=utf8";
|
||||||
}
|
}
|
||||||
|
|
||||||
ok(
|
ok(
|
||||||
no_diff(
|
no_diff(
|
||||||
"$ddl\n",
|
"$ddl\n",
|
||||||
$sandbox_version ge '5.1' ? "$sample/sakila.actor"
|
$sandbox_version ge '5.1' ? "$sample/sakila.actor"
|
||||||
: "$sample/sakila.actor-5.0",
|
: "$sample/sakila.actor-5.0",
|
||||||
cmd_output => 1,
|
cmd_output => 1,
|
||||||
|
transform_sample => $transform_int
|
||||||
),
|
),
|
||||||
"get_create_table(sakila.actor)"
|
"get_create_table(sakila.actor)"
|
||||||
);
|
);
|
||||||
|
@@ -28,7 +28,7 @@ elsif ( !$slave_dbh ) {
|
|||||||
} elsif ($sandbox_version lt '5.7') {
|
} elsif ($sandbox_version lt '5.7') {
|
||||||
plan skip_all => 'Only on MySQL 5.7+';
|
plan skip_all => 'Only on MySQL 5.7+';
|
||||||
} else {
|
} else {
|
||||||
plan tests => 4;
|
plan tests => 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
my ($master1_dbh, $master1_dsn) = $sb->start_sandbox(
|
my ($master1_dbh, $master1_dsn) = $sb->start_sandbox(
|
||||||
@@ -76,10 +76,19 @@ $output = output(
|
|||||||
sub { $exit_status = pt_archiver::main(@args) },
|
sub { $exit_status = pt_archiver::main(@args) },
|
||||||
stderr => 1,
|
stderr => 1,
|
||||||
);
|
);
|
||||||
is(
|
diag("Exit status: $exit_status") if ($exit_status);
|
||||||
|
diag($output);
|
||||||
|
|
||||||
|
isnt(
|
||||||
$exit_status,
|
$exit_status,
|
||||||
0,
|
0,
|
||||||
'No need of channel name since there is only one master',
|
'Must specify a channel name',
|
||||||
|
);
|
||||||
|
|
||||||
|
like (
|
||||||
|
$output,
|
||||||
|
qr/"channel" was not specified/,
|
||||||
|
'Message saying channel name must be specified'
|
||||||
);
|
);
|
||||||
|
|
||||||
push @args, ('--channel', 'masterchan1');
|
push @args, ('--channel', 'masterchan1');
|
||||||
|
@@ -71,13 +71,22 @@ sub reset_repl_db {
|
|||||||
# 1
|
# 1
|
||||||
# We need to remove mysql.plugin and percona_test.checksums tables from the
|
# We need to remove mysql.plugin and percona_test.checksums tables from the
|
||||||
# result and the sample, because they have different number of rows than default
|
# result and the sample, because they have different number of rows than default
|
||||||
# if run test with enabled MyRocks or TokuDB SE
|
# if run test with enabled MyRocks or TokuDB SE.
|
||||||
ok(
|
# We also need to remove mysql.global_grants because it contains dynamic privileges
|
||||||
|
# that could be modified by other tests. At the same time, privileges are not removed
|
||||||
|
# from this table after they have been added, so we cannot remove them when wipe cleaning
|
||||||
|
# sandbox. See https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html#static-dynamic-privileges
|
||||||
|
|
||||||
|
# This test often fails if run after other tests, we need to see what is wrong
|
||||||
|
# So we will re-run failed code if test does not pass.
|
||||||
|
my $cmd = sub { pt_table_checksum::main(@args) };
|
||||||
|
|
||||||
|
diag(output($cmd)) if not ok(
|
||||||
no_diff(
|
no_diff(
|
||||||
sub { pt_table_checksum::main(@args) },
|
$cmd,
|
||||||
"$sample/default-results-$sandbox_version.txt",
|
"$sample/default-results-$sandbox_version.txt",
|
||||||
sed_out => '\'/mysql.plugin$/d; /percona_test.checksums$/d\'',
|
sed_out => '\'/mysql.plugin$/d; /percona_test.checksums$/d\'',
|
||||||
post_pipe => 'sed \'/mysql.plugin$/d; /percona_test.checksums$/d\' | ' .
|
post_pipe => 'sed \'/mysql.plugin$/d; /percona_test.checksums$/d; /mysql.global_grants$/d\' | ' .
|
||||||
'awk \'{print $2 " " $3 " " $4 " " $7 " " $9}\'',
|
'awk \'{print $2 " " $3 " " $4 " " $7 " " $9}\'',
|
||||||
),
|
),
|
||||||
"Default checksum"
|
"Default checksum"
|
||||||
|
@@ -107,6 +107,7 @@ is(
|
|||||||
# #############################################################################
|
# #############################################################################
|
||||||
# Done.
|
# Done.
|
||||||
# #############################################################################
|
# #############################################################################
|
||||||
|
$master_dbh->do('DROP FUNCTION IF EXISTS fnv_64');
|
||||||
$sb->wipe_clean($master_dbh);
|
$sb->wipe_clean($master_dbh);
|
||||||
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
|
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
|
||||||
exit;
|
exit;
|
||||||
|
@@ -91,7 +91,8 @@ like(
|
|||||||
"Checksumming continues after waiting for slave lag"
|
"Checksumming continues after waiting for slave lag"
|
||||||
);
|
);
|
||||||
|
|
||||||
is(
|
# This test randomly fails, we need to know the reason
|
||||||
|
diag($output) if not is(
|
||||||
PerconaTest::count_checksum_results($output, 'errors'),
|
PerconaTest::count_checksum_results($output, 'errors'),
|
||||||
0,
|
0,
|
||||||
"No errors after waiting for slave lag"
|
"No errors after waiting for slave lag"
|
||||||
|
@@ -7,7 +7,6 @@ ERRORS DIFFS ROWS SKIPPED TABLE
|
|||||||
0 0 0 0 mysql.default_roles
|
0 0 0 0 mysql.default_roles
|
||||||
0 1 2 0 mysql.engine_cost
|
0 1 2 0 mysql.engine_cost
|
||||||
0 0 0 0 mysql.func
|
0 0 0 0 mysql.func
|
||||||
0 0 85 0 mysql.global_grants
|
|
||||||
0 0 53 0 mysql.help_category
|
0 0 53 0 mysql.help_category
|
||||||
0 0 985 0 mysql.help_keyword
|
0 0 985 0 mysql.help_keyword
|
||||||
0 0 2043 0 mysql.help_relation
|
0 0 2043 0 mysql.help_relation
|
||||||
|
@@ -8,7 +8,7 @@ REPLACE INTO `percona`.`checksums` (db, tbl, chunk, chunk_index, lower_boundary,
|
|||||||
|
|
||||||
REPLACE INTO `percona`.`checksums` (db, tbl, chunk, chunk_index, lower_boundary, upper_boundary, this_cnt, this_crc) SELECT ?, ?, ?, ?, ?, ?, COUNT(*), '0' FROM `osc`.`t2` FORCE INDEX(`c`) WHERE (((? IS NOT NULL AND `c` IS NULL) OR (`c` < ?))) ORDER BY `c` /*past lower chunk*/
|
REPLACE INTO `percona`.`checksums` (db, tbl, chunk, chunk_index, lower_boundary, upper_boundary, this_cnt, this_crc) SELECT ?, ?, ?, ?, ?, ?, COUNT(*), '0' FROM `osc`.`t2` FORCE INDEX(`c`) WHERE (((? IS NOT NULL AND `c` IS NULL) OR (`c` < ?))) ORDER BY `c` /*past lower chunk*/
|
||||||
|
|
||||||
REPLACE INTO `percona`.`checksums` (db, tbl, chunk, chunk_index, lower_boundary, upper_boundary, this_cnt, this_crc) SELECT ?, ?, ?, ?, ?, ?, COUNT(*), '0' FROM `osc`.`t2` FORCE INDEX(`c`) WHERE (((? IS NULL AND `c` IS NOT NULL) OR (`c` > ?))) ORDER BY `c` /*past upper chunk*/
|
REPLACE INTO `percona`.`checksums` (db, tbl, chunk, chunk_index, lower_boundary, upper_boundary, this_cnt, this_crc) SELECT ?, ?, ?, ?, ?, ?, COUNT(*), '0' FROM `osc`.`t2` FORCE INDEX(`c`) WHERE ((((? IS NULL AND `c` IS NOT NULL) OR (`c` > ?)))) ORDER BY `c` /*past upper chunk*/
|
||||||
|
|
||||||
SELECT /*!40001 SQL_NO_CACHE */ `c`, `c` FROM `osc`.`t2` FORCE INDEX(`c`) WHERE (((? IS NULL OR `c` >= ?))) ORDER BY `c` LIMIT ?, 2 /*next chunk boundary*/
|
SELECT /*!40001 SQL_NO_CACHE */ `c`, `c` FROM `osc`.`t2` FORCE INDEX(`c`) WHERE (((? IS NULL OR `c` >= ?))) ORDER BY `c` LIMIT ?, 2 /*next chunk boundary*/
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user