PT-2340 - Support MySQL 8.4

- Fixed staff I broke for 8.0
This commit is contained in:
Sveta Smirnova
2024-08-22 14:29:53 +03:00
parent a38bee6d60
commit b332537481
31 changed files with 222 additions and 160 deletions

View File

@@ -3922,8 +3922,10 @@ sub _find_replicas_by_hosts {
my $vp = VersionParser->new($dbh);
my $sql = 'SHOW REPLICAS';
my $source_name = 'source';
if ( $vp < '8.1' || $vp->flavor() =~ m/maria/ ) {
$sql = 'SHOW SLAVE HOSTS';
$source_name='master';
}
PTDEBUG && _d($dbh, $sql);
@@ -3939,7 +3941,7 @@ sub _find_replicas_by_hosts {
. ( $hash{password} ? ",p=$hash{password}" : '');
my $dsn = $dsn_parser->parse($spec, $dsn);
$dsn->{server_id} = $hash{server_id};
$dsn->{source_id} = $hash{source_id};
$dsn->{source_id} = $hash{"${source_name}_id"};
$dsn->{source} = 'hosts';
$dsn;
} @replicas;
@@ -4018,9 +4020,9 @@ sub is_source_of {
. "but the source's port is $port";
}
if ( !grep { $replica_status->{source_user} eq $_->{user} } @connected ) {
if ( !grep { $replica_status->{"${source_name}_user"} eq $_->{user} } @connected ) {
die "I don't see any replica I/O thread connected with user "
. $replica_status->{source_user};
. $replica_status->{"${source_name}_user"};
}
if ( ($replica_status->{replica_io_state} || '')
@@ -4063,7 +4065,7 @@ sub get_replica_status {
my $server_version = VersionParser->new($dbh);
my $replica_name = 'replica';
if ( $server_version < '8.1' || $server_version->flavor() =~ m/maria/ ) {
$replica_name = 'replica';
$replica_name = 'slave';
}
if ( !$self->{not_a_replica}->{$dbh} ) {
@@ -4206,7 +4208,7 @@ sub stop_replica {
my $vp = VersionParser->new($dbh);
my $replica_name = 'replica';
if ( $vp < '8.1' || $vp->flavor() =~ m/maria/ ) {
$replica_name = 'replica';
$replica_name = 'slave';
}
my $sth = $self->{sths}->{$dbh}->{STOP_REPLICA}
||= $dbh->prepare("STOP ${replica_name}");

View File

@@ -383,8 +383,10 @@ sub _find_replicas_by_hosts {
my $vp = VersionParser->new($dbh);
my $sql = 'SHOW REPLICAS';
my $source_name = 'source';
if ( $vp < '8.1' || $vp->flavor() =~ m/maria/ ) {
$sql = 'SHOW SLAVE HOSTS';
$source_name='master';
}
PTDEBUG && _d($dbh, $sql);
@@ -400,7 +402,7 @@ sub _find_replicas_by_hosts {
. ( $hash{password} ? ",p=$hash{password}" : '');
my $dsn = $dsn_parser->parse($spec, $dsn);
$dsn->{server_id} = $hash{server_id};
$dsn->{source_id} = $hash{source_id};
$dsn->{source_id} = $hash{"${source_name}_id"};
$dsn->{source} = 'hosts';
$dsn;
} @replicas;
@@ -479,9 +481,9 @@ sub is_source_of {
. "but the source's port is $port";
}
if ( !grep { $replica_status->{source_user} eq $_->{user} } @connected ) {
if ( !grep { $replica_status->{"${source_name}_user"} eq $_->{user} } @connected ) {
die "I don't see any replica I/O thread connected with user "
. $replica_status->{source_user};
. $replica_status->{"${source_name}_user"};
}
if ( ($replica_status->{replica_io_state} || '')
@@ -524,7 +526,7 @@ sub get_replica_status {
my $server_version = VersionParser->new($dbh);
my $replica_name = 'replica';
if ( $server_version < '8.1' || $server_version->flavor() =~ m/maria/ ) {
$replica_name = 'replica';
$replica_name = 'slave';
}
if ( !$self->{not_a_replica}->{$dbh} ) {
@@ -667,7 +669,7 @@ sub stop_replica {
my $vp = VersionParser->new($dbh);
my $replica_name = 'replica';
if ( $vp < '8.1' || $vp->flavor() =~ m/maria/ ) {
$replica_name = 'replica';
$replica_name = 'slave';
}
my $sth = $self->{sths}->{$dbh}->{STOP_REPLICA}
||= $dbh->prepare("STOP ${replica_name}");
@@ -6105,6 +6107,9 @@ sub main {
@dbhs = ();
@sths = ();
my $relay_source_log_file_col = 'relay_source_log_file';
my $exec_source_log_pos_col = 'exec_source_log_pos';
# ########################################################################
# Get configuration information.
# ########################################################################
@@ -6311,6 +6316,16 @@ sub main {
die "Heartbeat table $db_tbl does not have a ts column"
unless $tbl_struct->{is_col}->{ts};
if ( $tbl_struct->{is_col}->{exec_master_log_file}
&& !$tbl_struct->{is_col}->{exec_source_log_file} ) {
$exec_source_log_pos_col = 'exec_master_log_file';
}
if ( $tbl_struct->{is_col}->{exec_master_log_pos}
&& !$tbl_struct->{is_col}->{exec_source_log_pos} ) {
$exec_source_log_pos_col = 'exec_master_log_pos';
}
my $hires_ts = $tbl_struct->{type_for}->{ts} =~ m/char/i ? 1 : 0;
PTDEBUG && _d("Hi-res ts:", ($hires_ts ? 'yes' : 'no'));
@@ -6429,7 +6444,7 @@ sub main {
PTDEBUG && _d("Master status columns:", join(', ', @master_status_cols));
my @slave_status_cols = grep { $tbl_struct->{is_col}->{$_} }
("relay_${source_name}_log_file", "exec_${source_name}_log_pos");
($relay_source_log_file_col, $exec_source_log_pos_col);
PTDEBUG && _d("Slave status columns:", join(', ', @slave_status_cols));
# Just a shortcut so I don't have to check both arrays when creating
@@ -6486,6 +6501,7 @@ sub main {
}
else {
$sql = 'SHOW SLAVE STATUS';
s/source/master/ for @slave_status_cols;
}
PTDEBUG && _d($dbh, $sql);
my $row = $dbh->selectrow_hashref($sql);

View File

@@ -4199,8 +4199,10 @@ sub _find_replicas_by_hosts {
my $vp = VersionParser->new($dbh);
my $sql = 'SHOW REPLICAS';
my $source_name = 'source';
if ( $vp < '8.1' || $vp->flavor() =~ m/maria/ ) {
$sql = 'SHOW SLAVE HOSTS';
$source_name='master';
}
PTDEBUG && _d($dbh, $sql);
@@ -4216,7 +4218,7 @@ sub _find_replicas_by_hosts {
. ( $hash{password} ? ",p=$hash{password}" : '');
my $dsn = $dsn_parser->parse($spec, $dsn);
$dsn->{server_id} = $hash{server_id};
$dsn->{source_id} = $hash{source_id};
$dsn->{source_id} = $hash{"${source_name}_id"};
$dsn->{source} = 'hosts';
$dsn;
} @replicas;
@@ -4295,9 +4297,9 @@ sub is_source_of {
. "but the source's port is $port";
}
if ( !grep { $replica_status->{source_user} eq $_->{user} } @connected ) {
if ( !grep { $replica_status->{"${source_name}_user"} eq $_->{user} } @connected ) {
die "I don't see any replica I/O thread connected with user "
. $replica_status->{source_user};
. $replica_status->{"${source_name}_user"};
}
if ( ($replica_status->{replica_io_state} || '')
@@ -4340,7 +4342,7 @@ sub get_replica_status {
my $server_version = VersionParser->new($dbh);
my $replica_name = 'replica';
if ( $server_version < '8.1' || $server_version->flavor() =~ m/maria/ ) {
$replica_name = 'replica';
$replica_name = 'slave';
}
if ( !$self->{not_a_replica}->{$dbh} ) {
@@ -4483,7 +4485,7 @@ sub stop_replica {
my $vp = VersionParser->new($dbh);
my $replica_name = 'replica';
if ( $vp < '8.1' || $vp->flavor() =~ m/maria/ ) {
$replica_name = 'replica';
$replica_name = 'slave';
}
my $sth = $self->{sths}->{$dbh}->{STOP_REPLICA}
||= $dbh->prepare("STOP ${replica_name}");

View File

@@ -981,7 +981,7 @@ collect_mysql_show_replica_hosts () {
local replicas='replicas'
if [ "$version" '<' "8.1" ]; then
replicas='slave hosts'
replicas='slave hosts';
fi
$CMD_MYSQL $EXT_ARGV -ssE -e "SHOW ${replicas}" 2>/dev/null
@@ -995,8 +995,8 @@ collect_source_logs_status () {
local source_log='binary'
local source_status='binary log'
if [ "$version" '<' "8.1" ]; then
source_log = 'master'
source_status = 'master'
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

View File

@@ -4487,8 +4487,10 @@ sub _find_replicas_by_hosts {
my $vp = VersionParser->new($dbh);
my $sql = 'SHOW REPLICAS';
my $source_name = 'source';
if ( $vp < '8.1' || $vp->flavor() =~ m/maria/ ) {
$sql = 'SHOW SLAVE HOSTS';
$source_name='master';
}
PTDEBUG && _d($dbh, $sql);
@@ -4504,7 +4506,7 @@ sub _find_replicas_by_hosts {
. ( $hash{password} ? ",p=$hash{password}" : '');
my $dsn = $dsn_parser->parse($spec, $dsn);
$dsn->{server_id} = $hash{server_id};
$dsn->{source_id} = $hash{source_id};
$dsn->{source_id} = $hash{"${source_name}_id"};
$dsn->{source} = 'hosts';
$dsn;
} @replicas;
@@ -4583,9 +4585,9 @@ sub is_source_of {
. "but the source's port is $port";
}
if ( !grep { $replica_status->{source_user} eq $_->{user} } @connected ) {
if ( !grep { $replica_status->{"${source_name}_user"} eq $_->{user} } @connected ) {
die "I don't see any replica I/O thread connected with user "
. $replica_status->{source_user};
. $replica_status->{"${source_name}_user"};
}
if ( ($replica_status->{replica_io_state} || '')

View File

@@ -10793,8 +10793,10 @@ sub _find_replicas_by_hosts {
my $vp = VersionParser->new($dbh);
my $sql = 'SHOW REPLICAS';
my $source_name = 'source';
if ( $vp < '8.1' || $vp->flavor() =~ m/maria/ ) {
$sql = 'SHOW SLAVE HOSTS';
$source_name='master';
}
PTDEBUG && _d($dbh, $sql);
@@ -10810,7 +10812,7 @@ sub _find_replicas_by_hosts {
. ( $hash{password} ? ",p=$hash{password}" : '');
my $dsn = $dsn_parser->parse($spec, $dsn);
$dsn->{server_id} = $hash{server_id};
$dsn->{source_id} = $hash{source_id};
$dsn->{source_id} = $hash{"${source_name}_id"};
$dsn->{source} = 'hosts';
$dsn;
} @replicas;
@@ -10889,9 +10891,9 @@ sub is_source_of {
. "but the source's port is $port";
}
if ( !grep { $replica_status->{source_user} eq $_->{user} } @connected ) {
if ( !grep { $replica_status->{"${source_name}_user"} eq $_->{user} } @connected ) {
die "I don't see any replica I/O thread connected with user "
. $replica_status->{source_user};
. $replica_status->{"${source_name}_user"};
}
if ( ($replica_status->{replica_io_state} || '')

View File

@@ -2524,8 +2524,10 @@ sub _find_replicas_by_hosts {
my $vp = VersionParser->new($dbh);
my $sql = 'SHOW REPLICAS';
my $source_name = 'source';
if ( $vp < '8.1' || $vp->flavor() =~ m/maria/ ) {
$sql = 'SHOW SLAVE HOSTS';
$source_name='master';
}
PTDEBUG && _d($dbh, $sql);
@@ -2541,7 +2543,7 @@ sub _find_replicas_by_hosts {
. ( $hash{password} ? ",p=$hash{password}" : '');
my $dsn = $dsn_parser->parse($spec, $dsn);
$dsn->{server_id} = $hash{server_id};
$dsn->{source_id} = $hash{source_id};
$dsn->{source_id} = $hash{"${source_name}_id"};
$dsn->{source} = 'hosts';
$dsn;
} @replicas;
@@ -2620,9 +2622,9 @@ sub is_source_of {
. "but the source's port is $port";
}
if ( !grep { $replica_status->{source_user} eq $_->{user} } @connected ) {
if ( !grep { $replica_status->{"${source_name}_user"} eq $_->{user} } @connected ) {
die "I don't see any replica I/O thread connected with user "
. $replica_status->{source_user};
. $replica_status->{"${source_name}_user"};
}
if ( ($replica_status->{replica_io_state} || '')

View File

@@ -2935,8 +2935,10 @@ sub _find_replicas_by_hosts {
my $vp = VersionParser->new($dbh);
my $sql = 'SHOW REPLICAS';
my $source_name = 'source';
if ( $vp < '8.1' || $vp->flavor() =~ m/maria/ ) {
$sql = 'SHOW SLAVE HOSTS';
$source_name='master';
}
PTDEBUG && _d($dbh, $sql);
@@ -2952,7 +2954,7 @@ sub _find_replicas_by_hosts {
. ( $hash{password} ? ",p=$hash{password}" : '');
my $dsn = $dsn_parser->parse($spec, $dsn);
$dsn->{server_id} = $hash{server_id};
$dsn->{source_id} = $hash{source_id};
$dsn->{source_id} = $hash{"${source_name}_id"};
$dsn->{source} = 'hosts';
$dsn;
} @replicas;
@@ -3031,9 +3033,9 @@ sub is_source_of {
. "but the source's port is $port";
}
if ( !grep { $replica_status->{source_user} eq $_->{user} } @connected ) {
if ( !grep { $replica_status->{"${source_name}_user"} eq $_->{user} } @connected ) {
die "I don't see any replica I/O thread connected with user "
. $replica_status->{source_user};
. $replica_status->{"${source_name}_user"};
}
if ( ($replica_status->{replica_io_state} || '')
@@ -5518,7 +5520,7 @@ sub watch_server {
# Get master_uuid from SHOW REPLICA STATUS if a UUID is not specified
# with --source-uuid.
my $gtid_uuid = $o->get("${source_name}-uuid");
my $gtid_uuid = $o->get("source-uuid");
if ( !$gtid_uuid ) {
$gtid_uuid = $stat->{"${source_name}_uuid"};
die "No ${source_name}_uuid" unless $gtid_uuid; # shouldn't happen

View File

@@ -5442,8 +5442,10 @@ sub _find_replicas_by_hosts {
my $vp = VersionParser->new($dbh);
my $sql = 'SHOW REPLICAS';
my $source_name = 'source';
if ( $vp < '8.1' || $vp->flavor() =~ m/maria/ ) {
$sql = 'SHOW SLAVE HOSTS';
$source_name='master';
}
PTDEBUG && _d($dbh, $sql);
@@ -5459,7 +5461,7 @@ sub _find_replicas_by_hosts {
. ( $hash{password} ? ",p=$hash{password}" : '');
my $dsn = $dsn_parser->parse($spec, $dsn);
$dsn->{server_id} = $hash{server_id};
$dsn->{source_id} = $hash{source_id};
$dsn->{source_id} = $hash{"${source_name}_id"};
$dsn->{source} = 'hosts';
$dsn;
} @replicas;
@@ -5538,9 +5540,9 @@ sub is_source_of {
. "but the source's port is $port";
}
if ( !grep { $replica_status->{source_user} eq $_->{user} } @connected ) {
if ( !grep { $replica_status->{"${source_name}_user"} eq $_->{user} } @connected ) {
die "I don't see any replica I/O thread connected with user "
. $replica_status->{source_user};
. $replica_status->{"${source_name}_user"};
}
if ( ($replica_status->{replica_io_state} || '')
@@ -6499,11 +6501,11 @@ sub _make_xor_slices {
sub find_replication_differences {
my ($self, %args) = @_;
my @required_args = qw(dbh repl_table);
my @required_args = qw(dbh repl_table source_crc_name source_cnt_name);
foreach my $arg( @required_args ) {
die "I need a $arg argument" unless $args{$arg};
}
my ($dbh, $repl_table) = @args{@required_args};
my ($dbh, $repl_table, $source_crc_name, $source_cnt_name) = @args{@required_args};
my $tries = $self->{'OptionParser'}->get('replicate-check-retries') || 1;
@@ -6512,13 +6514,13 @@ sub find_replication_differences {
my $sql
= "SELECT CONCAT(db, '.', tbl) AS `table`, "
. "chunk, chunk_index, lower_boundary, upper_boundary, "
. "COALESCE(this_cnt-source_cnt, 0) AS cnt_diff, "
. "COALESCE(this_cnt-${source_cnt_name}, 0) AS cnt_diff, "
. "COALESCE("
. "this_crc <> source_crc OR ISNULL(source_crc) <> ISNULL(this_crc), 0"
. ") AS crc_diff, this_cnt, source_cnt, this_crc, source_crc "
. "this_crc <> ${source_crc_name} OR ISNULL(${source_crc_name}) <> ISNULL(this_crc), 0"
. ") AS crc_diff, this_cnt, ${source_cnt_name}, this_crc, ${source_crc_name} "
. "FROM $repl_table "
. "WHERE (source_cnt <> this_cnt OR source_crc <> this_crc "
. "OR ISNULL(source_crc) <> ISNULL(this_crc)) "
. "WHERE (${source_cnt_name} <> this_cnt OR ${source_crc_name} <> this_crc "
. "OR ISNULL(${source_crc_name}) <> ISNULL(this_crc)) "
. ($args{where} ? " AND ($args{where})" : "");
PTDEBUG && _d($sql);
$diffs = $dbh->selectall_arrayref($sql, { Slice => {} });
@@ -10558,6 +10560,9 @@ sub main {
my $update_sth; # update source_cnt and source_cnt in repl table
my $delete_sth; # delete checksums for one db.tbl from repl table
my ($source_crc_name, $source_cnt_name); # do we use legacy checksum table definition?
if ( $o->get('truncate-replicate-table') ) {
eval {
$source_dbh->do("TRUNCATE TABLE $repl_table");
@@ -10829,45 +10834,6 @@ sub main {
}
}
# #####################################################################
# Possibly check replication replicas and exit.
# #####################################################################
if ( $o->get('replicate-check') && $o->get('replicate-check-only') ) {
PTDEBUG && _d('Will --replicate-check and exit');
# --plugin hook
if ( $plugin && $plugin->can('before_replicate_check') ) {
$plugin->before_replicate_check();
}
foreach my $replica ( @$replicas ) {
my $diffs = $rc->find_replication_differences(
dbh => $replica->dbh(),
repl_table => $repl_table,
);
PTDEBUG && _d(scalar @$diffs, 'checksum diffs on',
$replica->name());
$diffs = filter_tables_replicate_check_only($diffs, $o);
if ( @$diffs ) {
$exit_status |= $PTC_EXIT_STATUS{TABLE_DIFF};
if ( $o->get('quiet') < 2 ) {
print_checksum_diffs(
cxn => $replica,
diffs => $diffs,
);
}
}
}
# --plugin hook
if ( $plugin && $plugin->can('after_replicate_check') ) {
$plugin->after_replicate_check();
}
PTDEBUG && _d('Exit status', $exit_status, 'oktorun', $oktorun);
return $exit_status;
}
# #####################################################################
# Check for replication filters.
# #####################################################################
@@ -10904,7 +10870,7 @@ sub main {
# Check that the replication table exists, or possibly create it.
# #####################################################################
eval {
check_repl_table(
($source_crc_name, $source_cnt_name) = check_repl_table(
dbh => $source_dbh,
repl_table => $repl_table,
replicas => $replicas,
@@ -10918,6 +10884,47 @@ sub main {
die ts($EVAL_ERROR);
}
# #####################################################################
# Possibly check replication replicas and exit.
# #####################################################################
if ( $o->get('replicate-check') && $o->get('replicate-check-only') ) {
PTDEBUG && _d('Will --replicate-check and exit');
# --plugin hook
if ( $plugin && $plugin->can('before_replicate_check') ) {
$plugin->before_replicate_check();
}
foreach my $replica ( @$replicas ) {
my $diffs = $rc->find_replication_differences(
dbh => $replica->dbh(),
repl_table => $repl_table,
source_crc_name => $source_crc_name,
source_cnt_name => $source_cnt_name,
);
PTDEBUG && _d(scalar @$diffs, 'checksum diffs on',
$replica->name());
$diffs = filter_tables_replicate_check_only($diffs, $o);
if ( @$diffs ) {
$exit_status |= $PTC_EXIT_STATUS{TABLE_DIFF};
if ( $o->get('quiet') < 2 ) {
print_checksum_diffs(
cxn => $replica,
diffs => $diffs,
);
}
}
}
# --plugin hook
if ( $plugin && $plugin->can('after_replicate_check') ) {
$plugin->after_replicate_check();
}
PTDEBUG && _d('Exit status', $exit_status, 'oktorun', $oktorun);
return $exit_status;
}
# #####################################################################
# Make a ReplicaLagWaiter to help wait for replicas after each chunk.
# #####################################################################
@@ -11037,7 +11044,7 @@ sub main {
"SELECT this_crc, this_cnt FROM $repl_table "
. "WHERE db = ? AND tbl = ? AND chunk = ?");
$update_sth = $source_dbh->prepare(
"UPDATE $repl_table SET chunk_time = ?, ${source_name}_crc = ?, ${source_name}_cnt = ? "
"UPDATE $repl_table SET chunk_time = ?, ${source_crc_name} = ?, ${source_cnt_name} = ? "
. "WHERE db = ? AND tbl = ? AND chunk = ?");
$delete_sth = $source_dbh->prepare(
"DELETE FROM $repl_table WHERE db = ? AND tbl = ?");
@@ -11076,6 +11083,7 @@ sub main {
$last_chunk = last_chunk(
dbh => $source_dbh,
repl_table => $repl_table,
source_cnt_name => $source_cnt_name,
);
}
@@ -11574,7 +11582,7 @@ sub main {
check_pr => $check_pr,
have_time => $have_time,
OptionParser => $o,
source_name => $source_name,
source_crc_name => $source_crc_name,
);
# Check each replica for checksum diffs.
@@ -11585,6 +11593,8 @@ sub main {
dbh => $replica->dbh(),
repl_table => $repl_table,
where => "db='$tbl->{db}' AND tbl='$tbl->{tbl}'",
source_crc_name => $source_crc_name,
source_cnt_name => $source_cnt_name,
);
PTDEBUG && _d(scalar @$diffs, 'checksum diffs on',
$replica->name());
@@ -12328,9 +12338,24 @@ sub check_repl_table {
}
}
my $create_table = $tp->get_create_table( $dbh, $db, $tbl );
my $source_crc_name = 'source_crc';
my $source_cnt_name = 'source_cnt';
if ( $create_table =~ /master_crc/si
|| $create_table =~ /master_cnt/si )
{
warn "The current checksum table uses deprecated column names. Support for these names "
. "will be occasionally removed. Please update the table definition with command:\n"
. "ALTER TABLE `$db`.`$tbl` RENAME COLUMN master_crc TO source_crc, "
. "RENAME COLUMN master_cnt TO source_cnt;\n";
$source_crc_name = 'master_crc';
$source_cnt_name = 'master_cnt';
}
if ( $o->get('binary-index') ) {
PTDEBUG && _d('--binary-index : checking if replicate table has binary type columns');
my $create_table = $tp->get_create_table( $dbh, $db, $tbl );
if ( $create_table !~ /lower_boundary`?\s+BLOB/si
|| $create_table !~ /upper_boundary`?\s+BLOB/si )
{
@@ -12340,7 +12365,7 @@ sub check_repl_table {
}
}
return; # success, repl table is ready to go
return ($source_crc_name, $source_cnt_name); # success, repl table is ready to go
}
# Check that db.tbl exists on all replicas and has the checksum cols,
@@ -12578,16 +12603,16 @@ sub explain_statement {
sub last_chunk {
my (%args) = @_;
my @required_args = qw(dbh repl_table);
my @required_args = qw(dbh repl_table source_cnt_name);
my $source_name = $args{source_name} ? $args{source_name} : 'source';
foreach my $arg ( @required_args ) {
die "I need a $arg argument" unless $args{$arg};
}
my ($dbh, $repl_table, $q) = @args{@required_args};
my ($dbh, $repl_table, $source_cnt_name) = @args{@required_args};
PTDEBUG && _d('Getting last chunk for --resume');
my $sql = "SELECT * FROM $repl_table FORCE INDEX (ts_db_tbl) "
. "WHERE ${source_name}_cnt IS NOT NULL "
. "WHERE ${source_cnt_name} IS NOT NULL "
. "ORDER BY ts DESC, db DESC, tbl DESC LIMIT 1";
PTDEBUG && _d($sql);
my $sth = $dbh->prepare($sql);
@@ -12660,13 +12685,12 @@ sub wait_for_replicas {
sub wait_for_last_checksum {
my (%args) = @_;
my @required_args = qw(tbl repl_table replicas max_chunk have_time OptionParser);
my @required_args = qw(tbl repl_table replicas max_chunk have_time OptionParser source_crc_name);
foreach my $arg ( @required_args ) {
die "I need a $arg argument" unless defined $args{$arg};
}
my ($tbl, $repl_table, $replicas, $max_chunk, $have_time, $o) = @args{@required_args};
my ($tbl, $repl_table, $replicas, $max_chunk, $have_time, $o, $source_crc_name) = @args{@required_args};
my $check_pr = $args{check_pr};
my $source_name = $args{source_name} ? $args{source_name} : 'source';
# Requiring "AND source_crc IS NOT NULL" avoids a race condition
# when the system is fast but replication is slow. In such cases,
@@ -12674,7 +12698,7 @@ sub wait_for_last_checksum {
# replicates; this causes a false-positive diff.
my $sql = "SELECT MAX(chunk) FROM $repl_table "
. "WHERE db='$tbl->{db}' AND tbl='$tbl->{tbl}' "
. "AND ${source_name}_crc IS NOT NULL";
. "AND ${source_crc_name} IS NOT NULL";
PTDEBUG && _d($sql);
my $sleep_time = 0;

View File

@@ -6953,8 +6953,10 @@ sub _find_replicas_by_hosts {
my $vp = VersionParser->new($dbh);
my $sql = 'SHOW REPLICAS';
my $source_name = 'source';
if ( $vp < '8.1' || $vp->flavor() =~ m/maria/ ) {
$sql = 'SHOW SLAVE HOSTS';
$source_name='master';
}
PTDEBUG && _d($dbh, $sql);
@@ -6970,7 +6972,7 @@ sub _find_replicas_by_hosts {
. ( $hash{password} ? ",p=$hash{password}" : '');
my $dsn = $dsn_parser->parse($spec, $dsn);
$dsn->{server_id} = $hash{server_id};
$dsn->{source_id} = $hash{source_id};
$dsn->{source_id} = $hash{"${source_name}_id"};
$dsn->{source} = 'hosts';
$dsn;
} @replicas;
@@ -7049,9 +7051,9 @@ sub is_source_of {
. "but the source's port is $port";
}
if ( !grep { $replica_status->{source_user} eq $_->{user} } @connected ) {
if ( !grep { $replica_status->{"${source_name}_user"} eq $_->{user} } @connected ) {
die "I don't see any replica I/O thread connected with user "
. $replica_status->{source_user};
. $replica_status->{"${source_name}_user"};
}
if ( ($replica_status->{replica_io_state} || '')
@@ -10349,7 +10351,7 @@ sub main {
# We should not die if replica connected via tunnel or port redirection
if ( $EVAL_ERROR ) {
$EVAL_ERROR =~ m/The ${replica_name} is connected to (\d+) but the ${source_name}'s port is \d+/;
$EVAL_ERROR =~ m/The ${replica_name} is connected to (\d+) but the source's port is \d+/;
if ( !$1 || $1 != $dsns[0]->{P} ) {
die $EVAL_ERROR;
}

View File

@@ -339,8 +339,10 @@ sub _find_replicas_by_hosts {
my $vp = VersionParser->new($dbh);
my $sql = 'SHOW REPLICAS';
my $source_name = 'source';
if ( $vp < '8.1' || $vp->flavor() =~ m/maria/ ) {
$sql = 'SHOW SLAVE HOSTS';
$source_name='master';
}
PTDEBUG && _d($dbh, $sql);
@@ -357,7 +359,7 @@ sub _find_replicas_by_hosts {
. ( $hash{password} ? ",p=$hash{password}" : '');
my $dsn = $dsn_parser->parse($spec, $dsn);
$dsn->{server_id} = $hash{server_id};
$dsn->{source_id} = $hash{source_id};
$dsn->{source_id} = $hash{"${source_name}_id"};
$dsn->{source} = 'hosts';
$dsn;
} @replicas;
@@ -446,9 +448,9 @@ sub is_source_of {
. "but the source's port is $port";
}
if ( !grep { $replica_status->{source_user} eq $_->{user} } @connected ) {
if ( !grep { $replica_status->{"${source_name}_user"} eq $_->{user} } @connected ) {
die "I don't see any replica I/O thread connected with user "
. $replica_status->{source_user};
. $replica_status->{"${source_name}_user"};
}
if ( ($replica_status->{replica_io_state} || '')

View File

@@ -471,11 +471,11 @@ sub _make_xor_slices {
# 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);
my @required_args = qw(dbh repl_table source_crc_name source_cnt_name);
foreach my $arg( @required_args ) {
die "I need a $arg argument" unless $args{$arg};
}
my ($dbh, $repl_table) = @args{@required_args};
my ($dbh, $repl_table, $source_crc_name, $source_cnt_name) = @args{@required_args};
my $tries = $self->{'OptionParser'}->get('replicate-check-retries') || 1;
@@ -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-source_cnt, 0) AS cnt_diff, "
. "COALESCE(this_cnt-${source_cnt_name}, 0) AS cnt_diff, "
. "COALESCE("
. "this_crc <> source_crc OR ISNULL(source_crc) <> ISNULL(this_crc), 0"
. ") AS crc_diff, this_cnt, source_cnt, this_crc, source_crc "
. "this_crc <> ${source_crc_name} OR ISNULL(${source_crc_name}) <> ISNULL(this_crc), 0"
. ") AS crc_diff, this_cnt, ${source_cnt_name}, this_crc, ${source_crc_name} "
. "FROM $repl_table "
. "WHERE (source_cnt <> this_cnt OR source_crc <> this_crc "
. "OR ISNULL(source_crc) <> ISNULL(this_crc)) "
. "WHERE (${source_cnt_name} <> this_cnt OR ${source_crc_name} <> this_crc "
. "OR ISNULL(${source_crc_name}) <> ISNULL(this_crc)) "
. ($args{where} ? " AND ($args{where})" : "");
PTDEBUG && _d($sql);
$diffs = $dbh->selectall_arrayref($sql, { Slice => {} });

View File

@@ -153,7 +153,7 @@ collect_mysql_show_replica_hosts () {
local replicas='replicas'
if [ "$version" '<' "8.1" ]; then
replicas='slave hosts'
replicas='slave hosts';
fi
$CMD_MYSQL $EXT_ARGV -ssE -e "SHOW ${replicas}" 2>/dev/null
@@ -167,8 +167,8 @@ collect_source_logs_status () {
local source_log='binary'
local source_status='binary log'
if [ "$version" '<' "8.1" ]; then
source_log = 'master'
source_status = 'master'
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

View File

@@ -88,7 +88,7 @@ PXC_SKIP: {
source => 'hosts',
},
'get_replicas() from recurse_to_replicas() with a default --recursion-method'
);
) or diag(Dumper($slaves->[0]->dsn()));
my ($id) = $slaves->[0]->dbh()->selectrow_array('SELECT @@SERVER_ID');
is(
@@ -315,15 +315,15 @@ is_deeply(
# +- 127.0.0.1:slave0
# | +- 127.0.0.1:slave1
# +- 127.0.0.1:slave2
is($ms->get_replica_status($slaves[0])->{source_port}, $port_for{source}, 'slave 1 port');
is($ms->get_replica_status($slaves[1])->{source_port}, $port_for{replica0}, 'slave 2 port');
is($ms->get_replica_status($slaves[2])->{source_port}, $port_for{source}, 'slave 3 port');
is($ms->get_replica_status($slaves[0])->{"${source_name}_port"}, $port_for{source}, 'slave 1 port');
is($ms->get_replica_status($slaves[1])->{"${source_name}_port"}, $port_for{replica0}, 'slave 2 port');
is($ms->get_replica_status($slaves[2])->{"${source_name}_port"}, $port_for{source}, 'slave 3 port');
ok($ms->is_source_of($slaves[0], $slaves[1]), 'slave 1 is slave of slave 0');
eval {
$ms->is_source_of($slaves[0], $slaves[2]);
};
like($EVAL_ERROR, qr/but the ${source_name}'s port/, 'slave 2 is not slave of slave 0');
like($EVAL_ERROR, qr/but the source's port/, 'slave 2 is not slave of slave 0') or diag($EVAL_ERROR);
eval {
$ms->is_source_of($slaves[2], $slaves[1]);
};

View File

@@ -163,11 +163,18 @@ cmd_ok \
# collect_master_logs_status
if [ -n "$(get_var log_bin "$p/mysql-variables")" ]; then
mysql_version="$(get_var version "$p/mysql-variables")"
source_logs_file="mysql-binary-logs"
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
cmd_ok \
"test -e $p/mysql-binary-logs" \
"test -e $p/$source_logs_file" \
"If we have a binlog, a file with the master logs should exist"
cmd_ok \
"test -e $p/mysql-binary-log-status" \
"test -e $p/$source_status_file" \
"And likewise for master status"
else
skip 1 2 "no binlog"

View File

@@ -16,7 +16,7 @@ CREATE TABLE `component` (
`component_group_id` int unsigned NOT NULL,
`component_urn` text NOT NULL,
PRIMARY KEY (`component_id`)
) /*!50100 TABLESPACE `mysql` */ ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 ROW_FORMAT=DYNAMIC COMMENT='Components'
) /*!50100 TABLESPACE `mysql` */ ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb3 ROW_FORMAT=DYNAMIC COMMENT='Components'
mysql.db
CREATE TABLE `db` (

View File

@@ -68,7 +68,7 @@ is(
"All rows were loaded into source 1",
);
my @args = ('--source', $source1_dsn.',D=test,t=t1', '--purge', '--where', sprintf('id >= %d', $num_rows / 2), "--check-${replica_name}-lag", $replica1_dsn);
my @args = ('--source', $source1_dsn.',D=test,t=t1', '--purge', '--where', sprintf('id >= %d', $num_rows / 2), "--check-replica-lag", $replica1_dsn);
my ($exit_status, $output);
@@ -76,8 +76,6 @@ $output = output(
sub { $exit_status = pt_archiver::main(@args) },
stderr => 1,
);
diag("Exit status: $exit_status") if ($exit_status);
diag($output);
isnt(
$exit_status,
@@ -89,7 +87,7 @@ like (
$output,
qr/"channel" was not specified/,
'Message saying channel name must be specified'
);
) or diag($output);
push @args, ('--channel', 'sourcechan1');

View File

@@ -110,7 +110,7 @@ ok(
);
ok(
$rows->{12346}->{"relay_${source_name}_log_file"} && $rows->{12346}->{"exec_${source_name}_log_pos"},
$rows->{12346}->{"relay_source_log_file"} && $rows->{12346}->{"exec_source_log_pos"},
"Replica1 relay_source_log_file and exec_source_log_pos for source"
) or diag(Dumper($rows));
@@ -144,7 +144,7 @@ ok(
);
ok(
$rows->{12347}->{"relay_${source_name}_log_file"} && $rows->{12347}->{"exec_${source_name}_log_pos"},
$rows->{12347}->{"relay_source_log_file"} && $rows->{12347}->{"exec_source_log_pos"},
"Replica2 relay_source_log_file and exec_source_log_pos for source"
);

View File

@@ -849,9 +849,9 @@ SKIP: {
like(
$output,
qr/Found 2 replicas.*Successfully altered/si,
qr/Found 2 ${replica_name}s.*Successfully altered/si,
"--recursion-method=dns works"
);
) or diag($output);
$source_dbh->do("DROP DATABASE test_recursion_method");

View File

@@ -1,5 +1,5 @@
No slaves found. See --recursion-method if host h=127.1,P=12345 has slaves.
Not checking slave lag because no slaves were found and --check-slave-lag was not specified.
Not checking slave lag because no slaves were found and --check-replica-lag was not specified.
Operation, tries, wait:
analyze_table, 10, 1
copy_rows, 10, 0.25

View File

@@ -1,5 +1,5 @@
No slaves found. See --recursion-method if host h=127.1,P=12345 has slaves.
Not checking slave lag because no slaves were found and --check-slave-lag was not specified.
Not checking slave lag because no slaves were found and --check-replica-lag was not specified.
Operation, tries, wait:
analyze_table, 10, 1
copy_rows, 10, 0.25

View File

@@ -1,5 +1,5 @@
No slaves found. See --recursion-method if host h=127.1,P=12345 has slaves.
Not checking slave lag because no slaves were found and --check-slave-lag was not specified.
Not checking slave lag because no slaves were found and --check-replica-lag was not specified.
Operation, tries, wait:
analyze_table, 10, 1
copy_rows, 10, 0.25

View File

@@ -1,5 +1,5 @@
No slaves found. See --recursion-method if host h=127.1,P=12345 has slaves.
Not checking slave lag because no slaves were found and --check-slave-lag was not specified.
Not checking slave lag because no slaves were found and --check-replica-lag was not specified.
Operation, tries, wait:
analyze_table, 10, 1
copy_rows, 10, 0.25

View File

@@ -157,15 +157,15 @@ unlink $filename;
like(
$output,
qr/${replica_name} set to watch has changed/is,
qr/Replica set to watch has changed/s,
"--recursion-method=dsn updates the replica list",
);
) or diag($output);
like(
$output,
qr/${replica_name} lag is \d+ seconds on .* Waiting/is,
qr/Replica lag is \d+ seconds on .* Waiting/s,
"--recursion-method waits on a replica",
);
) or diag($output);
# Repeat the test now using --skip-check-replica-lag
# Run a full table scan query to ensure the replica is behind the source

View File

@@ -10,6 +10,7 @@ use strict;
use warnings FATAL => 'all';
use English qw(-no_match_vars);
use Test::More;
use Data::Dumper;
use PerconaTest;
use Sandbox;
@@ -54,10 +55,10 @@ like($output, qr/Prompt for a password/, 'It compiles');
# Double check that we're setup correctly.
my $row = $replica2_dbh->selectall_arrayref("SHOW ${replica_name} STATUS", {Slice => {}});
is(
$row->[0]->{source_port},
$row->[0]->{"${source_name}_port"},
'12346',
'replica2 is replica of replica1'
);
) or diag(Dumper($row));
$output = `$trunk/bin/pt-slave-find -h 127.0.0.1 -P 12345 -u msandbox -p msandbox s=1 --report-format hostname`;
my $expected = <<EOF;

View File

@@ -442,7 +442,7 @@ $output = output(
like(
$output,
qr/no ${replica_name}s were found/,
qr/no replicas were found/,
"Warns when no replica are found (bug 1087804)"
) or diag($output);

View File

@@ -100,7 +100,7 @@ is(
"Bug 987393 (empty table): no errors"
);
my $rows = $source_dbh->selectall_arrayref("SELECT db, tbl, chunk, ${source_name}_crc, ${source_name}_cnt FROM percona.checksums ORDER BY db, tbl, chunk");
my $rows = $source_dbh->selectall_arrayref("SELECT db, tbl, chunk, source_crc, source_cnt FROM percona.checksums ORDER BY db, tbl, chunk");
is_deeply(
$rows,
[

View File

@@ -42,13 +42,13 @@ $output = output(
# We do not count these tables by default, because their presense depends from
# previously running tests
my $extra_tables = $dbh->selectrow_arrayref("select count(*) from percona_test.checksums where db_tbl in ('mysql.plugin', 'mysql.func', 'mysql.proxies_priv');")->[0];
my $extra_tables = $dbh->selectrow_arrayref("select count(*) from percona_test.checksums where db_tbl in ('mysql.plugin', 'mysql.func', 'mysql.proxies_priv', 'mysql.component');")->[0];
is(
PerconaTest::count_checksum_results($output, 'rows'),
$sandbox_version ge '8.0' ? 28 + $extra_tables : $sandbox_version lt '5.7' ? 24 : 23 + $extra_tables,
"Large BLOB/TEXT/BINARY Checksum"
);
) or diag($output);
# #############################################################################
# Done.

View File

@@ -93,7 +93,7 @@ is(
PerconaTest::get_source_binlog_pos($source_dbh),
$pos,
"Did not checksum with replication filter"
);
) or diag($output);
like(
$output,

View File

@@ -241,7 +241,7 @@ my $second_half = [
[qw(sakila store 1 2 )],
];
$row = $source_dbh->selectall_arrayref("select db, tbl, chunk, ${source_name}_cnt from percona.checksums order by db, tbl");
$row = $source_dbh->selectall_arrayref("select db, tbl, chunk, source_cnt from percona.checksums order by db, tbl");
is_deeply(
$row,
$first_half,
@@ -253,7 +253,7 @@ $output = output(
qw(--chunk-time 0)) },
);
$row = $source_dbh->selectall_arrayref("select db, tbl, chunk, ${source_name}_cnt from percona.checksums order by db, tbl");
$row = $source_dbh->selectall_arrayref("select db, tbl, chunk, source_cnt from percona.checksums order by db, tbl");
is_deeply(
$row,
[
@@ -306,7 +306,7 @@ is(
load_data_infile("sakila-done-1k-chunks", "ts='2011-10-15 13:00:57'");
$source_dbh->do("delete from percona.checksums where ts > '2011-10-15 13:00:38'");
$row = $source_dbh->selectall_arrayref("select db, tbl, chunk, ${source_name}_cnt from percona.checksums order by db, tbl");
$row = $source_dbh->selectall_arrayref("select db, tbl, chunk, source_cnt from percona.checksums order by db, tbl");
is_deeply(
$row,
[
@@ -332,7 +332,7 @@ $output = output(
qw(--chunk-time 0)) },
);
$row = $source_dbh->selectall_arrayref("select db, tbl, chunk, ${source_name}_cnt from percona.checksums order by db, tbl");
$row = $source_dbh->selectall_arrayref("select db, tbl, chunk, source_cnt from percona.checksums order by db, tbl");
is_deeply(
$row,
[
@@ -378,7 +378,7 @@ is(
# ############################################################################
load_data_infile("sakila-done-1k-chunks", "ts='2011-10-15 13:00:57'");
$source_dbh->do("delete from percona.checksums where ts > '2011-10-15 13:00:50'");
$source_dbh->do("update percona.checksums set ${source_name}_crc=NULL, ${source_name}_cnt=NULL, ts='2011-11-11 11:11:11' where db='sakila' and tbl='rental' and chunk=12");
$source_dbh->do("update percona.checksums set source_crc=NULL, source_cnt=NULL, ts='2011-11-11 11:11:11' where db='sakila' and tbl='rental' and chunk=12");
# Checksum table now ends with:
# *************************** 49. row ***************************
@@ -413,7 +413,7 @@ $source_dbh->do("update percona.checksums set ${source_name}_crc=NULL, ${source_
my $chunk11 = $source_dbh->selectall_arrayref(q{select * from percona.checksums where db='sakila' and tbl='rental' and chunk=11});
my $chunk12 = $source_dbh->selectall_arrayref(qq{select ${source_name}_crc from percona.checksums where db='sakila' and tbl='rental' and chunk=12});
my $chunk12 = $source_dbh->selectall_arrayref(qq{select source_crc from percona.checksums where db='sakila' and tbl='rental' and chunk=12});
is(
$chunk12->[0]->[0],
undef,
@@ -426,7 +426,7 @@ $output = output(
trf => sub { return PerconaTest::normalize_checksum_results(@_) },
);
$row = $source_dbh->selectall_arrayref("select db, tbl, chunk, ${source_name}_cnt from percona.checksums order by db, tbl");
$row = $source_dbh->selectall_arrayref("select db, tbl, chunk, source_cnt from percona.checksums order by db, tbl");
is_deeply(
$row,
[
@@ -455,7 +455,7 @@ is_deeply(
"Chunk 11 not updated"
);
$chunk12 = $source_dbh->selectall_arrayref(qq{select ${source_name}_crc, ${source_name}_cnt from percona.checksums where db='sakila' and tbl='rental' and chunk=12});
$chunk12 = $source_dbh->selectall_arrayref(qq{select source_crc, source_cnt from percona.checksums where db='sakila' and tbl='rental' and chunk=12});
ok(
defined $chunk12->[0]->[0],
"Chunk 12 source_crc updated"

View File

@@ -2,7 +2,7 @@ if all tables checksummed
checksum ...
ERRORS DIFFS ROWS SKIPPED TABLE
0 0 0 0 mysql.columns_priv
0 0 0 0 mysql.component
0 0 1 0 mysql.component
0 0 2 0 mysql.db
0 0 0 0 mysql.default_roles
0 1 2 0 mysql.engine_cost