Merge lp:~percona-toolkit-dev/percona-toolkit/pt-table-checksum-refuses-to-run-on-PXC-if-server_id-is-the-same-on-all-nodes-1217466 into lp:~percona-toolkit-dev/percona-toolkit/release-2.2.12
- pt-table-checksum-refuses-to-run-on-PXC-if-server_id-is-the-same-on-all-nodes-1217466
- Merge into release-2.2.12
Proposed by
Frank Cizmich
Status: | Merged |
---|---|
Approved by: | Daniel Nichter |
Approved revision: | 626 |
Merged at revision: | 635 |
Proposed branch: | lp:~percona-toolkit-dev/percona-toolkit/pt-table-checksum-refuses-to-run-on-PXC-if-server_id-is-the-same-on-all-nodes-1217466 |
Merge into: | lp:~percona-toolkit-dev/percona-toolkit/release-2.2.12 |
Diff against target: |
752 lines (+321/-78) 10 files modified
bin/pt-config-diff (+22/-3) bin/pt-deadlock-logger (+22/-3) bin/pt-fk-error-logger (+22/-3) bin/pt-kill (+22/-3) bin/pt-online-schema-change (+43/-6) bin/pt-table-checksum (+44/-6) bin/pt-upgrade (+22/-3) lib/Cxn.pm (+19/-2) lib/Percona/XtraDB/Cluster.pm (+23/-2) t/pt-table-checksum/pxc.t (+82/-47) |
To merge this branch: | bzr merge lp:~percona-toolkit-dev/percona-toolkit/pt-table-checksum-refuses-to-run-on-PXC-if-server_id-is-the-same-on-all-nodes-1217466 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Daniel Nichter | Approve | ||
Review via email: mp+239451@code.launchpad.net |
Commit message
Description of the change
problem:
Sometimes PXC setups use the same ID for all nodes ( no consensus yet if this is "right" or "wrong" )
This made pt-table-checksum discard nodes with the same ID although they were different nodes.
fix:
Changed remove_
Also changed pt-table-checksum to populate the %seen_ids param accordingly before passing it to the function.
caveat:
the seen_ids parameter has to be populated carefully using this criteria. At this point only pt-table-checksum uses it.
Maybe a cleaner way would be to create a get_unique_id function in Cxn
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'bin/pt-config-diff' |
2 | --- bin/pt-config-diff 2014-09-25 13:48:22 +0000 |
3 | +++ bin/pt-config-diff 2014-11-05 22:22:52 +0000 |
4 | @@ -2295,7 +2295,7 @@ |
5 | set => $args{set}, |
6 | NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1, |
7 | dbh_set => 0, |
8 | - ask_pass => $o->get('ask-pass'), |
9 | + ask_pass => $args{ask_pass}, |
10 | DSNParser => $dp, |
11 | is_cluster_node => undef, |
12 | parent => $args{parent}, |
13 | @@ -2306,7 +2306,7 @@ |
14 | |
15 | sub connect { |
16 | my ( $self, %opts ) = @_; |
17 | - my $dsn = $self->{dsn}; |
18 | + my $dsn = $opts{dsn} || $self->{dsn}; |
19 | my $dp = $self->{DSNParser}; |
20 | |
21 | my $dbh = $self->{dbh}; |
22 | @@ -2325,6 +2325,13 @@ |
23 | } |
24 | |
25 | $dbh = $self->set_dbh($dbh); |
26 | + if ( $opts{dsn} ) { |
27 | + $self->{dsn} = $dsn; |
28 | + $self->{dsn_name} = $dp->as_string($dsn, [qw(h P S)]) |
29 | + || $dp->as_string($dsn, [qw(F)]) |
30 | + || ''; |
31 | + |
32 | + } |
33 | PTDEBUG && _d($dbh, 'Connected dbh to', $self->{hostname},$self->{dsn_name}); |
34 | return $dbh; |
35 | } |
36 | @@ -2386,6 +2393,17 @@ |
37 | return $self->{hostname} || $self->{dsn_name} || 'unknown host'; |
38 | } |
39 | |
40 | +sub is_cluster_node { |
41 | + my ($self, $cxn) = @_; |
42 | + |
43 | + my $sql = "SHOW VARIABLES LIKE 'wsrep\_on'"; |
44 | + PTDEBUG && _d($cxn->name, $sql); |
45 | + my $row = $cxn->dbh->selectrow_arrayref($sql); |
46 | + PTDEBUG && _d(Dumper($row)); |
47 | + return $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1') ? 1 : 0; |
48 | + |
49 | +} |
50 | + |
51 | sub remove_duplicate_cxns { |
52 | my ($self, %args) = @_; |
53 | my @cxns = @{$args{cxns}}; |
54 | @@ -2395,7 +2413,8 @@ |
55 | |
56 | for my $cxn ( @cxns ) { |
57 | my $dbh = $cxn->dbh(); |
58 | - my $sql = q{SELECT @@server_id}; |
59 | + |
60 | + my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id}; |
61 | PTDEBUG && _d($sql); |
62 | my ($id) = $dbh->selectrow_array($sql); |
63 | PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id); |
64 | |
65 | === modified file 'bin/pt-deadlock-logger' |
66 | --- bin/pt-deadlock-logger 2014-09-25 13:48:22 +0000 |
67 | +++ bin/pt-deadlock-logger 2014-11-05 22:22:52 +0000 |
68 | @@ -2639,7 +2639,7 @@ |
69 | set => $args{set}, |
70 | NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1, |
71 | dbh_set => 0, |
72 | - ask_pass => $o->get('ask-pass'), |
73 | + ask_pass => $args{ask_pass}, |
74 | DSNParser => $dp, |
75 | is_cluster_node => undef, |
76 | parent => $args{parent}, |
77 | @@ -2650,7 +2650,7 @@ |
78 | |
79 | sub connect { |
80 | my ( $self, %opts ) = @_; |
81 | - my $dsn = $self->{dsn}; |
82 | + my $dsn = $opts{dsn} || $self->{dsn}; |
83 | my $dp = $self->{DSNParser}; |
84 | |
85 | my $dbh = $self->{dbh}; |
86 | @@ -2669,6 +2669,13 @@ |
87 | } |
88 | |
89 | $dbh = $self->set_dbh($dbh); |
90 | + if ( $opts{dsn} ) { |
91 | + $self->{dsn} = $dsn; |
92 | + $self->{dsn_name} = $dp->as_string($dsn, [qw(h P S)]) |
93 | + || $dp->as_string($dsn, [qw(F)]) |
94 | + || ''; |
95 | + |
96 | + } |
97 | PTDEBUG && _d($dbh, 'Connected dbh to', $self->{hostname},$self->{dsn_name}); |
98 | return $dbh; |
99 | } |
100 | @@ -2730,6 +2737,17 @@ |
101 | return $self->{hostname} || $self->{dsn_name} || 'unknown host'; |
102 | } |
103 | |
104 | +sub is_cluster_node { |
105 | + my ($self, $cxn) = @_; |
106 | + |
107 | + my $sql = "SHOW VARIABLES LIKE 'wsrep\_on'"; |
108 | + PTDEBUG && _d($cxn->name, $sql); |
109 | + my $row = $cxn->dbh->selectrow_arrayref($sql); |
110 | + PTDEBUG && _d(Dumper($row)); |
111 | + return $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1') ? 1 : 0; |
112 | + |
113 | +} |
114 | + |
115 | sub remove_duplicate_cxns { |
116 | my ($self, %args) = @_; |
117 | my @cxns = @{$args{cxns}}; |
118 | @@ -2739,7 +2757,8 @@ |
119 | |
120 | for my $cxn ( @cxns ) { |
121 | my $dbh = $cxn->dbh(); |
122 | - my $sql = q{SELECT @@server_id}; |
123 | + |
124 | + my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id}; |
125 | PTDEBUG && _d($sql); |
126 | my ($id) = $dbh->selectrow_array($sql); |
127 | PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id); |
128 | |
129 | === modified file 'bin/pt-fk-error-logger' |
130 | --- bin/pt-fk-error-logger 2014-09-25 13:48:22 +0000 |
131 | +++ bin/pt-fk-error-logger 2014-11-05 22:22:52 +0000 |
132 | @@ -1791,7 +1791,7 @@ |
133 | set => $args{set}, |
134 | NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1, |
135 | dbh_set => 0, |
136 | - ask_pass => $o->get('ask-pass'), |
137 | + ask_pass => $args{ask_pass}, |
138 | DSNParser => $dp, |
139 | is_cluster_node => undef, |
140 | parent => $args{parent}, |
141 | @@ -1802,7 +1802,7 @@ |
142 | |
143 | sub connect { |
144 | my ( $self, %opts ) = @_; |
145 | - my $dsn = $self->{dsn}; |
146 | + my $dsn = $opts{dsn} || $self->{dsn}; |
147 | my $dp = $self->{DSNParser}; |
148 | |
149 | my $dbh = $self->{dbh}; |
150 | @@ -1821,6 +1821,13 @@ |
151 | } |
152 | |
153 | $dbh = $self->set_dbh($dbh); |
154 | + if ( $opts{dsn} ) { |
155 | + $self->{dsn} = $dsn; |
156 | + $self->{dsn_name} = $dp->as_string($dsn, [qw(h P S)]) |
157 | + || $dp->as_string($dsn, [qw(F)]) |
158 | + || ''; |
159 | + |
160 | + } |
161 | PTDEBUG && _d($dbh, 'Connected dbh to', $self->{hostname},$self->{dsn_name}); |
162 | return $dbh; |
163 | } |
164 | @@ -1882,6 +1889,17 @@ |
165 | return $self->{hostname} || $self->{dsn_name} || 'unknown host'; |
166 | } |
167 | |
168 | +sub is_cluster_node { |
169 | + my ($self, $cxn) = @_; |
170 | + |
171 | + my $sql = "SHOW VARIABLES LIKE 'wsrep\_on'"; |
172 | + PTDEBUG && _d($cxn->name, $sql); |
173 | + my $row = $cxn->dbh->selectrow_arrayref($sql); |
174 | + PTDEBUG && _d(Dumper($row)); |
175 | + return $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1') ? 1 : 0; |
176 | + |
177 | +} |
178 | + |
179 | sub remove_duplicate_cxns { |
180 | my ($self, %args) = @_; |
181 | my @cxns = @{$args{cxns}}; |
182 | @@ -1891,7 +1909,8 @@ |
183 | |
184 | for my $cxn ( @cxns ) { |
185 | my $dbh = $cxn->dbh(); |
186 | - my $sql = q{SELECT @@server_id}; |
187 | + |
188 | + my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id}; |
189 | PTDEBUG && _d($sql); |
190 | my ($id) = $dbh->selectrow_array($sql); |
191 | PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id); |
192 | |
193 | === modified file 'bin/pt-kill' |
194 | --- bin/pt-kill 2014-09-25 13:48:22 +0000 |
195 | +++ bin/pt-kill 2014-11-05 22:22:52 +0000 |
196 | @@ -5158,7 +5158,7 @@ |
197 | set => $args{set}, |
198 | NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1, |
199 | dbh_set => 0, |
200 | - ask_pass => $o->get('ask-pass'), |
201 | + ask_pass => $args{ask_pass}, |
202 | DSNParser => $dp, |
203 | is_cluster_node => undef, |
204 | parent => $args{parent}, |
205 | @@ -5169,7 +5169,7 @@ |
206 | |
207 | sub connect { |
208 | my ( $self, %opts ) = @_; |
209 | - my $dsn = $self->{dsn}; |
210 | + my $dsn = $opts{dsn} || $self->{dsn}; |
211 | my $dp = $self->{DSNParser}; |
212 | |
213 | my $dbh = $self->{dbh}; |
214 | @@ -5188,6 +5188,13 @@ |
215 | } |
216 | |
217 | $dbh = $self->set_dbh($dbh); |
218 | + if ( $opts{dsn} ) { |
219 | + $self->{dsn} = $dsn; |
220 | + $self->{dsn_name} = $dp->as_string($dsn, [qw(h P S)]) |
221 | + || $dp->as_string($dsn, [qw(F)]) |
222 | + || ''; |
223 | + |
224 | + } |
225 | PTDEBUG && _d($dbh, 'Connected dbh to', $self->{hostname},$self->{dsn_name}); |
226 | return $dbh; |
227 | } |
228 | @@ -5249,6 +5256,17 @@ |
229 | return $self->{hostname} || $self->{dsn_name} || 'unknown host'; |
230 | } |
231 | |
232 | +sub is_cluster_node { |
233 | + my ($self, $cxn) = @_; |
234 | + |
235 | + my $sql = "SHOW VARIABLES LIKE 'wsrep\_on'"; |
236 | + PTDEBUG && _d($cxn->name, $sql); |
237 | + my $row = $cxn->dbh->selectrow_arrayref($sql); |
238 | + PTDEBUG && _d(Dumper($row)); |
239 | + return $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1') ? 1 : 0; |
240 | + |
241 | +} |
242 | + |
243 | sub remove_duplicate_cxns { |
244 | my ($self, %args) = @_; |
245 | my @cxns = @{$args{cxns}}; |
246 | @@ -5258,7 +5276,8 @@ |
247 | |
248 | for my $cxn ( @cxns ) { |
249 | my $dbh = $cxn->dbh(); |
250 | - my $sql = q{SELECT @@server_id}; |
251 | + |
252 | + my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id}; |
253 | PTDEBUG && _d($sql); |
254 | my ($id) = $dbh->selectrow_array($sql); |
255 | PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id); |
256 | |
257 | === modified file 'bin/pt-online-schema-change' |
258 | --- bin/pt-online-schema-change 2014-09-25 13:48:22 +0000 |
259 | +++ bin/pt-online-schema-change 2014-11-05 22:22:52 +0000 |
260 | @@ -3755,7 +3755,7 @@ |
261 | set => $args{set}, |
262 | NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1, |
263 | dbh_set => 0, |
264 | - ask_pass => $o->get('ask-pass'), |
265 | + ask_pass => $args{ask_pass}, |
266 | DSNParser => $dp, |
267 | is_cluster_node => undef, |
268 | parent => $args{parent}, |
269 | @@ -3766,12 +3766,12 @@ |
270 | |
271 | sub connect { |
272 | my ( $self, %opts ) = @_; |
273 | - my $dsn = $self->{dsn}; |
274 | + my $dsn = $opts{dsn} || $self->{dsn}; |
275 | my $dp = $self->{DSNParser}; |
276 | |
277 | my $dbh = $self->{dbh}; |
278 | if ( !$dbh || !$dbh->ping() ) { |
279 | - if ( $self->{ask_pass} && !$self->{asked_for_pass} && !defined $dsn->{p}) { |
280 | + if ( $self->{ask_pass} && !$self->{asked_for_pass} ) { |
281 | $dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: "); |
282 | $self->{asked_for_pass} = 1; |
283 | } |
284 | @@ -3785,6 +3785,13 @@ |
285 | } |
286 | |
287 | $dbh = $self->set_dbh($dbh); |
288 | + if ( $opts{dsn} ) { |
289 | + $self->{dsn} = $dsn; |
290 | + $self->{dsn_name} = $dp->as_string($dsn, [qw(h P S)]) |
291 | + || $dp->as_string($dsn, [qw(F)]) |
292 | + || ''; |
293 | + |
294 | + } |
295 | PTDEBUG && _d($dbh, 'Connected dbh to', $self->{hostname},$self->{dsn_name}); |
296 | return $dbh; |
297 | } |
298 | @@ -3846,6 +3853,17 @@ |
299 | return $self->{hostname} || $self->{dsn_name} || 'unknown host'; |
300 | } |
301 | |
302 | +sub is_cluster_node { |
303 | + my ($self, $cxn) = @_; |
304 | + |
305 | + my $sql = "SHOW VARIABLES LIKE 'wsrep\_on'"; |
306 | + PTDEBUG && _d($cxn->name, $sql); |
307 | + my $row = $cxn->dbh->selectrow_arrayref($sql); |
308 | + PTDEBUG && _d(Dumper($row)); |
309 | + return $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1') ? 1 : 0; |
310 | + |
311 | +} |
312 | + |
313 | sub remove_duplicate_cxns { |
314 | my ($self, %args) = @_; |
315 | my @cxns = @{$args{cxns}}; |
316 | @@ -3855,7 +3873,8 @@ |
317 | |
318 | for my $cxn ( @cxns ) { |
319 | my $dbh = $cxn->dbh(); |
320 | - my $sql = q{SELECT @@server_id}; |
321 | + |
322 | + my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id}; |
323 | PTDEBUG && _d($sql); |
324 | my ($id) = $dbh->selectrow_array($sql); |
325 | PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id); |
326 | @@ -7638,8 +7657,26 @@ |
327 | sub remove_duplicate_cxns { |
328 | my ($self, %args) = @_; |
329 | my @cxns = @{$args{cxns}}; |
330 | - my $seen_ids = $args{seen_ids}; |
331 | - return Cxn->remove_duplicate_cxns(%args); |
332 | + my $seen_ids = $args{seen_ids} || {}; |
333 | + PTDEBUG && _d("Removing duplicates nodes from ", join(" ", map { $_->name } @cxns)); |
334 | + my @trimmed_cxns; |
335 | + |
336 | + for my $cxn ( @cxns ) { |
337 | + my $dbh = $cxn->dbh(); |
338 | + my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id}; |
339 | + PTDEBUG && _d($sql); |
340 | + my ($id) = $dbh->selectrow_array($sql); |
341 | + PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id); |
342 | + |
343 | + if ( ! $seen_ids->{$id}++ ) { |
344 | + push @trimmed_cxns, $cxn |
345 | + } |
346 | + else { |
347 | + PTDEBUG && _d("Removing ", $cxn->name, |
348 | + ", ID ", $id, ", because we've already seen it"); |
349 | + } |
350 | + } |
351 | + return \@trimmed_cxns; |
352 | } |
353 | |
354 | sub same_cluster { |
355 | |
356 | === modified file 'bin/pt-table-checksum' |
357 | --- bin/pt-table-checksum 2014-09-25 13:48:22 +0000 |
358 | +++ bin/pt-table-checksum 2014-11-05 22:22:52 +0000 |
359 | @@ -3533,7 +3533,7 @@ |
360 | set => $args{set}, |
361 | NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1, |
362 | dbh_set => 0, |
363 | - ask_pass => $o->get('ask-pass'), |
364 | + ask_pass => $args{ask_pass}, |
365 | DSNParser => $dp, |
366 | is_cluster_node => undef, |
367 | parent => $args{parent}, |
368 | @@ -3544,7 +3544,7 @@ |
369 | |
370 | sub connect { |
371 | my ( $self, %opts ) = @_; |
372 | - my $dsn = $self->{dsn}; |
373 | + my $dsn = $opts{dsn} || $self->{dsn}; |
374 | my $dp = $self->{DSNParser}; |
375 | |
376 | my $dbh = $self->{dbh}; |
377 | @@ -3563,6 +3563,13 @@ |
378 | } |
379 | |
380 | $dbh = $self->set_dbh($dbh); |
381 | + if ( $opts{dsn} ) { |
382 | + $self->{dsn} = $dsn; |
383 | + $self->{dsn_name} = $dp->as_string($dsn, [qw(h P S)]) |
384 | + || $dp->as_string($dsn, [qw(F)]) |
385 | + || ''; |
386 | + |
387 | + } |
388 | PTDEBUG && _d($dbh, 'Connected dbh to', $self->{hostname},$self->{dsn_name}); |
389 | return $dbh; |
390 | } |
391 | @@ -3624,6 +3631,17 @@ |
392 | return $self->{hostname} || $self->{dsn_name} || 'unknown host'; |
393 | } |
394 | |
395 | +sub is_cluster_node { |
396 | + my ($self, $cxn) = @_; |
397 | + |
398 | + my $sql = "SHOW VARIABLES LIKE 'wsrep\_on'"; |
399 | + PTDEBUG && _d($cxn->name, $sql); |
400 | + my $row = $cxn->dbh->selectrow_arrayref($sql); |
401 | + PTDEBUG && _d(Dumper($row)); |
402 | + return $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1') ? 1 : 0; |
403 | + |
404 | +} |
405 | + |
406 | sub remove_duplicate_cxns { |
407 | my ($self, %args) = @_; |
408 | my @cxns = @{$args{cxns}}; |
409 | @@ -3633,7 +3651,8 @@ |
410 | |
411 | for my $cxn ( @cxns ) { |
412 | my $dbh = $cxn->dbh(); |
413 | - my $sql = q{SELECT @@server_id}; |
414 | + |
415 | + my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id}; |
416 | PTDEBUG && _d($sql); |
417 | my ($id) = $dbh->selectrow_array($sql); |
418 | PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id); |
419 | @@ -3788,8 +3807,26 @@ |
420 | sub remove_duplicate_cxns { |
421 | my ($self, %args) = @_; |
422 | my @cxns = @{$args{cxns}}; |
423 | - my $seen_ids = $args{seen_ids}; |
424 | - return Cxn->remove_duplicate_cxns(%args); |
425 | + my $seen_ids = $args{seen_ids} || {}; |
426 | + PTDEBUG && _d("Removing duplicates nodes from ", join(" ", map { $_->name } @cxns)); |
427 | + my @trimmed_cxns; |
428 | + |
429 | + for my $cxn ( @cxns ) { |
430 | + my $dbh = $cxn->dbh(); |
431 | + my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id}; |
432 | + PTDEBUG && _d($sql); |
433 | + my ($id) = $dbh->selectrow_array($sql); |
434 | + PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id); |
435 | + |
436 | + if ( ! $seen_ids->{$id}++ ) { |
437 | + push @trimmed_cxns, $cxn |
438 | + } |
439 | + else { |
440 | + PTDEBUG && _d("Removing ", $cxn->name, |
441 | + ", ID ", $id, ", because we've already seen it"); |
442 | + } |
443 | + } |
444 | + return \@trimmed_cxns; |
445 | } |
446 | |
447 | sub same_cluster { |
448 | @@ -9286,7 +9323,8 @@ |
449 | my %seen_ids; |
450 | for my $cxn ($master_cxn, @$slaves) { |
451 | my $dbh = $cxn->dbh(); |
452 | - my $sql = q{SELECT @@server_id}; |
453 | + # if it's a cluster node we use its incoming address as id ( see https://bugs.launchpad.net/percona-toolkit/+bug/1217466 ) |
454 | + my $sql = $cluster->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id}; |
455 | PTDEBUG && _d($cxn, $dbh, $sql); |
456 | my ($id) = $dbh->selectrow_array($sql); |
457 | $seen_ids{$id}++; |
458 | |
459 | === modified file 'bin/pt-upgrade' |
460 | --- bin/pt-upgrade 2014-09-25 13:48:22 +0000 |
461 | +++ bin/pt-upgrade 2014-11-05 22:22:52 +0000 |
462 | @@ -2464,7 +2464,7 @@ |
463 | set => $args{set}, |
464 | NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1, |
465 | dbh_set => 0, |
466 | - ask_pass => $o->get('ask-pass'), |
467 | + ask_pass => $args{ask_pass}, |
468 | DSNParser => $dp, |
469 | is_cluster_node => undef, |
470 | parent => $args{parent}, |
471 | @@ -2475,7 +2475,7 @@ |
472 | |
473 | sub connect { |
474 | my ( $self, %opts ) = @_; |
475 | - my $dsn = $self->{dsn}; |
476 | + my $dsn = $opts{dsn} || $self->{dsn}; |
477 | my $dp = $self->{DSNParser}; |
478 | |
479 | my $dbh = $self->{dbh}; |
480 | @@ -2494,6 +2494,13 @@ |
481 | } |
482 | |
483 | $dbh = $self->set_dbh($dbh); |
484 | + if ( $opts{dsn} ) { |
485 | + $self->{dsn} = $dsn; |
486 | + $self->{dsn_name} = $dp->as_string($dsn, [qw(h P S)]) |
487 | + || $dp->as_string($dsn, [qw(F)]) |
488 | + || ''; |
489 | + |
490 | + } |
491 | PTDEBUG && _d($dbh, 'Connected dbh to', $self->{hostname},$self->{dsn_name}); |
492 | return $dbh; |
493 | } |
494 | @@ -2555,6 +2562,17 @@ |
495 | return $self->{hostname} || $self->{dsn_name} || 'unknown host'; |
496 | } |
497 | |
498 | +sub is_cluster_node { |
499 | + my ($self, $cxn) = @_; |
500 | + |
501 | + my $sql = "SHOW VARIABLES LIKE 'wsrep\_on'"; |
502 | + PTDEBUG && _d($cxn->name, $sql); |
503 | + my $row = $cxn->dbh->selectrow_arrayref($sql); |
504 | + PTDEBUG && _d(Dumper($row)); |
505 | + return $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1') ? 1 : 0; |
506 | + |
507 | +} |
508 | + |
509 | sub remove_duplicate_cxns { |
510 | my ($self, %args) = @_; |
511 | my @cxns = @{$args{cxns}}; |
512 | @@ -2564,7 +2582,8 @@ |
513 | |
514 | for my $cxn ( @cxns ) { |
515 | my $dbh = $cxn->dbh(); |
516 | - my $sql = q{SELECT @@server_id}; |
517 | + |
518 | + my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id}; |
519 | PTDEBUG && _d($sql); |
520 | my ($id) = $dbh->selectrow_array($sql); |
521 | PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id); |
522 | |
523 | === modified file 'lib/Cxn.pm' |
524 | --- lib/Cxn.pm 2013-12-05 00:14:17 +0000 |
525 | +++ lib/Cxn.pm 2014-11-05 22:22:52 +0000 |
526 | @@ -226,6 +226,19 @@ |
527 | return $self->{hostname} || $self->{dsn_name} || 'unknown host'; |
528 | } |
529 | |
530 | +# This is used to help remove_duplicate_cxns detect cluster nodes |
531 | +# (which often have unreliable server_id's) |
532 | +sub is_cluster_node { |
533 | + my ($self, $cxn) = @_; |
534 | + |
535 | + my $sql = "SHOW VARIABLES LIKE 'wsrep\_on'"; |
536 | + PTDEBUG && _d($cxn->name, $sql); |
537 | + my $row = $cxn->dbh->selectrow_arrayref($sql); |
538 | + PTDEBUG && _d(Dumper($row)); |
539 | + return $row && $row->[1] && ($row->[1] eq 'ON' || $row->[1] eq '1') ? 1 : 0; |
540 | + |
541 | +} |
542 | + |
543 | # There's two reasons why there might be dupes: |
544 | # If the "master" is a cluster node, then a DSN table might have been |
545 | # used, and it may have all nodes' DSNs so the user can run the tool |
546 | @@ -233,7 +246,7 @@ |
547 | # on the command line. |
548 | # On the other hand, maybe find_cluster_nodes worked, in which case |
549 | # we definitely have a dupe for the master cxn, but we may also have a |
550 | -# dupe for every other node if this was unsed in conjunction with a |
551 | +# dupe for every other node if this was used in conjunction with a |
552 | # DSN table. |
553 | # So try to detect and remove those. |
554 | sub remove_duplicate_cxns { |
555 | @@ -245,7 +258,11 @@ |
556 | |
557 | for my $cxn ( @cxns ) { |
558 | my $dbh = $cxn->dbh(); |
559 | - my $sql = q{SELECT @@server_id}; |
560 | + |
561 | + # Very often cluster nodes are configured with matching server_id's |
562 | + # So in that case we'll use its incoming address as its unique identifier |
563 | + # Note: this relies on "seen_ids" being populated using the same strategy |
564 | + my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id}; |
565 | PTDEBUG && _d($sql); |
566 | my ($id) = $dbh->selectrow_array($sql); |
567 | PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id); |
568 | |
569 | === modified file 'lib/Percona/XtraDB/Cluster.pm' |
570 | --- lib/Percona/XtraDB/Cluster.pm 2013-04-16 20:40:32 +0000 |
571 | +++ lib/Percona/XtraDB/Cluster.pm 2014-11-05 22:22:52 +0000 |
572 | @@ -132,8 +132,29 @@ |
573 | sub remove_duplicate_cxns { |
574 | my ($self, %args) = @_; |
575 | my @cxns = @{$args{cxns}}; |
576 | - my $seen_ids = $args{seen_ids}; |
577 | - return Cxn->remove_duplicate_cxns(%args); |
578 | + my $seen_ids = $args{seen_ids} || {}; |
579 | + PTDEBUG && _d("Removing duplicates nodes from ", join(" ", map { $_->name } @cxns)); |
580 | + my @trimmed_cxns; |
581 | + |
582 | + for my $cxn ( @cxns ) { |
583 | + my $dbh = $cxn->dbh(); |
584 | + # Very often cluster nodes are configured with matching server_id's |
585 | + # So in that case we'll use its incoming address as its unique identifier |
586 | + # Note: This relies on "seen_ids" being populated using the same strategy |
587 | + my $sql = $self->is_cluster_node($cxn) ? q{SELECT @@wsrep_node_incoming_address} : q{SELECT @@server_id}; |
588 | + PTDEBUG && _d($sql); |
589 | + my ($id) = $dbh->selectrow_array($sql); |
590 | + PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id); |
591 | + |
592 | + if ( ! $seen_ids->{$id}++ ) { |
593 | + push @trimmed_cxns, $cxn |
594 | + } |
595 | + else { |
596 | + PTDEBUG && _d("Removing ", $cxn->name, |
597 | + ", ID ", $id, ", because we've already seen it"); |
598 | + } |
599 | + } |
600 | + return \@trimmed_cxns; |
601 | } |
602 | |
603 | sub same_cluster { |
604 | |
605 | === modified file 't/pt-table-checksum/pxc.t' |
606 | --- t/pt-table-checksum/pxc.t 2013-04-12 15:58:10 +0000 |
607 | +++ t/pt-table-checksum/pxc.t 2014-11-05 22:22:52 +0000 |
608 | @@ -144,54 +144,89 @@ |
609 | "Node3 not changed" |
610 | ); |
611 | |
612 | -for my $args ( |
613 | - ["using recusion-method=dsn", '--recursion-method', "dsn=$node1_dsn,D=dsns,t=dsns"], |
614 | - ["using recursion-method=cluster", '--recursion-method', 'cluster'] |
615 | - ) |
616 | -{ |
617 | - my $test = shift @$args; |
618 | - |
619 | - $output = output( |
620 | - sub { pt_table_checksum::main(@args, |
621 | - @$args) |
622 | - }, |
623 | - stderr => 1, |
624 | - ); |
625 | - |
626 | - is( |
627 | - PerconaTest::count_checksum_results($output, 'errors'), |
628 | - 0, |
629 | - "1 diff: no errors ($test)" |
630 | - ); |
631 | - |
632 | - is( |
633 | - PerconaTest::count_checksum_results($output, 'skipped'), |
634 | - 0, |
635 | - "1 diff: no skips ($test)" |
636 | - ); |
637 | - |
638 | - is( |
639 | - PerconaTest::count_checksum_results($output, 'diffs'), |
640 | - 1, |
641 | - "1 diff: 1 diff ($test)" |
642 | - ) or diag($output); |
643 | - |
644 | - # 11-17T13:02:54 0 1 26 1 0 0.021 test.t |
645 | - like( |
646 | - $output, |
647 | - qr/^\S+\s+ # ts |
648 | - 0\s+ # errors |
649 | - 1\s+ # diffs |
650 | - 26\s+ # rows |
651 | - \d+\s+ # chunks |
652 | - 0\s+ # skipped |
653 | - \S+\s+ # time |
654 | - test.t$ # table |
655 | - /xm, |
656 | - "1 diff: it's in test.t ($test)" |
657 | - ); |
658 | +sub test_recursion_methods { |
659 | + my $same_ids = shift; |
660 | + |
661 | + my ($orig_id_1, $orig_id_2, $orig_id_3); |
662 | + |
663 | + if ($same_ids) { |
664 | + # save original values |
665 | + my $sql = 'SELECT @@server_id'; |
666 | + ($orig_id_1) = $node1->selectrow_array($sql); |
667 | + ($orig_id_2) = $node2->selectrow_array($sql); |
668 | + ($orig_id_3) = $node3->selectrow_array($sql); |
669 | + # set server_id value to 1 on all nodes |
670 | + $sql = 'SET GLOBAL server_id = 1'; |
671 | + $node1->do($sql); |
672 | + $node2->do($sql); |
673 | + $node3->do($sql); |
674 | + } |
675 | + |
676 | + for my $args ( |
677 | + ["using recusion-method=dsn", '--recursion-method', "dsn=$node1_dsn,D=dsns,t=dsns"], |
678 | + ["using recursion-method=cluster", '--recursion-method', 'cluster'] |
679 | + ) |
680 | + { |
681 | + my $test = shift @$args; |
682 | + $test = $same_ids ? $test.' - Nodes with different ids' : $test.' - Nodes with same ids'; |
683 | + |
684 | + $output = output( |
685 | + sub { pt_table_checksum::main(@args, |
686 | + @$args) |
687 | + }, |
688 | + stderr => 1, |
689 | + ); |
690 | + |
691 | + is( |
692 | + PerconaTest::count_checksum_results($output, 'errors'), |
693 | + 0, |
694 | + "1 diff: no errors ($test)" |
695 | + ); |
696 | + |
697 | + is( |
698 | + PerconaTest::count_checksum_results($output, 'skipped'), |
699 | + 0, |
700 | + "1 diff: no skips ($test)" |
701 | + ); |
702 | + |
703 | + is( |
704 | + PerconaTest::count_checksum_results($output, 'diffs'), |
705 | + 1, |
706 | + "1 diff: 1 diff ($test)" |
707 | + ) or diag($output); |
708 | + |
709 | + # 11-17T13:02:54 0 1 26 1 0 0.021 test.t |
710 | + like( |
711 | + $output, |
712 | + qr/^\S+\s+ # ts |
713 | + 0\s+ # errors |
714 | + 1\s+ # diffs |
715 | + 26\s+ # rows |
716 | + \d+\s+ # chunks |
717 | + 0\s+ # skipped |
718 | + \S+\s+ # time |
719 | + test.t$ # table |
720 | + /xm, |
721 | + "1 diff: it's in test.t ($test)" |
722 | + ); |
723 | + } |
724 | + |
725 | + if ($same_ids) { |
726 | + # reset server_id's to original values |
727 | + $node1->do("SET GLOBAL server_id = $orig_id_1"); |
728 | + $node2->do("SET GLOBAL server_id = $orig_id_2"); |
729 | + $node3->do("SET GLOBAL server_id = $orig_id_3"); |
730 | + } |
731 | + |
732 | } |
733 | |
734 | +# test recursion methods |
735 | +test_recursion_methods(0); |
736 | + |
737 | +# test recursion methods when all nodes have the same id |
738 | +test_recursion_methods(1); |
739 | + |
740 | + |
741 | # ############################################################################# |
742 | # cluster, node1 -> slave, run on node1 |
743 | # ############################################################################# |
744 | @@ -232,7 +267,7 @@ |
745 | # Wait for the slave to apply the binlogs from node1 (its master). |
746 | # Then change it so it's not consistent. |
747 | PerconaTest::wait_for_table($slave_dbh, 'test.t'); |
748 | - $sb->wait_for_slaves('cslave1'); |
749 | + $sb->wait_for_slaves(master=> 'node1', slave => 'cslave1'); |
750 | $slave_dbh->do("update test.t set c='zebra' where c='z'"); |
751 | |
752 | $output = output( |
I added on comment. If you agree, then great, feel free to change code. Otherwise, is good.