From d7099496ca33f55449c0e19e73ea4d81b0085bc1 Mon Sep 17 00:00:00 2001 From: Daniel Nichter Date: Wed, 27 Jun 2012 11:57:08 -0600 Subject: [PATCH 1/4] Add Cxn::is_cluster_node(). Add /*!99997*/ to SELECT..INSERT if the master is a cluster ndoe. --- bin/pt-table-checksum | 41 ++++++++++++++++++++++++++++++++--------- lib/Cxn.pm | 30 ++++++++++++++++++++++-------- 2 files changed, 54 insertions(+), 17 deletions(-) diff --git a/bin/pt-table-checksum b/bin/pt-table-checksum index 0a87c20d..d33611b1 100755 --- a/bin/pt-table-checksum +++ b/bin/pt-table-checksum @@ -1436,14 +1436,15 @@ sub new { } my $self = { - dsn => $dsn, - dbh => $args{dbh}, - dsn_name => $dp->as_string($dsn, [qw(h P S)]), - hostname => '', - set => $args{set}, - dbh_set => 0, - OptionParser => $o, - DSNParser => $dp, + dsn => $dsn, + dbh => $args{dbh}, + dsn_name => $dp->as_string($dsn, [qw(h P S)]), + hostname => '', + set => $args{set}, + dbh_set => 0, + is_cluster_node => undef, + OptionParser => $o, + DSNParser => $dp, }; return bless $self, $class; @@ -1513,6 +1514,19 @@ sub name { return $self->{hostname} || $self->{dsn_name} || 'unknown host'; } +sub is_cluster_node { + my ($self) = @_; + return $self->{is_cluster_node} if defined $self->{is_cluster_node}; + + my $sql = "SHOW VARIABLES LIKE 'wsrep_on'"; + PTDEBUG && _d($sql); + my $row = $self->{dbh}->selectrow_arrayref($sql); + PTDEBUG && _d(defined $row ? @$row : 'undef'); + $self->{is_cluster_node} = $row && $row->[0] ? 1 : 0; + + return $self->{is_cluster_node}; +} + sub DESTROY { my ($self) = @_; if ( $self->{dbh} @@ -6499,6 +6513,7 @@ sub main { my $master_dbh = $master_cxn->dbh(); # just for brevity my $master_dsn = $master_cxn->dsn(); # just for brevity + # ######################################################################## # If this is not a dry run (--explain was not specified), then we're # going to checksum the tables, so do the necessary preparations and @@ -6539,6 +6554,12 @@ sub main { ); PTDEBUG && _d(scalar @$slaves, 'slaves found'); + if ( $master_cxn->is_cluster_node() && !@$slaves ) { + die $master_cxn->name() . " is a cluster node but no other nodes " + . "or regular replicas were found. Use --recursion-method=dsn " + . "to specify the other nodes in the cluster.\n"; + } + if ( $o->get('check-slave-lag') ) { PTDEBUG && _d('Will use --check-slave-lag to check for slave lag'); my $cxn = $make_cxn->( @@ -6744,7 +6765,9 @@ sub main { my $checksum_dml = "REPLACE INTO $repl_table " . "(db, tbl, chunk, chunk_index," . " lower_boundary, upper_boundary, this_cnt, this_crc) " - . "SELECT ?, ?, ?, ?, ?, ?,"; + . "SELECT " + . ($master_cxn->is_cluster_node() ? '/*!99997*/' : '') + . " ?, ?, ?, ?, ?, ?,"; my $past_cols = " COUNT(*), '0'"; # ######################################################################## diff --git a/lib/Cxn.pm b/lib/Cxn.pm index e35f4432..0d8461ef 100644 --- a/lib/Cxn.pm +++ b/lib/Cxn.pm @@ -98,14 +98,15 @@ sub new { } my $self = { - dsn => $dsn, - dbh => $args{dbh}, - dsn_name => $dp->as_string($dsn, [qw(h P S)]), - hostname => '', - set => $args{set}, - dbh_set => 0, - OptionParser => $o, - DSNParser => $dp, + dsn => $dsn, + dbh => $args{dbh}, + dsn_name => $dp->as_string($dsn, [qw(h P S)]), + hostname => '', + set => $args{set}, + dbh_set => 0, + is_cluster_node => undef, + OptionParser => $o, + DSNParser => $dp, }; return bless $self, $class; @@ -193,6 +194,19 @@ sub name { return $self->{hostname} || $self->{dsn_name} || 'unknown host'; } +sub is_cluster_node { + my ($self) = @_; + return $self->{is_cluster_node} if defined $self->{is_cluster_node}; + + my $sql = "SHOW VARIABLES LIKE 'wsrep_on'"; + PTDEBUG && _d($sql); + my $row = $self->{dbh}->selectrow_arrayref($sql); + PTDEBUG && _d(defined $row ? @$row : 'undef'); + $self->{is_cluster_node} = $row && $row->[0] ? 1 : 0; + + return $self->{is_cluster_node}; +} + sub DESTROY { my ($self) = @_; if ( $self->{dbh} From 18e4e1f0e5b30884d3c1bea94d9b246e74b0dc70 Mon Sep 17 00:00:00 2001 From: Daniel Nichter Date: Wed, 27 Jun 2012 15:53:09 -0600 Subject: [PATCH 2/4] Don't check slave lag on cluster nodes. --- bin/pt-table-checksum | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/bin/pt-table-checksum b/bin/pt-table-checksum index d33611b1..049b09b4 100755 --- a/bin/pt-table-checksum +++ b/bin/pt-table-checksum @@ -6513,7 +6513,6 @@ sub main { my $master_dbh = $master_cxn->dbh(); # just for brevity my $master_dsn = $master_cxn->dsn(); # just for brevity - # ######################################################################## # If this is not a dry run (--explain was not specified), then we're # going to checksum the tables, so do the necessary preparations and @@ -6573,6 +6572,23 @@ sub main { $slave_lag_cxns = $slaves; } + # Cluster nodes aren't slaves, so SHOW SLAVE STATUS doesn't work. + # Nodes shouldn't be out of sync anyway because the cluster is + # (virtually) synchronous, so waiting for the last checksum chunk + # to appear should be sufficient. + @$slave_lag_cxns = grep { + my $slave_cxn = $_; + if ( $slave_cxn->is_cluster_node() ) { + warn "Not checking replica lag on " . $slave_cxn->name() + . " because it is a cluster node.\n"; + 0; + } + else { + PTDEBUG && _d('Will check slave lag on', $slave_cxn->name()); + $slave_cxn; + } + } @$slave_lag_cxns; + # ##################################################################### # Possibly check replication slaves and exit. # ##################################################################### From d00cd2ebf0a748e82ffb31be06fb9247dd3a4fb3 Mon Sep 17 00:00:00 2001 From: Daniel Nichter Date: Wed, 29 Aug 2012 16:56:48 -0600 Subject: [PATCH 3/4] Docu limitations of using ptc with PXC. Update Cxn to get is_cluster_node(). Fix SELECT to make tests happy. --- bin/pt-table-checksum | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/bin/pt-table-checksum b/bin/pt-table-checksum index 40aaa422..354947d6 100755 --- a/bin/pt-table-checksum +++ b/bin/pt-table-checksum @@ -2987,6 +2987,7 @@ sub new { dbh_set => 0, OptionParser => $o, DSNParser => $dp, + is_cluster_node => undef, }; return bless $self, $class; @@ -3056,6 +3057,19 @@ sub name { return $self->{hostname} || $self->{dsn_name} || 'unknown host'; } +sub is_cluster_node { + my ($self) = @_; + return $self->{is_cluster_node} if defined $self->{is_cluster_node}; + + my $sql = "SHOW VARIABLES LIKE 'wsrep_on'"; + PTDEBUG && _d($sql); + my $row = $self->{dbh}->selectrow_arrayref($sql); + PTDEBUG && _d(defined $row ? @$row : 'undef'); + $self->{is_cluster_node} = $row && $row->[0] ? 1 : 0; + + return $self->{is_cluster_node}; +} + sub DESTROY { my ($self) = @_; if ( $self->{dbh} @@ -8533,7 +8547,7 @@ sub main { my $checksum_dml = "REPLACE INTO $repl_table " . "(db, tbl, chunk, chunk_index," . " lower_boundary, upper_boundary, this_cnt, this_crc) " - . "SELECT " + . "SELECT" . ($master_cxn->is_cluster_node() ? '/*!99997*/' : '') . " ?, ?, ?, ?, ?, ?,"; my $past_cols = " COUNT(*), '0'"; @@ -11028,6 +11042,14 @@ replicas do not honor this change. Therefore, checksums will not replicate past any replicas using row-based replication that are masters for further replicas. (L) +=item Percona XtraDB Cluster + +pt-table-checksum works with Percona XtraDB Cluster 5.5.27-23.6 and newer. +The C method for L<"--recursion-method"> must be used to specify cluster +nodes and regular replicas because nodes are not regular replicas so they +cannot be detected automatically. The lag check (see L<"REPLICA CHECKS">) +is not performed for cluster nodes. + =back =head1 BUGS From 1a895cb0e05f6bc9ad0569114bc73a39335cb860 Mon Sep 17 00:00:00 2001 From: Daniel Nichter Date: Wed, 29 Aug 2012 17:00:34 -0600 Subject: [PATCH 4/4] Add space for prettier SQL. --- bin/pt-table-checksum | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/pt-table-checksum b/bin/pt-table-checksum index 354947d6..629c2aa5 100755 --- a/bin/pt-table-checksum +++ b/bin/pt-table-checksum @@ -8548,7 +8548,7 @@ sub main { . "(db, tbl, chunk, chunk_index," . " lower_boundary, upper_boundary, this_cnt, this_crc) " . "SELECT" - . ($master_cxn->is_cluster_node() ? '/*!99997*/' : '') + . ($master_cxn->is_cluster_node() ? ' /*!99997*/' : '') . " ?, ?, ?, ?, ?, ?,"; my $past_cols = " COUNT(*), '0'";