mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-02 10:36:28 +00:00
Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
70c6c0be7f |
@@ -5838,6 +5838,7 @@ sub can_nibble {
|
||||
my $one_nibble = !defined $args{one_nibble} || $args{one_nibble}
|
||||
? $row_est <= $chunk_size * $chunk_size_limit
|
||||
: 0;
|
||||
|
||||
PTDEBUG && _d('One nibble:', $one_nibble ? 'yes' : 'no');
|
||||
|
||||
if ( $args{resume}
|
||||
@@ -5852,6 +5853,16 @@ sub can_nibble {
|
||||
die "There is no good index and the table is oversized.";
|
||||
}
|
||||
|
||||
if ($o->has('force-nibbling') && $o->get('force-nibbling')) {
|
||||
my @nibbling_tables = split(/,/, $o->get('force-nibbling'));
|
||||
my @table_in_list = grep (/$tbl->{tbl}/, @nibbling_tables);
|
||||
if (@table_in_list && $index && $row_est >= 2) {
|
||||
PTDEBUG && _d("Disabling one nibble for the entire table");
|
||||
$one_nibble = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
my $pause_file = ($o->has('pause-file') && $o->get('pause-file')) || undef;
|
||||
|
||||
return {
|
||||
|
@@ -6689,6 +6689,7 @@ sub can_nibble {
|
||||
my $one_nibble = !defined $args{one_nibble} || $args{one_nibble}
|
||||
? $row_est <= $chunk_size * $chunk_size_limit
|
||||
: 0;
|
||||
|
||||
PTDEBUG && _d('One nibble:', $one_nibble ? 'yes' : 'no');
|
||||
|
||||
if ( $args{resume}
|
||||
@@ -6703,6 +6704,16 @@ sub can_nibble {
|
||||
die "There is no good index and the table is oversized.";
|
||||
}
|
||||
|
||||
if ($o->has('force-nibbling') && $o->get('force-nibbling')) {
|
||||
my @nibbling_tables = split(/,/, $o->get('force-nibbling'));
|
||||
my @table_in_list = grep (/$tbl->{tbl}/, @nibbling_tables);
|
||||
if (@table_in_list && $index && $row_est >= 2) {
|
||||
PTDEBUG && _d("Disabling one nibble for the entire table");
|
||||
$one_nibble = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
my $pause_file = ($o->has('pause-file') && $o->get('pause-file')) || undef;
|
||||
|
||||
return {
|
||||
@@ -13262,6 +13273,16 @@ the values are converted to strings by the CONCAT() function, and MySQL chooses
|
||||
the string representation. If you specify a value of 2, for example, then the
|
||||
values 1.008 and 1.009 will be rounded to 1.01, and will checksum as equal.
|
||||
|
||||
=item --force-nibbling
|
||||
|
||||
type: string
|
||||
|
||||
Comma sepatered list of tables on which we want to force nibbling instead of
|
||||
checksuming the whole table in only one chunk,
|
||||
In some cases, MySQL returns a wrong estimate about number of rows in a table
|
||||
and NibbleIterator is trying to process huge tables in a single chunk.
|
||||
This parameter disable one nibble checksums for the specified tables.
|
||||
|
||||
=item --function
|
||||
|
||||
type: string
|
||||
|
@@ -495,6 +495,8 @@ sub can_nibble {
|
||||
my $one_nibble = !defined $args{one_nibble} || $args{one_nibble}
|
||||
? $row_est <= $chunk_size * $chunk_size_limit
|
||||
: 0;
|
||||
#
|
||||
|
||||
PTDEBUG && _d('One nibble:', $one_nibble ? 'yes' : 'no');
|
||||
|
||||
# Special case: we're resuming and there's no boundaries, so the table
|
||||
@@ -512,6 +514,23 @@ sub can_nibble {
|
||||
die "There is no good index and the table is oversized.";
|
||||
}
|
||||
|
||||
# In some cases, MySQL returns a wrong estimate about number of rows in a table
|
||||
# and NibbleIterator is trying to process huge tables in a single chunk.
|
||||
# This parameter disable one nibble.
|
||||
# See https://jira.percona.com/browse/PT-1585
|
||||
# This function should work on all scenarios so, to prevent trying to nibble on empty
|
||||
# (or really really small) tables, we need to ensure tha table has an index and it has
|
||||
# at least 2 rows, otherwise there is no way to split only one row into chunks.
|
||||
if ($o->has('force-nibbling') && $o->get('force-nibbling')) {
|
||||
my @nibbling_tables = split(/,/, $o->get('force-nibbling'));
|
||||
my @table_in_list = grep (/$tbl->{tbl}/, @nibbling_tables);
|
||||
if (@table_in_list && $index && $row_est >= 2) {
|
||||
PTDEBUG && _d("Disabling one nibble for the entire table");
|
||||
$one_nibble = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# The table can be nibbled if this point is reached, else we would have
|
||||
# died earlier. Return some values about nibbling the table.
|
||||
my $pause_file = ($o->has('pause-file') && $o->get('pause-file')) || undef;
|
||||
|
75
t/pt-table-checksum/pt-1584.t
Normal file
75
t/pt-table-checksum/pt-1584.t
Normal file
@@ -0,0 +1,75 @@
|
||||
#!/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 $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-226.sql');
|
||||
$sb->load_file('master', 't/pt-table-checksum/samples/pt-1585.sql');
|
||||
my $num_rows = 2000;
|
||||
diag(`util/mysql_random_data_load --host=127.0.0.1 --port=12345 --user=msandbox --password=msandbox test t1 $num_rows`);
|
||||
diag("$num_rows sample rows 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.
|
||||
# And --max-load "" prevents waiting for status variables.
|
||||
my $master_dsn = $sb->dsn_for('master');
|
||||
|
||||
my @args = ($master_dsn, "--set-vars", "innodb_lock_wait_timeout=50", "--force-nibbling");
|
||||
my $output;
|
||||
my $exit_status;
|
||||
warn @args;
|
||||
|
||||
$ENV{PTDEBUG} = 1;
|
||||
# Test #1
|
||||
$output = output(
|
||||
sub { $exit_status = pt_table_checksum::main(@args) },
|
||||
stderr => 1,
|
||||
);
|
||||
|
||||
delete $ENV{PTDEBUG};
|
||||
|
||||
is(
|
||||
$exit_status,
|
||||
0,
|
||||
"PT-226 SET binlog_format='STATEMENT' exit status",
|
||||
);
|
||||
|
||||
like(
|
||||
$output,
|
||||
qr/1\s+100\s+0\s+1\s+0\s+.*test.joinit/,
|
||||
"PT-226 table joinit has differences",
|
||||
);
|
||||
|
||||
$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;
|
9
t/pt-table-checksum/samples/pt-1585.sql
Normal file
9
t/pt-table-checksum/samples/pt-1585.sql
Normal file
@@ -0,0 +1,9 @@
|
||||
DROP DATABASE IF EXISTS test;
|
||||
CREATE DATABASE test;
|
||||
|
||||
USE test;
|
||||
|
||||
CREATE TABLE `test`.`t1` (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY NOT NULL,
|
||||
f1 INT
|
||||
) Engine=InnoDB CHARSET=utf8;
|
Reference in New Issue
Block a user