Fix KeySize to handle key=<key> but key_len=0. Add failing pt-dupe-key-checker test.

This commit is contained in:
Daniel Nichter
2013-12-11 16:51:19 -08:00
parent c726b8e624
commit d48d77269d
4 changed files with 155 additions and 7 deletions

View File

@@ -89,7 +89,7 @@ sub get_key_size {
# EXPLAIN rows will report only the rows that satisfy the query
# using the key, but this is not what we want. We want total table rows.
# In other words, we need an EXPLAIN type index, not ref or range.
if ( scalar @cols == 1 ) {
if ( scalar(@cols) == 1 && !$args{only_eq} ) {
push @where_cols, "$cols[0]<>1";
}
$sql .= join(' OR ', @where_cols);
@@ -113,6 +113,22 @@ sub get_key_size {
PTDEBUG && _d('MySQL chose key:', $chosen_key, 'len:', $key_len,
'rows:', $rows);
# https://bugs.launchpad.net/percona-toolkit/+bug/1201443
if ( $chosen_key && $key_len eq '0' ) {
if ( $args{recurse} ) {
$self->{error} = "key_len = 0 in EXPLAIN:\n"
. _explain_to_text($explain);
return;
}
else {
return $self->get_key_size(
%args,
only_eq => 1,
recurse => 1,
);
}
}
my $key_size = 0;
if ( $key_len && $rows ) {
if ( $chosen_key =~ m/,/ && $key_len =~ m/,/ ) {

View File

@@ -25,9 +25,6 @@ my $dbh = $sb->get_dbh_for('master');
if ( !$dbh ) {
plan skip_all => "Cannot connect to sandbox master";
}
else {
plan tests => 19;
}
my $q = new Quoter();
my $tp = new TableParser(Quoter => $q);
@@ -190,6 +187,107 @@ is(
'Query without FORCE INDEX (issue 364)'
);
# #############################################################################
# https://bugs.launchpad.net/percona-toolkit/+bug/1201443
# #############################################################################
$sb->load_file('master', "t/pt-duplicate-key-checker/samples/fk_chosen_index_bug_1201443.sql");
($size, $chosen_key) = $ks->get_key_size(
name => 'child_ibfk_2',
cols => [qw(parent_id)],
tbl_name => 'fk_chosen_index_bug_1201443.child',
tbl_struct => {
charset => 'latin1',
clustered_key => undef,
col_posn => {
id => 0,
parent_id => 1
},
cols => [
'id',
'parent_id'
],
defs => {
id => ' `id` int(11) NOT NULL AUTO_INCREMENT',
parent_id => ' `parent_id` int(11) NOT NULL'
},
engine => 'InnoDB',
is_autoinc => {
id => 1,
parent_id => 0
},
is_col => {
id => 1,
parent_id => 1
},
is_nullable => {},
is_numeric => {
id => 1,
parent_id => 1
},
keys => {
id => {
col_prefixes => [
undef
],
colnames => '`id`',
cols => [
'id'
],
ddl => 'KEY `id` (`id`),',
is_col => {
id => 1
},
is_nullable => 0,
is_unique => 0,
name => 'id',
type => 'BTREE'
},
parent_id => {
col_prefixes => [
undef
],
colnames => '`parent_id`',
cols => [
'parent_id'
],
ddl => 'KEY `parent_id` (`parent_id`),',
is_col => {
parent_id => 1
},
is_nullable => 0,
is_unique => 0,
name => 'parent_id',
type => 'BTREE'
}
},
name => 'child',
null_cols => [],
numeric_cols => [
'id',
'parent_id'
],
type_for => {
id => 'int',
parent_id => 'int'
}
},
dbh => $dbh,
);
cmp_ok(
$size,
'>',
15_000, # estimages range from 15k to 30k
"Bug 1201443: size"
);
is(
$chosen_key,
'parent_id',
"Bug 1201443: chosen key"
);
# #############################################################################
# Done.
# #############################################################################
@@ -206,4 +304,4 @@ like(
);
$sb->wipe_clean($dbh);
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
exit;
done_testing;

View File

@@ -41,7 +41,7 @@ ok(
: "$sample/issue_295.txt")
),
"Shorten, not remove, clustered dupes"
);
) or diag($test_diff);
# #############################################################################
# Error if InnoDB table has no PK or unique indexes
@@ -80,10 +80,23 @@ unlike(
'PTDEBUG doesn\'t auto-vivify cluster key hashref (bug 1036804)'
);
# #############################################################################
#
# https://bugs.launchpad.net/percona-toolkit/+bug/1201443
# #############################################################################
$sb->load_file('master', "t/pt-duplicate-key-checker/samples/fk_chosen_index_bug_1201443.sql");
$output = `$trunk/bin/pt-duplicate-key-checker F=$cnf -d fk_chosen_index_bug_1201443 2>&1`;
unlike(
$output,
qr/Use of uninitialized value/,
'fk_chosen_index_bug_1201443'
);
# #############################################################################
# Done.
# #############################################################################
$sb->wipe_clean($dbh);
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
done_testing;
exit;

File diff suppressed because one or more lines are too long