mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-01 18:25:59 +00:00
PT-2340 - Support MySQL 8.4
- Removed all unneeded occuriences of the word "master" in lib
This commit is contained in:
@@ -297,12 +297,12 @@ sub is_cluster_node {
|
||||
}
|
||||
|
||||
# There's two reasons why there might be dupes:
|
||||
# If the "master" is a cluster node, then a DSN table might have been
|
||||
# If the "source" is a cluster node, then a DSN table might have been
|
||||
# used, and it may have all nodes' DSNs so the user can run the tool
|
||||
# on any node, in which case it has the "master" node, the DSN given
|
||||
# on any node, in which case it has the "source" node, the DSN given
|
||||
# on the command line.
|
||||
# On the other hand, maybe find_cluster_nodes worked, in which case
|
||||
# we definitely have a dupe for the master cxn, but we may also have a
|
||||
# we definitely have a dupe for the source cxn, but we may also have a
|
||||
# dupe for every other node if this was used in conjunction with a
|
||||
# DSN table.
|
||||
# So try to detect and remove those.
|
||||
|
@@ -456,7 +456,7 @@ sub is_source_of {
|
||||
# compare and make sure the source and slave are reasonably close to each
|
||||
# other. Note that this is one of the few places where I check the I/O
|
||||
# thread positions instead of the SQL thread positions!
|
||||
# Master_Log_File/Read_Master_Log_Pos is the I/O thread's position on the
|
||||
# Source_Log_File/Read_Source_Log_Pos is the I/O thread's position on the
|
||||
# source.
|
||||
my ( $source_log_name, $source_log_num )
|
||||
= $source_status->{file} =~ m/^(.*?)\.0*([1-9][0-9]*)$/;
|
||||
@@ -474,7 +474,7 @@ sub is_source_of {
|
||||
}
|
||||
|
||||
# Figures out how to connect to the source, by examining SHOW SLAVE STATUS. But
|
||||
# does NOT use the value from Master_User for the username, because typically we
|
||||
# does NOT use the value from Source_User for the username, because typically we
|
||||
# want to perform operations as the username that was specified (usually to the
|
||||
# program's --user option, or in a DSN), rather than as the replication user,
|
||||
# which is often restricted.
|
||||
@@ -558,7 +558,7 @@ sub get_slave_status {
|
||||
}
|
||||
}
|
||||
|
||||
# Gets SHOW MASTER STATUS, with column names all lowercased, as a hashref.
|
||||
# Gets SHOW SOURCE STATUS, with column names all lowercased, as a hashref.
|
||||
sub get_source_status {
|
||||
my ( $self, $dbh ) = @_;
|
||||
|
||||
@@ -575,7 +575,7 @@ sub get_source_status {
|
||||
|
||||
my $sth;
|
||||
if ( $self->{sths}->{$dbh} && $dbh && $self->{sths}->{$dbh} == $dbh ) {
|
||||
$sth = $self->{sths}->{$dbh}->{MASTER_STATUS}
|
||||
$sth = $self->{sths}->{$dbh}->{SOURCE_STATUS}
|
||||
||= $dbh->prepare("SHOW ${source_name} STATUS");
|
||||
}
|
||||
else {
|
||||
@@ -597,7 +597,7 @@ sub get_source_status {
|
||||
}
|
||||
|
||||
# Sub: wait_for_source
|
||||
# Execute MASTER_POS_WAIT() to make slave wait for its source.
|
||||
# Execute SOURCE_POS_WAIT() to make slave wait for its source.
|
||||
#
|
||||
# Parameters:
|
||||
# %args - Arguments
|
||||
@@ -613,7 +613,7 @@ sub get_source_status {
|
||||
# Hashref with result of waiting, like:
|
||||
# (start code)
|
||||
# {
|
||||
# result => the result returned by MASTER_POS_WAIT: -1, undef, 0+
|
||||
# result => the result returned by SOURCE_POS_WAIT: -1, undef, 0+
|
||||
# waited => the number of seconds waited, might be zero
|
||||
# }
|
||||
# (end code)
|
||||
@@ -651,7 +651,7 @@ sub wait_for_source {
|
||||
my $start = time;
|
||||
($result) = $slave_dbh->selectrow_array($sql);
|
||||
|
||||
# If MASTER_POS_WAIT() returned NULL and we waited at least 1s
|
||||
# If SOURCE_POS_WAIT() returned NULL and we waited at least 1s
|
||||
# and the time we waited is less than the timeout then this is
|
||||
# a strong indication that the slave was stopped while we were
|
||||
# waiting.
|
||||
@@ -695,7 +695,7 @@ sub start_slave {
|
||||
$replica_name = 'slave';
|
||||
}
|
||||
if ( $pos ) {
|
||||
# Just like with CHANGE MASTER TO, you can't quote the position.
|
||||
# Just like with CHANGE REPLICATION SOURCE TO, you can't quote the position.
|
||||
my $sql = "START ${replica_name} UNTIL ${source_name}_LOG_FILE='$pos->{file}', "
|
||||
. "${source_name}_LOG_POS=$pos->{position}";
|
||||
PTDEBUG && _d($dbh, $sql);
|
||||
@@ -720,7 +720,7 @@ sub catchup_to_source {
|
||||
my $slave_pos = $self->repl_posn($slave_status);
|
||||
my $source_status = $self->get_source_status($source);
|
||||
my $source_pos = $self->repl_posn($source_status);
|
||||
PTDEBUG && _d('Master position:', $self->pos_to_string($source_pos),
|
||||
PTDEBUG && _d('Source position:', $self->pos_to_string($source_pos),
|
||||
'Slave position:', $self->pos_to_string($slave_pos));
|
||||
|
||||
my $result;
|
||||
@@ -729,7 +729,7 @@ sub catchup_to_source {
|
||||
$self->start_slave($slave, $source_pos);
|
||||
|
||||
# The slave may catch up instantly and stop, in which case
|
||||
# MASTER_POS_WAIT will return NULL and $result->{result} will be undef.
|
||||
# SOURCE_POS_WAIT will return NULL and $result->{result} will be undef.
|
||||
# We must catch this; if it returns NULL, then we check that
|
||||
# its position is as desired.
|
||||
# TODO: what if source_pos_wait times out and $result == -1? retry?
|
||||
@@ -745,12 +745,12 @@ sub catchup_to_source {
|
||||
if ( !defined $result->{result} ) {
|
||||
$slave_status = $self->get_slave_status($slave);
|
||||
if ( !$self->slave_is_running($slave_status) ) {
|
||||
PTDEBUG && _d('Master position:',
|
||||
PTDEBUG && _d('Source position:',
|
||||
$self->pos_to_string($source_pos),
|
||||
'Slave position:', $self->pos_to_string($slave_pos));
|
||||
$slave_pos = $self->repl_posn($slave_status);
|
||||
if ( $self->pos_cmp($slave_pos, $source_pos) != 0 ) {
|
||||
die "MASTER_POS_WAIT() returned NULL but slave has not "
|
||||
die "SOURCE_POS_WAIT() returned NULL but slave has not "
|
||||
. "caught up to source";
|
||||
}
|
||||
PTDEBUG && _d('Slave is caught up to source and stopped');
|
||||
@@ -815,12 +815,12 @@ sub has_slave_updates {
|
||||
return $value && $value =~ m/^(1|ON)$/;
|
||||
}
|
||||
|
||||
# Extracts the replication position out of either SHOW MASTER STATUS or SHOW
|
||||
# Extracts the replication position out of either SHOW REPLICATION SOURCE STATUS or SHOW
|
||||
# SLAVE STATUS, and returns it as a hashref { file, position }
|
||||
sub repl_posn {
|
||||
my ( $self, $status ) = @_;
|
||||
if ( exists $status->{file} && exists $status->{position} ) {
|
||||
# It's the output of SHOW MASTER STATUS
|
||||
# It's the output of SHOW BINARY LOG STATUS
|
||||
return {
|
||||
file => $status->{file},
|
||||
position => $status->{position},
|
||||
@@ -878,9 +878,9 @@ sub pos_cmp {
|
||||
sub short_host {
|
||||
my ( $self, $dsn ) = @_;
|
||||
my ($host, $port);
|
||||
if ( $dsn->{master_host} ) {
|
||||
$host = $dsn->{master_host};
|
||||
$port = $dsn->{master_port};
|
||||
if ( $dsn->{source_host} ) {
|
||||
$host = $dsn->{source_host};
|
||||
$port = $dsn->{source_port};
|
||||
}
|
||||
else {
|
||||
$host = $dsn->{h};
|
||||
|
@@ -702,18 +702,25 @@ sub normalize_checksum_results {
|
||||
return $normal_output;
|
||||
}
|
||||
|
||||
sub get_master_binlog_pos {
|
||||
sub get_source_binlog_pos {
|
||||
my ($dbh) = @_;
|
||||
my $sql = "SHOW MASTER STATUS";
|
||||
|
||||
my $vp = VersionParser->new($dbh);
|
||||
my $source_name = 'source';
|
||||
if ( $vp->cmp('8.1') < 0 || $vp->flavor() =~ m/maria/i ) {
|
||||
$source_name = 'master';
|
||||
}
|
||||
|
||||
my $sql = "SHOW ${source_name} STATUS";
|
||||
my $ms = $dbh->selectrow_hashref($sql);
|
||||
return $ms->{position};
|
||||
}
|
||||
|
||||
sub get_slave_pos_relative_to_master {
|
||||
sub get_slave_pos_relative_to_source {
|
||||
my ($dbh) = @_;
|
||||
my $sql = "SHOW SLAVE STATUS";
|
||||
my $ss = $dbh->selectrow_hashref($sql);
|
||||
return $ss->{exec_master_log_pos};
|
||||
return $ss->{exec_source_log_pos};
|
||||
}
|
||||
|
||||
# Like output(), but forks a process to execute the coderef.
|
||||
|
@@ -112,7 +112,7 @@ sub find_cluster_nodes {
|
||||
# If there wasn't a port, that means that this bug
|
||||
# https://bugs.launchpad.net/percona-toolkit/+bug/1082406
|
||||
# isn't fixed on this version of PXC. We tried using the
|
||||
# master's port, but that didn't work. So try again, using
|
||||
# source's port, but that didn't work. So try again, using
|
||||
# the default port.
|
||||
if ( !$port && $dsn->{P} != 3306 ) {
|
||||
$address .= ":3306";
|
||||
|
@@ -760,18 +760,34 @@ sub normalize_checksum_results {
|
||||
return $normal_output;
|
||||
}
|
||||
|
||||
sub get_master_binlog_pos {
|
||||
sub get_source_binlog_pos {
|
||||
my ($dbh) = @_;
|
||||
my $sql = "SHOW MASTER STATUS";
|
||||
|
||||
my $vp = VersionParser->new($dbh);
|
||||
my $source_name = 'source';
|
||||
if ( $vp->cmp('8.1') < 0 || $vp->flavor() =~ m/maria/i ) {
|
||||
$source_name = 'master';
|
||||
}
|
||||
|
||||
my $sql = "SHOW ${source_name} STATUS";
|
||||
my $ms = $dbh->selectrow_hashref($sql);
|
||||
return $ms->{position};
|
||||
}
|
||||
|
||||
sub get_slave_pos_relative_to_master {
|
||||
sub get_slave_pos_relative_to_source {
|
||||
my ($dbh) = @_;
|
||||
my $sql = "SHOW SLAVE STATUS";
|
||||
|
||||
my $vp = VersionParser->new($dbh);
|
||||
my $source_name = 'source';
|
||||
my $replica_name = 'replica';
|
||||
if ( $vp->cmp('8.1') < 0 || $vp->flavor() =~ m/maria/i ) {
|
||||
$source_name = 'master';
|
||||
$replica_name = 'slave';
|
||||
}
|
||||
|
||||
my $sql = "SHOW ${replica_name} STATUS";
|
||||
my $ss = $dbh->selectrow_hashref($sql);
|
||||
return $ss->{exec_master_log_pos};
|
||||
return $ss->{"exec_${source_name}_log_pos"};
|
||||
}
|
||||
|
||||
# Like output(), but forks a process to execute the coderef.
|
||||
|
@@ -19,7 +19,7 @@
|
||||
# ###########################################################################
|
||||
{
|
||||
# Package: ReplicaLagWaiter
|
||||
# ReplicaLagWaiter helps limit slave lag when working on the master.
|
||||
# ReplicaLagWaiter helps limit slave lag when working on the source.
|
||||
package ReplicaLagWaiter;
|
||||
|
||||
use strict;
|
||||
@@ -56,7 +56,7 @@ sub new {
|
||||
}
|
||||
|
||||
# Sub: wait
|
||||
# Wait for Seconds_Behind_Master on all slaves to become < max.
|
||||
# Wait for Seconds_Behind_Source on all slaves to become < max.
|
||||
#
|
||||
# Optional Arguments:
|
||||
# Progress - <Progress> object to report waiting
|
||||
|
@@ -468,7 +468,7 @@ sub _make_xor_slices {
|
||||
return join(', ', @slices);
|
||||
}
|
||||
|
||||
# Queries the replication table for chunks that differ from the master's data.
|
||||
# Queries the replication table for chunks that differ from the source's data.
|
||||
sub find_replication_differences {
|
||||
my ($self, %args) = @_;
|
||||
my @required_args = qw(dbh repl_table);
|
||||
@@ -484,13 +484,13 @@ sub find_replication_differences {
|
||||
my $sql
|
||||
= "SELECT CONCAT(db, '.', tbl) AS `table`, "
|
||||
. "chunk, chunk_index, lower_boundary, upper_boundary, "
|
||||
. "COALESCE(this_cnt-master_cnt, 0) AS cnt_diff, "
|
||||
. "COALESCE(this_cnt-source_cnt, 0) AS cnt_diff, "
|
||||
. "COALESCE("
|
||||
. "this_crc <> master_crc OR ISNULL(master_crc) <> ISNULL(this_crc), 0"
|
||||
. ") AS crc_diff, this_cnt, master_cnt, this_crc, master_crc "
|
||||
. "this_crc <> source_crc OR ISNULL(source_crc) <> ISNULL(this_crc), 0"
|
||||
. ") AS crc_diff, this_cnt, source_cnt, this_crc, source_crc "
|
||||
. "FROM $repl_table "
|
||||
. "WHERE (master_cnt <> this_cnt OR master_crc <> this_crc "
|
||||
. "OR ISNULL(master_crc) <> ISNULL(this_crc)) "
|
||||
. "WHERE (source_cnt <> this_cnt OR source_crc <> this_crc "
|
||||
. "OR ISNULL(source_crc) <> ISNULL(this_crc)) "
|
||||
. ($args{where} ? " AND ($args{where})" : "");
|
||||
PTDEBUG && _d($sql);
|
||||
$diffs = $dbh->selectall_arrayref($sql, { Slice => {} });
|
||||
|
@@ -218,22 +218,22 @@ sub wipe_clean {
|
||||
}
|
||||
|
||||
# Returns a string if there is a problem with the source.
|
||||
sub master_is_ok {
|
||||
my ($self, $master) = @_;
|
||||
my $master_dbh = $self->get_dbh_for($master);
|
||||
if ( !$master_dbh ) {
|
||||
return "Sandbox $master " . $port_for{$master} . " is down.";
|
||||
sub source_is_ok {
|
||||
my ($self, $source) = @_;
|
||||
my $source_dbh = $self->get_dbh_for($source);
|
||||
if ( !$source_dbh ) {
|
||||
return "Sandbox $source " . $port_for{$source} . " is down.";
|
||||
}
|
||||
$master_dbh->disconnect();
|
||||
$source_dbh->disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
# Returns a string if there is a problem with the replica.
|
||||
sub slave_is_ok {
|
||||
my ($self, $slave, $master, $ro) = @_;
|
||||
my ($self, $slave, $source, $ro) = @_;
|
||||
return if $self->is_cluster_node($slave);
|
||||
PTDEBUG && _d('Checking if replica', $slave, $port_for{$slave},
|
||||
'to', $master, $port_for{$master}, 'is ok');
|
||||
'to', $source, $port_for{$source}, 'is ok');
|
||||
|
||||
my $slave_dbh = $self->get_dbh_for($slave);
|
||||
if ( !$slave_dbh ) {
|
||||
@@ -242,10 +242,12 @@ sub slave_is_ok {
|
||||
|
||||
my $vp = VersionParser->new($slave_dbh);
|
||||
my $replica_name = 'replica';
|
||||
my $source_name = 'source';
|
||||
if ( $vp->cmp('8.1') < 0 || $vp->flavor() =~ m/maria/i ) {
|
||||
$replica_name = 'slave';
|
||||
$source_name = 'master';
|
||||
}
|
||||
my $master_port = $port_for{$master};
|
||||
my $source_port = $port_for{$source};
|
||||
my $status = $slave_dbh->selectall_arrayref(
|
||||
"SHOW ${replica_name} STATUS", { Slice => {} });
|
||||
if ( !$status || !@$status ) {
|
||||
@@ -276,9 +278,9 @@ sub slave_is_ok {
|
||||
|
||||
my $sleep_t = 0.25;
|
||||
my $total_t = 0;
|
||||
while ( defined $status->[0]->{seconds_behind_master}
|
||||
&& $status->[0]->{seconds_behind_master} > 0 ) {
|
||||
PTDEBUG && _d('Replica lag:', $status->[0]->{seconds_behind_master});
|
||||
while ( defined $status->[0]->{"seconds_behind_${source_name}"}
|
||||
&& $status->[0]->{"seconds_behind_${source_name}"} > 0 ) {
|
||||
PTDEBUG && _d('Replica lag:', $status->[0]->{"seconds_behind_${source_name}"});
|
||||
sleep $sleep_t;
|
||||
$total_t += $sleep_t;
|
||||
$status = $slave_dbh->selectall_arrayref(
|
||||
@@ -330,7 +332,7 @@ sub ok {
|
||||
my @errors;
|
||||
# First, wait for all replicas to be caught up to their sources.
|
||||
$self->wait_for_slaves();
|
||||
push @errors, $self->master_is_ok('source');
|
||||
push @errors, $self->source_is_ok('source');
|
||||
push @errors, $self->slave_is_ok('replica1', 'source');
|
||||
push @errors, $self->slave_is_ok('replica2', 'replica1', 1);
|
||||
push @errors, $self->leftover_servers();
|
||||
@@ -346,10 +348,10 @@ sub ok {
|
||||
# Dings a heartbeat on the source, and waits until the replica catches up fully.
|
||||
sub wait_for_slaves {
|
||||
my ($self, %args) = @_;
|
||||
my $master_dbh = $self->get_dbh_for($args{source} || 'source');
|
||||
my $source_dbh = $self->get_dbh_for($args{source} || 'source');
|
||||
my $slave2_dbh = $self->get_dbh_for($args{replica} || 'replica2');
|
||||
my ($ping) = $master_dbh->selectrow_array("SELECT MD5(RAND())");
|
||||
$master_dbh->do("UPDATE percona_test.sentinel SET ping='$ping' WHERE id=1 /* wait_for_slaves */");
|
||||
my ($ping) = $source_dbh->selectrow_array("SELECT MD5(RAND())");
|
||||
$source_dbh->do("UPDATE percona_test.sentinel SET ping='$ping' WHERE id=1 /* wait_for_slaves */");
|
||||
PerconaTest::wait_until(
|
||||
sub {
|
||||
my ($pong) = $slave2_dbh->selectrow_array(
|
||||
@@ -366,8 +368,8 @@ sub verify_test_data {
|
||||
my ($self, $host) = @_;
|
||||
|
||||
# Get the known-good checksums from the source.
|
||||
my $master = $self->get_dbh_for('source');
|
||||
my $ref = $self->{checksum_ref} || $master->selectall_hashref(
|
||||
my $source = $self->get_dbh_for('source');
|
||||
my $ref = $self->{checksum_ref} || $source->selectall_hashref(
|
||||
'SELECT * FROM percona_test.checksums',
|
||||
'db_tbl');
|
||||
$self->{checksum_ref} = $ref unless $self->{checksum_ref};
|
||||
@@ -379,11 +381,11 @@ sub verify_test_data {
|
||||
grep { !/user$/ }
|
||||
grep { !/proxies_priv$/ }
|
||||
grep { !/global_grants$/ }
|
||||
@{$master->selectcol_arrayref('SHOW TABLES FROM mysql')};
|
||||
@{$source->selectcol_arrayref('SHOW TABLES FROM mysql')};
|
||||
my @tables_in_sakila = qw(actor address category city country customer
|
||||
film film_actor film_category film_text inventory
|
||||
language payment rental staff store);
|
||||
$master->disconnect;
|
||||
$source->disconnect;
|
||||
|
||||
# Get the current checksums on the host.
|
||||
my $dbh = $self->get_dbh_for($host);
|
||||
@@ -468,15 +470,31 @@ sub can_load_data {
|
||||
}
|
||||
|
||||
sub set_as_slave {
|
||||
my ($self, $server, $master_server, @extras) = @_;
|
||||
PTDEBUG && _d("Setting $server as replica of $master_server");
|
||||
my $master_port = $port_for{$master_server};
|
||||
my $sql = join ", ", qq{change master to master_host='127.0.0.1'},
|
||||
qq{master_user='msandbox'},
|
||||
qq{master_password='msandbox'},
|
||||
qq{master_port=$master_port},
|
||||
my ($self, $server, $source_server, @extras) = @_;
|
||||
PTDEBUG && _d("Setting $server as replica of $source_server");
|
||||
|
||||
my $dbh = $self->get_dbh_for($server);
|
||||
if ( !$dbh ) {
|
||||
return "Sandbox $server " . $port_for{$server} . " is down.";
|
||||
}
|
||||
|
||||
my $vp = VersionParser->new($dbh);
|
||||
my $replica_name = 'replica';
|
||||
my $source_name = 'source';
|
||||
my $replication_source_name = 'replication source';
|
||||
if ( $vp->cmp('8.1') < 0 || $vp->flavor() =~ m/maria/i ) {
|
||||
$replica_name = 'slave';
|
||||
$source_name = 'master';
|
||||
$replication_source_name = 'master';
|
||||
}
|
||||
|
||||
my $source_port = $port_for{$source_server};
|
||||
my $sql = join ", ", qq{change ${replication_source_name} to ${source_name}_host='127.0.0.1'},
|
||||
qq{${source_name}_user='msandbox'},
|
||||
qq{${source_name}_password='msandbox'},
|
||||
qq{${source_name}_port=$source_port},
|
||||
@extras;
|
||||
for my $sql_to_run ($sql, "start slave") {
|
||||
for my $sql_to_run ($sql, "start ${replica_name}") {
|
||||
my $out = $self->use($server, qq{-e "$sql_to_run"});
|
||||
PTDEBUG && _d($out);
|
||||
}
|
||||
@@ -502,9 +520,9 @@ sub start_sandbox {
|
||||
elsif ( $type eq 'replica' ) {
|
||||
die "I need a replica arg" unless $args{source};
|
||||
_check_server($args{source});
|
||||
my $master_port = $port_for{$args{source}};
|
||||
my $source_port = $port_for{$args{source}};
|
||||
|
||||
my $out = `$env $trunk/sandbox/start-sandbox $type $port $master_port`;
|
||||
my $out = `$env $trunk/sandbox/start-sandbox $type $port $source_port`;
|
||||
die $out if $CHILD_ERROR;
|
||||
}
|
||||
elsif ( $type eq 'node' ) {
|
||||
|
@@ -469,20 +469,20 @@ sub make_checksum_query {
|
||||
return $result . "FROM /*DB_TBL*//*INDEX_HINT*//*WHERE*/";
|
||||
}
|
||||
|
||||
# Queries the replication table for chunks that differ from the master's data.
|
||||
# Queries the replication table for chunks that differ from the source's data.
|
||||
sub find_replication_differences {
|
||||
my ( $self, $dbh, $table ) = @_;
|
||||
|
||||
my $sql
|
||||
= "SELECT db, tbl, CONCAT(db, '.', tbl) AS `table`, "
|
||||
. "chunk, chunk_index, lower_boundary, upper_boundary, "
|
||||
. "COALESCE(this_cnt-master_cnt, 0) AS cnt_diff, "
|
||||
. "COALESCE(this_cnt-source_cnt, 0) AS cnt_diff, "
|
||||
. "COALESCE("
|
||||
. "this_crc <> master_crc OR ISNULL(master_crc) <> ISNULL(this_crc), 0"
|
||||
. ") AS crc_diff, this_cnt, master_cnt, this_crc, master_crc "
|
||||
. "this_crc <> source_crc OR ISNULL(source_crc) <> ISNULL(this_crc), 0"
|
||||
. ") AS crc_diff, this_cnt, source_cnt, this_crc, source_crc "
|
||||
. "FROM $table "
|
||||
. "WHERE master_cnt <> this_cnt OR master_crc <> this_crc "
|
||||
. "OR ISNULL(master_crc) <> ISNULL(this_crc)";
|
||||
. "WHERE source_cnt <> this_cnt OR source_crc <> this_crc "
|
||||
. "OR ISNULL(source_crc) <> ISNULL(this_crc)";
|
||||
PTDEBUG && _d($sql);
|
||||
my $diffs = $dbh->selectall_arrayref($sql, { Slice => {} });
|
||||
return $diffs;
|
||||
|
@@ -255,7 +255,7 @@ sub sync_table {
|
||||
$dst_sql .= ' FOR UPDATE';
|
||||
}
|
||||
elsif ( $args{changing_src} ) {
|
||||
# Making changes on master (src) which replicate to slave (dst).
|
||||
# Making changes on source (src) which replicate to slave (dst).
|
||||
$src_sql .= ' FOR UPDATE';
|
||||
$dst_sql .= ' LOCK IN SHARE MODE';
|
||||
}
|
||||
@@ -441,7 +441,7 @@ sub unlock {
|
||||
# src hashref
|
||||
# dst hashref
|
||||
# Optional arguments:
|
||||
# * wait_retry_args hashref: retry args for retrying wait/MASTER_POS_WAIT
|
||||
# * wait_retry_args hashref: retry args for retrying wait/SOURCE_POS_WAIT
|
||||
# Lock levels:
|
||||
# 0 => none
|
||||
# 1 => per sync cycle
|
||||
@@ -449,7 +449,7 @@ sub unlock {
|
||||
# 3 => global
|
||||
# This function might actually execute the $src_sth. If we're using
|
||||
# transactions instead of table locks, the $src_sth has to be executed before
|
||||
# the MASTER_POS_WAIT() on the slave. The return value is whether the
|
||||
# the SOURCE_POS_WAIT() on the slave. The return value is whether the
|
||||
# $src_sth was executed.
|
||||
sub lock_and_wait {
|
||||
my ( $self, %args ) = @_;
|
||||
@@ -523,10 +523,10 @@ sub lock_and_wait {
|
||||
# here are the passed-in args, not the args to lock_and_wait().
|
||||
|
||||
if ( $args{tryno} > 1 ) {
|
||||
warn "Retrying MASTER_POS_WAIT() for --wait $timeout...";
|
||||
warn "Retrying SOURCE_POS_WAIT() for --wait $timeout...";
|
||||
}
|
||||
|
||||
# Always use the misc_dbh dbh to check the master's position
|
||||
# Always use the misc_dbh dbh to check the source's position
|
||||
# because the main dbh might be in use due to executing
|
||||
# $src_sth.
|
||||
$wait = $ms->wait_for_source(
|
||||
@@ -552,10 +552,10 @@ sub lock_and_wait {
|
||||
my $msg;
|
||||
if ( $wait->{waited} ) {
|
||||
$msg = "The slave was stopped while waiting with "
|
||||
. "MASTER_POS_WAIT().";
|
||||
. "SOURCE_POS_WAIT().";
|
||||
}
|
||||
else {
|
||||
$msg = "MASTER_POS_WAIT() returned NULL. Verify that "
|
||||
$msg = "SOURCE_POS_WAIT() returned NULL. Verify that "
|
||||
. "the slave is running.";
|
||||
}
|
||||
if ( $tries - $args{tryno} ) {
|
||||
@@ -566,26 +566,26 @@ sub lock_and_wait {
|
||||
return 1; # call wait, call try
|
||||
}
|
||||
elsif ( $wait->{result} == -1 ) {
|
||||
# MASTER_POS_WAIT timed out, don't retry since we've
|
||||
# SOURCE_POS_WAIT timed out, don't retry since we've
|
||||
# already waited as long as the user specified with --wait.
|
||||
return 0; # call final_fail
|
||||
}
|
||||
},
|
||||
final_fail => sub {
|
||||
die "Slave did not catch up to its master after $tries attempts "
|
||||
. "of waiting $timeout seconds with MASTER_POS_WAIT. "
|
||||
die "Slave did not catch up to its source after $tries attempts "
|
||||
. "of waiting $timeout seconds with SOURCE_POS_WAIT. "
|
||||
. "Check that the slave is running, increase the --wait "
|
||||
. "time, or disable this feature by specifying --wait 0.";
|
||||
},
|
||||
); # retry MasterSlave::wait_for_master()
|
||||
); # retry MasterSlave::wait_for_source()
|
||||
}
|
||||
|
||||
# Don't lock the destination if we're making changes on the source
|
||||
# (for sync-to-master and sync via replicate) else the destination
|
||||
# (for sync-to-source and sync via replicate) else the destination
|
||||
# won't be apply to make the changes.
|
||||
if ( $args{changing_src} ) {
|
||||
PTDEBUG && _d('Not locking destination because changing source ',
|
||||
'(syncing via replication or sync-to-master)');
|
||||
'(syncing via replication or sync-to-source)');
|
||||
}
|
||||
else {
|
||||
if ( $args{lock} == 3 ) {
|
||||
|
@@ -67,7 +67,7 @@ sub new {
|
||||
# n adjust to meet target_t based on weighted decaying avg rate
|
||||
sub update {
|
||||
my ($self, $n, $t) = @_;
|
||||
PTDEBUG && _d('Master op time:', $n, 'n /', $t, 's');
|
||||
PTDEBUG && _d('Source op time:', $n, 'n /', $t, 's');
|
||||
|
||||
if ( $self->{avg_n} && $self->{avg_t} ) {
|
||||
$self->{avg_n} = ($self->{avg_n} * $self->{weight}) + $n;
|
||||
|
@@ -150,11 +150,19 @@ collect_mysql_show_slave_hosts () {
|
||||
$CMD_MYSQL $EXT_ARGV -ssE -e 'SHOW SLAVE HOSTS' 2>/dev/null
|
||||
}
|
||||
|
||||
collect_master_logs_status () {
|
||||
local master_logs_file="$1"
|
||||
local master_status_file="$2"
|
||||
$CMD_MYSQL $EXT_ARGV -ss -e 'SHOW MASTER LOGS' > "$master_logs_file" 2>/dev/null
|
||||
$CMD_MYSQL $EXT_ARGV -ss -e 'SHOW MASTER STATUS' > "$master_status_file" 2>/dev/null
|
||||
collect_source_logs_status () {
|
||||
local source_logs_file="$1"
|
||||
local source_status_file="$2"
|
||||
local version="$3"
|
||||
|
||||
local source_log='binary'
|
||||
local source_status='binary log'
|
||||
if [ "$version" '<' "8.1" ]; then
|
||||
source_log = 'master'
|
||||
source_status = 'master'
|
||||
fi
|
||||
$CMD_MYSQL $EXT_ARGV -ss -e "SHOW ${source_log} LOGS" > "$source_logs_file" 2>/dev/null
|
||||
$CMD_MYSQL $EXT_ARGV -ss -e "SHOW ${source_status} STATUS" > "$source_status_file" 2>/dev/null
|
||||
}
|
||||
|
||||
# Somewhat different from the others, this one joins the status we got earlier
|
||||
@@ -303,10 +311,19 @@ collect_mysql_info () {
|
||||
collect_mysqld_executables "$dir/mysqld-instances" > "$dir/mysqld-executables"
|
||||
collect_mysql_show_slave_hosts "$dir/mysql-slave-hosts" > "$dir/mysql-slave-hosts"
|
||||
|
||||
local mysql_version="$(get_var version "$dir/mysql-variables")"
|
||||
|
||||
local binlog="$(get_var log_bin "$dir/mysql-variables")"
|
||||
if [ "${binlog}" ]; then
|
||||
# "Got a binlog, going to get MASTER LOGS and MASTER STATUS"
|
||||
collect_master_logs_status "$dir/mysql-master-logs" "$dir/mysql-master-status"
|
||||
# "Got a binlog, going to get BINARY LOGS and BINARY LOG STATUS"
|
||||
local source_logs_file="mysql-binary-logs"
|
||||
local source_status_file="mysql-binary-log-status"
|
||||
|
||||
if [ "$mysql_version" '<' "8.1" ]; then
|
||||
source_logs_file='mysql-master-logs'
|
||||
source_status_file='mysql-master-status'
|
||||
fi
|
||||
collect_source_logs_status "$dir/$source_logs_file" "$dir/$source_status_file" ${mysql_version}
|
||||
fi
|
||||
|
||||
local uptime="$(get_var Uptime "$dir/mysql-status")"
|
||||
@@ -337,7 +354,6 @@ collect_mysql_info () {
|
||||
|
||||
# encrypted tables and tablespaces
|
||||
if [ "${OPT_LIST_ENCRYPTED_TABLES}" = 'yes' ]; then
|
||||
local mysql_version="$(get_var version "$dir/mysql-variables")"
|
||||
collect_encrypted_tables > "$dir/encrypted-tables"
|
||||
collect_encrypted_tablespaces ${mysql_version} > "$dir/encrypted-tablespaces"
|
||||
fi
|
||||
|
@@ -74,7 +74,7 @@ section () {
|
||||
}
|
||||
|
||||
NAME_VAL_LEN=12
|
||||
name_val () {
|
||||
name_val() {
|
||||
# We use $NAME_VAL_LEN here because the two summary tools, as well as
|
||||
# the tests, use different widths.
|
||||
printf "%+*s | %s\n" "${NAME_VAL_LEN}" "$1" "$2"
|
||||
@@ -113,7 +113,7 @@ shorten() {
|
||||
'
|
||||
}
|
||||
|
||||
group_concat () {
|
||||
group_concat() {
|
||||
sed -e '{H; $!d;}' -e 'x' -e 's/\n[[:space:]]*\([[:digit:]]*\)[[:space:]]*/, \1x/g' -e 's/[[:space:]][[:space:]]*/ /g' -e 's/, //' "${1}"
|
||||
}
|
||||
|
||||
|
@@ -200,7 +200,7 @@ get_mysql_uptime () {
|
||||
echo "${restart} (up ${uptime})"
|
||||
}
|
||||
|
||||
# Summarizes the output of SHOW MASTER LOGS.
|
||||
# Summarizes the output of SHOW BINARY LOGS.
|
||||
summarize_binlogs () {
|
||||
local file="$1"
|
||||
|
||||
@@ -1144,13 +1144,13 @@ _semi_sync_stats_for () {
|
||||
name_val "${target} semisync status" "${semisync_status}"
|
||||
name_val "${target} trace level" "${semisync_trace}, ${trace_extra}"
|
||||
|
||||
if [ "${target}" = "master" ]; then
|
||||
if [ "${target}" = "source" ] || [ "${target}" = "master" ]; then
|
||||
name_val "${target} timeout in milliseconds" \
|
||||
"$(get_var "rpl_semi_sync_${target}_timeout" "${file}")"
|
||||
name_val "${target} waits for slaves" \
|
||||
"$(get_var "rpl_semi_sync_${target}_wait_no_slave" "${file}")"
|
||||
|
||||
_d "Prepend Rpl_semi_sync_master_ to the following"
|
||||
_d "Prepend Rpl_semi_sync_${target}_ to the following"
|
||||
for v in \
|
||||
clients net_avg_wait_time net_wait_time net_waits \
|
||||
no_times no_tx timefunc_failures tx_avg_wait_time \
|
||||
@@ -1158,7 +1158,7 @@ _semi_sync_stats_for () {
|
||||
wait_sessions yes_tx;
|
||||
do
|
||||
name_val "${target} ${v}" \
|
||||
"$( get_var "Rpl_semi_sync_master_${v}" "${file}" )"
|
||||
"$( get_var "Rpl_semi_sync_${target}_${v}" "${file}" )"
|
||||
done
|
||||
fi
|
||||
}
|
||||
@@ -1330,6 +1330,21 @@ report_mysql_summary () {
|
||||
local user="$(get_var "pt-summary-internal-user" "$dir/mysql-variables")"
|
||||
local port="$(get_var port "$dir/mysql-variables")"
|
||||
local now="$(get_var "pt-summary-internal-now" "$dir/mysql-variables")"
|
||||
local mysql_version="$(get_var version "$dir/mysql-variables")"
|
||||
|
||||
local source_name='source'
|
||||
local source_log='binary'
|
||||
local source_status='binary log'
|
||||
local source_logs_file="mysql-binary-logs"
|
||||
local source_status_file="mysql-binary-log-status"
|
||||
if [ "${mysql_version}" '<' "8.1" ]; then
|
||||
source_name='master'
|
||||
source_log='master'
|
||||
source_status='master'
|
||||
source_logs_file='mysql-master-logs'
|
||||
source_status_file='mysql-master-status'
|
||||
fi
|
||||
|
||||
section "Report On Port ${port}"
|
||||
name_val User "${user}"
|
||||
name_val Time "${now} ($(get_mysql_timezone "$dir/mysql-variables"))"
|
||||
@@ -1432,13 +1447,13 @@ report_mysql_summary () {
|
||||
name_val HitToInsertRatio "${hrat}"
|
||||
fi
|
||||
|
||||
local semisync_enabled_master="$(get_var "rpl_semi_sync_master_enabled" "$dir/mysql-variables")"
|
||||
if [ -n "${semisync_enabled_master}" ]; then
|
||||
local semisync_enabled_source="$(get_var "rpl_semi_sync_${source_name}_enabled" "$dir/mysql-variables")"
|
||||
if [ -n "${semisync_enabled_source}" ]; then
|
||||
section "Semisynchronous Replication"
|
||||
if [ "$semisync_enabled_master" = "OFF" -o "$semisync_enabled_master" = "0" -o -z "$semisync_enabled_master" ]; then
|
||||
name_val "Master" "Disabled"
|
||||
if [ "$semisync_enabled_source" = "OFF" -o "$semisync_enabled_source" = "0" -o -z "$semisync_enabled_source" ]; then
|
||||
name_val "Source" "Disabled"
|
||||
else
|
||||
_semi_sync_stats_for "master" "$dir/mysql-variables"
|
||||
_semi_sync_stats_for "${source_name}" "$dir/mysql-variables"
|
||||
fi
|
||||
local semisync_enabled_slave="$(get_var rpl_semi_sync_slave_enabled "$dir/mysql-variables")"
|
||||
if [ "$semisync_enabled_slave" = "OFF" -o "$semisync_enabled_slave" = "0" -o -z "$semisync_enabled_slave" ]; then
|
||||
@@ -1610,15 +1625,15 @@ report_mysql_summary () {
|
||||
# ########################################################################
|
||||
section "Binary Logging"
|
||||
|
||||
if [ -s "$dir/mysql-master-logs" ] \
|
||||
|| [ -s "$dir/mysql-master-status" ]; then
|
||||
summarize_binlogs "$dir/mysql-master-logs"
|
||||
if [ -s "$dir/$source_logs_file" ] \
|
||||
|| [ -s "$dir/$source_status_file" ]; then
|
||||
summarize_binlogs "$dir/$source_logs_file"
|
||||
local format="$(get_var binlog_format "$dir/mysql-variables")"
|
||||
name_val binlog_format "${format:-STATEMENT}"
|
||||
name_val expire_logs_days "$(get_var expire_logs_days "$dir/mysql-variables")"
|
||||
name_val sync_binlog "$(get_var sync_binlog "$dir/mysql-variables")"
|
||||
name_val server_id "$(get_var server_id "$dir/mysql-variables")"
|
||||
format_binlog_filters "$dir/mysql-master-status"
|
||||
format_binlog_filters "$dir/$source_status_file"
|
||||
fi
|
||||
|
||||
# Replication: seconds behind, running, filters, skip_slave_start, skip_errors,
|
||||
|
Reference in New Issue
Block a user