From f237f4a0dfc80095e59f35ea9791efcabca16903 Mon Sep 17 00:00:00 2001 From: Frank Cizmich Date: Thu, 23 Oct 2014 15:32:34 -0200 Subject: [PATCH 1/2] We now use wsrep_node_incoming_address as a more reliable way to detect cluster node duplicates - 1217466 --- bin/pt-config-diff | 26 +++++++- bin/pt-deadlock-logger | 26 +++++++- bin/pt-fk-error-logger | 26 +++++++- bin/pt-kill | 26 +++++++- bin/pt-online-schema-change | 50 ++++++++++++-- bin/pt-table-checksum | 51 +++++++++++++-- bin/pt-upgrade | 26 +++++++- lib/Cxn.pm | 22 ++++++- lib/Percona/XtraDB/Cluster.pm | 25 ++++++- t/pt-table-checksum/pxc.t | 119 ++++++++++++++++++++++------------ 10 files changed, 324 insertions(+), 73 deletions(-) diff --git a/bin/pt-config-diff b/bin/pt-config-diff index b114f7b0..4ab90df4 100755 --- a/bin/pt-config-diff +++ b/bin/pt-config-diff @@ -2295,7 +2295,7 @@ sub new { set => $args{set}, NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1, dbh_set => 0, - ask_pass => $o->get('ask-pass'), + ask_pass => $args{ask_pass}, DSNParser => $dp, is_cluster_node => undef, parent => $args{parent}, @@ -2306,7 +2306,7 @@ sub new { sub connect { my ( $self, %opts ) = @_; - my $dsn = $self->{dsn}; + my $dsn = $opts{dsn} || $self->{dsn}; my $dp = $self->{DSNParser}; my $dbh = $self->{dbh}; @@ -2325,6 +2325,13 @@ sub connect { } $dbh = $self->set_dbh($dbh); + if ( $opts{dsn} ) { + $self->{dsn} = $dsn; + $self->{dsn_name} = $dp->as_string($dsn, [qw(h P S)]) + || $dp->as_string($dsn, [qw(F)]) + || ''; + + } PTDEBUG && _d($dbh, 'Connected dbh to', $self->{hostname},$self->{dsn_name}); return $dbh; } @@ -2386,6 +2393,18 @@ sub name { return $self->{hostname} || $self->{dsn_name} || 'unknown host'; } +sub is_cluster_node { + my ($self, $cxn) = @_; + + my $sql = "SHOW VARIABLES LIKE 'wsrep\_on'"; + PTDEBUG && _d($cxn->name, $sql); + my $row = $cxn->dbh->selectrow_arrayref($sql); + PTDEBUG && _d(Dumper($row)); + return unless $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1'); + + return 1; +} + sub remove_duplicate_cxns { my ($self, %args) = @_; my @cxns = @{$args{cxns}}; @@ -2395,7 +2414,8 @@ sub remove_duplicate_cxns { for my $cxn ( @cxns ) { my $dbh = $cxn->dbh(); - my $sql = q{SELECT @@server_id}; + + my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id}; PTDEBUG && _d($sql); my ($id) = $dbh->selectrow_array($sql); PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id); diff --git a/bin/pt-deadlock-logger b/bin/pt-deadlock-logger index dd3e93b1..ab93561e 100755 --- a/bin/pt-deadlock-logger +++ b/bin/pt-deadlock-logger @@ -2639,7 +2639,7 @@ sub new { set => $args{set}, NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1, dbh_set => 0, - ask_pass => $o->get('ask-pass'), + ask_pass => $args{ask_pass}, DSNParser => $dp, is_cluster_node => undef, parent => $args{parent}, @@ -2650,7 +2650,7 @@ sub new { sub connect { my ( $self, %opts ) = @_; - my $dsn = $self->{dsn}; + my $dsn = $opts{dsn} || $self->{dsn}; my $dp = $self->{DSNParser}; my $dbh = $self->{dbh}; @@ -2669,6 +2669,13 @@ sub connect { } $dbh = $self->set_dbh($dbh); + if ( $opts{dsn} ) { + $self->{dsn} = $dsn; + $self->{dsn_name} = $dp->as_string($dsn, [qw(h P S)]) + || $dp->as_string($dsn, [qw(F)]) + || ''; + + } PTDEBUG && _d($dbh, 'Connected dbh to', $self->{hostname},$self->{dsn_name}); return $dbh; } @@ -2730,6 +2737,18 @@ sub name { return $self->{hostname} || $self->{dsn_name} || 'unknown host'; } +sub is_cluster_node { + my ($self, $cxn) = @_; + + my $sql = "SHOW VARIABLES LIKE 'wsrep\_on'"; + PTDEBUG && _d($cxn->name, $sql); + my $row = $cxn->dbh->selectrow_arrayref($sql); + PTDEBUG && _d(Dumper($row)); + return unless $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1'); + + return 1; +} + sub remove_duplicate_cxns { my ($self, %args) = @_; my @cxns = @{$args{cxns}}; @@ -2739,7 +2758,8 @@ sub remove_duplicate_cxns { for my $cxn ( @cxns ) { my $dbh = $cxn->dbh(); - my $sql = q{SELECT @@server_id}; + + my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id}; PTDEBUG && _d($sql); my ($id) = $dbh->selectrow_array($sql); PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id); diff --git a/bin/pt-fk-error-logger b/bin/pt-fk-error-logger index 4ef78285..891d713a 100755 --- a/bin/pt-fk-error-logger +++ b/bin/pt-fk-error-logger @@ -1791,7 +1791,7 @@ sub new { set => $args{set}, NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1, dbh_set => 0, - ask_pass => $o->get('ask-pass'), + ask_pass => $args{ask_pass}, DSNParser => $dp, is_cluster_node => undef, parent => $args{parent}, @@ -1802,7 +1802,7 @@ sub new { sub connect { my ( $self, %opts ) = @_; - my $dsn = $self->{dsn}; + my $dsn = $opts{dsn} || $self->{dsn}; my $dp = $self->{DSNParser}; my $dbh = $self->{dbh}; @@ -1821,6 +1821,13 @@ sub connect { } $dbh = $self->set_dbh($dbh); + if ( $opts{dsn} ) { + $self->{dsn} = $dsn; + $self->{dsn_name} = $dp->as_string($dsn, [qw(h P S)]) + || $dp->as_string($dsn, [qw(F)]) + || ''; + + } PTDEBUG && _d($dbh, 'Connected dbh to', $self->{hostname},$self->{dsn_name}); return $dbh; } @@ -1882,6 +1889,18 @@ sub name { return $self->{hostname} || $self->{dsn_name} || 'unknown host'; } +sub is_cluster_node { + my ($self, $cxn) = @_; + + my $sql = "SHOW VARIABLES LIKE 'wsrep\_on'"; + PTDEBUG && _d($cxn->name, $sql); + my $row = $cxn->dbh->selectrow_arrayref($sql); + PTDEBUG && _d(Dumper($row)); + return unless $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1'); + + return 1; +} + sub remove_duplicate_cxns { my ($self, %args) = @_; my @cxns = @{$args{cxns}}; @@ -1891,7 +1910,8 @@ sub remove_duplicate_cxns { for my $cxn ( @cxns ) { my $dbh = $cxn->dbh(); - my $sql = q{SELECT @@server_id}; + + my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id}; PTDEBUG && _d($sql); my ($id) = $dbh->selectrow_array($sql); PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id); diff --git a/bin/pt-kill b/bin/pt-kill index 61d1b6d8..bb394235 100755 --- a/bin/pt-kill +++ b/bin/pt-kill @@ -5158,7 +5158,7 @@ sub new { set => $args{set}, NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1, dbh_set => 0, - ask_pass => $o->get('ask-pass'), + ask_pass => $args{ask_pass}, DSNParser => $dp, is_cluster_node => undef, parent => $args{parent}, @@ -5169,7 +5169,7 @@ sub new { sub connect { my ( $self, %opts ) = @_; - my $dsn = $self->{dsn}; + my $dsn = $opts{dsn} || $self->{dsn}; my $dp = $self->{DSNParser}; my $dbh = $self->{dbh}; @@ -5188,6 +5188,13 @@ sub connect { } $dbh = $self->set_dbh($dbh); + if ( $opts{dsn} ) { + $self->{dsn} = $dsn; + $self->{dsn_name} = $dp->as_string($dsn, [qw(h P S)]) + || $dp->as_string($dsn, [qw(F)]) + || ''; + + } PTDEBUG && _d($dbh, 'Connected dbh to', $self->{hostname},$self->{dsn_name}); return $dbh; } @@ -5249,6 +5256,18 @@ sub name { return $self->{hostname} || $self->{dsn_name} || 'unknown host'; } +sub is_cluster_node { + my ($self, $cxn) = @_; + + my $sql = "SHOW VARIABLES LIKE 'wsrep\_on'"; + PTDEBUG && _d($cxn->name, $sql); + my $row = $cxn->dbh->selectrow_arrayref($sql); + PTDEBUG && _d(Dumper($row)); + return unless $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1'); + + return 1; +} + sub remove_duplicate_cxns { my ($self, %args) = @_; my @cxns = @{$args{cxns}}; @@ -5258,7 +5277,8 @@ sub remove_duplicate_cxns { for my $cxn ( @cxns ) { my $dbh = $cxn->dbh(); - my $sql = q{SELECT @@server_id}; + + my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id}; PTDEBUG && _d($sql); my ($id) = $dbh->selectrow_array($sql); PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id); diff --git a/bin/pt-online-schema-change b/bin/pt-online-schema-change index 1595699f..0850a9c8 100755 --- a/bin/pt-online-schema-change +++ b/bin/pt-online-schema-change @@ -3755,7 +3755,7 @@ sub new { set => $args{set}, NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1, dbh_set => 0, - ask_pass => $o->get('ask-pass'), + ask_pass => $args{ask_pass}, DSNParser => $dp, is_cluster_node => undef, parent => $args{parent}, @@ -3766,12 +3766,12 @@ sub new { sub connect { my ( $self, %opts ) = @_; - my $dsn = $self->{dsn}; + my $dsn = $opts{dsn} || $self->{dsn}; my $dp = $self->{DSNParser}; my $dbh = $self->{dbh}; if ( !$dbh || !$dbh->ping() ) { - if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p}) { + if ( $self->{ask_pass} && !$self->{asked_for_pass} ) { $dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: "); $self->{asked_for_pass} = 1; } @@ -3785,6 +3785,13 @@ sub connect { } $dbh = $self->set_dbh($dbh); + if ( $opts{dsn} ) { + $self->{dsn} = $dsn; + $self->{dsn_name} = $dp->as_string($dsn, [qw(h P S)]) + || $dp->as_string($dsn, [qw(F)]) + || ''; + + } PTDEBUG && _d($dbh, 'Connected dbh to', $self->{hostname},$self->{dsn_name}); return $dbh; } @@ -3846,6 +3853,18 @@ sub name { return $self->{hostname} || $self->{dsn_name} || 'unknown host'; } +sub is_cluster_node { + my ($self, $cxn) = @_; + + my $sql = "SHOW VARIABLES LIKE 'wsrep\_on'"; + PTDEBUG && _d($cxn->name, $sql); + my $row = $cxn->dbh->selectrow_arrayref($sql); + PTDEBUG && _d(Dumper($row)); + return unless $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1'); + + return 1; +} + sub remove_duplicate_cxns { my ($self, %args) = @_; my @cxns = @{$args{cxns}}; @@ -3855,7 +3874,8 @@ sub remove_duplicate_cxns { for my $cxn ( @cxns ) { my $dbh = $cxn->dbh(); - my $sql = q{SELECT @@server_id}; + + my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id}; PTDEBUG && _d($sql); my ($id) = $dbh->selectrow_array($sql); PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id); @@ -7638,8 +7658,26 @@ sub find_cluster_nodes { sub remove_duplicate_cxns { my ($self, %args) = @_; my @cxns = @{$args{cxns}}; - my $seen_ids = $args{seen_ids}; - return Cxn->remove_duplicate_cxns(%args); + my $seen_ids = $args{seen_ids} || {}; + PTDEBUG && _d("Removing duplicates nodes from ", join(" ", map { $_->name } @cxns)); + my @trimmed_cxns; + + for my $cxn ( @cxns ) { + my $dbh = $cxn->dbh(); + my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id}; + PTDEBUG && _d($sql); + my ($id) = $dbh->selectrow_array($sql); + PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id); + + if ( ! $seen_ids->{$id}++ ) { + push @trimmed_cxns, $cxn + } + else { + PTDEBUG && _d("Removing ", $cxn->name, + ", ID ", $id, ", because we've already seen it"); + } + } + return \@trimmed_cxns; } sub same_cluster { diff --git a/bin/pt-table-checksum b/bin/pt-table-checksum index 7bcb4880..0b966195 100755 --- a/bin/pt-table-checksum +++ b/bin/pt-table-checksum @@ -3533,7 +3533,7 @@ sub new { set => $args{set}, NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1, dbh_set => 0, - ask_pass => $o->get('ask-pass'), + ask_pass => $args{ask_pass}, DSNParser => $dp, is_cluster_node => undef, parent => $args{parent}, @@ -3544,7 +3544,7 @@ sub new { sub connect { my ( $self, %opts ) = @_; - my $dsn = $self->{dsn}; + my $dsn = $opts{dsn} || $self->{dsn}; my $dp = $self->{DSNParser}; my $dbh = $self->{dbh}; @@ -3563,6 +3563,13 @@ sub connect { } $dbh = $self->set_dbh($dbh); + if ( $opts{dsn} ) { + $self->{dsn} = $dsn; + $self->{dsn_name} = $dp->as_string($dsn, [qw(h P S)]) + || $dp->as_string($dsn, [qw(F)]) + || ''; + + } PTDEBUG && _d($dbh, 'Connected dbh to', $self->{hostname},$self->{dsn_name}); return $dbh; } @@ -3624,6 +3631,18 @@ sub name { return $self->{hostname} || $self->{dsn_name} || 'unknown host'; } +sub is_cluster_node { + my ($self, $cxn) = @_; + + my $sql = "SHOW VARIABLES LIKE 'wsrep\_on'"; + PTDEBUG && _d($cxn->name, $sql); + my $row = $cxn->dbh->selectrow_arrayref($sql); + PTDEBUG && _d(Dumper($row)); + return unless $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1'); + + return 1; +} + sub remove_duplicate_cxns { my ($self, %args) = @_; my @cxns = @{$args{cxns}}; @@ -3633,7 +3652,8 @@ sub remove_duplicate_cxns { for my $cxn ( @cxns ) { my $dbh = $cxn->dbh(); - my $sql = q{SELECT @@server_id}; + + my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id}; PTDEBUG && _d($sql); my ($id) = $dbh->selectrow_array($sql); PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id); @@ -3788,8 +3808,26 @@ sub find_cluster_nodes { sub remove_duplicate_cxns { my ($self, %args) = @_; my @cxns = @{$args{cxns}}; - my $seen_ids = $args{seen_ids}; - return Cxn->remove_duplicate_cxns(%args); + my $seen_ids = $args{seen_ids} || {}; + PTDEBUG && _d("Removing duplicates nodes from ", join(" ", map { $_->name } @cxns)); + my @trimmed_cxns; + + for my $cxn ( @cxns ) { + my $dbh = $cxn->dbh(); + my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id}; + PTDEBUG && _d($sql); + my ($id) = $dbh->selectrow_array($sql); + PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id); + + if ( ! $seen_ids->{$id}++ ) { + push @trimmed_cxns, $cxn + } + else { + PTDEBUG && _d("Removing ", $cxn->name, + ", ID ", $id, ", because we've already seen it"); + } + } + return \@trimmed_cxns; } sub same_cluster { @@ -9286,7 +9324,8 @@ sub main { my %seen_ids; for my $cxn ($master_cxn, @$slaves) { my $dbh = $cxn->dbh(); - my $sql = q{SELECT @@server_id}; + # if it's a cluster node we use its incoming address as id ( see https://bugs.launchpad.net/percona-toolkit/+bug/1217466 ) + my $sql = $cluster->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id}; PTDEBUG && _d($cxn, $dbh, $sql); my ($id) = $dbh->selectrow_array($sql); $seen_ids{$id}++; diff --git a/bin/pt-upgrade b/bin/pt-upgrade index d06b503e..991181ab 100755 --- a/bin/pt-upgrade +++ b/bin/pt-upgrade @@ -2464,7 +2464,7 @@ sub new { set => $args{set}, NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1, dbh_set => 0, - ask_pass => $o->get('ask-pass'), + ask_pass => $args{ask_pass}, DSNParser => $dp, is_cluster_node => undef, parent => $args{parent}, @@ -2475,7 +2475,7 @@ sub new { sub connect { my ( $self, %opts ) = @_; - my $dsn = $self->{dsn}; + my $dsn = $opts{dsn} || $self->{dsn}; my $dp = $self->{DSNParser}; my $dbh = $self->{dbh}; @@ -2494,6 +2494,13 @@ sub connect { } $dbh = $self->set_dbh($dbh); + if ( $opts{dsn} ) { + $self->{dsn} = $dsn; + $self->{dsn_name} = $dp->as_string($dsn, [qw(h P S)]) + || $dp->as_string($dsn, [qw(F)]) + || ''; + + } PTDEBUG && _d($dbh, 'Connected dbh to', $self->{hostname},$self->{dsn_name}); return $dbh; } @@ -2555,6 +2562,18 @@ sub name { return $self->{hostname} || $self->{dsn_name} || 'unknown host'; } +sub is_cluster_node { + my ($self, $cxn) = @_; + + my $sql = "SHOW VARIABLES LIKE 'wsrep\_on'"; + PTDEBUG && _d($cxn->name, $sql); + my $row = $cxn->dbh->selectrow_arrayref($sql); + PTDEBUG && _d(Dumper($row)); + return unless $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1'); + + return 1; +} + sub remove_duplicate_cxns { my ($self, %args) = @_; my @cxns = @{$args{cxns}}; @@ -2564,7 +2583,8 @@ sub remove_duplicate_cxns { for my $cxn ( @cxns ) { my $dbh = $cxn->dbh(); - my $sql = q{SELECT @@server_id}; + + my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id}; PTDEBUG && _d($sql); my ($id) = $dbh->selectrow_array($sql); PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id); diff --git a/lib/Cxn.pm b/lib/Cxn.pm index 38469319..aff491db 100644 --- a/lib/Cxn.pm +++ b/lib/Cxn.pm @@ -226,6 +226,20 @@ sub name { return $self->{hostname} || $self->{dsn_name} || 'unknown host'; } +# This is used to help remove_duplicate_cxns detect cluster nodes +# (which often have unreliable server_id's) +sub is_cluster_node { + my ($self, $cxn) = @_; + + my $sql = "SHOW VARIABLES LIKE 'wsrep\_on'"; + PTDEBUG && _d($cxn->name, $sql); + my $row = $cxn->dbh->selectrow_arrayref($sql); + PTDEBUG && _d(Dumper($row)); + return unless $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1'); + + return 1; +} + # There's two reasons why there might be dupes: # If the "master" is a cluster node, then a DSN table might have been # used, and it may have all nodes' DSNs so the user can run the tool @@ -233,7 +247,7 @@ sub name { # on the command line. # On the other hand, maybe find_cluster_nodes worked, in which case # we definitely have a dupe for the master cxn, but we may also have a -# dupe for every other node if this was unsed in conjunction with a +# dupe for every other node if this was used in conjunction with a # DSN table. # So try to detect and remove those. sub remove_duplicate_cxns { @@ -245,7 +259,11 @@ sub remove_duplicate_cxns { for my $cxn ( @cxns ) { my $dbh = $cxn->dbh(); - my $sql = q{SELECT @@server_id}; + + # Very often cluster nodes are configured with matching server_id's + # So in that case we'll use its incoming address as its unique identifier + # Note: this relies on "seen_ids" being populated using the same strategy + my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id}; PTDEBUG && _d($sql); my ($id) = $dbh->selectrow_array($sql); PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id); diff --git a/lib/Percona/XtraDB/Cluster.pm b/lib/Percona/XtraDB/Cluster.pm index 218875f2..c8ad96ce 100644 --- a/lib/Percona/XtraDB/Cluster.pm +++ b/lib/Percona/XtraDB/Cluster.pm @@ -132,8 +132,29 @@ sub find_cluster_nodes { sub remove_duplicate_cxns { my ($self, %args) = @_; my @cxns = @{$args{cxns}}; - my $seen_ids = $args{seen_ids}; - return Cxn->remove_duplicate_cxns(%args); + my $seen_ids = $args{seen_ids} || {}; + PTDEBUG && _d("Removing duplicates nodes from ", join(" ", map { $_->name } @cxns)); + my @trimmed_cxns; + + for my $cxn ( @cxns ) { + my $dbh = $cxn->dbh(); + # Very often cluster nodes are configured with matching server_id's + # So in that case we'll use its incoming address as its unique identifier + # Note: This relies on "seen_ids" being populated using the same strategy + my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id}; + PTDEBUG && _d($sql); + my ($id) = $dbh->selectrow_array($sql); + PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id); + + if ( ! $seen_ids->{$id}++ ) { + push @trimmed_cxns, $cxn + } + else { + PTDEBUG && _d("Removing ", $cxn->name, + ", ID ", $id, ", because we've already seen it"); + } + } + return \@trimmed_cxns; } sub same_cluster { diff --git a/t/pt-table-checksum/pxc.t b/t/pt-table-checksum/pxc.t index 35b0e759..6b3ad8e2 100644 --- a/t/pt-table-checksum/pxc.t +++ b/t/pt-table-checksum/pxc.t @@ -144,54 +144,89 @@ is( "Node3 not changed" ); -for my $args ( - ["using recusion-method=dsn", '--recursion-method', "dsn=$node1_dsn,D=dsns,t=dsns"], - ["using recursion-method=cluster", '--recursion-method', 'cluster'] - ) -{ - my $test = shift @$args; +sub test_recursion_methods { + my $same_ids = shift; - $output = output( - sub { pt_table_checksum::main(@args, - @$args) - }, - stderr => 1, - ); + my ($orig_id_1, $orig_id_2, $orig_id_3); - is( - PerconaTest::count_checksum_results($output, 'errors'), - 0, - "1 diff: no errors ($test)" - ); + if ($same_ids) { + # save original values + my $sql = 'SELECT @@server_id'; + ($orig_id_1) = $node1->selectrow_array($sql); + ($orig_id_2) = $node2->selectrow_array($sql); + ($orig_id_3) = $node3->selectrow_array($sql); + # set server_id value to 1 on all nodes + $sql = 'SET GLOBAL server_id = 1'; + $node1->do($sql); + $node2->do($sql); + $node3->do($sql); + } - is( - PerconaTest::count_checksum_results($output, 'skipped'), - 0, - "1 diff: no skips ($test)" - ); + for my $args ( + ["using recusion-method=dsn", '--recursion-method', "dsn=$node1_dsn,D=dsns,t=dsns"], + ["using recursion-method=cluster", '--recursion-method', 'cluster'] + ) + { + my $test = shift @$args; + $test = $same_ids ? $test.' - Nodes with different ids' : $test.' - Nodes with same ids'; - is( - PerconaTest::count_checksum_results($output, 'diffs'), - 1, - "1 diff: 1 diff ($test)" - ) or diag($output); + $output = output( + sub { pt_table_checksum::main(@args, + @$args) + }, + stderr => 1, + ); + + is( + PerconaTest::count_checksum_results($output, 'errors'), + 0, + "1 diff: no errors ($test)" + ); + + is( + PerconaTest::count_checksum_results($output, 'skipped'), + 0, + "1 diff: no skips ($test)" + ); + + is( + PerconaTest::count_checksum_results($output, 'diffs'), + 1, + "1 diff: 1 diff ($test)" + ) or diag($output); + + # 11-17T13:02:54 0 1 26 1 0 0.021 test.t + like( + $output, + qr/^\S+\s+ # ts + 0\s+ # errors + 1\s+ # diffs + 26\s+ # rows + \d+\s+ # chunks + 0\s+ # skipped + \S+\s+ # time + test.t$ # table + /xm, + "1 diff: it's in test.t ($test)" + ); + } + + if ($same_ids) { + # reset server_id's to original values + $node1->do("SET GLOBAL server_id = $orig_id_1"); + $node2->do("SET GLOBAL server_id = $orig_id_2"); + $node3->do("SET GLOBAL server_id = $orig_id_3"); + } - # 11-17T13:02:54 0 1 26 1 0 0.021 test.t - like( - $output, - qr/^\S+\s+ # ts - 0\s+ # errors - 1\s+ # diffs - 26\s+ # rows - \d+\s+ # chunks - 0\s+ # skipped - \S+\s+ # time - test.t$ # table - /xm, - "1 diff: it's in test.t ($test)" - ); } +# test recursion methods +test_recursion_methods(0); + +# test recursion methods when all nodes have the same id +test_recursion_methods(1); + + # ############################################################################# # cluster, node1 -> slave, run on node1 # ############################################################################# @@ -232,7 +267,7 @@ for my $args ( # Wait for the slave to apply the binlogs from node1 (its master). # Then change it so it's not consistent. PerconaTest::wait_for_table($slave_dbh, 'test.t'); - $sb->wait_for_slaves('cslave1'); + $sb->wait_for_slaves(master=> 'node1', slave => 'cslave1'); $slave_dbh->do("update test.t set c='zebra' where c='z'"); $output = output( From cdc7596a329e57406c10e5f2564663b3df329965 Mon Sep 17 00:00:00 2001 From: Frank Cizmich Date: Wed, 5 Nov 2014 20:21:51 -0200 Subject: [PATCH 2/2] minor style change --- bin/pt-config-diff | 3 +-- bin/pt-deadlock-logger | 3 +-- bin/pt-fk-error-logger | 3 +-- bin/pt-kill | 3 +-- bin/pt-online-schema-change | 3 +-- bin/pt-table-checksum | 3 +-- bin/pt-upgrade | 3 +-- lib/Cxn.pm | 3 +-- 8 files changed, 8 insertions(+), 16 deletions(-) diff --git a/bin/pt-config-diff b/bin/pt-config-diff index 4ab90df4..8ee7a9f9 100755 --- a/bin/pt-config-diff +++ b/bin/pt-config-diff @@ -2400,9 +2400,8 @@ sub is_cluster_node { PTDEBUG && _d($cxn->name, $sql); my $row = $cxn->dbh->selectrow_arrayref($sql); PTDEBUG && _d(Dumper($row)); - return unless $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1'); + return $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1') ? 1 : 0; - return 1; } sub remove_duplicate_cxns { diff --git a/bin/pt-deadlock-logger b/bin/pt-deadlock-logger index ab93561e..a5d6b97c 100755 --- a/bin/pt-deadlock-logger +++ b/bin/pt-deadlock-logger @@ -2744,9 +2744,8 @@ sub is_cluster_node { PTDEBUG && _d($cxn->name, $sql); my $row = $cxn->dbh->selectrow_arrayref($sql); PTDEBUG && _d(Dumper($row)); - return unless $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1'); + return $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1') ? 1 : 0; - return 1; } sub remove_duplicate_cxns { diff --git a/bin/pt-fk-error-logger b/bin/pt-fk-error-logger index 891d713a..13d5ba65 100755 --- a/bin/pt-fk-error-logger +++ b/bin/pt-fk-error-logger @@ -1896,9 +1896,8 @@ sub is_cluster_node { PTDEBUG && _d($cxn->name, $sql); my $row = $cxn->dbh->selectrow_arrayref($sql); PTDEBUG && _d(Dumper($row)); - return unless $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1'); + return $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1') ? 1 : 0; - return 1; } sub remove_duplicate_cxns { diff --git a/bin/pt-kill b/bin/pt-kill index bb394235..1b5c1a82 100755 --- a/bin/pt-kill +++ b/bin/pt-kill @@ -5263,9 +5263,8 @@ sub is_cluster_node { PTDEBUG && _d($cxn->name, $sql); my $row = $cxn->dbh->selectrow_arrayref($sql); PTDEBUG && _d(Dumper($row)); - return unless $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1'); + return $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1') ? 1 : 0; - return 1; } sub remove_duplicate_cxns { diff --git a/bin/pt-online-schema-change b/bin/pt-online-schema-change index 0850a9c8..a12d6c39 100755 --- a/bin/pt-online-schema-change +++ b/bin/pt-online-schema-change @@ -3860,9 +3860,8 @@ sub is_cluster_node { PTDEBUG && _d($cxn->name, $sql); my $row = $cxn->dbh->selectrow_arrayref($sql); PTDEBUG && _d(Dumper($row)); - return unless $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1'); + return $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1') ? 1 : 0; - return 1; } sub remove_duplicate_cxns { diff --git a/bin/pt-table-checksum b/bin/pt-table-checksum index 0b966195..f7e486ca 100755 --- a/bin/pt-table-checksum +++ b/bin/pt-table-checksum @@ -3638,9 +3638,8 @@ sub is_cluster_node { PTDEBUG && _d($cxn->name, $sql); my $row = $cxn->dbh->selectrow_arrayref($sql); PTDEBUG && _d(Dumper($row)); - return unless $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1'); + return $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1') ? 1 : 0; - return 1; } sub remove_duplicate_cxns { diff --git a/bin/pt-upgrade b/bin/pt-upgrade index 991181ab..8f57b7eb 100755 --- a/bin/pt-upgrade +++ b/bin/pt-upgrade @@ -2569,9 +2569,8 @@ sub is_cluster_node { PTDEBUG && _d($cxn->name, $sql); my $row = $cxn->dbh->selectrow_arrayref($sql); PTDEBUG && _d(Dumper($row)); - return unless $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1'); + return $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1') ? 1 : 0; - return 1; } sub remove_duplicate_cxns { diff --git a/lib/Cxn.pm b/lib/Cxn.pm index aff491db..b8dc7168 100644 --- a/lib/Cxn.pm +++ b/lib/Cxn.pm @@ -235,9 +235,8 @@ sub is_cluster_node { PTDEBUG && _d($cxn->name, $sql); my $row = $cxn->dbh->selectrow_arrayref($sql); PTDEBUG && _d(Dumper($row)); - return unless $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1'); + return $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1') ? 1 : 0; - return 1; } # There's two reasons why there might be dupes: