PT-1114 test fix

This commit is contained in:
Carlos Salguero
2019-01-11 15:43:38 -03:00
parent 7748cc765d
commit 424a48518c
3 changed files with 120 additions and 10 deletions

View File

@@ -6292,6 +6292,7 @@ use strict;
use warnings FATAL => 'all'; use warnings FATAL => 'all';
use English qw(-no_match_vars); use English qw(-no_match_vars);
use constant PTDEBUG => $ENV{PTDEBUG} || 0; use constant PTDEBUG => $ENV{PTDEBUG} || 0;
use IndexLength;
use Data::Dumper; use Data::Dumper;
$Data::Dumper::Indent = 1; $Data::Dumper::Indent = 1;
@@ -6690,11 +6691,11 @@ sub row_estimate {
sub can_nibble { sub can_nibble {
my (%args) = @_; 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 ) { foreach my $arg ( @required_args ) {
die "I need a $arg argument" unless $args{$arg}; 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') : ''; my $where = $o->has('where') ? $o->get('where') : '';
@@ -6705,13 +6706,30 @@ sub can_nibble {
); );
if ( !$where ) { if ( !$where ) {
$mysql_index = undef; $mysql_index = undef;
} }
my $chunk_size_limit = $o->get('chunk-size-limit') || 1; my $chunk_size_limit = $o->get('chunk-size-limit') || 1;
my $one_nibble = !defined $args{one_nibble} || $args{one_nibble} my $one_nibble = !defined $args{one_nibble} || $args{one_nibble}
? $row_est <= $chunk_size * $chunk_size_limit ? $row_est <= $chunk_size * $chunk_size_limit
: 0; : 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'); PTDEBUG && _d('One nibble:', $one_nibble ? 'yes' : 'no');
if ( $args{resume} if ( $args{resume}
@@ -9660,14 +9678,14 @@ sub _get_first_values {
. "WHERE " . join(' AND ', @where) . "WHERE " . join(' AND ', @where)
. " ORDER BY $index_columns " . " ORDER BY $index_columns "
. "LIMIT 1 /*key_len*/"; # only need 1 row . "LIMIT 1 /*key_len*/"; # only need 1 row
PTDEBUG && _d($sql); PTDEBUG && _d("_get_first_values: $sql");
my $vals = $cxn->dbh()->selectrow_arrayref($sql); my $vals = $cxn->dbh()->selectrow_arrayref($sql);
return $vals; return $vals;
} }
sub _make_range_query { sub _make_range_query {
my ($self, %args) = @_; 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 ) { foreach my $arg ( @required_args ) {
die "I need a $arg argument" unless $args{$arg}; die "I need a $arg argument" unless $args{$arg};
} }
@@ -9682,13 +9700,11 @@ sub _make_range_query {
if ( $n_index_cols > 1 ) { if ( $n_index_cols > 1 ) {
foreach my $n ( 0..($n_index_cols - 2) ) { foreach my $n ( 0..($n_index_cols - 2) ) {
my $col = $index_cols->[$n]; my $col = $index_cols->[$n];
my $val = $vals->[$n];
push @where, $q->quote($col) . " = ?"; push @where, $q->quote($col) . " = ?";
} }
} }
my $col = $index_cols->[$n_index_cols - 1]; 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) . " >= ?"; push @where, $q->quote($col) . " >= ?";
my $sql = "EXPLAIN SELECT /*!40001 SQL_NO_CACHE */ * " my $sql = "EXPLAIN SELECT /*!40001 SQL_NO_CACHE */ * "

View File

@@ -26,6 +26,7 @@ use strict;
use warnings FATAL => 'all'; use warnings FATAL => 'all';
use English qw(-no_match_vars); use English qw(-no_match_vars);
use constant PTDEBUG => $ENV{PTDEBUG} || 0; use constant PTDEBUG => $ENV{PTDEBUG} || 0;
use IndexLength;
use Data::Dumper; use Data::Dumper;
$Data::Dumper::Indent = 1; $Data::Dumper::Indent = 1;
@@ -487,11 +488,11 @@ sub row_estimate {
sub can_nibble { sub can_nibble {
my (%args) = @_; 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 ) { foreach my $arg ( @required_args ) {
die "I need a $arg argument" unless $args{$arg}; 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') : ''; my $where = $o->has('where') ? $o->get('where') : '';
@@ -502,6 +503,23 @@ sub can_nibble {
where => $where, 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 # MySQL's chosen index is only something we should prefer
# if --where is used. Else, we can chose our own index # if --where is used. Else, we can chose our own index
# and disregard the MySQL index from the row estimate. # 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} my $one_nibble = !defined $args{one_nibble} || $args{one_nibble}
? $row_est <= $chunk_size * $chunk_size_limit ? $row_est <= $chunk_size * $chunk_size_limit
: 0; : 0;
if (!$can_get_keys) {
$one_nibble = 1;
}
PTDEBUG && _d('One nibble:', $one_nibble ? 'yes' : 'no'); PTDEBUG && _d('One nibble:', $one_nibble ? 'yes' : 'no');
# Special case: we're resuming and there's no boundaries, so the table # Special case: we're resuming and there's no boundaries, so the table

View 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;