Files
percona-toolkit/t/pt-table-sync/basics.t
Sveta Smirnova 33086769a1 PT-2340 - Support MySQL 8.4
- Added test for replica lag check for pt-archiver
- Re-added deprecated slave- options
- Added tests for deprecation warnings and for legacy options for pt-archiver
- Removed practically not supported options --replica-user and --replica-password from pt-archiver, pt-kill, pt-query-digest
- Added legacy source/replica options (master/slave) variants and tests for pt-heartbeat, pt-online-schema-change, pt-replica-find, pt-replica-restart, pt-table-checksum, pt-table-sync
- Updated modules after lib/MasterSlave.pm change
2024-10-04 18:27:00 +03:00

306 lines
11 KiB
Perl

#!/usr/bin/env perl
BEGIN {
die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n"
unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH};
unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib";
};
use strict;
use warnings FATAL => 'all';
use English qw(-no_match_vars);
use Test::More;
use PerconaTest;
use Sandbox;
require "$trunk/bin/pt-table-sync";
my $output;
my $dp = new DSNParser(opts=>$dsn_opts);
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
my $source_dbh = $sb->get_dbh_for('source');
my $replica_dbh = $sb->get_dbh_for('replica1');
if ( !$source_dbh ) {
plan skip_all => 'Cannot connect to sandbox source';
}
elsif ( !$replica_dbh ) {
plan skip_all => 'Cannot connect to sandbox replica';
}
else {
plan tests => 30;
}
$sb->create_dbs($source_dbh, [qw(test)]);
sub query_replica {
return $replica_dbh->selectall_arrayref(@_, {Slice => {}});
}
sub run {
my ($src, $dst, $other) = @_;
my $output = output(
sub {
pt_table_sync::main(qw(--print --execute),
"h=127.1,P=12345,u=msandbox,p=msandbox,D=test,t=$src,s=1",
"h=127.1,P=12346,u=msandbox,p=msandbox,D=test,t=$dst,s=1",
($other ? split(" ", $other) : ())
);
},
stderr => 1,
);
if ( $output ) {
chomp $output;
# Remove trace comments from end of change statements.
$output = remove_traces($output);
};
return $output;
}
sub run_cmd {
my ($src, $dst, $other) = @_;
my $cmd = "$trunk/bin/pt-table-sync --print --execute h=127.1,P=12345,u=msandbox,p=msandbox,D=test,t=$src,s=1 h=127.1,P=12346,D=test,t=$dst,s=1 $other 2>&1";
chomp($output=`$cmd`);
return $output;
}
# #############################################################################
# Test basic source-replica syncing
# #############################################################################
$sb->load_file('source', 't/pt-table-sync/samples/before.sql');
$output = run('test1', 'test2', '');
like($output, qr/Can't make changes/, 'It dislikes changing a replica');
$output = run('test1', 'test2', '--no-bin-log');
is($output, "INSERT INTO `test`.`test2`(`a`, `b`) VALUES ('1', 'en');
INSERT INTO `test`.`test2`(`a`, `b`) VALUES ('2', 'ca');", 'No alg sync');
is_deeply(
query_replica('select * from test.test2'),
[ { a => 1, b => 'en' }, { a => 2, b => 'ca' } ],
'Synced OK with no alg'
);
$sb->load_file('source', 't/pt-table-sync/samples/before.sql');
$output = run('test1', 'test2', '--algorithms Stream --no-bin-log');
is($output, "INSERT INTO `test`.`test2`(`a`, `b`) VALUES ('1', 'en');
INSERT INTO `test`.`test2`(`a`, `b`) VALUES ('2', 'ca');", 'Basic Stream sync');
is_deeply(
query_replica('select * from test.test2'),
[ { a => 1, b => 'en' }, { a => 2, b => 'ca' } ],
'Synced OK with Stream'
);
$sb->load_file('source', 't/pt-table-sync/samples/before.sql');
$output = run('test1', 'test2', '--algorithms GroupBy --no-bin-log');
is($output, "INSERT INTO `test`.`test2`(`a`, `b`) VALUES ('1', 'en');
INSERT INTO `test`.`test2`(`a`, `b`) VALUES ('2', 'ca');", 'Basic GroupBy sync');
is_deeply(
query_replica('select * from test.test2'),
[ { a => 1, b => 'en' }, { a => 2, b => 'ca' } ],
'Synced OK with GroupBy'
);
$sb->load_file('source', 't/pt-table-sync/samples/before.sql');
$output = run('test1', 'test2', '--algorithms Chunk,GroupBy --no-bin-log');
is($output, "INSERT INTO `test`.`test2`(`a`, `b`) VALUES ('1', 'en');
INSERT INTO `test`.`test2`(`a`, `b`) VALUES ('2', 'ca');", 'Basic Chunk sync');
is_deeply(
query_replica('select * from test.test2'),
[ { a => 1, b => 'en' }, { a => 2, b => 'ca' } ],
'Synced OK with Chunk'
);
# Create a new user that is going to be replicated on replicas.
# After that, stop replication, delete the user from the source just to ensure that
# on the source we are using the sandbox user, and start relication again to run
# the tests
$sb->do_as_root("source", q/CREATE USER 'replica_user'@'%' IDENTIFIED BY 'replica_password'/);
$sb->do_as_root("source", q/GRANT REPLICATION SLAVE ON *.* TO 'replica_user'@'%'/);
$sb->do_as_root("source", q/set sql_log_bin=0/);
$sb->do_as_root("source", q/DROP USER 'replica_user'/);
$sb->do_as_root("source", q/set sql_log_bin=1/);
$sb->load_file('source', 't/pt-table-sync/samples/before.sql');
$output = run('test1', 'test2', '--algorithms Chunk,GroupBy --no-bin-log --replica-user replica_user --replica-password replica_password');
is($output, "INSERT INTO `test`.`test2`(`a`, `b`) VALUES ('1', 'en');
INSERT INTO `test`.`test2`(`a`, `b`) VALUES ('2', 'ca');", 'Basic Chunk sync');
is_deeply(
query_replica('select * from test.test2'),
[ { a => 1, b => 'en' }, { a => 2, b => 'ca' } ],
'Synced OK with --replica-user'
);
unlike(
$output,
qr/Option --slave-user is deprecated and will be removed in future versions./,
'Deprecation warning not printed when option --replica-user provided'
) or diag($output);
unlike(
$output,
qr/Option --slave-password is deprecated and will be removed in future versions./,
'Deprecation warning not printed when option --replica-password provided'
) or diag($output);
$sb->load_file('source', 't/pt-table-sync/samples/before.sql');
$output = run('test1', 'test2', '--algorithms Chunk,GroupBy --no-bin-log --slave-user replica_user --slave-password replica_password');
like(
$output,
qr/INSERT INTO `test`.`test2`\(`a`, `b`\) VALUES \('1', 'en'\);\nINSERT INTO `test`.`test2`\(`a`, `b`\) VALUES \('2', 'ca'\);/,
'Basic Chunk sync with --slave-user/--slave-password'
);
is_deeply(
query_replica('select * from test.test2'),
[ { a => 1, b => 'en' }, { a => 2, b => 'ca' } ],
'Synced OK with --slave-user'
);
like(
$output,
qr/Option --slave-user is deprecated and will be removed in future versions./,
'Deprecation warning printed when option --slave-user provided'
) or diag($output);
like(
$output,
qr/Option --slave-password is deprecated and will be removed in future versions./,
'Deprecation warning printed when option --slave-password provided'
) or diag($output);
$sb->load_file('source', 't/pt-table-sync/samples/before.sql');
$output = run('test1', 'test2', '--algorithms Nibble --no-bin-log');
is($output, "INSERT INTO `test`.`test2`(`a`, `b`) VALUES ('1', 'en');
INSERT INTO `test`.`test2`(`a`, `b`) VALUES ('2', 'ca');", 'Basic Nibble sync');
is_deeply(
query_replica('select * from test.test2'),
[ { a => 1, b => 'en' }, { a => 2, b => 'ca' } ],
'Synced OK with Nibble'
);
# Save original PTDEBUG env because we modify it below.
my $dbg = $ENV{PTDEBUG};
$sb->load_file('source', 't/pt-table-sync/samples/before.sql');
$ENV{PTDEBUG} = 1;
$output = run_cmd('test1', 'test2', '--algorithms Nibble --no-bin-log --chunk-size 1 --transaction --lock 1');
delete $ENV{PTDEBUG};
like(
$output,
qr/Executing statement on source/,
'Nibble with transactions and locking'
);
is_deeply(
query_replica('select * from test.test2'),
[ { a => 1, b => 'en' }, { a => 2, b => 'ca' } ],
'Synced OK with Nibble'
);
# Sync tables that have values with leading zeroes
$ENV{PTDEBUG} = 1;
$output = run('test3', 'test4', '--print --no-bin-log --verbose --function MD5');
delete $ENV{PTDEBUG};
like(
$output,
qr/UPDATE `test`.`test4`.*51707/,
'Found the first row',
);
like(
$output,
qr/UPDATE `test`.`test4`.*'001'/,
'Found the second row',
);
like(
$output,
qr/2 Chunk\s+\S+\s+\S+\s+2\s+test.test3/,
'Right number of rows to update',
);
# Sync a table with Nibble and a chunksize in data size, not number of rows
$output = run('test3', 'test4', '--algorithms Nibble --chunk-size 1k --print --verbose --function MD5');
# If it lived, it's OK.
ok($output, 'Synced with Nibble and data-size chunksize');
# Restore PTDEBUG env.
$ENV{PTDEBUG} = $dbg || 0;
# ###########################################################################
# Fix bug 911996.
# ###########################################################################
# pt-table-checksum waits for all checksums to replicate to all replicas,
# so no need to call $sb->wait_for_replicas() after this.
`$trunk/bin/pt-table-checksum h=127.1,P=12345,u=msandbox,p=msandbox --max-load '' --set-vars innodb_lock_wait_timeout=3 --chunk-size 50 --chunk-index idx_actor_last_name -t sakila.actor --quiet`;
$replica_dbh->do("update percona.checksums set this_crc='' where db='sakila' and tbl='actor' and chunk=3");
$replica_dbh->do("update sakila.actor set last_name='' where actor_id=30");
$sb->wait_for_replicas(); # wait for those ^ updates to replicate to replica2 (!2347)
$output = output(
sub {
pt_table_sync::main('h=127.1,P=12345,u=msandbox,p=msandbox',
qw(--print --execute --replicate percona.checksums),
qw(--no-foreign-key-checks --no-check-child-tables))
}
);
like(
$output,
qr/^REPLACE INTO `sakila`.`actor`\(`actor_id`, `first_name`, `last_name`, `last_update`\) VALUES \('30', 'SANDRA', 'PECK', '2006-02-15 11:34:33'\)/,
"--replicate with char index col (bug 911996)"
);
$output = `$trunk/bin/pt-table-checksum h=127.1,P=12345,u=msandbox,p=msandbox --max-load '' --set-vars innodb_lock_wait_timeout=3 --chunk-size 50 --chunk-index idx_actor_last_name -t sakila.actor`;
is(
PerconaTest::count_checksum_results($output, 'diffs'),
0,
"Synced diff (bug 911996)"
);
# Fix bug 927771.
$sb->load_file('source', 't/pt-table-sync/samples/bug_927771.sql');
$replica_dbh->do("update test.t set c='z' where id>8");
# pt-table-checksum waits for all checksums to replicate to all replicas,
# so no need to call $sb->wait_for_replicas() after this.
`$trunk/bin/pt-table-checksum h=127.1,P=12345,u=msandbox,p=msandbox --max-load '' --set-vars innodb_lock_wait_timeout=3 --chunk-size 2 -t test.t --quiet`;
$output = output(
sub {
pt_table_sync::main('h=127.1,P=12346,u=msandbox,p=msandbox',
# qw(--print --execute --replicate percona.checksums),
qw(--print --execute --sync-to-source),
qw(--no-foreign-key-checks))
},
stderr => 1,
);
$sb->wait_for_replicas(); # wait for sync to replicate
like(
$output,
qr/REPLACE INTO `test`.`t`\(`id`, `c`\) VALUES \('9', 'i'\)/,
"--replicate with uc index (bug 927771)"
);
my $rows = $replica_dbh->selectall_arrayref("select id, c from test.t where id>8 order by id");
is_deeply(
$rows,
[
[9, 'i'],
[10, 'j'],
],
"Synced replicad (bug 927771)"
);
# #############################################################################
# Done.
# #############################################################################
$sb->wipe_clean($source_dbh);
$sb->wipe_clean($replica_dbh);
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
exit;