mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-11 21:51:21 +00:00
412 lines
12 KiB
Perl
412 lines
12 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;
|
|
|
|
# Hostnames make testing less accurate. Tests need to see
|
|
# that such-and-such happened on specific replica hosts, but
|
|
# the sandbox servers are all on one host so all replicas have
|
|
# the same hostname.
|
|
$ENV{PERCONA_TOOLKIT_TEST_USE_DSN_NAMES} = 1;
|
|
|
|
use Data::Dumper;
|
|
use PerconaTest;
|
|
use Sandbox;
|
|
|
|
require "$trunk/bin/pt-table-checksum";
|
|
|
|
my $dp = new DSNParser(opts=>$dsn_opts);
|
|
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
|
|
my $source_dbh = $sb->get_dbh_for('source');
|
|
my $replica1_dbh = $sb->get_dbh_for('replica1');
|
|
my $replica2_dbh = $sb->get_dbh_for('replica2');
|
|
|
|
if ( !$source_dbh ) {
|
|
plan skip_all => 'Cannot connect to sandbox source';
|
|
}
|
|
elsif ( !$replica1_dbh ) {
|
|
plan skip_all => 'Cannot connect to sandbox replica1';
|
|
}
|
|
elsif ( !$replica2_dbh ) {
|
|
plan skip_all => 'Cannot connect to sandbox replica2';
|
|
}
|
|
|
|
# The sandbox servers run with lock_wait_timeout=3 and it's not dynamic
|
|
# so we need to specify --set-vars innodb_lock_wait_timeout=3 else the tool will die.
|
|
my $source_dsn = 'h=127.1,P=12345,u=msandbox,p=msandbox,s=1';
|
|
my @args = ($source_dsn, qw(--set-vars innodb_lock_wait_timeout=3));
|
|
my $output;
|
|
my $exit_status;
|
|
my $sample = "t/pt-table-checksum/samples/";
|
|
|
|
# ############################################################################
|
|
# https://bugs.launchpad.net/percona-toolkit/+bug/995274
|
|
# Can't use an undefined value as an ARRAY reference at pt-table-checksum
|
|
# line 2206
|
|
# ############################################################################
|
|
$sb->load_file('source', "$sample/undef-arrayref-bug-995274.sql");
|
|
|
|
# Must chunk the table so an index is used.
|
|
$output = output(
|
|
sub { $exit_status = pt_table_checksum::main(@args,
|
|
qw(-d test --chunk-size 100)) },
|
|
stderr => 1,
|
|
);
|
|
|
|
is(
|
|
$exit_status,
|
|
0,
|
|
"Bug 995274 (undef array): zero exit status"
|
|
) or diag($output);
|
|
|
|
cmp_ok(
|
|
PerconaTest::count_checksum_results($output, 'rows'),
|
|
'>',
|
|
1,
|
|
"Bug 995274 (undef array): checksummed rows"
|
|
);
|
|
|
|
|
|
# #############################################################################
|
|
# https://bugs.launchpad.net/percona-toolkit/+bug/987393
|
|
# Empy tables cause "undefined value as an ARRAY" errors
|
|
# #############################################################################
|
|
$source_dbh->do("DROP DATABASE IF EXISTS percona"); # clear old checksums
|
|
$sb->load_file('source', "$sample/empty-table-bug-987393.sql");
|
|
|
|
$output = output(
|
|
sub { $exit_status = pt_table_checksum::main(
|
|
@args, qw(-d test --chunk-size-limit 0)) },
|
|
stderr => 1,
|
|
);
|
|
|
|
is(
|
|
$exit_status,
|
|
0,
|
|
"Bug 987393 (empty table): zero exit status"
|
|
);
|
|
|
|
is(
|
|
PerconaTest::count_checksum_results($output, 'errors'),
|
|
0,
|
|
"Bug 987393 (empty table): no errors"
|
|
);
|
|
|
|
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,
|
|
[
|
|
['test', 'test_empty', '1', '0', '0'], # empty
|
|
['test', 'test_full', '1', '4d284606', '1'], # row
|
|
],
|
|
"Bug 987393 (empty table): checksums"
|
|
) or print STDERR Dumper($rows);
|
|
|
|
# #############################################################################
|
|
# https://bugs.launchpad.net/percona-toolkit/+bug/919499
|
|
# MySQL error 1592 with MySQL 5.5.18+ and Perl 5.8
|
|
# #############################################################################
|
|
$output = output(
|
|
sub {
|
|
print `$trunk/bin/pt-table-checksum $source_dsn -t sakila.country 2>&1`;
|
|
}
|
|
);
|
|
|
|
is(
|
|
PerconaTest::count_checksum_results($output, 'errors'),
|
|
0,
|
|
"Bug 987393 (Perl 5.8 scoping): no errors"
|
|
);
|
|
|
|
is(
|
|
PerconaTest::count_checksum_results($output, 'rows'),
|
|
109,
|
|
"Bug 987393 (Perl 5.8 scoping): checksummed table"
|
|
);
|
|
|
|
# #############################################################################
|
|
# https://bugs.launchpad.net/percona-toolkit/+bug/1030031
|
|
# pt-table-checksum reports wrong number of DIFFS
|
|
# #############################################################################
|
|
$sb->load_file('source', "$sample/a-z.sql");
|
|
$sb->wait_for_replicas();
|
|
|
|
# Create 2 diffs on replica1 and 1 diff on replica2.
|
|
$replica1_dbh->do("UPDATE test.t SET c='' WHERE id=5"); # diff on replica1 & 2
|
|
$replica1_dbh->do("SET SQL_LOG_BIN=0");
|
|
$replica1_dbh->do("UPDATE test.t SET c='' WHERE id=20"); # diff only on replica1
|
|
|
|
# Restore sql_log_bin on replica1 in case later tests use it.
|
|
$replica1_dbh->do("SET SQL_LOG_BIN=1");
|
|
|
|
$output = output(
|
|
sub { pt_table_checksum::main(@args, qw(-t test.t --chunk-size 10)) },
|
|
);
|
|
|
|
is(
|
|
PerconaTest::count_checksum_results($output, 'diffs'),
|
|
2,
|
|
"Bug 1030031 (wrong DIFFS): 2 diffs"
|
|
);
|
|
|
|
# Restore replica2, but then give it 1 diff that's not the same chunk#
|
|
# as replica1, so there's 3 unique chunk that differ.
|
|
$replica2_dbh->do("UPDATE test.t SET c='e' WHERE id=5");
|
|
$replica2_dbh->do("UPDATE test.t SET c='' WHERE id=26");
|
|
|
|
$output = output(
|
|
sub { pt_table_checksum::main(@args, qw(-t test.t --chunk-size 10)) },
|
|
);
|
|
|
|
is(
|
|
PerconaTest::count_checksum_results($output, 'diffs'),
|
|
3,
|
|
"Bug 1030031 (wrong DIFFS): 3 diffs"
|
|
);
|
|
|
|
# #############################################################################
|
|
# pt-table-checksum does't ignore tables for --replicate-check-only
|
|
# https://bugs.launchpad.net/percona-toolkit/+bug/1074179
|
|
# #############################################################################
|
|
|
|
$output = output(
|
|
sub { pt_table_checksum::main(@args, qw(--replicate-check-only --ignore-tables-regex=t)) },
|
|
stderr => 1,
|
|
);
|
|
|
|
chomp($output);
|
|
|
|
like(
|
|
$output,
|
|
qr/Starting checksum/,
|
|
"Bug 1074179: ignore-tables-regex works with --replicate-check-only"
|
|
);
|
|
# #############################################################################
|
|
# pt-table-checksum can crash with --columns if none match
|
|
# https://bugs.launchpad.net/percona-toolkit/+bug/1016131
|
|
# #############################################################################
|
|
|
|
($output) = output(
|
|
sub { pt_table_checksum::main(@args, '--tables', 'mysql.user,mysql.db',
|
|
'--columns', 'some_fale_column') },
|
|
stderr => 1,
|
|
);
|
|
|
|
like(
|
|
$output,
|
|
qr/\QSkipping table mysql.user because all columns are excluded by --columns or --ignore-columns/,
|
|
"Bug 1016131: ptc should skip tables where all columns are excluded"
|
|
);
|
|
|
|
{
|
|
$output = output(
|
|
sub { pt_table_checksum::main(@args,
|
|
'--skip-check-replica-lag', "h=127.0.0.1,P=".$sb->port_for('replica1'),
|
|
),
|
|
},
|
|
);
|
|
|
|
my $skipping_str = "Skipping.*".$sb->port_for('replica1');
|
|
like(
|
|
$output,
|
|
qr/$skipping_str/s,
|
|
"--skip-check-replica-lag",
|
|
);
|
|
|
|
unlike(
|
|
$output,
|
|
qr/Option --skip-check-slave-lag is deprecated and will be removed in future versions./,
|
|
'Deprecation warning not printed when option --skip-check-replica-lag provided'
|
|
) or diag($output);
|
|
|
|
# Deprecatted option --skip-check-slave-lag
|
|
$output = output(
|
|
sub {
|
|
pt_table_checksum::main(@args,
|
|
'--skip-check-slave-lag', "h=127.0.0.1,P=".$sb->port_for('replica1'),
|
|
),
|
|
},
|
|
stderr => 1,
|
|
);
|
|
|
|
$skipping_str = "Skipping.*".$sb->port_for('replica1');
|
|
like(
|
|
$output,
|
|
qr/$skipping_str/s,
|
|
"--skip-check-slave-lag",
|
|
);
|
|
|
|
like(
|
|
$output,
|
|
qr/Option --skip-check-slave-lag is deprecated and will be removed in future versions./,
|
|
'Deprecation warning printed when option --skip-check-slave-lag provided'
|
|
) or diag($output);
|
|
|
|
# Test #12
|
|
# Test for skip-check-replica-lag and empty replica port
|
|
$output = output(
|
|
sub { pt_table_checksum::main(@args,
|
|
'--skip-check-replica-lag', "h=127.0.0.1",
|
|
),
|
|
},
|
|
stderr => 1
|
|
);
|
|
|
|
unlike(
|
|
$output,
|
|
qr/Use of uninitialized value.*/,
|
|
'No syntax error if port is missed in --skip-check-replica-lag DSN',
|
|
) or diag($output);
|
|
}
|
|
# #############################################################################
|
|
# Illegal division by zero at pt-table-checksum line 7950
|
|
# https://bugs.launchpad.net/percona-toolkit/+bug/1075638
|
|
# and the ptc part of
|
|
# divison by zero errors on default Gentoo mysql
|
|
# https://bugs.launchpad.net/percona-toolkit/+bug/1050737
|
|
# #############################################################################
|
|
|
|
{
|
|
no warnings qw(redefine once);
|
|
my $orig = \&Time::HiRes::time;
|
|
my $time = Time::HiRes::time();
|
|
local *pt_table_checksum::time = local *Time::HiRes::time = sub { $time };
|
|
|
|
($output) = output(
|
|
sub { pt_table_checksum::main(@args,
|
|
qw(--replicate=pt.checksums -t test.t --chunk-size 10))
|
|
},
|
|
stderr => 1
|
|
);
|
|
|
|
unlike(
|
|
$output,
|
|
qr/Illegal division by zero/,
|
|
"Bugs 1075638 and 1050737: No division by zero error when nibble_time is zero"
|
|
);
|
|
|
|
is(
|
|
PerconaTest::count_checksum_results($output, 'diffs'),
|
|
3,
|
|
"Bug 1075638 and 1050737: ...And we get the correct number of diffs"
|
|
);
|
|
}
|
|
|
|
# #############################################################################
|
|
# pt-table-checksum doesn't warn if binlog_format=row or mixed on replicas
|
|
# https://bugs.launchpad.net/percona-toolkit/+bug/938068
|
|
# #############################################################################
|
|
|
|
SKIP: {
|
|
skip "binlog_format tests require MySQL 5.1 and newer", 2
|
|
unless $sandbox_version ge '5.1';
|
|
|
|
local $ENV{BINLOG_FORMAT} = 'ROW';
|
|
diag(`$trunk/sandbox/start-sandbox replica 12348 12345`);
|
|
local $ENV{BINLOG_FORMAT} = 'MIXED';
|
|
diag(`$trunk/sandbox/start-sandbox replica 12349 12348`);
|
|
|
|
$output = output( sub { pt_table_checksum::main(@args) }, stderr => 1 );
|
|
|
|
my $re = qr/Replica .+? has binlog_format (\S+)/msi;
|
|
like(
|
|
$output,
|
|
$re,
|
|
"Bug 938068: doesn't warn if binlog_format=row or mixed on replicas"
|
|
);
|
|
|
|
is_deeply(
|
|
[ $output =~ /$re/g ],
|
|
[ 'ROW', 'MIXED' ],
|
|
"...and warns for both level 1 and level 2 replicas"
|
|
) or diag($output);
|
|
|
|
diag(`$trunk/sandbox/stop-sandbox 12349 12348`);
|
|
}
|
|
|
|
# #############################################################################
|
|
# pt-table-checksum --recursion-method cluster crashes
|
|
# https://bugs.launchpad.net/percona-toolkit/+bug/1210537
|
|
# #############################################################################
|
|
|
|
$output = output(sub {
|
|
pt_table_checksum::main($source_dsn,
|
|
qw(--recursion-method cluster -t mysql.user)
|
|
)},
|
|
stderr => 1,
|
|
);
|
|
unlike(
|
|
$output,
|
|
qr/uninitialized value/,
|
|
"Bug 1210537: no crash with --recursion-method cluster"
|
|
);
|
|
like(
|
|
$output,
|
|
qr/mysql.user/,
|
|
"Bug 1210537: tool ran"
|
|
);
|
|
|
|
# #############################################################################
|
|
# pt-table-checksum has errors when replicas have different system_time_zone
|
|
# https://bugs.launchpad.net/percona-toolkit/+bug/1388870
|
|
# #############################################################################
|
|
|
|
# make replica set diferent system_time_zone by changing env var TZ.
|
|
diag(`/tmp/12346/stop >/dev/null`);
|
|
diag(`export TZ='HST';/tmp/12346/start >/dev/null`);
|
|
|
|
$output = output(
|
|
sub { pt_table_checksum::main(@args, qw(-t sakila.payment)) },
|
|
);
|
|
|
|
|
|
is(
|
|
PerconaTest::count_checksum_results($output, 'diffs'),
|
|
0,
|
|
"Bug 1388870 - No false positive reported when system_tz differ on replica"
|
|
);
|
|
|
|
# restore replica to original system_tz
|
|
diag(`/tmp/12346/stop >/dev/null`);
|
|
diag(`/tmp/12346/start >/dev/null`);
|
|
|
|
# #############################################################################
|
|
# typo in pt-table-checksum error message
|
|
# https://perconadev.atlassian.net/browse/PT-2424
|
|
# #############################################################################
|
|
|
|
$output = output(sub {
|
|
pt_table_checksum::main($source_dsn,
|
|
qw(--no-empty-replicate-table --truncate-replicate-table)
|
|
)},
|
|
stderr => 1,
|
|
);
|
|
|
|
unlike(
|
|
$output,
|
|
qr/--resume and --no-empty-replicate-table are mutually exclusive/,
|
|
"PT-2424: no typo in the error message"
|
|
);
|
|
|
|
like(
|
|
$output,
|
|
qr/--truncate-replicate-table and --no-empty-replicate-table are mutually exclusive/,
|
|
"PT-2424: correct error message"
|
|
);
|
|
|
|
#
|
|
# #############################################################################
|
|
# Done.
|
|
# #############################################################################
|
|
$sb->wipe_clean($source_dbh);
|
|
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
|
|
done_testing;
|