Files
percona-toolkit/t/pt-table-checksum/chunk_index.t
Sveta Smirnova d02355f89b PT-2340 - Support MySQL 8.4
- Updated modules and tests for pt-query-digest, pt-show-grants, pt-slave-delay, pt-slave-find, pt-slave-restart, pt-stalk, pt-summary, pt-table-checksum
2024-08-03 14:24:10 +03:00

265 lines
7.9 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-checksum";
my $dp = new DSNParser(opts=>$dsn_opts);
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
my $dbh = $sb->get_dbh_for('source');
if ( !$dbh ) {
plan skip_all => 'Cannot connect to sandbox source';
}
else {
plan tests => 14;
}
# 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.
# And --max-load "" prevents waiting for status variables.
my $source_dsn = 'h=127.1,P=12345,u=msandbox,p=msandbox';
my @args = ($source_dsn, qw(--set-vars innodb_lock_wait_timeout=3 --explain --chunk-size 3), '--max-load', '');
my $output;
my $out = "t/pt-table-checksum/samples/";
$sb->load_file('source', "t/pt-table-checksum/samples/issue_519.sql");
ok(
no_diff(
sub { pt_table_checksum::main(@args, qw(-t issue_519.t --explain)) },
"$out/chunkidx001.txt",
),
"Chooses chunk index by default"
);
ok(
no_diff(
sub { pt_table_checksum::main(@args, qw(--chunk-index dog),
qw(-t issue_519.t --explain)) },
"$out/chunkidx001.txt",
),
"Chooses chunk index if --chunk-index doesn't exist"
);
ok(
no_diff(
sub { pt_table_checksum::main(@args, qw(--chunk-index myidx),
qw(-t issue_519.t --explain)) },
"$out/chunkidx002.txt",
),
"Use --chunk-index"
);
# XXX I'm not sure what this tests thinks it's testing because index y
# is a single column index, so there's really not "left-most".
ok(
no_diff(
sub { pt_table_checksum::main(@args, qw(--chunk-index y),
qw(-t issue_519.t --explain)) },
"$out/chunkidx003.txt",
),
"Chunks on left-most --chunk-index column"
);
# #############################################################################
# Issue 378: Make mk-table-checksum try to use the index preferred by the
# optimizer
# #############################################################################
# This issue affect --chunk-index. Tool should auto-choose chunk-index
# when --where is given but no explicit --chunk-index|column is given.
# Given the --where clause, MySQL will prefer the idx_fk_country_id index.
# UPDATE: I think the order of preference for the tool should be:
# (user chosen idx) > (mysql chosen idx IF it's unique) >
# (any unique idx) > (non unique idx with highest cardinality)
# Test below assumes tool should choose mysql chosen idx even if unique idx
# is available, so I'm commenting it out.
# TODO: A test that checks that tool prefers non unique mysql chosen idx
# from other non unique idx.
#ok(
# no_diff(
# sub { pt_table_checksum::main(@args, "--where", "country_id > 100",
# qw(-t sakila.city)) },
# "$out/chunkidx004.txt",
# keep_output => 1
# ),
# "Auto-chosen --chunk-index for --where (issue 378)"
#);
# If user specifies --chunk-index, then ignore the index MySQL wants to
# use (idx_fk_country_id in this case) and use the user's index.
ok(
no_diff(
sub { pt_table_checksum::main(@args, qw(--chunk-index PRIMARY),
"--where", "country_id > 100", qw(-t sakila.city)) },
"$out/chunkidx005.txt",
),
"Explicit --chunk-index overrides MySQL's index for --where"
);
# #############################################################################
# Bug 925855: pt-table-checksum index check is case-sensitive
# #############################################################################
$sb->load_file('source', "t/pt-table-checksum/samples/all-uc-table.sql");
my $exit_status = 0;
$output = output(sub {
$exit_status = pt_table_checksum::main(
$source_dsn, '--max-load', '',
qw(--set-vars innodb_lock_wait_timeout=3 --chunk-size 5 -t ALL_UC.T)
) },
stderr => 1,
);
is(
$exit_status,
0,
"Zero exit status (bug 925855)"
);
is(
PerconaTest::count_checksum_results($output, 'skipped'),
0,
"0 skipped (bug 925855)"
);
is(
PerconaTest::count_checksum_results($output, 'errors'),
0,
"0 errors (bug 925855)"
);
is(
PerconaTest::count_checksum_results($output, 'rows'),
13,
"14 rows checksummed (bug 925855)"
);
# #############################################################################
# Bug 978432: PK is ignored
# #############################################################################
$sb->load_file('source', "t/pt-table-checksum/samples/not-using-pk-bug.sql");
ok(
no_diff(
sub { pt_table_checksum::main(@args,
qw(-t test.multi_resource_apt --chunk-size 2 --explain --explain))
},
"t/pt-table-checksum/samples/not-using-pk-bug.out",
),
"Smarter chunk index selection (bug 978432)"
);
# the following 2 tests seem to rely on EXPLAIN getting key_len wrong
# on a poorly indexed table.
# but this doesn't happen on all configurations of OS/MySQL
# commenting out for now, until I think of an alternate way to test this
# #############################################################################
# PK but bad explain plan.
# https://bugs.launchpad.net/percona-toolkit/+bug/1010232
# #############################################################################
#$sb->load_file('source', "t/pt-table-checksum/samples/bad-plan-bug-1010232.sql");
#PerconaTest::wait_for_table($dbh, "bad_plan.t", "(c1,c2,c3,c4)=(1,1,2,100)");
#$output = output(sub {
# $exit_status = pt_table_checksum::main(
# $source_dsn, '--max-load', '',
# qw(--set-vars innodb_lock_wait_timeout=3 --chunk-size 10 -t bad_plan.t)
# ) },
# stderr => 1,
#);
#
#is(
# $exit_status,
# 32, # SKIP_CHUNK
# "Bad key_len chunks are not errors"
#) or diag($output);
#
#cmp_ok(
# PerconaTest::count_checksum_results($output, 'skipped'),
# '>',
# 1,
# "Skipped bad key_len chunks"
#);
# Use --chunk-index:3 to use only the first 3 left-most columns of the index.
# Can't use bad_plan.t, however, because its row are almost all identical,
# so using 3 of 4 pk cols creates an infinite loop.
ok(
no_diff(
sub {
pt_table_checksum::main(
$source_dsn, '--max-load', '',
qw(--set-vars innodb_lock_wait_timeout=3 --chunk-size 5000 -t sakila.rental),
qw(--chunk-index rental_date --chunk-index-columns 2),
qw(--explain --explain));
},
"t/pt-table-checksum/samples/n-chunk-index-cols.txt",
),
"--chunk-index-columns"
);
$output = output(
sub {
$exit_status = pt_table_checksum::main(
$source_dsn, '--max-load', '',
qw(--set-vars innodb_lock_wait_timeout=3 --chunk-size 1000 -t sakila.film_actor),
qw(--chunk-index PRIMARY --chunk-index-columns 9),
);
},
stderr => 1,
);
is(
PerconaTest::count_checksum_results($output, 'rows'),
5462,
"--chunk-index-columns > number of index columns"
) or diag($output);
$output = output(
sub {
$exit_status = pt_table_checksum::main(
$source_dsn, '--max-load', '',
qw(--set-vars innodb_lock_wait_timeout=3 --chunk-size 1000 -t sakila.film_actor),
qw(--chunk-index-columns 1 --chunk-size-limit 3),
);
},
stderr => 1,
);
# Since we're not using the full index, it's basically a non-unique index,
# so there are dupes. The table really has 5462 rows, so we must get
# at least that many, and probably a few more.
cmp_ok(
PerconaTest::count_checksum_results($output, 'rows'),
'>=',
5462,
"Initial key_len reflects --chunk-index-columns"
) or diag($output);
# #############################################################################
# Done.
# #############################################################################
$sb->wipe_clean($dbh);
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
exit;