mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-02 02:34:19 +00:00
Compare commits
4 Commits
release-v3
...
PT-2156_Fi
Author | SHA1 | Date | |
---|---|---|---|
![]() |
59b80afe93 | ||
![]() |
51bc8c2d57 | ||
![]() |
69a9933125 | ||
![]() |
1095a87f5e |
@@ -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; }
|
||||
|
@@ -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; }
|
||||
|
@@ -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; }
|
||||
|
@@ -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|`[^`]*`)/;
|
||||
|
@@ -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|`[^`]*`)/;
|
||||
|
@@ -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; }
|
||||
|
@@ -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|`[^`]*`)/;
|
||||
|
@@ -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|`[^`]*`)/;
|
||||
|
71
bin/pt-kill
71
bin/pt-kill
@@ -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; }
|
||||
|
@@ -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; }
|
||||
|
@@ -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';
|
||||
|
@@ -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';
|
||||
|
@@ -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';
|
||||
|
@@ -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';
|
||||
|
@@ -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';
|
||||
|
@@ -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; }
|
||||
|
50
lib/Cxn.pm
50
lib/Cxn.pm
@@ -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; }
|
||||
|
@@ -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))";
|
||||
|
@@ -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|`[^`]*`)/;
|
||||
|
@@ -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';
|
||||
|
||||
|
@@ -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',
|
||||
);
|
||||
|
||||
|
@@ -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`), }
|
||||
|
@@ -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 '
|
||||
|
@@ -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)"
|
||||
);
|
||||
|
@@ -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');
|
||||
|
@@ -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"
|
||||
|
@@ -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;
|
||||
|
@@ -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"
|
||||
|
@@ -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
|
||||
|
@@ -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*/
|
||||
|
||||
|
Reference in New Issue
Block a user