mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-10 21:19:59 +00:00
PT-139 Added replication channels suport to pt-table-sync
This commit is contained in:
@@ -3863,16 +3863,35 @@ sub get_slave_status {
|
||||
||= $dbh->prepare('SHOW SLAVE STATUS');
|
||||
PTDEBUG && _d($dbh, 'SHOW SLAVE STATUS');
|
||||
$sth->execute();
|
||||
my ($ss) = @{$sth->fetchall_arrayref({})};
|
||||
my ($sss_rows) = $sth->fetchall_arrayref({}); # Show Slave Status rows
|
||||
|
||||
if ( $ss && %$ss ) {
|
||||
$ss = { map { lc($_) => $ss->{$_} } keys %$ss }; # lowercase the keys
|
||||
return $ss;
|
||||
my $ss;
|
||||
if ( $sss_rows && @$sss_rows ) {
|
||||
if (scalar @$sss_rows > 1) {
|
||||
if (!$self->{channel}) {
|
||||
warn 'This server returned more than one row for SHOW SLAVE STATUS but "channel" was not specified on the command line';
|
||||
return undef;
|
||||
}
|
||||
for my $row (@$sss_rows) {
|
||||
$row = { map { lc($_) => $row->{$_} } keys %$row }; # lowercase the keys
|
||||
if ($row->{channel_name} eq $self->{channel}) {
|
||||
$ss = $row;
|
||||
last;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$ss = $sss_rows->[0];
|
||||
}
|
||||
|
||||
if ( $ss && %$ss ) {
|
||||
$ss = { map { lc($_) => $ss->{$_} } keys %$ss }; # lowercase the keys
|
||||
return $ss;
|
||||
}
|
||||
}
|
||||
|
||||
PTDEBUG && _d('This server returns nothing for SHOW SLAVE STATUS');
|
||||
$self->{not_a_slave}->{$dbh}++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub get_master_status {
|
||||
@@ -3912,8 +3931,9 @@ sub wait_for_master {
|
||||
my $result;
|
||||
my $waited;
|
||||
if ( $master_status ) {
|
||||
my $sql = "SELECT MASTER_POS_WAIT('$master_status->{file}', "
|
||||
. "$master_status->{position}, $timeout)";
|
||||
my $server_version = VersionParser->new($slave_dbh);
|
||||
my $channel_sql = $server_version > '5.6' && $self->{channel} ? ", '$self->{channel}'" : '';
|
||||
my $sql = "SELECT MASTER_POS_WAIT('$master_status->{file}', $master_status->{position}, $timeout $channel_sql)";
|
||||
PTDEBUG && _d($slave_dbh, $sql);
|
||||
my $start = time;
|
||||
($result) = $slave_dbh->selectrow_array($sql);
|
||||
|
@@ -456,16 +456,35 @@ sub get_slave_status {
|
||||
||= $dbh->prepare('SHOW SLAVE STATUS');
|
||||
PTDEBUG && _d($dbh, 'SHOW SLAVE STATUS');
|
||||
$sth->execute();
|
||||
my ($ss) = @{$sth->fetchall_arrayref({})};
|
||||
my ($sss_rows) = $sth->fetchall_arrayref({}); # Show Slave Status rows
|
||||
|
||||
if ( $ss && %$ss ) {
|
||||
$ss = { map { lc($_) => $ss->{$_} } keys %$ss }; # lowercase the keys
|
||||
return $ss;
|
||||
my $ss;
|
||||
if ( $sss_rows && @$sss_rows ) {
|
||||
if (scalar @$sss_rows > 1) {
|
||||
if (!$self->{channel}) {
|
||||
warn 'This server returned more than one row for SHOW SLAVE STATUS but "channel" was not specified on the command line';
|
||||
return undef;
|
||||
}
|
||||
for my $row (@$sss_rows) {
|
||||
$row = { map { lc($_) => $row->{$_} } keys %$row }; # lowercase the keys
|
||||
if ($row->{channel_name} eq $self->{channel}) {
|
||||
$ss = $row;
|
||||
last;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$ss = $sss_rows->[0];
|
||||
}
|
||||
|
||||
if ( $ss && %$ss ) {
|
||||
$ss = { map { lc($_) => $ss->{$_} } keys %$ss }; # lowercase the keys
|
||||
return $ss;
|
||||
}
|
||||
}
|
||||
|
||||
PTDEBUG && _d('This server returns nothing for SHOW SLAVE STATUS');
|
||||
$self->{not_a_slave}->{$dbh}++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub get_master_status {
|
||||
@@ -505,8 +524,9 @@ sub wait_for_master {
|
||||
my $result;
|
||||
my $waited;
|
||||
if ( $master_status ) {
|
||||
my $sql = "SELECT MASTER_POS_WAIT('$master_status->{file}', "
|
||||
. "$master_status->{position}, $timeout)";
|
||||
my $server_version = VersionParser->new($slave_dbh);
|
||||
my $channel_sql = $server_version > '5.6' && $self->{channel} ? ", '$self->{channel}'" : '';
|
||||
my $sql = "SELECT MASTER_POS_WAIT('$master_status->{file}', $master_status->{position}, $timeout $channel_sql)";
|
||||
PTDEBUG && _d($slave_dbh, $sql);
|
||||
my $start = time;
|
||||
($result) = $slave_dbh->selectrow_array($sql);
|
||||
|
34
bin/pt-kill
34
bin/pt-kill
@@ -4133,16 +4133,35 @@ sub get_slave_status {
|
||||
||= $dbh->prepare('SHOW SLAVE STATUS');
|
||||
PTDEBUG && _d($dbh, 'SHOW SLAVE STATUS');
|
||||
$sth->execute();
|
||||
my ($ss) = @{$sth->fetchall_arrayref({})};
|
||||
my ($sss_rows) = $sth->fetchall_arrayref({}); # Show Slave Status rows
|
||||
|
||||
if ( $ss && %$ss ) {
|
||||
$ss = { map { lc($_) => $ss->{$_} } keys %$ss }; # lowercase the keys
|
||||
return $ss;
|
||||
my $ss;
|
||||
if ( $sss_rows && @$sss_rows ) {
|
||||
if (scalar @$sss_rows > 1) {
|
||||
if (!$self->{channel}) {
|
||||
warn 'This server returned more than one row for SHOW SLAVE STATUS but "channel" was not specified on the command line';
|
||||
return undef;
|
||||
}
|
||||
for my $row (@$sss_rows) {
|
||||
$row = { map { lc($_) => $row->{$_} } keys %$row }; # lowercase the keys
|
||||
if ($row->{channel_name} eq $self->{channel}) {
|
||||
$ss = $row;
|
||||
last;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$ss = $sss_rows->[0];
|
||||
}
|
||||
|
||||
if ( $ss && %$ss ) {
|
||||
$ss = { map { lc($_) => $ss->{$_} } keys %$ss }; # lowercase the keys
|
||||
return $ss;
|
||||
}
|
||||
}
|
||||
|
||||
PTDEBUG && _d('This server returns nothing for SHOW SLAVE STATUS');
|
||||
$self->{not_a_slave}->{$dbh}++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub get_master_status {
|
||||
@@ -4182,8 +4201,9 @@ sub wait_for_master {
|
||||
my $result;
|
||||
my $waited;
|
||||
if ( $master_status ) {
|
||||
my $sql = "SELECT MASTER_POS_WAIT('$master_status->{file}', "
|
||||
. "$master_status->{position}, $timeout)";
|
||||
my $server_version = VersionParser->new($slave_dbh);
|
||||
my $channel_sql = $server_version > '5.6' && $self->{channel} ? ", '$self->{channel}'" : '';
|
||||
my $sql = "SELECT MASTER_POS_WAIT('$master_status->{file}', $master_status->{position}, $timeout $channel_sql)";
|
||||
PTDEBUG && _d($slave_dbh, $sql);
|
||||
my $start = time;
|
||||
($result) = $slave_dbh->selectrow_array($sql);
|
||||
|
@@ -4415,16 +4415,35 @@ sub get_slave_status {
|
||||
||= $dbh->prepare('SHOW SLAVE STATUS');
|
||||
PTDEBUG && _d($dbh, 'SHOW SLAVE STATUS');
|
||||
$sth->execute();
|
||||
my ($ss) = @{$sth->fetchall_arrayref({})};
|
||||
my ($sss_rows) = $sth->fetchall_arrayref({}); # Show Slave Status rows
|
||||
|
||||
if ( $ss && %$ss ) {
|
||||
$ss = { map { lc($_) => $ss->{$_} } keys %$ss }; # lowercase the keys
|
||||
return $ss;
|
||||
my $ss;
|
||||
if ( $sss_rows && @$sss_rows ) {
|
||||
if (scalar @$sss_rows > 1) {
|
||||
if (!$self->{channel}) {
|
||||
warn 'This server returned more than one row for SHOW SLAVE STATUS but "channel" was not specified on the command line';
|
||||
return undef;
|
||||
}
|
||||
for my $row (@$sss_rows) {
|
||||
$row = { map { lc($_) => $row->{$_} } keys %$row }; # lowercase the keys
|
||||
if ($row->{channel_name} eq $self->{channel}) {
|
||||
$ss = $row;
|
||||
last;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$ss = $sss_rows->[0];
|
||||
}
|
||||
|
||||
if ( $ss && %$ss ) {
|
||||
$ss = { map { lc($_) => $ss->{$_} } keys %$ss }; # lowercase the keys
|
||||
return $ss;
|
||||
}
|
||||
}
|
||||
|
||||
PTDEBUG && _d('This server returns nothing for SHOW SLAVE STATUS');
|
||||
$self->{not_a_slave}->{$dbh}++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub get_master_status {
|
||||
@@ -4464,8 +4483,9 @@ sub wait_for_master {
|
||||
my $result;
|
||||
my $waited;
|
||||
if ( $master_status ) {
|
||||
my $sql = "SELECT MASTER_POS_WAIT('$master_status->{file}', "
|
||||
. "$master_status->{position}, $timeout)";
|
||||
my $server_version = VersionParser->new($slave_dbh);
|
||||
my $channel_sql = $server_version > '5.6' && $self->{channel} ? ", '$self->{channel}'" : '';
|
||||
my $sql = "SELECT MASTER_POS_WAIT('$master_status->{file}', $master_status->{position}, $timeout $channel_sql)";
|
||||
PTDEBUG && _d($slave_dbh, $sql);
|
||||
my $start = time;
|
||||
($result) = $slave_dbh->selectrow_array($sql);
|
||||
|
@@ -10750,16 +10750,35 @@ sub get_slave_status {
|
||||
||= $dbh->prepare('SHOW SLAVE STATUS');
|
||||
PTDEBUG && _d($dbh, 'SHOW SLAVE STATUS');
|
||||
$sth->execute();
|
||||
my ($ss) = @{$sth->fetchall_arrayref({})};
|
||||
my ($sss_rows) = $sth->fetchall_arrayref({}); # Show Slave Status rows
|
||||
|
||||
if ( $ss && %$ss ) {
|
||||
$ss = { map { lc($_) => $ss->{$_} } keys %$ss }; # lowercase the keys
|
||||
return $ss;
|
||||
my $ss;
|
||||
if ( $sss_rows && @$sss_rows ) {
|
||||
if (scalar @$sss_rows > 1) {
|
||||
if (!$self->{channel}) {
|
||||
warn 'This server returned more than one row for SHOW SLAVE STATUS but "channel" was not specified on the command line';
|
||||
return undef;
|
||||
}
|
||||
for my $row (@$sss_rows) {
|
||||
$row = { map { lc($_) => $row->{$_} } keys %$row }; # lowercase the keys
|
||||
if ($row->{channel_name} eq $self->{channel}) {
|
||||
$ss = $row;
|
||||
last;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$ss = $sss_rows->[0];
|
||||
}
|
||||
|
||||
if ( $ss && %$ss ) {
|
||||
$ss = { map { lc($_) => $ss->{$_} } keys %$ss }; # lowercase the keys
|
||||
return $ss;
|
||||
}
|
||||
}
|
||||
|
||||
PTDEBUG && _d('This server returns nothing for SHOW SLAVE STATUS');
|
||||
$self->{not_a_slave}->{$dbh}++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub get_master_status {
|
||||
@@ -10799,8 +10818,9 @@ sub wait_for_master {
|
||||
my $result;
|
||||
my $waited;
|
||||
if ( $master_status ) {
|
||||
my $sql = "SELECT MASTER_POS_WAIT('$master_status->{file}', "
|
||||
. "$master_status->{position}, $timeout)";
|
||||
my $server_version = VersionParser->new($slave_dbh);
|
||||
my $channel_sql = $server_version > '5.6' && $self->{channel} ? ", '$self->{channel}'" : '';
|
||||
my $sql = "SELECT MASTER_POS_WAIT('$master_status->{file}', $master_status->{position}, $timeout $channel_sql)";
|
||||
PTDEBUG && _d($slave_dbh, $sql);
|
||||
my $start = time;
|
||||
($result) = $slave_dbh->selectrow_array($sql);
|
||||
|
@@ -2570,16 +2570,35 @@ sub get_slave_status {
|
||||
||= $dbh->prepare('SHOW SLAVE STATUS');
|
||||
PTDEBUG && _d($dbh, 'SHOW SLAVE STATUS');
|
||||
$sth->execute();
|
||||
my ($ss) = @{$sth->fetchall_arrayref({})};
|
||||
my ($sss_rows) = $sth->fetchall_arrayref({}); # Show Slave Status rows
|
||||
|
||||
if ( $ss && %$ss ) {
|
||||
$ss = { map { lc($_) => $ss->{$_} } keys %$ss }; # lowercase the keys
|
||||
return $ss;
|
||||
my $ss;
|
||||
if ( $sss_rows && @$sss_rows ) {
|
||||
if (scalar @$sss_rows > 1) {
|
||||
if (!$self->{channel}) {
|
||||
warn 'This server returned more than one row for SHOW SLAVE STATUS but "channel" was not specified on the command line';
|
||||
return undef;
|
||||
}
|
||||
for my $row (@$sss_rows) {
|
||||
$row = { map { lc($_) => $row->{$_} } keys %$row }; # lowercase the keys
|
||||
if ($row->{channel_name} eq $self->{channel}) {
|
||||
$ss = $row;
|
||||
last;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$ss = $sss_rows->[0];
|
||||
}
|
||||
|
||||
if ( $ss && %$ss ) {
|
||||
$ss = { map { lc($_) => $ss->{$_} } keys %$ss }; # lowercase the keys
|
||||
return $ss;
|
||||
}
|
||||
}
|
||||
|
||||
PTDEBUG && _d('This server returns nothing for SHOW SLAVE STATUS');
|
||||
$self->{not_a_slave}->{$dbh}++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub get_master_status {
|
||||
@@ -2619,8 +2638,9 @@ sub wait_for_master {
|
||||
my $result;
|
||||
my $waited;
|
||||
if ( $master_status ) {
|
||||
my $sql = "SELECT MASTER_POS_WAIT('$master_status->{file}', "
|
||||
. "$master_status->{position}, $timeout)";
|
||||
my $server_version = VersionParser->new($slave_dbh);
|
||||
my $channel_sql = $server_version > '5.6' && $self->{channel} ? ", '$self->{channel}'" : '';
|
||||
my $sql = "SELECT MASTER_POS_WAIT('$master_status->{file}', $master_status->{position}, $timeout $channel_sql)";
|
||||
PTDEBUG && _d($slave_dbh, $sql);
|
||||
my $start = time;
|
||||
($result) = $slave_dbh->selectrow_array($sql);
|
||||
|
@@ -2981,16 +2981,35 @@ sub get_slave_status {
|
||||
||= $dbh->prepare('SHOW SLAVE STATUS');
|
||||
PTDEBUG && _d($dbh, 'SHOW SLAVE STATUS');
|
||||
$sth->execute();
|
||||
my ($ss) = @{$sth->fetchall_arrayref({})};
|
||||
my ($sss_rows) = $sth->fetchall_arrayref({}); # Show Slave Status rows
|
||||
|
||||
if ( $ss && %$ss ) {
|
||||
$ss = { map { lc($_) => $ss->{$_} } keys %$ss }; # lowercase the keys
|
||||
return $ss;
|
||||
my $ss;
|
||||
if ( $sss_rows && @$sss_rows ) {
|
||||
if (scalar @$sss_rows > 1) {
|
||||
if (!$self->{channel}) {
|
||||
warn 'This server returned more than one row for SHOW SLAVE STATUS but "channel" was not specified on the command line';
|
||||
return undef;
|
||||
}
|
||||
for my $row (@$sss_rows) {
|
||||
$row = { map { lc($_) => $row->{$_} } keys %$row }; # lowercase the keys
|
||||
if ($row->{channel_name} eq $self->{channel}) {
|
||||
$ss = $row;
|
||||
last;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$ss = $sss_rows->[0];
|
||||
}
|
||||
|
||||
if ( $ss && %$ss ) {
|
||||
$ss = { map { lc($_) => $ss->{$_} } keys %$ss }; # lowercase the keys
|
||||
return $ss;
|
||||
}
|
||||
}
|
||||
|
||||
PTDEBUG && _d('This server returns nothing for SHOW SLAVE STATUS');
|
||||
$self->{not_a_slave}->{$dbh}++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub get_master_status {
|
||||
@@ -3030,8 +3049,9 @@ sub wait_for_master {
|
||||
my $result;
|
||||
my $waited;
|
||||
if ( $master_status ) {
|
||||
my $sql = "SELECT MASTER_POS_WAIT('$master_status->{file}', "
|
||||
. "$master_status->{position}, $timeout)";
|
||||
my $server_version = VersionParser->new($slave_dbh);
|
||||
my $channel_sql = $server_version > '5.6' && $self->{channel} ? ", '$self->{channel}'" : '';
|
||||
my $sql = "SELECT MASTER_POS_WAIT('$master_status->{file}', $master_status->{position}, $timeout $channel_sql)";
|
||||
PTDEBUG && _d($slave_dbh, $sql);
|
||||
my $start = time;
|
||||
($result) = $slave_dbh->selectrow_array($sql);
|
||||
|
@@ -5361,16 +5361,35 @@ sub get_slave_status {
|
||||
||= $dbh->prepare('SHOW SLAVE STATUS');
|
||||
PTDEBUG && _d($dbh, 'SHOW SLAVE STATUS');
|
||||
$sth->execute();
|
||||
my ($ss) = @{$sth->fetchall_arrayref({})};
|
||||
my ($sss_rows) = $sth->fetchall_arrayref({}); # Show Slave Status rows
|
||||
|
||||
if ( $ss && %$ss ) {
|
||||
$ss = { map { lc($_) => $ss->{$_} } keys %$ss }; # lowercase the keys
|
||||
return $ss;
|
||||
my $ss;
|
||||
if ( $sss_rows && @$sss_rows ) {
|
||||
if (scalar @$sss_rows > 1) {
|
||||
if (!$self->{channel}) {
|
||||
warn 'This server returned more than one row for SHOW SLAVE STATUS but "channel" was not specified on the command line';
|
||||
return undef;
|
||||
}
|
||||
for my $row (@$sss_rows) {
|
||||
$row = { map { lc($_) => $row->{$_} } keys %$row }; # lowercase the keys
|
||||
if ($row->{channel_name} eq $self->{channel}) {
|
||||
$ss = $row;
|
||||
last;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$ss = $sss_rows->[0];
|
||||
}
|
||||
|
||||
if ( $ss && %$ss ) {
|
||||
$ss = { map { lc($_) => $ss->{$_} } keys %$ss }; # lowercase the keys
|
||||
return $ss;
|
||||
}
|
||||
}
|
||||
|
||||
PTDEBUG && _d('This server returns nothing for SHOW SLAVE STATUS');
|
||||
$self->{not_a_slave}->{$dbh}++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub get_master_status {
|
||||
@@ -5410,8 +5429,9 @@ sub wait_for_master {
|
||||
my $result;
|
||||
my $waited;
|
||||
if ( $master_status ) {
|
||||
my $sql = "SELECT MASTER_POS_WAIT('$master_status->{file}', "
|
||||
. "$master_status->{position}, $timeout)";
|
||||
my $server_version = VersionParser->new($slave_dbh);
|
||||
my $channel_sql = $server_version > '5.6' && $self->{channel} ? ", '$self->{channel}'" : '';
|
||||
my $sql = "SELECT MASTER_POS_WAIT('$master_status->{file}', $master_status->{position}, $timeout $channel_sql)";
|
||||
PTDEBUG && _d($slave_dbh, $sql);
|
||||
my $start = time;
|
||||
($result) = $slave_dbh->selectrow_array($sql);
|
||||
|
@@ -6945,43 +6945,33 @@ sub get_slave_status {
|
||||
$sth->execute();
|
||||
my ($sss_rows) = $sth->fetchall_arrayref({}); # Show Slave Status rows
|
||||
|
||||
warn ">>>>====================================================================================================";
|
||||
warn Data::Dumper::Dumper($sss_rows);
|
||||
warn ">>>>====================================================================================================";
|
||||
# If SHOW SLAVE STATUS returns more than one row it means that this slave is connected to more
|
||||
# than one master using replication channels.
|
||||
# If we have a channel name as a parameter, we need to select the correct row and return it.
|
||||
# If we don't have a channel name as a parameter, there is no way to know what the correct master is so,
|
||||
# return an error.
|
||||
my $ss;
|
||||
$self->{channel} = 'masterchan2';
|
||||
if ( $sss_rows && @$sss_rows && scalar @$sss_rows > 1) {
|
||||
warn "KKKKKKKKKKKKKKKKKK";
|
||||
if (!$self->{channel}) {
|
||||
warn 'This server returned more than one row for SHOW SLAVE STATUS but "channel" was not specified on the command line';
|
||||
$self->{not_a_slave}->{$dbh}++;
|
||||
return;
|
||||
}
|
||||
for my $row (@$sss_rows) {
|
||||
if ($row->{Channel_Name} eq $self->{channel}) {
|
||||
$ss = $row;
|
||||
last;
|
||||
if ( $sss_rows && @$sss_rows ) {
|
||||
if (scalar @$sss_rows > 1) {
|
||||
if (!$self->{channel}) {
|
||||
warn 'This server returned more than one row for SHOW SLAVE STATUS but "channel" was not specified on the command line';
|
||||
return undef;
|
||||
}
|
||||
for my $row (@$sss_rows) {
|
||||
$row = { map { lc($_) => $row->{$_} } keys %$row }; # lowercase the keys
|
||||
if ($row->{channel_name} eq $self->{channel}) {
|
||||
$ss = $row;
|
||||
last;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$ss = $sss_rows->[0];
|
||||
}
|
||||
} else {
|
||||
warn "MMMMMMMMMMMMMMMMMMMMMMMMM";
|
||||
$ss = $sss_rows->[0];
|
||||
}
|
||||
|
||||
|
||||
if ( $ss && %$ss ) {
|
||||
$ss = { map { lc($_) => $ss->{$_} } keys %$ss }; # lowercase the keys
|
||||
return $ss;
|
||||
if ( $ss && %$ss ) {
|
||||
$ss = { map { lc($_) => $ss->{$_} } keys %$ss }; # lowercase the keys
|
||||
return $ss;
|
||||
}
|
||||
}
|
||||
|
||||
PTDEBUG && _d('This server returns nothing for SHOW SLAVE STATUS');
|
||||
$self->{not_a_slave}->{$dbh}++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub get_master_status {
|
||||
@@ -7021,20 +7011,15 @@ sub wait_for_master {
|
||||
my $result;
|
||||
my $waited;
|
||||
if ( $master_status ) {
|
||||
my $sql = "SELECT MASTER_POS_WAIT('$master_status->{file}', "
|
||||
. "$master_status->{position}, $timeout)";
|
||||
my $server_version = VersionParser->new($slave_dbh);
|
||||
my $channel_sql = $server_version > '5.6' && $self->{channel} ? ", '$self->{channel}'" : '';
|
||||
my $sql = "SELECT MASTER_POS_WAIT('$master_status->{file}', $master_status->{position}, $timeout $channel_sql)";
|
||||
PTDEBUG && _d($slave_dbh, $sql);
|
||||
my $start = time;
|
||||
$result = $slave_dbh->selectrow_array($sql);
|
||||
warn ">>>";
|
||||
warn Data::Dumper::Dumper($result);
|
||||
($result) = $slave_dbh->selectrow_array($sql);
|
||||
|
||||
$waited = time - $start;
|
||||
|
||||
warn "====================================================================================================";
|
||||
warn "slave_dbh $slave_dbh";
|
||||
warn Data::Dumper::Dumper($slave_dbh);
|
||||
warn Data::Dumper::Dumper($master_status);
|
||||
PTDEBUG && _d('Result of waiting:', $result);
|
||||
PTDEBUG && _d("Waited", $waited, "seconds");
|
||||
}
|
||||
@@ -9884,7 +9869,7 @@ sub main {
|
||||
# Do the work.
|
||||
# ########################################################################
|
||||
my $tp = new TableParser( Quoter => $q );
|
||||
my $ms = new MasterSlave(OptionParser=>$o,DSNParser=>$dp,Quoter=>$q);
|
||||
my $ms = new MasterSlave(OptionParser=>$o,DSNParser=>$dp,Quoter=>$q, channel=>$o->get('channel'));
|
||||
my $rt = new Retry();
|
||||
my $chunker = new TableChunker( Quoter => $q, TableParser => $tp );
|
||||
my $nibbler = new TableNibbler( Quoter => $q, TableParser => $tp );
|
||||
@@ -12055,6 +12040,18 @@ For most non-trivial data sizes, you want to leave this option enabled.
|
||||
|
||||
This option is disabled when L<"--bidirectional"> is used.
|
||||
|
||||
=item --channel
|
||||
|
||||
type: string
|
||||
|
||||
Channel name used when connected to a server using replication channels.
|
||||
Suppose you have two masters, master_a at port 12345, master_b at port 1236 and
|
||||
a slave connected to both masters using channels chan_master_a and chan_master_b.
|
||||
If you want to run pt-table-sync to syncronize the slave against master_a, pt-table-sync
|
||||
won't be able to determine what's the correct master since SHOW SLAVE STATUS
|
||||
will return 2 rows. In this case, you can use --channel=chan_master_a to specify
|
||||
the channel name to use in the SHOW SLAVE STATUS command.
|
||||
|
||||
=item --charset
|
||||
|
||||
short form: -A; type: string
|
||||
|
@@ -430,21 +430,46 @@ sub get_master_dsn {
|
||||
# Gets SHOW SLAVE STATUS, with column names all lowercased, as a hashref.
|
||||
sub get_slave_status {
|
||||
my ( $self, $dbh ) = @_;
|
||||
|
||||
if ( !$self->{not_a_slave}->{$dbh} ) {
|
||||
my $sth = $self->{sths}->{$dbh}->{SLAVE_STATUS}
|
||||
||= $dbh->prepare('SHOW SLAVE STATUS');
|
||||
PTDEBUG && _d($dbh, 'SHOW SLAVE STATUS');
|
||||
$sth->execute();
|
||||
my ($ss) = @{$sth->fetchall_arrayref({})};
|
||||
my ($sss_rows) = $sth->fetchall_arrayref({}); # Show Slave Status rows
|
||||
|
||||
if ( $ss && %$ss ) {
|
||||
$ss = { map { lc($_) => $ss->{$_} } keys %$ss }; # lowercase the keys
|
||||
return $ss;
|
||||
# If SHOW SLAVE STATUS returns more than one row it means that this slave is connected to more
|
||||
# than one master using replication channels.
|
||||
# If we have a channel name as a parameter, we need to select the correct row and return it.
|
||||
# If we don't have a channel name as a parameter, there is no way to know what the correct master is so,
|
||||
# return an error.
|
||||
my $ss;
|
||||
if ( $sss_rows && @$sss_rows ) {
|
||||
if (scalar @$sss_rows > 1) {
|
||||
if (!$self->{channel}) {
|
||||
warn 'This server returned more than one row for SHOW SLAVE STATUS but "channel" was not specified on the command line';
|
||||
return undef;
|
||||
}
|
||||
for my $row (@$sss_rows) {
|
||||
$row = { map { lc($_) => $row->{$_} } keys %$row }; # lowercase the keys
|
||||
if ($row->{channel_name} eq $self->{channel}) {
|
||||
$ss = $row;
|
||||
last;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$ss = $sss_rows->[0];
|
||||
}
|
||||
|
||||
if ( $ss && %$ss ) {
|
||||
$ss = { map { lc($_) => $ss->{$_} } keys %$ss }; # lowercase the keys
|
||||
return $ss;
|
||||
}
|
||||
}
|
||||
|
||||
PTDEBUG && _d('This server returns nothing for SHOW SLAVE STATUS');
|
||||
$self->{not_a_slave}->{$dbh}++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Gets SHOW MASTER STATUS, with column names all lowercased, as a hashref.
|
||||
@@ -506,8 +531,9 @@ sub wait_for_master {
|
||||
my $result;
|
||||
my $waited;
|
||||
if ( $master_status ) {
|
||||
my $sql = "SELECT MASTER_POS_WAIT('$master_status->{file}', "
|
||||
. "$master_status->{position}, $timeout)";
|
||||
my $server_version = VersionParser->new($slave_dbh);
|
||||
my $channel_sql = $server_version > '5.6' && $self->{channel} ? ", '$self->{channel}'" : '';
|
||||
my $sql = "SELECT MASTER_POS_WAIT('$master_status->{file}', $master_status->{position}, $timeout $channel_sql)";
|
||||
PTDEBUG && _d($slave_dbh, $sql);
|
||||
my $start = time;
|
||||
($result) = $slave_dbh->selectrow_array($sql);
|
||||
|
@@ -1,3 +1,4 @@
|
||||
STOP SLAVE FOR CHANNEL '';
|
||||
SET GLOBAL master_info_repository = 'TABLE';
|
||||
SET @@GLOBAL.relay_log_info_repository = 'TABLE';
|
||||
SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY=ON;
|
||||
|
@@ -750,6 +750,70 @@ like(
|
||||
"--recursion-method none,none"
|
||||
);
|
||||
|
||||
SKIP: {
|
||||
|
||||
skip "Only test on mysql 5.7" if ( $sandbox_version lt '5.7' );
|
||||
|
||||
my ($master1_dbh, $master1_dsn) = $sb->start_sandbox(
|
||||
server => 'chan_master1',
|
||||
type => 'master',
|
||||
);
|
||||
my ($master2_dbh, $master2_dsn) = $sb->start_sandbox(
|
||||
server => 'chan_master2',
|
||||
type => 'master',
|
||||
);
|
||||
my ($slave1_dbh, $slave1_dsn) = $sb->start_sandbox(
|
||||
server => 'chan_slave1',
|
||||
type => 'master',
|
||||
);
|
||||
my $slave1_port = $sb->port_for('chan_slave1');
|
||||
|
||||
$sb->load_file('chan_master1', "sandbox/gtid_on.sql", undef, no_wait => 1);
|
||||
$sb->load_file('chan_master2', "sandbox/gtid_on.sql", undef, no_wait => 1);
|
||||
$sb->load_file('chan_slave1', "sandbox/slave_channels.sql", undef, no_wait => 1);
|
||||
|
||||
my $chan_slaves = $ms->get_slaves(
|
||||
dbh => $master1_dbh,
|
||||
dsn => $master1_dsn,
|
||||
make_cxn => sub {
|
||||
my $cxn = new Cxn(
|
||||
@_,
|
||||
DSNParser => $dp,
|
||||
OptionParser => $o,
|
||||
);
|
||||
$cxn->connect();
|
||||
return $cxn;
|
||||
},
|
||||
);
|
||||
|
||||
our $message;
|
||||
local $SIG{__WARN__} = sub {
|
||||
$message = shift;
|
||||
};
|
||||
my $css = $ms->get_slave_status($slave1_dbh);
|
||||
local $SIG{__WARN__} = undef;
|
||||
is (
|
||||
$css,
|
||||
undef,
|
||||
'Cannot determine slave in a multi source config without --channel param'
|
||||
);
|
||||
like (
|
||||
$message,
|
||||
qr/This server returned more than one row for SHOW SLAVE STATUS/,
|
||||
'Got warning message if we cannot determine slave in a multi source config without --channel param',
|
||||
);
|
||||
|
||||
# Now try specifying a channel name
|
||||
$ms->{channel} = 'masterchan1';
|
||||
$css = $ms->get_slave_status($slave1_dbh);
|
||||
is (
|
||||
$css->{channel_name},
|
||||
'masterchan1',
|
||||
'Returned the correct slave',
|
||||
);
|
||||
|
||||
$sb->stop_sandbox(qw(chan_master1 chan_master2 chan_slave1));
|
||||
}
|
||||
# #############################################################################
|
||||
# Done.
|
||||
# #############################################################################
|
||||
|
Reference in New Issue
Block a user