mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-25 21:54:48 +00:00
PT-1114 test fix
This commit is contained in:
@@ -6292,6 +6292,7 @@ use strict;
|
||||
use warnings FATAL => 'all';
|
||||
use English qw(-no_match_vars);
|
||||
use constant PTDEBUG => $ENV{PTDEBUG} || 0;
|
||||
use IndexLength;
|
||||
|
||||
use Data::Dumper;
|
||||
$Data::Dumper::Indent = 1;
|
||||
@@ -6690,11 +6691,11 @@ sub row_estimate {
|
||||
|
||||
sub can_nibble {
|
||||
my (%args) = @_;
|
||||
my @required_args = qw(Cxn tbl chunk_size OptionParser TableParser);
|
||||
my @required_args = qw(Cxn tbl chunk_size OptionParser TableParser Quoter);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
my ($cxn, $tbl, $chunk_size, $o) = @args{@required_args};
|
||||
my ($cxn, $tbl, $chunk_size, $o, $q) = @args{@required_args};
|
||||
|
||||
my $where = $o->has('where') ? $o->get('where') : '';
|
||||
|
||||
@@ -6705,13 +6706,30 @@ sub can_nibble {
|
||||
);
|
||||
|
||||
if ( !$where ) {
|
||||
$mysql_index = undef;
|
||||
}
|
||||
$mysql_index = undef;
|
||||
}
|
||||
|
||||
my $chunk_size_limit = $o->get('chunk-size-limit') || 1;
|
||||
my $one_nibble = !defined $args{one_nibble} || $args{one_nibble}
|
||||
? $row_est <= $chunk_size * $chunk_size_limit
|
||||
: 0;
|
||||
|
||||
if ($mysql_index) {
|
||||
my $idx_len = IndexLength->new(Quoter => $q);
|
||||
my ($key_len, $key) = $idx_len->index_length(
|
||||
Cxn => $args{Cxn},
|
||||
tbl => $tbl,
|
||||
index => $mysql_index,
|
||||
n_index_cols => $o->get('chunk-index-columns'),
|
||||
);
|
||||
|
||||
if ( !$key || !$key_len || lc($key) ne lc($mysql_index)) {
|
||||
$one_nibble = 1;
|
||||
}
|
||||
} else {
|
||||
$one_nibble = 1;
|
||||
}
|
||||
|
||||
PTDEBUG && _d('One nibble:', $one_nibble ? 'yes' : 'no');
|
||||
|
||||
if ( $args{resume}
|
||||
@@ -9660,14 +9678,14 @@ sub _get_first_values {
|
||||
. "WHERE " . join(' AND ', @where)
|
||||
. " ORDER BY $index_columns "
|
||||
. "LIMIT 1 /*key_len*/"; # only need 1 row
|
||||
PTDEBUG && _d($sql);
|
||||
PTDEBUG && _d("_get_first_values: $sql");
|
||||
my $vals = $cxn->dbh()->selectrow_arrayref($sql);
|
||||
return $vals;
|
||||
}
|
||||
|
||||
sub _make_range_query {
|
||||
my ($self, %args) = @_;
|
||||
my @required_args = qw(tbl index n_index_cols vals);
|
||||
my @required_args = qw(tbl index n_index_cols);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
@@ -9682,13 +9700,11 @@ sub _make_range_query {
|
||||
if ( $n_index_cols > 1 ) {
|
||||
foreach my $n ( 0..($n_index_cols - 2) ) {
|
||||
my $col = $index_cols->[$n];
|
||||
my $val = $vals->[$n];
|
||||
push @where, $q->quote($col) . " = ?";
|
||||
}
|
||||
}
|
||||
|
||||
my $col = $index_cols->[$n_index_cols - 1];
|
||||
my $val = $vals->[-1]; # should only be as many vals as cols
|
||||
push @where, $q->quote($col) . " >= ?";
|
||||
|
||||
my $sql = "EXPLAIN SELECT /*!40001 SQL_NO_CACHE */ * "
|
||||
|
@@ -26,6 +26,7 @@ use strict;
|
||||
use warnings FATAL => 'all';
|
||||
use English qw(-no_match_vars);
|
||||
use constant PTDEBUG => $ENV{PTDEBUG} || 0;
|
||||
use IndexLength;
|
||||
|
||||
use Data::Dumper;
|
||||
$Data::Dumper::Indent = 1;
|
||||
@@ -487,11 +488,11 @@ sub row_estimate {
|
||||
|
||||
sub can_nibble {
|
||||
my (%args) = @_;
|
||||
my @required_args = qw(Cxn tbl chunk_size OptionParser TableParser);
|
||||
my @required_args = qw(Cxn tbl chunk_size OptionParser TableParser Quoter);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
my ($cxn, $tbl, $chunk_size, $o) = @args{@required_args};
|
||||
my ($cxn, $tbl, $chunk_size, $o, $q) = @args{@required_args};
|
||||
|
||||
my $where = $o->has('where') ? $o->get('where') : '';
|
||||
|
||||
@@ -502,6 +503,23 @@ sub can_nibble {
|
||||
where => $where,
|
||||
);
|
||||
|
||||
my $can_get_keys;
|
||||
if ($mysql_index) {
|
||||
my $idx_len = IndexLength->new(Quoter => $q);
|
||||
my ($key_len, $key) = $idx_len->index_length(
|
||||
Cxn => $args{Cxn},
|
||||
tbl => $tbl,
|
||||
index => $mysql_index,
|
||||
n_index_cols => $o->get('chunk-index-columns'),
|
||||
);
|
||||
|
||||
if ( !$key || !$key_len || lc($key) ne lc($mysql_index)) {
|
||||
$can_get_keys = 0;
|
||||
} else {
|
||||
$can_get_keys = 1;
|
||||
}
|
||||
}
|
||||
|
||||
# MySQL's chosen index is only something we should prefer
|
||||
# if --where is used. Else, we can chose our own index
|
||||
# and disregard the MySQL index from the row estimate.
|
||||
@@ -521,6 +539,10 @@ sub can_nibble {
|
||||
my $one_nibble = !defined $args{one_nibble} || $args{one_nibble}
|
||||
? $row_est <= $chunk_size * $chunk_size_limit
|
||||
: 0;
|
||||
if (!$can_get_keys) {
|
||||
$one_nibble = 1;
|
||||
}
|
||||
|
||||
PTDEBUG && _d('One nibble:', $one_nibble ? 'yes' : 'no');
|
||||
|
||||
# Special case: we're resuming and there's no boundaries, so the table
|
||||
|
72
t/pt-table-checksum/pt-1114.t
Normal file
72
t/pt-table-checksum/pt-1114.t
Normal file
@@ -0,0 +1,72 @@
|
||||
#!/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;
|
||||
use SqlModes;
|
||||
require "$trunk/bin/pt-table-checksum";
|
||||
|
||||
my $dp = new DSNParser(opts=>$dsn_opts);
|
||||
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
|
||||
my $dsn = $sb->dsn_for('master');
|
||||
my $dbh = $sb->get_dbh_for('master');
|
||||
|
||||
if ( !$dbh ) {
|
||||
plan skip_all => 'Cannot connect to sandbox master';
|
||||
}
|
||||
else {
|
||||
plan tests => 3;
|
||||
}
|
||||
|
||||
diag("loading samples");
|
||||
$sb->load_file('master', 't/pt-table-checksum/samples/pt-1114.sql');
|
||||
|
||||
my $master_port = $sb->port_for('master');
|
||||
my $num_rows = 40000;
|
||||
|
||||
diag(`util/mysql_random_data_load --host=127.0.0.1 --port=$master_port --user=msandbox --password=msandbox test t1 $num_rows`);
|
||||
|
||||
$dbh->do('set global innodb_stats_persistent=0;');
|
||||
$dbh->do('DELETE FROM test.t1');
|
||||
|
||||
my @args = ($dsn);
|
||||
my $output;
|
||||
my $exit_status;
|
||||
|
||||
# Test #1
|
||||
$output = output(
|
||||
sub { $exit_status = pt_table_checksum::main(@args) },
|
||||
stderr => 1,
|
||||
);
|
||||
|
||||
is(
|
||||
$exit_status,
|
||||
0,
|
||||
"Exit status OK",
|
||||
);
|
||||
diag($output);
|
||||
|
||||
like(
|
||||
$output,
|
||||
qr/0\s+0\s+0\s+0\s+1\s+0\s+\d+\.\d+\s+test\.t1/,
|
||||
"Checksumed test.t1 even when it is empty",
|
||||
);
|
||||
|
||||
$dbh->do('SET GLOBAL binlog_format="STATEMENT"');
|
||||
|
||||
# #############################################################################
|
||||
# Done.
|
||||
# #############################################################################
|
||||
$sb->wipe_clean($dbh);
|
||||
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
|
||||
exit;
|
Reference in New Issue
Block a user