From e89ce13e976f34ee55269e152e88e2f6d7f507a6 Mon Sep 17 00:00:00 2001 From: Daniel Nichter Date: Wed, 11 Dec 2013 19:39:09 -0800 Subject: [PATCH] Test and fix bug 1217013. --- bin/pt-duplicate-key-checker | 24 ++++++++++++++----- t/pt-duplicate-key-checker/basics.t | 19 +++++++++++---- .../samples/bug-894140.txt | 1 + .../samples/simple_dupe_bug_1217013.txt | 21 ++++++++++++++++ 4 files changed, 55 insertions(+), 10 deletions(-) create mode 100644 t/pt-duplicate-key-checker/samples/simple_dupe_bug_1217013.txt diff --git a/bin/pt-duplicate-key-checker b/bin/pt-duplicate-key-checker index 1ff067ab..2def80ab 100755 --- a/bin/pt-duplicate-key-checker +++ b/bin/pt-duplicate-key-checker @@ -2387,7 +2387,6 @@ sub get_duplicate_keys { push @dupes, $self->remove_prefix_duplicates(\@fulltext_keys, \@fulltext_keys, %args, exact_duplicates => 1); - my $clustered_key = $args{clustered_key} ? $keys{$args{clustered_key}} : undef; PTDEBUG && _d('clustered key:', @@ -2522,10 +2521,10 @@ sub remove_prefix_duplicates { PTDEBUG && _d('Remove', $right_name); my $reason; - if ( $right_keys->[$right_index]->{unconstrained} ) { + if ( my $type = $right_keys->[$right_index]->{unconstrained} ) { $reason .= "Uniqueness of $right_name ignored because " . $right_keys->[$right_index]->{constraining_key}->{name} - . " is a stronger constraint\n"; + . " is a $type constraint\n"; } my $exact_dupe = $right_len_cols < $left_len_cols ? 0 : 1; $reason .= $right_name @@ -2625,11 +2624,18 @@ sub unconstrain_keys { next unless $unique_key; # primary key may be undefined my $cols = $unique_key->{cols}; if ( @$cols == 1 ) { - PTDEBUG && _d($unique_key->{name},'defines unique column:',$cols->[0]); if ( !exists $unique_cols{$cols->[0]} ) { + PTDEBUG && _d($unique_key->{name}, 'defines unique column:', + $cols->[0]); $unique_cols{$cols->[0]} = $unique_key; $unique_key->{unique_col} = 1; } + else { + PTDEBUG && _d($unique_key->{name}, + 'redundantly constrains unique column:', $cols->[0]); + $unique_key->{exact_dupe} = 1; + $unique_key->{constraining_key} = $unique_cols{$cols->[0]}; + } } else { local $LIST_SEPARATOR = '-'; @@ -2663,13 +2669,19 @@ sub unconstrain_keys { for my $i ( 0..(scalar @$unique_keys-1) ) { if ( exists $unconstrain{$unique_keys->[$i]->{name}} ) { - PTDEBUG && _d('Unconstraining', $unique_keys->[$i]->{name}); - $unique_keys->[$i]->{unconstrained} = 1; + PTDEBUG && _d('Unconstraining weak', $unique_keys->[$i]->{name}); + $unique_keys->[$i]->{unconstrained} = 'stronger'; $unique_keys->[$i]->{constraining_key} = $unconstrain{$unique_keys->[$i]->{name}}; push @unconstrained_keys, $unique_keys->[$i]; delete $unique_keys->[$i]; } + elsif ( $unique_keys->[$i]->{exact_dupe} ) { + PTDEBUG && _d('Unconstraining dupe', $unique_keys->[$i]->{name}); + $unique_keys->[$i]->{unconstrained} = 'duplicate'; + push @unconstrained_keys, $unique_keys->[$i]; + delete $unique_keys->[$i]; + } } PTDEBUG && _d('No more keys'); diff --git a/t/pt-duplicate-key-checker/basics.t b/t/pt-duplicate-key-checker/basics.t index 94dbaa9d..3999ee78 100644 --- a/t/pt-duplicate-key-checker/basics.t +++ b/t/pt-duplicate-key-checker/basics.t @@ -22,9 +22,6 @@ my $dbh = $sb->get_dbh_for('master'); if ( !$dbh ) { plan skip_all => 'Cannot connect to sandbox master'; } -else { - plan tests => 13; -} my $output; my $sample = "t/pt-duplicate-key-checker/samples/"; @@ -136,9 +133,23 @@ ok( '--key-types fk (explicit)' ); +# ############################################################################# +# Exact unique dupes +# https://bugs.launchpad.net/percona-toolkit/+bug/1217013 +# ############################################################################# + +$sb->load_file('master', 't/lib/samples/dupekeys/simple_dupe_bug_1217013.sql', 'test'); + +ok( + no_diff( + sub { pt_duplicate_key_checker::main(@args, qw(-t test.domains)) }, + "$sample/simple_dupe_bug_1217013.txt"), + 'Exact unique dupes (bug 1217013)' +) or diag($test_diff); + # ############################################################################# # Done. # ############################################################################# $sb->wipe_clean($dbh); ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); -exit; +done_testing; diff --git a/t/pt-duplicate-key-checker/samples/bug-894140.txt b/t/pt-duplicate-key-checker/samples/bug-894140.txt index 9142fee7..b8ed23a4 100644 --- a/t/pt-duplicate-key-checker/samples/bug-894140.txt +++ b/t/pt-duplicate-key-checker/samples/bug-894140.txt @@ -2,6 +2,7 @@ # test.bug_894140 # ######################################################################## +# Uniqueness of row_id ignored because PRIMARY is a duplicate constraint # row_id is a duplicate of PRIMARY # Key definitions: # UNIQUE KEY `row_id` (`row_id`), diff --git a/t/pt-duplicate-key-checker/samples/simple_dupe_bug_1217013.txt b/t/pt-duplicate-key-checker/samples/simple_dupe_bug_1217013.txt new file mode 100644 index 00000000..628b1a61 --- /dev/null +++ b/t/pt-duplicate-key-checker/samples/simple_dupe_bug_1217013.txt @@ -0,0 +1,21 @@ +# ######################################################################## +# test.domains +# ######################################################################## + +# Uniqueness of domain ignored because unique_key_domain is a duplicate constraint +# domain is a duplicate of unique_key_domain +# Key definitions: +# UNIQUE KEY `domain` (`domain`), +# UNIQUE KEY `unique_key_domain` (`domain`) +# Column types: +# `domain` varchar(175) collate utf8_bin not null +# To remove this duplicate index, execute: +ALTER TABLE `test`.`domains` DROP INDEX `domain`; + +# ######################################################################## +# Summary of indexes +# ######################################################################## + +# Size Duplicate Indexes 527 +# Total Duplicate Indexes 1 +# Total Indexes 3