1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
|
#!/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 slave hosts, but
# the sandbox servers are all on one host so all slaves have
# the same hostname.
$ENV{PERCONA_TOOLKIT_TEST_USE_DSN_NAMES} = 1;
use Data::Dumper;
use PerconaTest;
use Sandbox;
# Fix @INC because pt-table-checksum uses subclass OobNibbleIterator.
require "$trunk/bin/pt-table-checksum";
my $dp = new DSNParser(opts=>$dsn_opts);
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
my $master_dbh = $sb->get_dbh_for('master');
my $slave1_dbh = $sb->get_dbh_for('slave1');
my $slave2_dbh = $sb->get_dbh_for('slave2');
if ( !$master_dbh ) {
plan skip_all => 'Cannot connect to sandbox master';
}
elsif ( !$slave1_dbh ) {
plan skip_all => 'Cannot connect to sandbox slave1';
}
elsif ( !@{$master_dbh->selectall_arrayref("show databases like 'sakila'")} ) {
plan skip_all => 'sakila database is not loaded';
}
# 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 $master_dsn = 'h=127.1,P=12345';
my @args = (qw(--set-vars innodb_lock_wait_timeout=3));
my $row;
my $output;
my $exit_status;
my $sample = "t/pt-table-checksum/samples/";
# ############################################################################
# Should always create schema and tables with IF NOT EXISTS
# https://bugs.launchpad.net/percona-toolkit/+bug/950294
# ############################################################################
$master_dbh->do("DROP DATABASE IF EXISTS percona");
diag(`/tmp/12345/use -u root < $trunk/t/lib/samples/ro-checksum-user.sql 2>/dev/null`);
PerconaTest::wait_for_table($slave2_dbh, "mysql.user", "user='ro_checksum_user'");
$output = output(
sub { $exit_status = pt_table_checksum::main(@args,
"$master_dsn,u=ro_checksum_user,p=msandbox",
qw(--recursion-method none)
) },
stderr => 1,
);
like(
$output,
qr/\Qdatabase percona does not exist and it cannot be created automatically/,
"Error if percona db doesn't exist and user can't create it",
);
$output = output(
sub { pt_table_checksum::main(@args,
"$master_dsn,u=ro_checksum_user,p=msandbox",
qw(--recursion-method none --no-create-replicate-table)
) },
stderr => 1,
);
like(
$output,
qr/\Qdatabase percona does not exist and --no-create-replicate-table was/,
"Error if percona db doesn't exist and --no-create-replicate-table",
);
diag(`/tmp/12345/use -u root -e "drop user 'ro_checksum_user'\@'%'"`);
wait_until(
sub {
my $rows=$slave2_dbh->selectall_arrayref("SELECT user FROM mysql.user");
return !grep { ($_->[0] || '') eq 'ro_checksum_user' } @$rows;
}
);
# ############################################################################
# --recursion-method=none to avoid SHOW SLAVE HOSTS
# https://bugs.launchpad.net/percona-toolkit/+bug/987694
# ############################################################################
# Create percona.checksums because ro_checksum_user doesn't have the privs.
pt_table_checksum::main(@args,
"$master_dsn,u=msandbox,p=msandbox",
qw(-t sakila.country --quiet --quiet));
diag(`/tmp/12345/use -u root < $trunk/t/lib/samples/ro-checksum-user.sql 2>/dev/null`);
PerconaTest::wait_for_table($slave1_dbh, "mysql.tables_priv", "user='ro_checksum_user'");
$output = output(
sub { $exit_status = pt_table_checksum::main(@args,
"$master_dsn,u=ro_checksum_user,p=msandbox",
# Comment out this line and the tests fail because ro_checksum_user
# doesn't have privs to SHOW SLAVE HOSTS. This proves that
# --recursion-method none is working.
qw(--recursion-method none --no-create-replicate-table)
) },
stderr => 1,
);
is(
$exit_status,
0,
"Read-only user (bug 987694): 0 exit"
);
like(
$output,
qr/ sakila.store$/m,
"Read-only user (bug 987694): checksummed rows"
);
($output, $exit_status) = full_output(
sub { pt_table_checksum::main(@args,
"$master_dsn,u=ro_checksum_user,p=msandbox",
qw(--recursion-method none)
) }
);
is(
$exit_status,
0,
"No error if db exists on the master, can't CREATE DATABASE, --no-create-replicate-table was not specified, but the database does exist in all slaves"
);
diag(qx{/tmp/12345/use -u root -e 'DROP TABLE `percona`.`checksums`'});
($output, $exit_status) = full_output(
sub { pt_table_checksum::main(@args,
"$master_dsn,u=ro_checksum_user,p=msandbox",
qw(--recursion-method none --no-create-replicate-table)
) },
);
like($output,
qr/\Q--replicate table `percona`.`checksums` does not exist and --no/,
"Error if checksums db doesn't exist and --no-create-replicate-table"
);
diag(`/tmp/12345/use -u root -e "drop user 'ro_checksum_user'\@'%'"`);
wait_until(
sub {
my $rows=$slave2_dbh->selectall_arrayref("SELECT user FROM mysql.user");
return !grep { ($_->[0] || '') eq 'ro_checksum_user' } @$rows;
}
);
# #############################################################################
# Bug 916168: bug in pt-table-checksum privileges check
# #############################################################################
diag(`/tmp/12345/use -u root < $trunk/t/pt-table-checksum/samples/privs-bug-916168.sql`);
$output = output(
sub { $exit_status = pt_table_checksum::main(@args,
"$master_dsn,u=test_user,p=foo", qw(-t sakila.country)) },
);
is(
PerconaTest::count_checksum_results($output, 'rows'),
109,
"test_user privs work (bug 916168)"
);
diag(`/tmp/12345/use -u root -e "drop user 'test_user'\@'%'"`);
wait_until(
sub {
my $rows=$slave2_dbh->selectall_arrayref("SELECT user FROM mysql.user");
return !grep { ($_->[0] || '') eq 'test_user' } @$rows;
}
);
# #############################################################################
# Done.
# #############################################################################
$sb->wipe_clean($master_dbh);
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
done_testing;
exit;
|