507.1.4
by Daniel Nichter
Stripping down pt-upgrade; work in progress. |
1 |
# This program is copyright 2013 Percona Ireland Ltd.
|
2 |
# Feedback and improvements are welcome.
|
|
3 |
#
|
|
4 |
# THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
|
|
5 |
# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
|
6 |
# MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
7 |
#
|
|
8 |
# This program is free software; you can redistribute it and/or modify it under
|
|
9 |
# the terms of the GNU General Public License as published by the Free Software
|
|
10 |
# Foundation, version 2; OR the Perl Artistic License. On UNIX and similar
|
|
11 |
# systems, you can issue `man perlgpl' or `man perlartistic' to read these
|
|
12 |
# licenses.
|
|
13 |
#
|
|
14 |
# You should have received a copy of the GNU General Public License along with
|
|
15 |
# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
|
16 |
# Place, Suite 330, Boston, MA 02111-1307 USA.
|
|
17 |
# ###########################################################################
|
|
18 |
# UpgradeResults package
|
|
19 |
# ###########################################################################
|
|
20 |
{
|
|
21 |
package UpgradeResults; |
|
22 |
||
507.1.7
by Daniel Nichter
First working scaffolding and fondation of host-to-host comparison. |
23 |
use strict; |
24 |
use warnings FATAL => 'all'; |
|
507.1.4
by Daniel Nichter
Stripping down pt-upgrade; work in progress. |
25 |
use English qw(-no_match_vars); |
26 |
use constant PTDEBUG => $ENV{PTDEBUG} || 0; |
|
27 |
||
507.1.30
by Daniel Nichter
eval the critical parts. Use specific exit codes. Add --run-time, --progress, --continue-on-error, and --defaults-file. Uncomment the version check call. Update the docs. |
28 |
use Data::Dumper; |
507.1.7
by Daniel Nichter
First working scaffolding and fondation of host-to-host comparison. |
29 |
use Digest::MD5 qw(md5_hex); |
30 |
||
31 |
use Lmo; |
|
32 |
||
33 |
has 'max_class_size' => ( |
|
34 |
is => 'ro', |
|
35 |
isa => 'Int', |
|
36 |
required => 1, |
|
37 |
);
|
|
38 |
||
39 |
has 'max_examples' => ( |
|
40 |
is => 'ro', |
|
41 |
isa => 'Int', |
|
42 |
required => 1, |
|
43 |
);
|
|
44 |
||
45 |
has 'classes' => ( |
|
507.1.4
by Daniel Nichter
Stripping down pt-upgrade; work in progress. |
46 |
is => 'rw', |
47 |
isa => 'HashRef', |
|
48 |
required => 0, |
|
49 |
default => sub { return {} }, |
|
50 |
);
|
|
51 |
||
507.1.7
by Daniel Nichter
First working scaffolding and fondation of host-to-host comparison. |
52 |
sub save_diffs { |
53 |
my ($self, %args) = @_; |
|
54 |
||
507.1.10
by Daniel Nichter
Test pt-upgrade host-to-host. Implement diff_query_times(). Export $test_diff from PerconaTest instead of doing diag() in no_diff(). |
55 |
my $event = $args{event}; |
56 |
my $query_time_diffs = $args{query_time_diffs}; |
|
57 |
my $warning_diffs = $args{warning_diffs}; |
|
58 |
my $row_diffs = $args{row_diffs}; |
|
507.1.7
by Daniel Nichter
First working scaffolding and fondation of host-to-host comparison. |
59 |
|
60 |
my $class = $self->class(event => $event); |
|
61 |
||
62 |
if ( my $query = $self->_can_save(event => $event, class => $class) ) { |
|
507.1.10
by Daniel Nichter
Test pt-upgrade host-to-host. Implement diff_query_times(). Export $test_diff from PerconaTest instead of doing diag() in no_diff(). |
63 |
if ( $query_time_diffs |
507.1.7
by Daniel Nichter
First working scaffolding and fondation of host-to-host comparison. |
64 |
&& scalar @{$class->{query_time_diffs}} < $self->max_examples ) { |
65 |
push @{$class->{query_time_diffs}}, [ |
|
66 |
$query, |
|
507.1.37
by Daniel Nichter
Functional test and fix query time diffs. |
67 |
$query_time_diffs, |
507.1.7
by Daniel Nichter
First working scaffolding and fondation of host-to-host comparison. |
68 |
];
|
69 |
}
|
|
70 |
||
507.1.8
by Daniel Nichter
Largely working, but un-tested, pt-upgrade 2.2 for host-to-host comparison. Add EventExecutor.pm. |
71 |
if ( $warning_diffs && @$warning_diffs |
507.1.7
by Daniel Nichter
First working scaffolding and fondation of host-to-host comparison. |
72 |
&& scalar @{$class->{warning_diffs}} < $self->max_examples ) { |
507.1.8
by Daniel Nichter
Largely working, but un-tested, pt-upgrade 2.2 for host-to-host comparison. Add EventExecutor.pm. |
73 |
push @{$class->{warning_diffs}}, [ |
507.1.7
by Daniel Nichter
First working scaffolding and fondation of host-to-host comparison. |
74 |
$query, |
75 |
$warning_diffs, |
|
76 |
];
|
|
77 |
}
|
|
78 |
||
507.1.8
by Daniel Nichter
Largely working, but un-tested, pt-upgrade 2.2 for host-to-host comparison. Add EventExecutor.pm. |
79 |
if ( $row_diffs && @$row_diffs |
507.1.7
by Daniel Nichter
First working scaffolding and fondation of host-to-host comparison. |
80 |
&& scalar @{$class->{row_diffs}} < $self->max_examples ) { |
81 |
push @{$class->{row_diffs}}, [ |
|
82 |
$query, |
|
83 |
$row_diffs, |
|
84 |
];
|
|
85 |
}
|
|
86 |
}
|
|
87 |
||
507.1.8
by Daniel Nichter
Largely working, but un-tested, pt-upgrade 2.2 for host-to-host comparison. Add EventExecutor.pm. |
88 |
$self->report_if_ready(class => $class); |
89 |
||
507.1.7
by Daniel Nichter
First working scaffolding and fondation of host-to-host comparison. |
90 |
return; |
91 |
}
|
|
92 |
||
93 |
sub save_error { |
|
94 |
my ($self, %args) = @_; |
|
95 |
||
96 |
my $event = $args{event}; |
|
97 |
my $error1 = $args{error1}; |
|
98 |
my $error2 = $args{error2}; |
|
99 |
||
100 |
my $class = $self->class(event => $event); |
|
101 |
||
102 |
if ( my $query = $self->_can_save(event => $event, class => $class) ) { |
|
103 |
if ( scalar @{$class->{errors}} < $self->max_examples ) { |
|
104 |
push @{$class->{errors}}, [ |
|
105 |
$query, |
|
106 |
$error1, |
|
107 |
$error2, |
|
108 |
];
|
|
109 |
}
|
|
110 |
}
|
|
111 |
||
507.1.8
by Daniel Nichter
Largely working, but un-tested, pt-upgrade 2.2 for host-to-host comparison. Add EventExecutor.pm. |
112 |
$self->report_if_ready(class => $class); |
113 |
||
114 |
return; |
|
115 |
}
|
|
116 |
||
117 |
sub save_failed_query { |
|
118 |
my ($self, %args) = @_; |
|
119 |
||
120 |
my $event = $args{event}; |
|
121 |
my $error1 = $args{error1}; |
|
122 |
my $error2 = $args{error2}; |
|
123 |
||
124 |
my $class = $self->class(event => $event); |
|
125 |
||
126 |
if ( my $query = $self->_can_save(event => $event, class => $class) ) { |
|
127 |
if ( scalar @{$class->{failures}} < $self->max_examples ) { |
|
128 |
push @{$class->{failures}}, [ |
|
129 |
$query, |
|
130 |
$error1, |
|
131 |
$error2, |
|
132 |
];
|
|
133 |
}
|
|
134 |
}
|
|
135 |
||
136 |
$self->report_if_ready(class => $class); |
|
137 |
||
507.1.7
by Daniel Nichter
First working scaffolding and fondation of host-to-host comparison. |
138 |
return; |
139 |
}
|
|
140 |
||
141 |
sub _can_save { |
|
142 |
my ($self, %args) = @_; |
|
143 |
my $event = $args{event}; |
|
144 |
my $class = $args{class}; |
|
145 |
my $query = $event->{arg}; |
|
507.1.8
by Daniel Nichter
Largely working, but un-tested, pt-upgrade 2.2 for host-to-host comparison. Add EventExecutor.pm. |
146 |
if ( $class->{reported} ) { |
147 |
PTDEBUG && _d('Class already reported'); |
|
148 |
return; |
|
149 |
}
|
|
150 |
$class->{total_queries}++; |
|
507.1.7
by Daniel Nichter
First working scaffolding and fondation of host-to-host comparison. |
151 |
if ( exists $class->{unique_queries}->{$query} |
152 |
|| scalar keys %{$class->{unique_queries}} < $self->max_class_size ) { |
|
153 |
$class->{unique_queries}->{$query}++; |
|
154 |
return $query; |
|
155 |
}
|
|
156 |
PTDEBUG && _d('Too many queries in class, discarding', $query); |
|
157 |
$class->{discarded}++; |
|
158 |
return; |
|
159 |
}
|
|
160 |
||
161 |
sub class { |
|
162 |
my ($self, %args) = @_; |
|
163 |
my $event = $args{event}; |
|
164 |
||
165 |
my $id = uc(substr(md5_hex($event->{fingerprint}), -16)); |
|
166 |
my $classes = $self->classes; |
|
167 |
my $class = $classes->{$id}; |
|
168 |
if ( !$class ) { |
|
169 |
$class = $self->_new_class( |
|
170 |
id => $id, |
|
171 |
event => $event, |
|
172 |
);
|
|
173 |
$classes->{$id} = $class; |
|
174 |
}
|
|
175 |
return $class; |
|
176 |
}
|
|
177 |
||
178 |
sub _new_class { |
|
179 |
my ($self, %args) = @_; |
|
180 |
my $id = $args{id}; |
|
181 |
my $event = $args{event}; |
|
182 |
PTDEBUG && _d('New query class:', $id, $event->{fingerprint}); |
|
183 |
my $class = { |
|
184 |
id => $id, |
|
185 |
fingerprint => $event->{fingerprint}, |
|
186 |
discarded => 0, |
|
187 |
unique_queries => { |
|
188 |
$event->{arg} => 0, |
|
189 |
},
|
|
507.1.8
by Daniel Nichter
Largely working, but un-tested, pt-upgrade 2.2 for host-to-host comparison. Add EventExecutor.pm. |
190 |
failures => [], # error on both hosts |
191 |
errors => [], # error on one host |
|
192 |
query_time_diffs => [], |
|
507.1.7
by Daniel Nichter
First working scaffolding and fondation of host-to-host comparison. |
193 |
warning_diffs => [], |
194 |
row_diffs => [], |
|
195 |
};
|
|
196 |
return $class; |
|
197 |
}
|
|
198 |
||
507.1.8
by Daniel Nichter
Largely working, but un-tested, pt-upgrade 2.2 for host-to-host comparison. Add EventExecutor.pm. |
199 |
sub report_unreported_classes { |
200 |
my ($self) = @_; |
|
507.1.30
by Daniel Nichter
eval the critical parts. Use specific exit codes. Add --run-time, --progress, --continue-on-error, and --defaults-file. Uncomment the version check call. Update the docs. |
201 |
my $success = 1; |
507.1.8
by Daniel Nichter
Largely working, but un-tested, pt-upgrade 2.2 for host-to-host comparison. Add EventExecutor.pm. |
202 |
my $classes = $self->classes; |
203 |
foreach my $id ( sort keys %$classes ) { |
|
507.1.30
by Daniel Nichter
eval the critical parts. Use specific exit codes. Add --run-time, --progress, --continue-on-error, and --defaults-file. Uncomment the version check call. Update the docs. |
204 |
eval { |
205 |
my $class = $classes->{$id}; |
|
206 |
my $reason; |
|
207 |
if ( !scalar @{$class->{failures}} ) { |
|
208 |
$reason = 'it has diffs'; |
|
209 |
}
|
|
210 |
elsif ( scalar @{$class->{errors}} |
|
211 |
|| scalar @{$class->{query_time_diffs}} |
|
212 |
|| scalar @{$class->{warning_diffs}} |
|
213 |
|| scalar @{$class->{row_diffs}} ) { |
|
214 |
$reason = 'it has SQL errors and diffs'; |
|
215 |
}
|
|
216 |
else { |
|
217 |
$reason = 'it has SQL errors' |
|
218 |
}
|
|
219 |
$self->report_class( |
|
220 |
class => $class, |
|
221 |
reasons => ["$reason, but hasn't been reported yet"], |
|
222 |
);
|
|
223 |
$class = { reported => 1 }; |
|
224 |
};
|
|
225 |
if ( $EVAL_ERROR ) { |
|
226 |
$success = 1; |
|
227 |
warn Dumper($classes->{$id}); |
|
228 |
warn "Error reporting query class $id: $EVAL_ERROR"; |
|
229 |
}
|
|
507.1.8
by Daniel Nichter
Largely working, but un-tested, pt-upgrade 2.2 for host-to-host comparison. Add EventExecutor.pm. |
230 |
}
|
507.1.30
by Daniel Nichter
eval the critical parts. Use specific exit codes. Add --run-time, --progress, --continue-on-error, and --defaults-file. Uncomment the version check call. Update the docs. |
231 |
return $success; |
507.1.8
by Daniel Nichter
Largely working, but un-tested, pt-upgrade 2.2 for host-to-host comparison. Add EventExecutor.pm. |
232 |
}
|
233 |
||
234 |
sub report_if_ready { |
|
235 |
my ($self, %args) = @_; |
|
236 |
my $class = $args{class}; |
|
237 |
||
238 |
my $max_examples = $self->max_class_size; |
|
239 |
my @report_reasons; |
|
240 |
||
241 |
if ( scalar keys %{$class->{unique_queries}} >= $self->max_class_size ) { |
|
242 |
push @report_reasons, "it's full (--max-class-size)"; |
|
243 |
}
|
|
244 |
||
245 |
if ( scalar @{$class->{query_time_diffs}} >= $max_examples ) { |
|
246 |
push @report_reasons, "there are $max_examples query diffs"; |
|
247 |
}
|
|
248 |
||
249 |
if ( scalar @{$class->{warning_diffs}} >= $max_examples ) { |
|
250 |
push @report_reasons, "there are $max_examples warning diffs"; |
|
251 |
}
|
|
252 |
||
253 |
if ( scalar @{$class->{row_diffs}} >= $self->max_examples ) { |
|
254 |
push @report_reasons, "there are $max_examples row diffs"; |
|
255 |
}
|
|
256 |
||
257 |
if ( scalar @{$class->{errors}} >= $self->max_examples ) { |
|
258 |
push @report_reasons, "there are $max_examples query errors"; |
|
259 |
}
|
|
260 |
||
261 |
if ( scalar @{$class->{failures}} >= $self->max_examples ) { |
|
262 |
push @report_reasons, "there are $max_examples failed queries"; |
|
263 |
}
|
|
264 |
||
265 |
if ( scalar @report_reasons ) { |
|
266 |
PTDEBUG && _d('Reporting class because', @report_reasons); |
|
267 |
$self->report_class( |
|
268 |
class => $class, |
|
269 |
reasons => \@report_reasons, |
|
270 |
);
|
|
271 |
$class = { reported => 1 }; |
|
272 |
}
|
|
273 |
||
274 |
return; |
|
275 |
}
|
|
276 |
||
277 |
sub report_class { |
|
278 |
my ($self, %args) = @_; |
|
279 |
my $class = $args{class}; |
|
280 |
my $reasons = $args{reasons}; |
|
281 |
||
282 |
PTDEBUG && _d('Reporting class', $class->{id}, $class->{fingerprint}); |
|
283 |
||
284 |
$self->_print_class_header( |
|
285 |
class => $class, |
|
286 |
reasons => $reasons, |
|
287 |
);
|
|
288 |
||
289 |
if ( scalar @{$class->{failures}} ) { |
|
290 |
$self->_print_failures( |
|
291 |
failures => $class->{failures}, |
|
292 |
);
|
|
293 |
}
|
|
294 |
||
295 |
if ( scalar @{$class->{errors}} ) { |
|
507.1.10
by Daniel Nichter
Test pt-upgrade host-to-host. Implement diff_query_times(). Export $test_diff from PerconaTest instead of doing diag() in no_diff(). |
296 |
$self->_print_errors( |
297 |
errors => $class->{errors}, |
|
507.1.8
by Daniel Nichter
Largely working, but un-tested, pt-upgrade 2.2 for host-to-host comparison. Add EventExecutor.pm. |
298 |
);
|
299 |
}
|
|
300 |
||
301 |
if ( scalar @{$class->{query_time_diffs}} ) { |
|
302 |
$self->_print_diffs( |
|
507.1.10
by Daniel Nichter
Test pt-upgrade host-to-host. Implement diff_query_times(). Export $test_diff from PerconaTest instead of doing diag() in no_diff(). |
303 |
diffs => $class->{query_time_diffs}, |
304 |
name => 'Query time', |
|
305 |
formatter => \&_format_query_times, |
|
507.1.8
by Daniel Nichter
Largely working, but un-tested, pt-upgrade 2.2 for host-to-host comparison. Add EventExecutor.pm. |
306 |
);
|
307 |
}
|
|
308 |
||
309 |
if ( scalar @{$class->{warning_diffs}} ) { |
|
507.1.10
by Daniel Nichter
Test pt-upgrade host-to-host. Implement diff_query_times(). Export $test_diff from PerconaTest instead of doing diag() in no_diff(). |
310 |
$self->_print_diffs( |
507.1.8
by Daniel Nichter
Largely working, but un-tested, pt-upgrade 2.2 for host-to-host comparison. Add EventExecutor.pm. |
311 |
diffs => $class->{warning_diffs}, |
312 |
name => 'Warning', |
|
313 |
formatter => \&_format_warnings, |
|
314 |
);
|
|
315 |
}
|
|
316 |
||
317 |
if ( scalar @{$class->{row_diffs}} ) { |
|
507.1.10
by Daniel Nichter
Test pt-upgrade host-to-host. Implement diff_query_times(). Export $test_diff from PerconaTest instead of doing diag() in no_diff(). |
318 |
$self->_print_diffs( |
507.1.8
by Daniel Nichter
Largely working, but un-tested, pt-upgrade 2.2 for host-to-host comparison. Add EventExecutor.pm. |
319 |
diffs => $class->{row_diffs}, |
320 |
name => 'Row', |
|
321 |
formatter => \&_format_rows, |
|
322 |
);
|
|
323 |
}
|
|
324 |
||
325 |
return; |
|
326 |
}
|
|
327 |
||
328 |
# This is a terrible hack due to two things: 1) our own util/update-modules
|
|
329 |
# things lines starting with multiple # are package headers; 2) the same
|
|
330 |
# util strips all comment lines start with #. So if we use the literal #
|
|
331 |
# for this header, util/update-modules will remove them from the code.
|
|
332 |
# *facepalm*
|
|
333 |
my $class_header_format = <<'EOF'; |
|
507.1.21
by Daniel Nichter
Implement all MySQL log parsers. Add report sections, and --report. |
334 |
|
507.1.8
by Daniel Nichter
Largely working, but un-tested, pt-upgrade 2.2 for host-to-host comparison. Add EventExecutor.pm. |
335 |
%s
|
336 |
%s
|
|
337 |
%s
|
|
338 |
||
339 |
Reporting class because %s.
|
|
340 |
||
341 |
Total queries %s
|
|
342 |
Unique queries %s
|
|
343 |
Discarded queries %s
|
|
344 |
||
345 |
%s
|
|
346 |
EOF
|
|
347 |
||
348 |
sub _print_class_header { |
|
349 |
my ($self, %args) = @_; |
|
350 |
my $class = $args{class}; |
|
351 |
my @reasons = @{ $args{reasons} }; |
|
352 |
||
353 |
my $unique_queries = do { |
|
354 |
my $i = 0; |
|
355 |
map { $i += $_ } values %{$class->{unique_queries}}; |
|
356 |
$i; |
|
357 |
};
|
|
358 |
PTDEBUG && _d('Unique queries:', $unique_queries); |
|
359 |
||
360 |
my $reasons; |
|
361 |
if ( scalar @reasons > 1 ) { |
|
362 |
$reasons = join(', ', @reasons[0..($#reasons - 1)]) |
|
363 |
. ', and ' . $reasons[-1]; |
|
364 |
}
|
|
365 |
else { |
|
366 |
$reasons = $reasons[0]; |
|
367 |
}
|
|
368 |
PTDEBUG && _d('Reasons:', $reasons); |
|
369 |
||
370 |
printf $class_header_format, |
|
371 |
('#' x 72), |
|
372 |
('# Query class ' . ($class->{id} || '?')), |
|
373 |
('#' x 72), |
|
374 |
($reasons || '?'), |
|
375 |
(defined $class->{total_queries} ? $class->{total_queries} : '?'), |
|
376 |
(defined $unique_queries ? $unique_queries : '?'), |
|
377 |
(defined $class->{discarded} ? $class->{discarded} : '?'), |
|
378 |
($class->{fingerprint} || '?'); |
|
379 |
||
380 |
return; |
|
381 |
}
|
|
382 |
||
383 |
sub _print_diff_header { |
|
384 |
my ($self, %args) = @_; |
|
385 |
my $name = $args{name} || '?'; |
|
386 |
my $count = $args{count} || '?'; |
|
387 |
print "\n##\n## $name diffs: $count\n##\n"; |
|
388 |
return; |
|
389 |
}
|
|
390 |
||
391 |
sub _print_failures { |
|
392 |
my ($self, %args) = @_; |
|
393 |
my $failures = $args{failures}; |
|
394 |
||
395 |
my $n_failures = scalar @$failures; |
|
396 |
||
397 |
print "\n##\n## SQL errors: $n_failures\n##\n"; |
|
398 |
||
399 |
my $failno = 1; |
|
400 |
foreach my $failure ( @$failures ) { |
|
401 |
print "\n-- $failno.\n"; |
|
402 |
if ( ($failure->[1] || '') eq ($failure->[2] || '') ) { |
|
403 |
printf "\nOn both hosts:\n\n" . ($failure->[1] || '') . "\n"; |
|
404 |
}
|
|
405 |
else { |
|
406 |
printf "\n%s\n\nvs.\n\n%s\n", |
|
407 |
($failure->[1] || ''), |
|
408 |
($failure->[2] || ''); |
|
409 |
}
|
|
410 |
print "\n" . ($failure->[0] || '?') . "\n"; |
|
411 |
$failno++; |
|
412 |
}
|
|
413 |
||
414 |
return; |
|
415 |
}
|
|
416 |
||
507.1.10
by Daniel Nichter
Test pt-upgrade host-to-host. Implement diff_query_times(). Export $test_diff from PerconaTest instead of doing diag() in no_diff(). |
417 |
sub _print_errors { |
418 |
my ($self, %args) = @_; |
|
419 |
my $errors = $args{errors}; |
|
420 |
||
421 |
$self->_print_diff_header( |
|
422 |
name => 'Query errors', |
|
423 |
count => scalar @$errors, |
|
424 |
);
|
|
425 |
||
426 |
my $fmt = "\n%s\n\nvs.\n\n%s\n"; |
|
427 |
||
428 |
my $errorno = 1; |
|
429 |
foreach my $error ( @$errors ) { |
|
430 |
print "\n-- $errorno.\n"; |
|
431 |
printf $fmt, |
|
432 |
($error->[1] || 'No error'), |
|
433 |
($error->[2] || 'No error'); |
|
434 |
print "\n" . ($error->[0] || '?') . "\n"; |
|
435 |
$errorno++; |
|
436 |
}
|
|
437 |
||
438 |
return; |
|
439 |
}
|
|
440 |
||
441 |
sub _print_diffs { |
|
442 |
my ($self, %args) = @_; |
|
443 |
my $diffs = $args{diffs}; |
|
444 |
my $name = $args{name}; |
|
445 |
my $formatter = $args{formatter}; |
|
446 |
||
447 |
$self->_print_diff_header( |
|
448 |
name => $name, |
|
449 |
count => scalar @$diffs, |
|
450 |
);
|
|
451 |
||
452 |
my $diffno = 1; |
|
453 |
foreach my $diff ( @$diffs ) { |
|
561
by Daniel Nichter
Fix query time diff formatting in pt-upgrade. |
454 |
my $query = $diff->[0]; |
455 |
my $diff_vals = $diff->[1]; |
|
507.1.10
by Daniel Nichter
Test pt-upgrade host-to-host. Implement diff_query_times(). Export $test_diff from PerconaTest instead of doing diag() in no_diff(). |
456 |
print "\n-- $diffno.\n"; |
561
by Daniel Nichter
Fix query time diff formatting in pt-upgrade. |
457 |
my $formatted_diff_vals = $formatter->($diff_vals); |
458 |
print $formatted_diff_vals || '?'; |
|
459 |
print "\n" . ($query || '?') . "\n"; |
|
507.1.10
by Daniel Nichter
Test pt-upgrade host-to-host. Implement diff_query_times(). Export $test_diff from PerconaTest instead of doing diag() in no_diff(). |
460 |
$diffno++; |
461 |
}
|
|
462 |
||
463 |
return; |
|
464 |
}
|
|
465 |
||
507.1.8
by Daniel Nichter
Largely working, but un-tested, pt-upgrade 2.2 for host-to-host comparison. Add EventExecutor.pm. |
466 |
my $warning_format = <<'EOL'; |
467 |
Code: %s
|
|
468 |
Level: %s
|
|
469 |
Message: %s
|
|
470 |
EOL
|
|
471 |
||
472 |
sub _format_warnings { |
|
473 |
my ($warnings) = @_; |
|
474 |
return unless $warnings && @$warnings; |
|
475 |
my @warnings; |
|
476 |
foreach my $warn ( @$warnings ) { |
|
477 |
my $code = $warn->[0]; |
|
478 |
my $warn1 = $warn->[1]; |
|
479 |
my $warn2 = $warn->[2]; |
|
480 |
my $host1_warn |
|
481 |
= $warn1 ? sprintf $warning_format, |
|
482 |
($warn1->{Code} || $warn1->{code} || '?'), |
|
483 |
($warn1->{Level} || $warn1->{level} || '?'), |
|
484 |
($warn1->{Message} || $warn1->{message} || '?') |
|
485 |
: "No warning $code\n"; |
|
486 |
my $host2_warn |
|
487 |
= $warn2 ? sprintf $warning_format, |
|
488 |
($warn2->{Code} || $warn2->{code} || '?'), |
|
489 |
($warn2->{Level} || $warn2->{level} || '?'), |
|
490 |
($warn2->{Message} || $warn2->{message} || '?') |
|
491 |
: "No warning $code\n"; |
|
492 |
||
493 |
my $warning = sprintf "\n%s\nvs.\n\n%s", $host1_warn, $host2_warn; |
|
494 |
push @warnings, $warning; |
|
495 |
}
|
|
496 |
return join("\n\n", @warnings); |
|
497 |
}
|
|
498 |
||
499 |
sub _format_rows { |
|
500 |
my ($rows) = @_; |
|
501 |
return unless $rows && @$rows; |
|
502 |
my @diffs; |
|
503 |
foreach my $row ( @$rows ) { |
|
507.1.10
by Daniel Nichter
Test pt-upgrade host-to-host. Implement diff_query_times(). Export $test_diff from PerconaTest instead of doing diag() in no_diff(). |
504 |
if ( !defined $row->[1] || !defined $row->[2] ) { |
505 |
# missing rows
|
|
506 |
my $n_missing_rows = $row->[0]; |
|
507 |
my $missing_rows = $row->[1] || $row->[2]; |
|
508 |
my $dir = !defined $row->[1] ? '>' : '<'; |
|
509 |
my $diff |
|
510 |
= '@ first ' . scalar @$missing_rows |
|
511 |
. ' of ' . ($n_missing_rows || '?') . " missing rows\n"; |
|
512 |
foreach my $row ( @$missing_rows ) { |
|
513 |
$diff .= "$dir " |
|
514 |
. join(',', map {defined $_ ? $_ : 'NULL'} @$row) . "\n"; |
|
515 |
}
|
|
516 |
push @diffs, $diff; |
|
517 |
}
|
|
518 |
else { |
|
519 |
# diff rows
|
|
520 |
my $rowno = $row->[0]; |
|
521 |
my $cols1 = $row->[1]; |
|
522 |
my $cols2 = $row->[2]; |
|
523 |
my $diff |
|
524 |
= "@ row " . ($rowno || '?') . "\n" |
|
525 |
. '< ' . join(',', map {defined $_ ? $_ : 'NULL'} @$cols1) . "\n" |
|
526 |
. '> ' . join(',', map {defined $_ ? $_ : 'NULL'} @$cols2) . "\n"; |
|
527 |
push @diffs, $diff; |
|
528 |
}
|
|
507.1.8
by Daniel Nichter
Largely working, but un-tested, pt-upgrade 2.2 for host-to-host comparison. Add EventExecutor.pm. |
529 |
}
|
530 |
return "\n" . join("\n", @diffs); |
|
531 |
}
|
|
532 |
||
507.1.10
by Daniel Nichter
Test pt-upgrade host-to-host. Implement diff_query_times(). Export $test_diff from PerconaTest instead of doing diag() in no_diff(). |
533 |
sub _format_query_times { |
534 |
my ($query_times) = @_; |
|
507.1.36
by Daniel Nichter
Fix and test UpgradeResults::format_query_times001(). |
535 |
return unless $query_times; |
561
by Daniel Nichter
Fix query time diff formatting in pt-upgrade. |
536 |
my $fmt = "\n%s vs. %s seconds (%sx increase)\n"; |
507.1.36
by Daniel Nichter
Fix and test UpgradeResults::format_query_times001(). |
537 |
my $diff = sprintf $fmt, |
561
by Daniel Nichter
Fix query time diff formatting in pt-upgrade. |
538 |
($query_times->[0] || '?'), |
507.1.36
by Daniel Nichter
Fix and test UpgradeResults::format_query_times001(). |
539 |
($query_times->[1] || '?'), |
561
by Daniel Nichter
Fix query time diff formatting in pt-upgrade. |
540 |
($query_times->[2] || '?'); |
507.1.36
by Daniel Nichter
Fix and test UpgradeResults::format_query_times001(). |
541 |
return $diff; |
507.1.10
by Daniel Nichter
Test pt-upgrade host-to-host. Implement diff_query_times(). Export $test_diff from PerconaTest instead of doing diag() in no_diff(). |
542 |
}
|
543 |
||
507.1.7
by Daniel Nichter
First working scaffolding and fondation of host-to-host comparison. |
544 |
sub _d { |
545 |
my ($package, undef, $line) = caller 0; |
|
546 |
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; } |
|
547 |
map { defined $_ ? $_ : 'undef' } |
|
548 |
@_; |
|
549 |
print STDERR "# $package:$line $PID ", join(' ', @_), "\n"; |
|
550 |
}
|
|
551 |
||
552 |
no Lmo; |
|
507.1.4
by Daniel Nichter
Stripping down pt-upgrade; work in progress. |
553 |
1; |
554 |
}
|
|
555 |
# ###########################################################################
|
|
556 |
# End UpgradeResults package
|
|
557 |
# ###########################################################################
|