Compare commits

..

5 Commits

Author SHA1 Message Date
Sveta Smirnova
c1ba474a84 Updated version properly (#611)
* Release v3.5.1 Go 1.20 and upgrade deps

* Release v3.5.2

* PT-2193 Release Notes 3.5.2 (#610)

modified:   Changelog
	modified:   Makefile.PL
	modified:   config/sphinx-build/conf.py
	modified:   docs/release_notes.rst
	new file:   docs/rn.3-5-2.txt

* Updated version properly

---------

Co-authored-by: Carlos Salguero <carlos.salguero@percona.com>
Co-authored-by: Alina Derkach <alina.derkach@percona.com>
2023-03-28 12:28:10 +03:00
Alina Derkach
74e186f524 PT-2193 Release Notes 3.5.2 (#610)
modified:   Changelog
	modified:   Makefile.PL
	modified:   config/sphinx-build/conf.py
	modified:   docs/release_notes.rst
	new file:   docs/rn.3-5-2.txt
2023-03-27 19:15:03 +03:00
Carlos Salguero
e9d522cc58 Release v3.5.2 2023-03-27 09:08:42 -03:00
Carlos Salguero
4b5940807f Merge branch 'release-v3.5.1' of percona.github.com:percona/percona-toolkit into release-v3.5.2 2023-03-27 08:42:23 -03:00
Sveta Smirnova
642253ce52 PT-2156 Fix tests for lib (#606)
* PT-2156 - Fix tests for lib

- Fixed tests broken for lib/TableParser.pm after fix for PT-1059
- Updated tests for lib/TableParser.pm that are broken due to SHOW CREATE TABLE output format change in 8.0
- Updated modules for all tools that use lib/TableParser.pm

* Revert "Fixed pt-archiver tests"

This reverts commit a3ab87b12e.

This commit wa needed, because removed code in sandbox/slave_channels.sql broked the test. Proper fix would be to do not remove channel names rather than chaging the test. So revertig it.

* PT-2156 - Fix tests for lib

- Updated test t/lib/TableChecksum.t so it reflects changes, introduced in the fix for PT-2016
- Updated test t/lib/RowChecksum.t so it reflects changes added to in the fix for PT-2138: UTF8 support
- Uncommented SQL in sandbox/slave_channels.sql that made t/lib/MasterSlave.t to fail
- Added check for undef into t/pt-archiver/archive_using_channels.t
- Updated lib/Cxn.pm so it uses $dbh->{Active} after issue with the ping() call, reported at https://github.com/perl5-dbi/DBD-mysql/issues/306

* PT-2156 - Fix tests for lib

- Impoved the fix for PT-2016, so it does not files with keys with USING keyword
- Added brackets to expression in lib/TableNibbler.pm, so it does not crap query wit many indexes with OR keyword
- Adjusted test t/lib/TableNibbler.t, so it reflects above chages
- Modified lib/Cxn.pm, so it has workaround for https://github.com/perl5-dbi/DBD-mysql/issues/306 , introduced in DBD::mysql 4.0.50
- Updated tests: added debugging code and cleanups
- Updated modules for tools
2023-03-27 14:18:26 +03:00
53 changed files with 647 additions and 290 deletions

View File

@@ -1,5 +1,38 @@
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
* Feature PT-2134: Add support for PostgreSQL and MySQL operators in pt-k8s-debug-collector

View File

@@ -2,7 +2,7 @@ use ExtUtils::MakeMaker;
WriteMakefile(
NAME => 'Percona::Toolkit',
VERSION => '3.5.1',
VERSION => '3.5.2',
EXE_FILES => [ <bin/*> ],
MAN1PODS => {
'docs/percona-toolkit.pod' => 'blib/man1/percona-toolkit.1p',

View File

@@ -1364,6 +1364,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-align 3.5.1
pt-align 3.5.2
=cut

View File

@@ -45,7 +45,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.5.1';
our $VERSION = '3.5.2';
use strict;
use warnings FATAL => 'all';
@@ -2139,8 +2139,7 @@ sub get_keys {
my $clustered_key = undef;
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/;
my $key_ddl = $key;
@@ -2150,7 +2149,7 @@ sub get_keys {
$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)/;
$type = $type || $special || 'BTREE';
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
@@ -3221,7 +3220,7 @@ sub generate_cmp_where {
push @clause, "($val IS NULL OR $quo $type $val)";
}
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/</ ) {
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 $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} ) {
$dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
$self->{asked_for_pass} = 1;
@@ -4630,19 +4629,20 @@ sub connect {
sub set_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');
$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);
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);
if ( $self->{dbh} && $self->{dbh} == $dbh && $self->{dbh_set} && $self->{dbh_set} == $connection_id) {
PTDEBUG && _d($dbh, 'Already set dbh');
return $dbh;
}
if ( $hostname ) {
$self->{hostname} = $hostname;
}
@@ -4657,7 +4657,7 @@ sub set_dbh {
}
$self->{dbh} = $dbh;
$self->{dbh_set} = 1;
$self->{dbh_set} = $connection_id;
return $dbh;
}
@@ -4783,6 +4783,17 @@ sub DESTROY {
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 {
my ($package, undef, $line) = caller 0;
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
@@ -8767,6 +8778,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-archiver 3.5.1
pt-archiver 3.5.2
=cut

View File

@@ -43,7 +43,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.5.1';
our $VERSION = '3.5.2';
use strict;
use warnings FATAL => 'all';
@@ -2368,7 +2368,7 @@ sub connect {
my $dp = $self->{DSNParser};
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} ) {
$dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
$self->{asked_for_pass} = 1;
@@ -2397,19 +2397,20 @@ sub connect {
sub set_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');
$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);
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);
if ( $self->{dbh} && $self->{dbh} == $dbh && $self->{dbh_set} && $self->{dbh_set} == $connection_id) {
PTDEBUG && _d($dbh, 'Already set dbh');
return $dbh;
}
if ( $hostname ) {
$self->{hostname} = $hostname;
}
@@ -2424,7 +2425,7 @@ sub set_dbh {
}
$self->{dbh} = $dbh;
$self->{dbh_set} = 1;
$self->{dbh_set} = $connection_id;
return $dbh;
}
@@ -2550,6 +2551,17 @@ sub DESTROY {
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 {
my ($package, undef, $line) = caller 0;
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
@@ -5999,6 +6011,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-config-diff 3.5.1
pt-config-diff 3.5.2
=cut

View File

@@ -42,7 +42,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.5.1';
our $VERSION = '3.5.2';
use strict;
use warnings FATAL => 'all';
@@ -2712,7 +2712,7 @@ sub connect {
my $dp = $self->{DSNParser};
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} ) {
$dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
$self->{asked_for_pass} = 1;
@@ -2741,19 +2741,20 @@ sub connect {
sub set_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');
$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);
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);
if ( $self->{dbh} && $self->{dbh} == $dbh && $self->{dbh_set} && $self->{dbh_set} == $connection_id) {
PTDEBUG && _d($dbh, 'Already set dbh');
return $dbh;
}
if ( $hostname ) {
$self->{hostname} = $hostname;
}
@@ -2768,7 +2769,7 @@ sub set_dbh {
}
$self->{dbh} = $dbh;
$self->{dbh_set} = 1;
$self->{dbh_set} = $connection_id;
return $dbh;
}
@@ -2894,6 +2895,17 @@ sub DESTROY {
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 {
my ($package, undef, $line) = caller 0;
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
@@ -5776,6 +5788,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-deadlock-logger 3.5.1
pt-deadlock-logger 3.5.2
=cut

View File

@@ -38,7 +38,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.5.1';
our $VERSION = '3.5.2';
use strict;
use warnings FATAL => 'all';
@@ -5692,6 +5692,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-diskstats 3.5.1
pt-diskstats 3.5.2
=cut

View File

@@ -39,7 +39,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.5.1';
our $VERSION = '3.5.2';
use strict;
use warnings FATAL => 'all';
@@ -345,7 +345,7 @@ sub parse {
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;
PTDEBUG && _d('Table cols:', join(', ', map { "`$_`" } @cols));
@@ -526,8 +526,7 @@ sub get_keys {
my $clustered_key = undef;
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/;
my $key_ddl = $key;
@@ -537,7 +536,7 @@ sub get_keys {
$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)/;
$type = $type || $special || 'BTREE';
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
@@ -5787,6 +5786,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-duplicate-key-checker 3.5.1
pt-duplicate-key-checker 3.5.2
=cut

View File

@@ -1708,6 +1708,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-fifo-split 3.5.1
pt-fifo-split 3.5.2
=cut

View File

@@ -35,7 +35,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.5.1';
our $VERSION = '3.5.2';
use strict;
use warnings FATAL => 'all';
@@ -1897,7 +1897,7 @@ sub parse {
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;
PTDEBUG && _d('Table cols:', join(', ', map { "`$_`" } @cols));
@@ -2078,8 +2078,7 @@ sub get_keys {
my $clustered_key = undef;
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/;
my $key_ddl = $key;
@@ -2089,7 +2088,7 @@ sub get_keys {
$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)/;
$type = $type || $special || 'BTREE';
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
@@ -5202,6 +5201,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-find 3.5.1
pt-find 3.5.2
=cut

View File

@@ -2271,6 +2271,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-fingerprint 3.5.1
pt-fingerprint 3.5.2
=cut

View File

@@ -37,7 +37,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.5.1';
our $VERSION = '3.5.2';
use strict;
use warnings FATAL => 'all';
@@ -1866,7 +1866,7 @@ sub connect {
my $dp = $self->{DSNParser};
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} ) {
$dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
$self->{asked_for_pass} = 1;
@@ -1895,19 +1895,20 @@ sub connect {
sub set_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');
$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);
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);
if ( $self->{dbh} && $self->{dbh} == $dbh && $self->{dbh_set} && $self->{dbh_set} == $connection_id) {
PTDEBUG && _d($dbh, 'Already set dbh');
return $dbh;
}
if ( $hostname ) {
$self->{hostname} = $hostname;
}
@@ -1922,7 +1923,7 @@ sub set_dbh {
}
$self->{dbh} = $dbh;
$self->{dbh_set} = 1;
$self->{dbh_set} = $connection_id;
return $dbh;
}
@@ -2048,6 +2049,17 @@ sub DESTROY {
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 {
my ($package, undef, $line) = caller 0;
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
@@ -4763,6 +4775,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-fk-error-logger 3.5.1
pt-fk-error-logger 3.5.2
=cut

View File

@@ -44,7 +44,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.5.1';
our $VERSION = '3.5.2';
use strict;
use warnings FATAL => 'all';
@@ -170,6 +170,7 @@ sub get_slaves {
dsn => $dsn,
slave_user => $o->got('slave-user') ? $o->get('slave-user') : '',
slave_password => $o->got('slave-password') ? $o->get('slave-password') : '',
slaves => $args{slaves},
callback => sub {
my ( $dsn, $dbh, $level, $parent ) = @_;
return unless $level;
@@ -246,16 +247,29 @@ sub recurse_to_slaves {
PTDEBUG && _d("Slave password set");
}
my $dbh;
eval {
$dbh = $args->{dbh} || $dp->get_dbh(
$dp->get_cxn_params($slave_dsn), { AutoCommit => 1 });
PTDEBUG && _d('Connected to', $dp->as_string($slave_dsn));
};
if ( $EVAL_ERROR ) {
print STDERR "Cannot connect to ", $dp->as_string($slave_dsn), "\n"
or die "Cannot print: $OS_ERROR";
return;
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 {
$dbh = $dp->get_dbh(
$dp->get_cxn_params($slave_dsn), { AutoCommit => 1 });
PTDEBUG && _d('Connected to', $dp->as_string($slave_dsn));
};
if ( $EVAL_ERROR ) {
print STDERR "Cannot connect to ", $dp->as_string($slave_dsn), ": ", $EVAL_ERROR, "\n"
or die "Cannot print: $OS_ERROR";
return;
}
}
}
my $sql = 'SELECT @@SERVER_ID';
@@ -3624,7 +3638,7 @@ sub parse {
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;
PTDEBUG && _d('Table cols:', join(', ', map { "`$_`" } @cols));
@@ -3805,8 +3819,7 @@ sub get_keys {
my $clustered_key = undef;
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/;
my $key_ddl = $key;
@@ -3816,7 +3829,7 @@ sub get_keys {
$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)/;
$type = $type || $special || 'BTREE';
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
@@ -7460,6 +7473,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-heartbeat 3.5.1
pt-heartbeat 3.5.2
=cut

View File

@@ -45,7 +45,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.5.1';
our $VERSION = '3.5.2';
use strict;
use warnings FATAL => 'all';
@@ -3149,7 +3149,7 @@ sub parse {
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;
PTDEBUG && _d('Table cols:', join(', ', map { "`$_`" } @cols));
@@ -3330,8 +3330,7 @@ sub get_keys {
my $clustered_key = undef;
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/;
my $key_ddl = $key;
@@ -3341,7 +3340,7 @@ sub get_keys {
$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)/;
$type = $type || $special || 'BTREE';
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
@@ -7732,6 +7731,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-index-usage 3.5.1
pt-index-usage 3.5.2
=cut

View File

@@ -1132,7 +1132,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-ioprofile 3.5.1
pt-ioprofile 3.5.2
=cut

View File

@@ -47,7 +47,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.5.1';
our $VERSION = '3.5.2';
use strict;
use warnings FATAL => 'all';
@@ -3012,7 +3012,7 @@ sub parse {
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;
PTDEBUG && _d('Table cols:', join(', ', map { "`$_`" } @cols));
@@ -3193,8 +3193,7 @@ sub get_keys {
my $clustered_key = undef;
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/;
my $key_ddl = $key;
@@ -3204,7 +3203,7 @@ sub get_keys {
$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)/;
$type = $type || $special || 'BTREE';
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
@@ -3951,6 +3950,7 @@ sub get_slaves {
dsn => $dsn,
slave_user => $o->got('slave-user') ? $o->get('slave-user') : '',
slave_password => $o->got('slave-password') ? $o->get('slave-password') : '',
slaves => $args{slaves},
callback => sub {
my ( $dsn, $dbh, $level, $parent ) = @_;
return unless $level;
@@ -4027,16 +4027,29 @@ sub recurse_to_slaves {
PTDEBUG && _d("Slave password set");
}
my $dbh;
eval {
$dbh = $args->{dbh} || $dp->get_dbh(
$dp->get_cxn_params($slave_dsn), { AutoCommit => 1 });
PTDEBUG && _d('Connected to', $dp->as_string($slave_dsn));
};
if ( $EVAL_ERROR ) {
print STDERR "Cannot connect to ", $dp->as_string($slave_dsn), "\n"
or die "Cannot print: $OS_ERROR";
return;
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 {
$dbh = $dp->get_dbh(
$dp->get_cxn_params($slave_dsn), { AutoCommit => 1 });
PTDEBUG && _d('Connected to', $dp->as_string($slave_dsn));
};
if ( $EVAL_ERROR ) {
print STDERR "Cannot connect to ", $dp->as_string($slave_dsn), ": ", $EVAL_ERROR, "\n"
or die "Cannot print: $OS_ERROR";
return;
}
}
}
my $sql = 'SELECT @@SERVER_ID';
@@ -5402,7 +5415,7 @@ sub connect {
my $dp = $self->{DSNParser};
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} ) {
$dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
$self->{asked_for_pass} = 1;
@@ -5431,19 +5444,20 @@ sub connect {
sub set_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');
$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);
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);
if ( $self->{dbh} && $self->{dbh} == $dbh && $self->{dbh_set} && $self->{dbh_set} == $connection_id) {
PTDEBUG && _d($dbh, 'Already set dbh');
return $dbh;
}
if ( $hostname ) {
$self->{hostname} = $hostname;
}
@@ -5458,7 +5472,7 @@ sub set_dbh {
}
$self->{dbh} = $dbh;
$self->{dbh_set} = 1;
$self->{dbh_set} = $connection_id;
return $dbh;
}
@@ -5584,6 +5598,17 @@ sub DESTROY {
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 {
my ($package, undef, $line) = caller 0;
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
@@ -8734,6 +8759,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-kill 3.5.1
pt-kill 3.5.2
=cut

View File

@@ -808,7 +808,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-mext 3.5.1
pt-mext 3.5.2
=cut

View File

@@ -3325,7 +3325,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-mysql-summary 3.5.1
pt-mysql-summary 3.5.2
=cut

View File

@@ -56,7 +56,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.5.1';
our $VERSION = '3.5.2';
use strict;
use warnings FATAL => 'all';
@@ -3102,7 +3102,7 @@ sub generate_cmp_where {
push @clause, "($val IS NULL OR $quo $type $val)";
}
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/</ ) {
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;
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/;
my $key_ddl = $key;
@@ -3520,7 +3519,7 @@ sub get_keys {
$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)/;
$type = $type || $special || 'BTREE';
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
@@ -3955,7 +3954,7 @@ sub connect {
my $dp = $self->{DSNParser};
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} ) {
$dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
$self->{asked_for_pass} = 1;
@@ -3984,19 +3983,20 @@ sub connect {
sub set_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');
$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);
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);
if ( $self->{dbh} && $self->{dbh} == $dbh && $self->{dbh_set} && $self->{dbh_set} == $connection_id) {
PTDEBUG && _d($dbh, 'Already set dbh');
return $dbh;
}
if ( $hostname ) {
$self->{hostname} = $hostname;
}
@@ -4011,7 +4011,7 @@ sub set_dbh {
}
$self->{dbh} = $dbh;
$self->{dbh_set} = 1;
$self->{dbh_set} = $connection_id;
return $dbh;
}
@@ -4137,6 +4137,17 @@ sub DESTROY {
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 {
my ($package, undef, $line) = caller 0;
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
@@ -13482,6 +13493,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-online-schema-change 3.5.1
pt-online-schema-change 3.5.2
=cut

View File

@@ -901,7 +901,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-pmp 3.5.1
pt-pmp 3.5.2
=cut

View File

@@ -64,7 +64,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.5.1';
our $VERSION = '3.5.2';
use strict;
use warnings FATAL => 'all';
@@ -8894,7 +8894,7 @@ sub parse {
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;
PTDEBUG && _d('Table cols:', join(', ', map { "`$_`" } @cols));
@@ -9075,8 +9075,7 @@ sub get_keys {
my $clustered_key = undef;
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/;
my $key_ddl = $key;
@@ -9086,7 +9085,7 @@ sub get_keys {
$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)/;
$type = $type || $special || 'BTREE';
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
@@ -10539,6 +10538,7 @@ sub get_slaves {
dsn => $dsn,
slave_user => $o->got('slave-user') ? $o->get('slave-user') : '',
slave_password => $o->got('slave-password') ? $o->get('slave-password') : '',
slaves => $args{slaves},
callback => sub {
my ( $dsn, $dbh, $level, $parent ) = @_;
return unless $level;
@@ -10615,16 +10615,29 @@ sub recurse_to_slaves {
PTDEBUG && _d("Slave password set");
}
my $dbh;
eval {
$dbh = $args->{dbh} || $dp->get_dbh(
$dp->get_cxn_params($slave_dsn), { AutoCommit => 1 });
PTDEBUG && _d('Connected to', $dp->as_string($slave_dsn));
};
if ( $EVAL_ERROR ) {
print STDERR "Cannot connect to ", $dp->as_string($slave_dsn), "\n"
or die "Cannot print: $OS_ERROR";
return;
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 {
$dbh = $dp->get_dbh(
$dp->get_cxn_params($slave_dsn), { AutoCommit => 1 });
PTDEBUG && _d('Connected to', $dp->as_string($slave_dsn));
};
if ( $EVAL_ERROR ) {
print STDERR "Cannot connect to ", $dp->as_string($slave_dsn), ": ", $EVAL_ERROR, "\n"
or die "Cannot print: $OS_ERROR";
return;
}
}
}
my $sql = 'SELECT @@SERVER_ID';
@@ -16977,6 +16990,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-query-digest 3.5.1
pt-query-digest 3.5.2
=cut

View File

@@ -2673,6 +2673,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-show-grants 3.5.1
pt-show-grants 3.5.2
=cut

View File

@@ -1249,7 +1249,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-sift 3.5.1
pt-sift 3.5.2
=cut

View File

@@ -40,7 +40,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.5.1';
our $VERSION = '3.5.2';
use strict;
use warnings FATAL => 'all';
@@ -5061,6 +5061,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-slave-delay 3.5.1
pt-slave-delay 3.5.2
=cut

View File

@@ -2306,6 +2306,7 @@ sub get_slaves {
dsn => $dsn,
slave_user => $o->got('slave-user') ? $o->get('slave-user') : '',
slave_password => $o->got('slave-password') ? $o->get('slave-password') : '',
slaves => $args{slaves},
callback => sub {
my ( $dsn, $dbh, $level, $parent ) = @_;
return unless $level;
@@ -2382,16 +2383,29 @@ sub recurse_to_slaves {
PTDEBUG && _d("Slave password set");
}
my $dbh;
eval {
$dbh = $args->{dbh} || $dp->get_dbh(
$dp->get_cxn_params($slave_dsn), { AutoCommit => 1 });
PTDEBUG && _d('Connected to', $dp->as_string($slave_dsn));
};
if ( $EVAL_ERROR ) {
print STDERR "Cannot connect to ", $dp->as_string($slave_dsn), "\n"
or die "Cannot print: $OS_ERROR";
return;
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 {
$dbh = $dp->get_dbh(
$dp->get_cxn_params($slave_dsn), { AutoCommit => 1 });
PTDEBUG && _d('Connected to', $dp->as_string($slave_dsn));
};
if ( $EVAL_ERROR ) {
print STDERR "Cannot connect to ", $dp->as_string($slave_dsn), ": ", $EVAL_ERROR, "\n"
or die "Cannot print: $OS_ERROR";
return;
}
}
}
my $sql = 'SELECT @@SERVER_ID';
@@ -4581,6 +4595,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-slave-find 3.5.1
pt-slave-find 3.5.2
=cut

View File

@@ -41,7 +41,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.5.1';
our $VERSION = '3.5.2';
use strict;
use warnings FATAL => 'all';
@@ -2717,6 +2717,7 @@ sub get_slaves {
dsn => $dsn,
slave_user => $o->got('slave-user') ? $o->get('slave-user') : '',
slave_password => $o->got('slave-password') ? $o->get('slave-password') : '',
slaves => $args{slaves},
callback => sub {
my ( $dsn, $dbh, $level, $parent ) = @_;
return unless $level;
@@ -2793,16 +2794,29 @@ sub recurse_to_slaves {
PTDEBUG && _d("Slave password set");
}
my $dbh;
eval {
$dbh = $args->{dbh} || $dp->get_dbh(
$dp->get_cxn_params($slave_dsn), { AutoCommit => 1 });
PTDEBUG && _d('Connected to', $dp->as_string($slave_dsn));
};
if ( $EVAL_ERROR ) {
print STDERR "Cannot connect to ", $dp->as_string($slave_dsn), "\n"
or die "Cannot print: $OS_ERROR";
return;
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 {
$dbh = $dp->get_dbh(
$dp->get_cxn_params($slave_dsn), { AutoCommit => 1 });
PTDEBUG && _d('Connected to', $dp->as_string($slave_dsn));
};
if ( $EVAL_ERROR ) {
print STDERR "Cannot connect to ", $dp->as_string($slave_dsn), ": ", $EVAL_ERROR, "\n"
or die "Cannot print: $OS_ERROR";
return;
}
}
}
my $sql = 'SELECT @@SERVER_ID';
@@ -6232,6 +6246,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-slave-restart 3.5.1
pt-slave-restart 3.5.2
=cut

View File

@@ -2564,7 +2564,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-stalk 3.5.1
pt-stalk 3.5.2
=cut

View File

@@ -2769,7 +2769,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-summary 3.5.1
pt-summary 3.5.2
=cut

View File

@@ -58,7 +58,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.5.1';
our $VERSION = '3.5.2';
use strict;
use warnings FATAL => 'all';
@@ -3673,7 +3673,7 @@ sub connect {
my $dp = $self->{DSNParser};
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} ) {
$dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
$self->{asked_for_pass} = 1;
@@ -3702,19 +3702,20 @@ sub connect {
sub set_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');
$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);
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);
if ( $self->{dbh} && $self->{dbh} == $dbh && $self->{dbh_set} && $self->{dbh_set} == $connection_id) {
PTDEBUG && _d($dbh, 'Already set dbh');
return $dbh;
}
if ( $hostname ) {
$self->{hostname} = $hostname;
}
@@ -3729,7 +3730,7 @@ sub set_dbh {
}
$self->{dbh} = $dbh;
$self->{dbh_set} = 1;
$self->{dbh_set} = $connection_id;
return $dbh;
}
@@ -3855,6 +3856,17 @@ sub DESTROY {
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 {
my ($package, undef, $line) = caller 0;
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
@@ -4697,8 +4709,7 @@ sub get_keys {
my $clustered_key = undef;
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/;
my $key_ddl = $key;
@@ -4708,7 +4719,7 @@ sub get_keys {
$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)/;
$type = $type || $special || 'BTREE';
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
@@ -4989,7 +5000,7 @@ sub generate_cmp_where {
push @clause, "($val IS NULL OR $quo $type $val)";
}
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/</ ) {
push @clauses, "(($val IS NOT NULL AND $quo IS NULL) OR ($quo $cmp $val))";
@@ -5188,6 +5199,7 @@ sub get_slaves {
dsn => $dsn,
slave_user => $o->got('slave-user') ? $o->get('slave-user') : '',
slave_password => $o->got('slave-password') ? $o->get('slave-password') : '',
slaves => $args{slaves},
callback => sub {
my ( $dsn, $dbh, $level, $parent ) = @_;
return unless $level;
@@ -5264,16 +5276,29 @@ sub recurse_to_slaves {
PTDEBUG && _d("Slave password set");
}
my $dbh;
eval {
$dbh = $args->{dbh} || $dp->get_dbh(
$dp->get_cxn_params($slave_dsn), { AutoCommit => 1 });
PTDEBUG && _d('Connected to', $dp->as_string($slave_dsn));
};
if ( $EVAL_ERROR ) {
print STDERR "Cannot connect to ", $dp->as_string($slave_dsn), "\n"
or die "Cannot print: $OS_ERROR";
return;
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 {
$dbh = $dp->get_dbh(
$dp->get_cxn_params($slave_dsn), { AutoCommit => 1 });
PTDEBUG && _d('Connected to', $dp->as_string($slave_dsn));
};
if ( $EVAL_ERROR ) {
print STDERR "Cannot connect to ", $dp->as_string($slave_dsn), ": ", $EVAL_ERROR, "\n"
or die "Cannot print: $OS_ERROR";
return;
}
}
}
my $sql = 'SELECT @@SERVER_ID';
@@ -14130,6 +14155,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-table-checksum 3.5.1
pt-table-checksum 3.5.2
=cut

View File

@@ -55,7 +55,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.5.1';
our $VERSION = '3.5.2';
use strict;
use warnings FATAL => 'all';
@@ -2877,7 +2877,7 @@ sub parse {
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;
PTDEBUG && _d('Table cols:', join(', ', map { "`$_`" } @cols));
@@ -3058,8 +3058,7 @@ sub get_keys {
my $clustered_key = undef;
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/;
my $key_ddl = $key;
@@ -3069,7 +3068,7 @@ sub get_keys {
$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)/;
$type = $type || $special || 'BTREE';
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;
@@ -6517,7 +6516,7 @@ sub generate_cmp_where {
push @clause, "($val IS NULL OR $quo $type $val)";
}
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/</ ) {
push @clauses, "(($val IS NOT NULL AND $quo IS NULL) OR ($quo $cmp $val))";
@@ -6716,6 +6715,7 @@ sub get_slaves {
dsn => $dsn,
slave_user => $o->got('slave-user') ? $o->get('slave-user') : '',
slave_password => $o->got('slave-password') ? $o->get('slave-password') : '',
slaves => $args{slaves},
callback => sub {
my ( $dsn, $dbh, $level, $parent ) = @_;
return unless $level;
@@ -6792,16 +6792,29 @@ sub recurse_to_slaves {
PTDEBUG && _d("Slave password set");
}
my $dbh;
eval {
$dbh = $args->{dbh} || $dp->get_dbh(
$dp->get_cxn_params($slave_dsn), { AutoCommit => 1 });
PTDEBUG && _d('Connected to', $dp->as_string($slave_dsn));
};
if ( $EVAL_ERROR ) {
print STDERR "Cannot connect to ", $dp->as_string($slave_dsn), "\n"
or die "Cannot print: $OS_ERROR";
return;
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 {
$dbh = $dp->get_dbh(
$dp->get_cxn_params($slave_dsn), { AutoCommit => 1 });
PTDEBUG && _d('Connected to', $dp->as_string($slave_dsn));
};
if ( $EVAL_ERROR ) {
print STDERR "Cannot connect to ", $dp->as_string($slave_dsn), ": ", $EVAL_ERROR, "\n"
or die "Cannot print: $OS_ERROR";
return;
}
}
}
my $sql = 'SELECT @@SERVER_ID';
@@ -13165,6 +13178,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-table-sync 3.5.1
pt-table-sync 3.5.2
=cut

View File

@@ -8519,6 +8519,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-table-usage 3.5.1
pt-table-usage 3.5.2
=cut

View File

@@ -61,7 +61,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.5.1';
our $VERSION = '3.5.2';
use strict;
use warnings FATAL => 'all';
@@ -2539,7 +2539,7 @@ sub connect {
my $dp = $self->{DSNParser};
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} ) {
$dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
$self->{asked_for_pass} = 1;
@@ -2568,19 +2568,20 @@ sub connect {
sub set_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');
$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);
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);
if ( $self->{dbh} && $self->{dbh} == $dbh && $self->{dbh_set} && $self->{dbh_set} == $connection_id) {
PTDEBUG && _d($dbh, 'Already set dbh');
return $dbh;
}
if ( $hostname ) {
$self->{hostname} = $hostname;
}
@@ -2595,7 +2596,7 @@ sub set_dbh {
}
$self->{dbh} = $dbh;
$self->{dbh_set} = 1;
$self->{dbh_set} = $connection_id;
return $dbh;
}
@@ -2721,6 +2722,17 @@ sub DESTROY {
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 {
my ($package, undef, $line) = caller 0;
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
@@ -11516,6 +11528,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-upgrade 3.5.1
pt-upgrade 3.5.2
=cut

View File

@@ -44,7 +44,7 @@ BEGIN {
{
package Percona::Toolkit;
our $VERSION = '3.5.1';
our $VERSION = '3.5.2';
use strict;
use warnings FATAL => 'all';
@@ -6326,6 +6326,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-variable-advisor 3.5.1
pt-variable-advisor 3.5.2
=cut

View File

@@ -3308,6 +3308,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-visual-explain 3.5.1
pt-visual-explain 3.5.2
=cut

View File

@@ -50,7 +50,7 @@ copyright = u'2023, Percona LLC and/or its affiliates'
# The short X.Y version.
version = '3.5'
# 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
# for a list of supported languages.

View File

@@ -575,6 +575,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
Percona Toolkit v3.5.1 released 2023-01-23
Percona Toolkit v3.5.2 released 2023-03-28
=cut

View File

@@ -1,6 +1,48 @@
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
==============================

48
docs/rn.3-5-2.txt Normal file
View 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

View File

@@ -123,7 +123,8 @@ sub connect {
my $dp = $self->{DSNParser};
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.
if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p} ) {
$dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: ");
@@ -153,18 +154,6 @@ sub connect {
sub set_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');
# 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
# 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);
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);
# 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 ) {
$self->{hostname} = $hostname;
}
@@ -191,7 +196,7 @@ sub set_dbh {
}
$self->{dbh} = $dbh;
$self->{dbh_set} = 1;
$self->{dbh_set} = $connection_id;
return $dbh;
}
@@ -343,6 +348,19 @@ sub DESTROY {
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 {
my ($package, undef, $line) = caller 0;
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }

View File

@@ -18,7 +18,7 @@
# ###########################################################################
package Percona::Toolkit;
our $VERSION = '3.5.1';
our $VERSION = '3.5.2';
use strict;
use warnings FATAL => 'all';

View File

@@ -197,7 +197,7 @@ sub generate_cmp_where {
push @clause, "($val IS NULL OR $quo $type $val)";
}
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/</ ) {
push @clauses, "(($val IS NOT NULL AND $quo IS NULL) OR ($quo $cmp $val))";

View File

@@ -389,8 +389,7 @@ sub get_keys {
my $clustered_key = undef;
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.
next KEY if $key =~ m/FOREIGN/;
@@ -407,7 +406,7 @@ sub get_keys {
}
# 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)/;
$type = $type || $special || 'BTREE';
my ($name) = $key =~ m/(PRIMARY|`[^`]*`)/;

View File

@@ -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=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 'masterchan2';
START SLAVE for channel 'masterchan2';

View File

@@ -128,9 +128,9 @@ is(
),
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{ 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{ `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{ISNULL(`original_language_id`), ISNULL(`length`), ISNULL(`rating`), ISNULL(`special_features`))))},
'SHA1 query for sakila.film',
@@ -180,7 +180,7 @@ is(
tbl => $tbl,
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',
);
@@ -191,7 +191,7 @@ is(
tbl => $tbl,
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',
);
@@ -204,7 +204,7 @@ is(
cols => [qw(film_id title)],
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',
);

View File

@@ -229,9 +229,9 @@ is (
function => 'SHA1',
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{`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{`replacement_cost`, `rating`, `special_features`, `last_update` + 0, }
. q{CONCAT(ISNULL(`description`), ISNULL(`release_year`), }
@@ -245,9 +245,9 @@ is (
function => 'FNV_64',
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{`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{`replacement_cost`, `rating`, `special_features`, `last_update` + 0)},
'FNV_64 query for sakila.film',
@@ -490,7 +490,7 @@ is (
q{SELECT /*PROGRESS_COMMENT*//*CHUNK_NUM*/ COUNT(*) AS cnt, }
. q{COALESCE(RIGHT(MAX(@crc := CONCAT(LPAD(@cnt := @cnt + 1, 16, '0'), }
. 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{`replacement_cost`, `rating`, `special_features`, `last_update` + 0, }
. q{CONCAT(ISNULL(`description`), ISNULL(`release_year`), }
@@ -514,7 +514,7 @@ is (
q{SELECT /*PROGRESS_COMMENT*//*CHUNK_NUM*/ COUNT(*) AS cnt, }
. q{COALESCE(RIGHT(MAX(@crc := CONCAT(LPAD(@cnt := @cnt + 1, 16, '0'), }
. 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{`replacement_cost`, `rating`, `special_features`, `last_update` + 0}
. q{))) AS UNSIGNED), 10, 16))), 16), 0) AS crc }
@@ -559,7 +559,7 @@ is (
. q{SELECT ?, ?, /*CHUNK_NUM*/ ?, COUNT(*) AS cnt, }
. q{COALESCE(RIGHT(MAX(@crc := CONCAT(LPAD(@cnt := @cnt + 1, 16, '0'), }
. 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{`replacement_cost`, `rating`, `special_features`, `last_update` + 0, }
. q{CONCAT(ISNULL(`description`), ISNULL(`release_year`), }

View File

@@ -419,7 +419,7 @@ is_deeply(
. '= ? AND (? IS NULL OR `customer_id` >= ?)))',
'>' => '((`rental_date` > ?) OR (`rental_date` = ? AND `inventory_id` > ?) OR '
. '(`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` > ?) OR (`rental_date` = ? AND `inventory_id` '
# . '= ? AND ((? IS NULL AND `customer_id` IS NOT NULL) '
@@ -469,7 +469,7 @@ is_deeply(
index => 'rental_date',
where => '((`rental_date` > ?) OR (`rental_date` = ? AND `inventory_id` > ?) OR '
. '(`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` > ?)'
#. ' OR (`rental_date` = ? AND `inventory_id` = ? AND '
#. '((? IS NULL AND `customer_id` IS NOT NULL) OR (`customer_id` > ?))))',
@@ -481,7 +481,7 @@ is_deeply(
. '= ? AND (? IS NULL OR `customer_id` >= ?)))',
'>' => '((`rental_date` > ?) OR (`rental_date` = ? AND `inventory_id` > ?) 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 '
#. '`inventory_id` > ?) OR (`rental_date` = ? AND `inventory_id` '
#. '= ? AND ((? IS NULL AND `customer_id` IS NOT NULL) '
@@ -517,7 +517,7 @@ is_deeply(
return_date staff_id last_update)],
index => 'rental_date',
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` >= ?))',
# '((`rental_date` > ?) OR '
#. '(`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)],
boundaries => {
'>=' => '((`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` >= ?))',
# '((`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` = ?)) AND `customer_id` >= ?))',
'>' => '((`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` > ?))',
# '((`rental_date` > ?) OR (`rental_date` = ? AND ((? IS NULL '
#. 'AND `inventory_id` IS NOT NULL) OR (`inventory_id` > ?))) OR '
@@ -572,7 +572,7 @@ is_deeply(
return_date staff_id last_update)],
index => 'rental_date',
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` > ?))',
# '((`rental_date` > ?) OR '
#. '(`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)],
boundaries => {
'>=' => '((`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` >= ?))',
# '((`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` = ?)) AND `customer_id` >= ?))',
'>' => '((`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` > ?))',
# '((`rental_date` > ?) OR (`rental_date` = ? AND ((? IS NULL '
#. 'AND `inventory_id` IS NOT NULL) OR (`inventory_id` > ?))) OR '

View File

@@ -28,6 +28,18 @@ my $tp = new TableParser(Quoter=>$q);
my $tbl;
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 "Cannot connect to sandbox master", 2 unless $dbh;
skip 'Sandbox master does not have the sakila database', 2
@@ -44,12 +56,14 @@ SKIP: {
$ddl = $tp->ansi_to_legacy($ddl);
$ddl = "$ddl ENGINE=InnoDB AUTO_INCREMENT=201 DEFAULT CHARSET=utf8";
}
ok(
no_diff(
"$ddl\n",
$sandbox_version ge '5.1' ? "$sample/sakila.actor"
: "$sample/sakila.actor-5.0",
cmd_output => 1,
transform_sample => $transform_int
),
"get_create_table(sakila.actor)"
);

View File

@@ -28,7 +28,7 @@ elsif ( !$slave_dbh ) {
} elsif ($sandbox_version lt '5.7') {
plan skip_all => 'Only on MySQL 5.7+';
} else {
plan tests => 4;
plan tests => 5;
}
my ($master1_dbh, $master1_dsn) = $sb->start_sandbox(
@@ -76,10 +76,19 @@ $output = output(
sub { $exit_status = pt_archiver::main(@args) },
stderr => 1,
);
is(
diag("Exit status: $exit_status") if ($exit_status);
diag($output);
isnt(
$exit_status,
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');

View File

@@ -71,13 +71,22 @@ sub reset_repl_db {
# 1
# 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
# if run test with enabled MyRocks or TokuDB SE
ok(
# if run test with enabled MyRocks or TokuDB SE.
# 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(
sub { pt_table_checksum::main(@args) },
$cmd,
"$sample/default-results-$sandbox_version.txt",
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}\'',
),
"Default checksum"

View File

@@ -107,6 +107,7 @@ is(
# #############################################################################
# Done.
# #############################################################################
$master_dbh->do('DROP FUNCTION IF EXISTS fnv_64');
$sb->wipe_clean($master_dbh);
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
exit;

View File

@@ -91,7 +91,8 @@ like(
"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'),
0,
"No errors after waiting for slave lag"

View File

@@ -7,7 +7,6 @@ ERRORS DIFFS ROWS SKIPPED TABLE
0 0 0 0 mysql.default_roles
0 1 2 0 mysql.engine_cost
0 0 0 0 mysql.func
0 0 85 0 mysql.global_grants
0 0 53 0 mysql.help_category
0 0 985 0 mysql.help_keyword
0 0 2043 0 mysql.help_relation

View File

@@ -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 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*/