diff --git a/bin/pt-archiver b/bin/pt-archiver index 136c324e..4356114a 100755 --- a/bin/pt-archiver +++ b/bin/pt-archiver @@ -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); diff --git a/bin/pt-heartbeat b/bin/pt-heartbeat index 151f405d..4f1c06dc 100755 --- a/bin/pt-heartbeat +++ b/bin/pt-heartbeat @@ -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); diff --git a/bin/pt-kill b/bin/pt-kill index 539eedfa..6631affa 100755 --- a/bin/pt-kill +++ b/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); diff --git a/bin/pt-online-schema-change b/bin/pt-online-schema-change index 95d5cc38..fb92c18f 100755 --- a/bin/pt-online-schema-change +++ b/bin/pt-online-schema-change @@ -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); diff --git a/bin/pt-query-digest b/bin/pt-query-digest index 2fad690b..6eba03da 100755 --- a/bin/pt-query-digest +++ b/bin/pt-query-digest @@ -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); diff --git a/bin/pt-slave-find b/bin/pt-slave-find index 578afa54..a7b4b153 100755 --- a/bin/pt-slave-find +++ b/bin/pt-slave-find @@ -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); diff --git a/bin/pt-slave-restart b/bin/pt-slave-restart index 52893fde..30941fa4 100755 --- a/bin/pt-slave-restart +++ b/bin/pt-slave-restart @@ -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); diff --git a/bin/pt-table-checksum b/bin/pt-table-checksum index 338c1bee..3f3ab88a 100755 --- a/bin/pt-table-checksum +++ b/bin/pt-table-checksum @@ -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); diff --git a/bin/pt-table-sync b/bin/pt-table-sync index 43e5e446..1fcbb6c3 100755 --- a/bin/pt-table-sync +++ b/bin/pt-table-sync @@ -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 diff --git a/lib/MasterSlave.pm b/lib/MasterSlave.pm index fa6b9852..276fec99 100644 --- a/lib/MasterSlave.pm +++ b/lib/MasterSlave.pm @@ -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); diff --git a/sandbox/gtid_on.sql b/sandbox/gtid_on.sql index 1de63bc2..f436d19e 100644 --- a/sandbox/gtid_on.sql +++ b/sandbox/gtid_on.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; diff --git a/t/lib/MasterSlave.t b/t/lib/MasterSlave.t index c2477ce7..152c46da 100644 --- a/t/lib/MasterSlave.t +++ b/t/lib/MasterSlave.t @@ -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. # #############################################################################