mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-14 15:33:49 +00:00
Update progress.t, option_sanity.t, and standard_options.t. Make test env always have slave2 (12347, slave of 12346). Add PerconaTest::count_checksum_results(). Add util/wait-to-exec.
This commit is contained in:
@@ -224,11 +224,11 @@ sub wait_until {
|
||||
|
||||
my $slept = 0;
|
||||
while ( $slept <= $max_t ) {
|
||||
return if $code->();
|
||||
return 1 if $code->();
|
||||
sleep $t;
|
||||
$slept += $t;
|
||||
}
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
# Wait t seconds for code to return.
|
||||
@@ -558,6 +558,41 @@ sub test_bash_tool {
|
||||
return;
|
||||
}
|
||||
|
||||
my %checksum_result_col = (
|
||||
ts => 0,
|
||||
errors => 1,
|
||||
diffs => 2,
|
||||
rows => 3,
|
||||
chunks => 4,
|
||||
skipped => 5,
|
||||
time => 6,
|
||||
table => 7,
|
||||
);
|
||||
sub count_checksum_results {
|
||||
my ($output, $column, $table) = @_;
|
||||
|
||||
my (@res) = map {
|
||||
my $line = $_;
|
||||
my (@cols) = $line =~ m/(\S+)/g;
|
||||
\@cols;
|
||||
}
|
||||
grep {
|
||||
my $line = $_;
|
||||
if ( !$table ) {
|
||||
$line;
|
||||
}
|
||||
else {
|
||||
$line =~ m/$table$/m ? $line : '';
|
||||
}
|
||||
}
|
||||
grep { m/^\d+\-\d+T/ } split /\n/, $output;
|
||||
my $colno = $checksum_result_col{lc $column};
|
||||
die "Invalid checksum result column: $column" unless defined $colno;
|
||||
my $total = 0;
|
||||
map { $total += $_->[$colno] } @res;
|
||||
return $total;
|
||||
}
|
||||
|
||||
1;
|
||||
}
|
||||
# ###########################################################################
|
||||
|
@@ -46,7 +46,4 @@ exit_status=$((exit_status | $?))
|
||||
/tmp/$PORT/use < sakila-db/sakila-data.sql
|
||||
exit_status=$((exit_status | $?))
|
||||
|
||||
$PERCONA_TOOLKIT_BRANCH/sandbox/test-env reset
|
||||
exit_status=$((exit_status | $?))
|
||||
|
||||
exit $exit_status
|
||||
|
@@ -291,6 +291,7 @@ case $opt in
|
||||
exit_status=$?
|
||||
if [ $exit_status -eq 0 ]; then
|
||||
./start-sandbox slave 12346 12345
|
||||
./start-sandbox slave 12347 12346
|
||||
exit_status=$?
|
||||
if [ "$version" != "4.0" ] && [ "$version" != "4.1" ]; then
|
||||
if [ $? -eq 0 ]; then
|
||||
@@ -353,11 +354,18 @@ case $opt in
|
||||
# don't replicate to new sandbox servers. This makes creating new
|
||||
# sandbox servers a lot faster. There's no check if this works or
|
||||
# not, so... yeah.
|
||||
/tmp/12345/use -e "RESET MASTER"
|
||||
/tmp/12346/use -e "RESET MASTER"
|
||||
/tmp/12347/use -e "STOP SLAVE"
|
||||
/tmp/12346/use -e "STOP SLAVE"
|
||||
|
||||
/tmp/12346/use -e "RESET MASTER"
|
||||
/tmp/12345/use -e "RESET MASTER"
|
||||
|
||||
/tmp/12347/use -e "change master to master_host='127.0.0.1', master_user='msandbox', master_password='msandbox', master_port=12346, master_log_file='mysql-bin.000001', master_log_pos=0"
|
||||
/tmp/12346/use -e "change master to master_host='127.0.0.1', master_user='msandbox', master_password='msandbox', master_port=12345, master_log_file='mysql-bin.000001', master_log_pos=0"
|
||||
|
||||
/tmp/12347/use -e "START SLAVE"
|
||||
/tmp/12346/use -e "START SLAVE"
|
||||
|
||||
exit_status=0
|
||||
;;
|
||||
version)
|
||||
|
@@ -42,21 +42,9 @@ $sb->load_file('master', 't/pt-table-checksum/samples/issue_94.sql');
|
||||
PerconaTest::wait_for_table($slave_dbh, 'test.issue_94', 'a=11');
|
||||
$slave_dbh->do("update test.issue_94 set c=''");
|
||||
|
||||
sub get_diffs {
|
||||
my ($output) = @_;
|
||||
my (@diffs) = $output =~ m/
|
||||
^\S+\s+ # TS
|
||||
\d+\s+ # ERRORS
|
||||
(\d+) # DIFFS
|
||||
/gmx;
|
||||
my $total_diffs = 0;
|
||||
map { $total_diffs += $_ } @diffs;
|
||||
return $total_diffs;
|
||||
}
|
||||
|
||||
$output = output(
|
||||
sub { pt_table_checksum::main(@args, qw(-d test -t issue_94)) },
|
||||
trf => \&get_diffs,
|
||||
trf => sub { return PerconaTest::count_checksum_results(@_, 'DIFFS') },
|
||||
);
|
||||
is(
|
||||
$output,
|
||||
@@ -67,7 +55,7 @@ is(
|
||||
$output = output(
|
||||
sub { pt_table_checksum::main(@args, qw(-d test -t issue_94),
|
||||
qw(--ignore-columns c)) },
|
||||
trf => \&get_diffs,
|
||||
trf => sub { return PerconaTest::count_checksum_results(@_, 'DIFFS') },
|
||||
);
|
||||
is(
|
||||
$output,
|
||||
|
@@ -9,26 +9,132 @@ BEGIN {
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
use English qw(-no_match_vars);
|
||||
use Test::More tests => 2;
|
||||
use Test::More tests => 16;
|
||||
|
||||
use PerconaTest;
|
||||
require "$trunk/bin/pt-table-checksum";
|
||||
|
||||
my $output;
|
||||
|
||||
# Test DSN value inheritance
|
||||
$output = `$trunk/bin/pt-table-checksum h=127.1 --replicate table`;
|
||||
# Calling the tool pt_table_checksum::main() doesn't work when we're
|
||||
# dealing with cmd line option error and --help because OptionParser
|
||||
# exits on such things which would cause this test to exit too.
|
||||
|
||||
# ############################################################################
|
||||
# Check default values for some options to ensure something wasn't
|
||||
# changed accidentally. A lot of tests rely on these defaults, so
|
||||
# if they change, it can have weird side-effects.
|
||||
# ############################################################################
|
||||
$output = `$trunk/bin/pt-table-checksum h=127.1 --help`;
|
||||
|
||||
like(
|
||||
$output,
|
||||
qr/^ --check-replication-filters\s+TRUE$/m,
|
||||
"Default --check-replication-filters=TRUE"
|
||||
);
|
||||
|
||||
like(
|
||||
$output,
|
||||
qr/^ --create-replicate-table\s+TRUE$/m,
|
||||
"Default --create-replicate-table=TRUE"
|
||||
);
|
||||
|
||||
like(
|
||||
$output,
|
||||
qr/^ --empty-replicate-table\s+TRUE$/m,
|
||||
"Default --empty-replicate-table=TRUE"
|
||||
);
|
||||
|
||||
like(
|
||||
$output,
|
||||
qr/^ --explain\s+0$/m,
|
||||
"Default --explain=0"
|
||||
);
|
||||
|
||||
like(
|
||||
$output,
|
||||
qr/^ --host\s+localhost$/m,
|
||||
"Default --host=localhost"
|
||||
);
|
||||
|
||||
like(
|
||||
$output,
|
||||
qr/^ --lock-wait-timeout\s+1$/m,
|
||||
"Default --lock-wait-timeout=1"
|
||||
);
|
||||
|
||||
like(
|
||||
$output,
|
||||
qr/^ --max-lag\s+1$/m,
|
||||
"Default --max-lag=1"
|
||||
);
|
||||
|
||||
like(
|
||||
$output,
|
||||
qr/^ --quiet\s+0$/m,
|
||||
"Default --quiet=0"
|
||||
);
|
||||
|
||||
like(
|
||||
$output,
|
||||
qr/^ --recheck\s+TRUE$/m,
|
||||
"Default --recheck=TRUE"
|
||||
);
|
||||
|
||||
like(
|
||||
$output,
|
||||
qr/^ --replicate\s+percona\.checksums$/m,
|
||||
"Default --replicate=percona.checksums"
|
||||
);
|
||||
|
||||
like(
|
||||
$output,
|
||||
qr/^ --replicate-check\s+TRUE$/m,
|
||||
"Default --replicate-check=TRUE"
|
||||
);
|
||||
|
||||
# ############################################################################
|
||||
# Check opts that disable other opts.
|
||||
# ############################################################################
|
||||
$output = `$trunk/bin/pt-table-checksum h=127.1 --help --explain`;
|
||||
like(
|
||||
$output,
|
||||
qr/^ --empty-replicate-table\s+FALSE$/m,
|
||||
"--explain disables --empty-replicate-table"
|
||||
);
|
||||
|
||||
$output = `$trunk/bin/pt-table-checksum h=127.1 --help --resume`;
|
||||
like(
|
||||
$output,
|
||||
qr/^ --empty-replicate-table\s+FALSE$/m,
|
||||
"--resume disables --empty-replicate-table"
|
||||
);
|
||||
|
||||
$output = `$trunk/bin/pt-table-checksum h=127.1 --help --quiet`;
|
||||
like(
|
||||
$output,
|
||||
qr/^ --progress\s+\(No value\)$/m,
|
||||
"--quiet disables --progress"
|
||||
);
|
||||
|
||||
# ############################################################################
|
||||
# Only 1 DSN should be allowed on the command line; no extra args.
|
||||
# ############################################################################
|
||||
$output = `$trunk/bin/pt-table-checksum h=127.1 h=host1 h=host2`;
|
||||
like(
|
||||
$output,
|
||||
qr/More than one host specified; only one allowed/,
|
||||
"Only one DSN allowed on the command line"
|
||||
);
|
||||
|
||||
# ############################################################################
|
||||
# --replicate table must be db-qualified.
|
||||
# ############################################################################
|
||||
$output = `$trunk/bin/pt-table-checksum h=127.1 --replicate checksums`;
|
||||
like(
|
||||
$output,
|
||||
qr/--replicate table must be database-qualified/,
|
||||
"--replicate table must be db-qualified"
|
||||
);
|
||||
|
||||
$output = `$trunk/bin/pt-table-checksum h=127.1 --replicate test.checksum --throttle-method foo`;
|
||||
like(
|
||||
$output,
|
||||
qr/Invalid --throttle-method: foo/,
|
||||
"Invalid --throttle-method"
|
||||
"--replicate table must be database-qualified"
|
||||
);
|
||||
|
||||
# #############################################################################
|
||||
|
@@ -15,10 +15,6 @@ use PerconaTest;
|
||||
use Sandbox;
|
||||
require "$trunk/bin/pt-table-checksum";
|
||||
|
||||
diag(`$trunk/sandbox/test-env reset`);
|
||||
diag(`$trunk/sandbox/stop-sandbox 12347 >/dev/null`);
|
||||
diag(`$trunk/sandbox/start-sandbox slave 12347 12346 >/dev/null`);
|
||||
|
||||
my $dp = new DSNParser(opts=>$dsn_opts);
|
||||
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
|
||||
my $master_dbh = $sb->get_dbh_for('master');
|
||||
@@ -38,17 +34,21 @@ else {
|
||||
plan tests => 3;
|
||||
}
|
||||
|
||||
# Must have empty checksums table for these tests.
|
||||
$master_dbh->do('drop table if exists percona.checksums');
|
||||
|
||||
# The sandbox servers run with lock_wait_timeout=3 and it's not dynamic
|
||||
# so we need to specify --lock-wait-timeout=3 else the tool will die.
|
||||
my $master_dsn = 'h=127.1,P=12345,u=msandbox,p=msandbox';
|
||||
my @args = ($master_dsn, qw(--lock-wait-timeout 3),
|
||||
'--progress', 'time,1');
|
||||
my $output;
|
||||
my $row;
|
||||
my $cnf ='/tmp/12345/my.sandbox.cnf';
|
||||
my @args = (qw(--replicate test.checksum --empty-replicate-table -d test -t resume -q), '-F', $cnf, 'h=127.1', '--progress', 'time,1');
|
||||
|
||||
$sb->create_dbs($master_dbh, [qw(test)]);
|
||||
$sb->load_file('master', 't/pt-table-checksum/samples/checksum_tbl.sql');
|
||||
# We're not using resume table for anything specific, we just need
|
||||
# any table to checksum.
|
||||
$sb->load_file('master', 't/pt-table-checksum/samples/resume.sql');
|
||||
my $scripts = "$trunk/t/pt-table-checksum/scripts/";
|
||||
|
||||
# ############################################################################
|
||||
# Tool should check all slaves' lag, so slave2, not just slave1.
|
||||
# ############################################################################
|
||||
wait_until( # slaves aren't lagging
|
||||
sub {
|
||||
$row = $slave1_dbh->selectrow_hashref('show slave status');
|
||||
@@ -56,47 +56,40 @@ wait_until( # slaves aren't lagging
|
||||
$row = $slave2_dbh->selectrow_hashref('show slave status');
|
||||
return 0 if $row->{Seconds_Behind_Master};
|
||||
return 1;
|
||||
}, 0.5, 10);
|
||||
}
|
||||
) or die "Slaves are still lagging";
|
||||
|
||||
$slave1_dbh->do('stop slave sql_thread');
|
||||
$row = $slave1_dbh->selectrow_hashref('show slave status');
|
||||
is(
|
||||
$row->{slave_sql_running},
|
||||
'No',
|
||||
'Stopped slave SQL thread on slave1'
|
||||
);
|
||||
# This big fancy command waits until it sees the checksum for sakila.city
|
||||
# in the repl table on the master, then it stops slave2 for 2 seconds,
|
||||
# then starts it again.
|
||||
system("$trunk/util/wait-to-exec '$scripts/wait-for-chunk.sh 12345 sakila city 1' '$scripts/exec-wait-exec.sh 12347 \"stop slave sql_thread\" 2 \"start slave sql_thread\"' 3 >/dev/null &");
|
||||
|
||||
$slave2_dbh->do('stop slave sql_thread');
|
||||
$row = $slave2_dbh->selectrow_hashref('show slave status');
|
||||
is(
|
||||
$row->{slave_sql_running},
|
||||
'No',
|
||||
'Stopped slave SQL thread on slave2'
|
||||
);
|
||||
|
||||
system("sleep 2 && /tmp/12346/use -e 'start slave sql_thread' >/dev/null 2>/dev/null &");
|
||||
system("sleep 3 && /tmp/12347/use -e 'start slave sql_thread' >/dev/null 2>/dev/null &");
|
||||
|
||||
# This time we do not need to capture STDERR because mk-table-checksum
|
||||
# should see slave2 come alive in 2 seconds then return before wait_for
|
||||
# dies.
|
||||
$output = output(
|
||||
sub { pt_table_checksum::main(@args); },
|
||||
sub { pt_table_checksum::main(@args, qw(-d sakila)); },
|
||||
stderr => 1,
|
||||
);
|
||||
|
||||
like(
|
||||
$output,
|
||||
qr/Waiting for slave.+?Still waiting/s,
|
||||
"Progress reports while waiting for slaves"
|
||||
qr/Replica h=127.0.0.1,P=12347 is stopped/,
|
||||
"--progress for slave lag"
|
||||
);
|
||||
|
||||
like(
|
||||
$output,
|
||||
qr/sakila.store$/m,
|
||||
"Checksumming continues after waiting for slave lag"
|
||||
);
|
||||
|
||||
is(
|
||||
PerconaTest::count_checksum_results($output, 'errors'),
|
||||
0,
|
||||
"No errors after waiting for slave lag"
|
||||
);
|
||||
|
||||
# #############################################################################
|
||||
# Done.
|
||||
# #############################################################################
|
||||
diag(`$trunk/sandbox/stop-sandbox 12347 >/dev/null`);
|
||||
diag(`/tmp/12346/stop >/dev/null`); # Start/stop clears SHOW SLAVE HOSTS.
|
||||
diag(`/tmp/12346/start >/dev/null`);
|
||||
$sb->wipe_clean($master_dbh);
|
||||
diag(`$trunk/sandbox/test-env reset >/dev/null`);
|
||||
exit;
|
||||
|
@@ -3,3 +3,8 @@ TABLE CHUNK CNT_DIFF CRC_DIFF CHUNK_INDEX LOWER_BOUNDARY UPPER_BOUNDARY
|
||||
sakila.city 1 0 1 PRIMARY 1 100
|
||||
sakila.city 6 0 1 PRIMARY 501 600
|
||||
|
||||
Differences on h=127.0.0.1,P=12347
|
||||
TABLE CHUNK CNT_DIFF CRC_DIFF CHUNK_INDEX LOWER_BOUNDARY UPPER_BOUNDARY
|
||||
sakila.city 1 0 1 PRIMARY 1 100
|
||||
sakila.city 6 0 1 PRIMARY 501 600
|
||||
|
||||
|
10
t/pt-table-checksum/scripts/exec-wait-exec.sh
Executable file
10
t/pt-table-checksum/scripts/exec-wait-exec.sh
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
port=$1
|
||||
query1=$2
|
||||
t=$3
|
||||
query2=$4
|
||||
|
||||
/tmp/$port/use -e "$query1"
|
||||
sleep $t
|
||||
/tmp/$port/use -e "$query2"
|
8
t/pt-table-checksum/scripts/wait-for-chunk.sh
Executable file
8
t/pt-table-checksum/scripts/wait-for-chunk.sh
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
port=$1
|
||||
db=$2
|
||||
tbl=$3
|
||||
chunk=$4
|
||||
|
||||
/tmp/$port/use -e "select 1 from percona.checksums where db='$db' and tbl='$tbl' and chunk=$chunk" 2>/dev/null | grep -q 1 2>/dev/null
|
@@ -27,7 +27,7 @@ elsif ( !$slave_dbh ) {
|
||||
plan skip_all => 'Cannot connect to sandbox slave1';
|
||||
}
|
||||
else {
|
||||
plan tests => 4;
|
||||
plan tests => 5;
|
||||
}
|
||||
|
||||
# The sandbox servers run with lock_wait_timeout=3 and it's not dynamic
|
||||
@@ -36,6 +36,37 @@ my @args = (qw(--lock-wait-timeout 3 --explain --tables sakila.country));
|
||||
my $cnf = "/tmp/12345/my.sandbox.cnf";
|
||||
my $pid_file = "/tmp/mk-table-checksum-test.pid";
|
||||
my $output;
|
||||
my $exit_status;
|
||||
|
||||
# ############################################################################
|
||||
# Tool should connect to localhost without any options.
|
||||
# ############################################################################
|
||||
|
||||
# This may not work because the sandbox servers aren't on localhost,
|
||||
# but if your box has MySQL running on localhost then maybe it will,
|
||||
# so we'll account for both of these possibilities.
|
||||
|
||||
eval {
|
||||
$exit_status = pt_table_checksum::main(@args);
|
||||
};
|
||||
if ( $EVAL_ERROR ) {
|
||||
# It's ok that this fails. It means that your box, like mine, doesn't
|
||||
# have MySQL on localhost:3306:/tmp/mysql.socket/etc.
|
||||
like(
|
||||
$EVAL_ERROR,
|
||||
qr/connect\(';host=localhost;/,
|
||||
'Default DSN is h=localhost'
|
||||
);
|
||||
}
|
||||
else {
|
||||
# Apparently, your box is running MySQL on default ports. That
|
||||
# means the tool ran, so it should run without errors.
|
||||
is(
|
||||
$exit_status,
|
||||
0,
|
||||
'Default DSN is h=localhost'
|
||||
);
|
||||
}
|
||||
|
||||
# ############################################################################
|
||||
# DSN should inherit connection options (--port, etc.)
|
||||
|
40
util/wait-to-exec
Executable file
40
util/wait-to-exec
Executable file
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
use Time::HiRes qw(sleep time);
|
||||
|
||||
if ( !@ARGV || @ARGV < 2 ) {
|
||||
print STDERR "Usage: wait-to-exec WAIT EXEC [RUNTIME [INTERVAL]]\n",
|
||||
"When the WAIT script exits 0, execute the EXEC script.\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
my ($wait, $exec, $runtime, $interval) = @ARGV;
|
||||
$runtime ||= 1.0;
|
||||
$interval ||= 0.1;
|
||||
|
||||
#warn "wait: $wait\n";
|
||||
#warn "exec: $exec\n";
|
||||
|
||||
my $t_start = time;
|
||||
while ( time - $t_start < $runtime ) {
|
||||
if ( exit_status($wait) ) {
|
||||
sleep $interval;
|
||||
}
|
||||
else {
|
||||
# exec does not return; this script becomes the exec process.
|
||||
exec($exec);
|
||||
}
|
||||
}
|
||||
|
||||
warn "Never observed wait condition";
|
||||
exit 1;
|
||||
|
||||
sub exit_status {
|
||||
my ($wait) = @_;
|
||||
system($wait);
|
||||
# Like grep, exit status 0 means "match found", so stop waiting.
|
||||
my $exit_status = $? >> 8;
|
||||
return $exit_status;
|
||||
}
|
Reference in New Issue
Block a user