PT-1766 Fixed DIFF_ROWS calculation

- Fixed DIFF_ROWS calculation
- Removed unused param --force-concat-enums
This commit is contained in:
Carlos Salguero
2019-12-23 08:42:38 -03:00
parent 68dc98c2ba
commit 2821b847b3
2 changed files with 229 additions and 181 deletions

View File

@@ -6493,9 +6493,6 @@ sub _nibble_params {
);
PTDEBUG && _d('Ascend params:', Dumper($asc));
my $force_concat_enums;
my $from = "$tbl->{name} FORCE INDEX(`$index`)";
my $order_by = join(', ', map {$q->quote($_)} @{$index_cols});
my $order_by_dec = join(' DESC,', map {$q->quote($_)} @{$index_cols});
@@ -11437,10 +11434,11 @@ sub main {
map { $diff_chunks{ $_->{chunk} }++ } @$diffs;
$exit_status |= $PTC_EXIT_STATUS{TABLE_DIFF};
}
my $max_cnt_diff=0;
for my $diff (@$diffs) {
if ( $diff->{cnt_diff} > $max_cnt_diff ) {
$tbl->{checksum_results}->{max_rows_cnt_diff} = $diff->{cnt_diff};
if (abs($diff->{cnt_diff}) > $max_cnt_diff) {
$tbl->{checksum_results}->{max_rows_cnt_diff} = abs($diff->{cnt_diff});
}
}
};
@@ -12932,11 +12930,11 @@ More Information: (L<https://www.percona.com/doc/percona-server/LATEST/myrocks/l
The tool prints tabular results, one line per table:
TS ERRORS DIFFS ROWS CHUNKS SKIPPED TIME TABLE
10-20T08:36:50 0 0 200 1 0 0.005 db1.tbl1
10-20T08:36:50 0 0 603 7 0 0.035 db1.tbl2
10-20T08:36:50 0 0 16 1 0 0.003 db2.tbl3
10-20T08:36:50 0 0 600 6 0 0.024 db2.tbl4
TS ERRORS DIFFS ROWS DIFF_ROWS CHUNKS SKIPPED TIME TABLE
10-20T08:36:50 0 0 200 0 1 0 0.005 db1.tbl1
10-20T08:36:50 0 0 603 3 7 0 0.035 db1.tbl2
10-20T08:36:50 0 0 16 0 1 0 0.003 db2.tbl3
10-20T08:36:50 0 0 600 0 6 0 0.024 db2.tbl4
Errors, warnings, and progress reports are printed to standard error. See also
L<"--quiet">.
@@ -12968,6 +12966,11 @@ are printed.
The number of rows selected and checksummed from the table. It might be
different from the number of rows in the table if you use the --where option.
=item DIFF_ROWS
The maximum number of differences per chunk. If a chunk has 2 different rows and
another chunk has 3 different rows, this value will be 3.
=item CHUNKS
The number of chunks into which the table was divided.
@@ -13405,30 +13408,6 @@ 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-concat-enums
The NibbleIterator in Percona Toolkit can detect indexes having ENUM fields and
if the items it has are sorted or not. According to MySQL documentation at
L<https://dev.mysql.com/doc/refman/8.0/en/enum.html>:
ENUM values are sorted based on their index numbers, which depend on the order in
which the enumeration members were listed in the column specification.
For example, 'b' sorts before 'a' for ENUM('b', 'a').
The empty string sorts before nonempty strings, and NULL values sort before all other
enumeration values.
To prevent unexpected results when using the ORDER BY clause on an ENUM column,
use one of these techniques:
- Specify the ENUM list in alphabetic order.
- Make sure that the column is sorted lexically rather than by index number by coding
ORDER BY CAST(col AS CHAR) or ORDER BY CONCAT(col).
The NibbleIterator in Percona Toolkit uses CONCAT(col) but, doing that, adds overhead
since MySQL cannot use the column directly and has to calculate the result of CONCAT
for every row.
To make this scenario vissible to the user, if there are indexes having ENUM fields
with usorted items, it is necessary to specify the C<--force-concat-enums> parameter.
=item --function
type: string

View File

@@ -0,0 +1,69 @@
#!/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;
use threads;
use Time::HiRes qw( usleep );
use constant PTDEBUG => $ENV{PTDEBUG} || 0;
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');
my $slave1_dbh = $sb->get_dbh_for('slave1');
if ( !$dbh ) {
plan skip_all => 'Cannot connect to sandbox master';
}
else {
plan tests => 2;
}
my $num_rows = 1000;
my $table = 't1';
$dbh->do("DROP DATABASE IF EXISTS test");
$dbh->do("CREATE DATABASE IF NOT EXISTS test");
$dbh->do("CREATE TABLE `test`.`$table` (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(5)) Engine=InnoDB");
diag(`util/mysql_random_data_load --host=127.0.0.1 --port=12345 --user=msandbox --password=msandbox test $table $num_rows`);
$slave1_dbh->do("DELETE FROM `test`.`$table` WHERE 1=1");
diag("Starting checksum");
# 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 = 'h=127.1,P=12345,u=msandbox,p=msandbox';
my @args = ($master_dsn, qw(--no-check-binlog-format --chunk-size 10));
my $output;
$output = output(
sub { pt_table_checksum::main(@args) },
stderr => 1,
);
like(
$output,
qr/100\s+1000\s+10\s+102\s+0\s+\d+\.\d+\s+test.t1/,
"Truncating tables while checksum is running"
);
# #############################################################################
# Done.
# #############################################################################
$sb->wipe_clean($dbh);
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
exit;