Merge lp:~percona-toolkit-dev/percona-toolkit/fix-pqd-distill-bugs into lp:percona-toolkit/2.2
- fix-pqd-distill-bugs
- Merge into 2.2
Proposed by
Daniel Nichter
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Merged at revision: | 585 | ||||||||
Proposed branch: | lp:~percona-toolkit-dev/percona-toolkit/fix-pqd-distill-bugs | ||||||||
Merge into: | lp:percona-toolkit/2.2 | ||||||||
Diff against target: |
1655 lines (+779/-514) 18 files modified
bin/pt-query-digest (+559/-490) lib/HTTP/Micro.pm (+1/-1) lib/QueryParser.pm (+16/-4) lib/QueryRewriter.pm (+10/-0) lib/VersionCheck.pm (+2/-2) t/lib/QueryParser.t (+6/-0) t/lib/QueryRewriter.t (+28/-0) t/lib/samples/slowlogs/slow051.txt (+2/-2) t/lib/samples/slowlogs/slow058.txt (+24/-0) t/pt-query-digest/binlog_analyses.t (+2/-2) t/pt-query-digest/daemon.t (+2/-2) t/pt-query-digest/json.t (+1/-1) t/pt-query-digest/samples/binlog002.txt (+4/-1) t/pt-query-digest/samples/empty_report.txt (+2/-0) t/pt-query-digest/samples/slow051.txt (+5/-5) t/pt-query-digest/samples/slow058.txt (+94/-0) t/pt-query-digest/slowlog_analyses.t (+20/-3) util/update-modules (+1/-1) |
||||||||
To merge this branch: | bzr merge lp:~percona-toolkit-dev/percona-toolkit/fix-pqd-distill-bugs | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Daniel Nichter | Approve | ||
Review via email: mp+178434@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
- 596. By Daniel Nichter
-
Use new Daemon API.
- 597. By Daniel Nichter
-
Fix empty json report test.
- 598. By Daniel Nichter
-
Update t/pt-query-
digest/ binlog_ analyses. t now that INSERT without INTO parses correctly. - 599. By Daniel Nichter
-
Fix version check in pqd by calling HTTP::Micro, not old HTTPMicro.
- 600. By Daniel Nichter
-
Update/fix binlog_analyses.t for real.
Revision history for this message
Daniel Nichter (daniel-nichter) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'bin/pt-query-digest' | |||
2 | --- bin/pt-query-digest 2013-07-17 19:41:00 +0000 | |||
3 | +++ bin/pt-query-digest 2013-08-03 19:47:33 +0000 | |||
4 | @@ -48,7 +48,7 @@ | |||
5 | 48 | FileIterator | 48 | FileIterator |
6 | 49 | Runtime | 49 | Runtime |
7 | 50 | Pipeline | 50 | Pipeline |
9 | 51 | HTTPMicro | 51 | HTTP::Micro |
10 | 52 | VersionCheck | 52 | VersionCheck |
11 | 53 | )); | 53 | )); |
12 | 54 | } | 54 | } |
13 | @@ -2928,6 +2928,13 @@ | |||
14 | 2928 | $query =~ m/\A\s*UNLOCK TABLES/i && return "UNLOCK"; | 2928 | $query =~ m/\A\s*UNLOCK TABLES/i && return "UNLOCK"; |
15 | 2929 | $query =~ m/\A\s*xa\s+(\S+)/i && return "XA_$1"; | 2929 | $query =~ m/\A\s*xa\s+(\S+)/i && return "XA_$1"; |
16 | 2930 | 2930 | ||
17 | 2931 | if ( $query =~ m/\A\s*LOAD/i ) { | ||
18 | 2932 | my ($tbl) = $query =~ m/INTO TABLE\s+(\S+)/i; | ||
19 | 2933 | $tbl ||= ''; | ||
20 | 2934 | $tbl =~ s/`//g; | ||
21 | 2935 | return "LOAD DATA $tbl"; | ||
22 | 2936 | } | ||
23 | 2937 | |||
24 | 2931 | if ( $query =~ m/\Aadministrator command:/ ) { | 2938 | if ( $query =~ m/\Aadministrator command:/ ) { |
25 | 2932 | $query =~ s/administrator command:/ADMIN/; | 2939 | $query =~ s/administrator command:/ADMIN/; |
26 | 2933 | $query = uc $query; | 2940 | $query = uc $query; |
27 | @@ -3021,6 +3028,9 @@ | |||
28 | 3021 | map { $verbs =~ s/$_/$alias_for{$_}/ } keys %alias_for; | 3028 | map { $verbs =~ s/$_/$alias_for{$_}/ } keys %alias_for; |
29 | 3022 | $query = $verbs; | 3029 | $query = $verbs; |
30 | 3023 | } | 3030 | } |
31 | 3031 | elsif ( $verbs && $verbs =~ m/^LOAD DATA/ ) { | ||
32 | 3032 | return $verbs; | ||
33 | 3033 | } | ||
34 | 3024 | else { | 3034 | else { |
35 | 3025 | my @tables = $self->__distill_tables($query, $table, %args); | 3035 | my @tables = $self->__distill_tables($query, $table, %args); |
36 | 3026 | $query = join(q{ }, $verbs, @tables); | 3036 | $query = join(q{ }, $verbs, @tables); |
37 | @@ -8259,7 +8269,7 @@ | |||
38 | 8259 | return ($tbl); | 8269 | return ($tbl); |
39 | 8260 | } | 8270 | } |
40 | 8261 | 8271 | ||
42 | 8262 | $query =~ s/ (?:LOW_PRIORITY|IGNORE|STRAIGHT_JOIN)//ig; | 8272 | $query =~ s/(?:LOW_PRIORITY|IGNORE|STRAIGHT_JOIN|DELAYED)\s+/ /ig; |
43 | 8263 | 8273 | ||
44 | 8264 | if ( $query =~ s/^\s*LOCK TABLES\s+//i ) { | 8274 | if ( $query =~ s/^\s*LOCK TABLES\s+//i ) { |
45 | 8265 | PTDEBUG && _d('Special table type: LOCK TABLES'); | 8275 | PTDEBUG && _d('Special table type: LOCK TABLES'); |
46 | @@ -8268,9 +8278,18 @@ | |||
47 | 8268 | $query = "FROM $query"; | 8278 | $query = "FROM $query"; |
48 | 8269 | } | 8279 | } |
49 | 8270 | 8280 | ||
53 | 8271 | $query =~ s/\\["']//g; # quoted strings | 8281 | $query =~ s/\\["']//g; # quoted strings |
54 | 8272 | $query =~ s/".*?"/?/sg; # quoted strings | 8282 | $query =~ s/".*?"/?/sg; # quoted strings |
55 | 8273 | $query =~ s/'.*?'/?/sg; # quoted strings | 8283 | $query =~ s/'.*?'/?/sg; # quoted strings |
56 | 8284 | |||
57 | 8285 | if ( $query =~ m/\A\s*(?:INSERT|REPLACE)(?!\s+INTO)/i ) { | ||
58 | 8286 | $query =~ s/\A\s*((?:INSERT|REPLACE))\s+/$1 INTO /i; | ||
59 | 8287 | } | ||
60 | 8288 | |||
61 | 8289 | if ( $query =~ m/\A\s*LOAD DATA/i ) { | ||
62 | 8290 | my ($tbl) = $query =~ m/INTO TABLE\s+(\S+)/i; | ||
63 | 8291 | return $tbl; | ||
64 | 8292 | } | ||
65 | 8274 | 8293 | ||
66 | 8275 | my @tables; | 8294 | my @tables; |
67 | 8276 | foreach my $tbls ( $query =~ m/$tbl_regex/gio ) { | 8295 | foreach my $tbls ( $query =~ m/$tbl_regex/gio ) { |
68 | @@ -9253,157 +9272,214 @@ | |||
69 | 9253 | use strict; | 9272 | use strict; |
70 | 9254 | use warnings FATAL => 'all'; | 9273 | use warnings FATAL => 'all'; |
71 | 9255 | use English qw(-no_match_vars); | 9274 | use English qw(-no_match_vars); |
72 | 9275 | |||
73 | 9256 | use constant PTDEBUG => $ENV{PTDEBUG} || 0; | 9276 | use constant PTDEBUG => $ENV{PTDEBUG} || 0; |
74 | 9257 | 9277 | ||
75 | 9258 | use POSIX qw(setsid); | 9278 | use POSIX qw(setsid); |
76 | 9279 | use Fcntl qw(:DEFAULT); | ||
77 | 9259 | 9280 | ||
78 | 9260 | sub new { | 9281 | sub new { |
84 | 9261 | my ( $class, %args ) = @_; | 9282 | my ($class, %args) = @_; |
80 | 9262 | foreach my $arg ( qw(o) ) { | ||
81 | 9263 | die "I need a $arg argument" unless $args{$arg}; | ||
82 | 9264 | } | ||
83 | 9265 | my $o = $args{o}; | ||
85 | 9266 | my $self = { | 9283 | my $self = { |
89 | 9267 | o => $o, | 9284 | log_file => $args{log_file}, |
90 | 9268 | log_file => $o->has('log') ? $o->get('log') : undef, | 9285 | pid_file => $args{pid_file}, |
91 | 9269 | PID_file => $o->has('pid') ? $o->get('pid') : undef, | 9286 | daemonize => $args{daemonize}, |
92 | 9287 | force_log_file => $args{force_log_file}, | ||
93 | 9288 | parent_exit => $args{parent_exit}, | ||
94 | 9289 | pid_file_owner => 0, | ||
95 | 9270 | }; | 9290 | }; |
96 | 9271 | |||
97 | 9272 | check_PID_file(undef, $self->{PID_file}); | ||
98 | 9273 | |||
99 | 9274 | PTDEBUG && _d('Daemonized child will log to', $self->{log_file}); | ||
100 | 9275 | return bless $self, $class; | 9291 | return bless $self, $class; |
101 | 9276 | } | 9292 | } |
102 | 9277 | 9293 | ||
143 | 9278 | sub daemonize { | 9294 | sub run { |
144 | 9279 | my ( $self ) = @_; | 9295 | my ($self) = @_; |
145 | 9280 | 9296 | ||
146 | 9281 | PTDEBUG && _d('About to fork and daemonize'); | 9297 | my $daemonize = $self->{daemonize}; |
147 | 9282 | defined (my $pid = fork()) or die "Cannot fork: $OS_ERROR"; | 9298 | my $pid_file = $self->{pid_file}; |
148 | 9283 | if ( $pid ) { | 9299 | my $log_file = $self->{log_file}; |
149 | 9284 | PTDEBUG && _d('Parent PID', $PID, 'exiting after forking child PID',$pid); | 9300 | my $force_log_file = $self->{force_log_file}; |
150 | 9285 | exit; | 9301 | my $parent_exit = $self->{parent_exit}; |
151 | 9286 | } | 9302 | |
152 | 9287 | 9303 | PTDEBUG && _d('Starting daemon'); | |
153 | 9288 | PTDEBUG && _d('Daemonizing child PID', $PID); | 9304 | |
154 | 9289 | $self->{PID_owner} = $PID; | 9305 | if ( $pid_file ) { |
155 | 9290 | $self->{child} = 1; | 9306 | eval { |
156 | 9291 | 9307 | $self->_make_pid_file( | |
157 | 9292 | POSIX::setsid() or die "Cannot start a new session: $OS_ERROR"; | 9308 | pid => $PID, # parent's pid |
158 | 9293 | chdir '/' or die "Cannot chdir to /: $OS_ERROR"; | 9309 | pid_file => $pid_file, |
159 | 9294 | 9310 | ); | |
160 | 9295 | $self->_make_PID_file(); | 9311 | }; |
161 | 9296 | 9312 | die "$EVAL_ERROR\n" if $EVAL_ERROR; | |
162 | 9297 | $OUTPUT_AUTOFLUSH = 1; | 9313 | if ( !$daemonize ) { |
163 | 9298 | 9314 | $self->{pid_file_owner} = $PID; # parent's pid | |
164 | 9299 | PTDEBUG && _d('Redirecting STDIN to /dev/null'); | 9315 | } |
165 | 9300 | close STDIN; | 9316 | } |
166 | 9301 | open STDIN, '/dev/null' | 9317 | |
167 | 9302 | or die "Cannot reopen STDIN to /dev/null: $OS_ERROR"; | 9318 | if ( $daemonize ) { |
168 | 9303 | 9319 | defined (my $child_pid = fork()) or die "Cannot fork: $OS_ERROR"; | |
169 | 9304 | if ( $self->{log_file} ) { | 9320 | if ( $child_pid ) { |
170 | 9305 | PTDEBUG && _d('Redirecting STDOUT and STDERR to', $self->{log_file}); | 9321 | PTDEBUG && _d('Forked child', $child_pid); |
171 | 9306 | close STDOUT; | 9322 | $parent_exit->($child_pid) if $parent_exit; |
172 | 9307 | open STDOUT, '>>', $self->{log_file} | 9323 | exit 0; |
173 | 9308 | or die "Cannot open log file $self->{log_file}: $OS_ERROR"; | 9324 | } |
174 | 9309 | 9325 | ||
175 | 9310 | close STDERR; | 9326 | POSIX::setsid() or die "Cannot start a new session: $OS_ERROR"; |
176 | 9311 | open STDERR, ">&STDOUT" | 9327 | chdir '/' or die "Cannot chdir to /: $OS_ERROR"; |
177 | 9312 | or die "Cannot dupe STDERR to STDOUT: $OS_ERROR"; | 9328 | |
178 | 9313 | } | 9329 | if ( $pid_file ) { |
179 | 9314 | else { | 9330 | $self->_update_pid_file( |
180 | 9315 | if ( -t STDOUT ) { | 9331 | pid => $PID, # child's pid |
181 | 9316 | PTDEBUG && _d('No log file and STDOUT is a terminal;', | 9332 | pid_file => $pid_file, |
182 | 9317 | 'redirecting to /dev/null'); | 9333 | ); |
183 | 9334 | $self->{pid_file_owner} = $PID; | ||
184 | 9335 | } | ||
185 | 9336 | } | ||
186 | 9337 | |||
187 | 9338 | if ( $daemonize || $force_log_file ) { | ||
188 | 9339 | PTDEBUG && _d('Redirecting STDIN to /dev/null'); | ||
189 | 9340 | close STDIN; | ||
190 | 9341 | open STDIN, '/dev/null' | ||
191 | 9342 | or die "Cannot reopen STDIN to /dev/null: $OS_ERROR"; | ||
192 | 9343 | if ( $log_file ) { | ||
193 | 9344 | PTDEBUG && _d('Redirecting STDOUT and STDERR to', $log_file); | ||
194 | 9318 | close STDOUT; | 9345 | close STDOUT; |
201 | 9319 | open STDOUT, '>', '/dev/null' | 9346 | open STDOUT, '>>', $log_file |
202 | 9320 | or die "Cannot reopen STDOUT to /dev/null: $OS_ERROR"; | 9347 | or die "Cannot open log file $log_file: $OS_ERROR"; |
203 | 9321 | } | 9348 | |
198 | 9322 | if ( -t STDERR ) { | ||
199 | 9323 | PTDEBUG && _d('No log file and STDERR is a terminal;', | ||
200 | 9324 | 'redirecting to /dev/null'); | ||
204 | 9325 | close STDERR; | 9349 | close STDERR; |
229 | 9326 | open STDERR, '>', '/dev/null' | 9350 | open STDERR, ">&STDOUT" |
230 | 9327 | or die "Cannot reopen STDERR to /dev/null: $OS_ERROR"; | 9351 | or die "Cannot dupe STDERR to STDOUT: $OS_ERROR"; |
231 | 9328 | } | 9352 | } |
232 | 9329 | } | 9353 | else { |
233 | 9330 | 9354 | if ( -t STDOUT ) { | |
234 | 9331 | return; | 9355 | PTDEBUG && _d('No log file and STDOUT is a terminal;', |
235 | 9332 | } | 9356 | 'redirecting to /dev/null'); |
236 | 9333 | 9357 | close STDOUT; | |
237 | 9334 | sub check_PID_file { | 9358 | open STDOUT, '>', '/dev/null' |
238 | 9335 | my ( $self, $file ) = @_; | 9359 | or die "Cannot reopen STDOUT to /dev/null: $OS_ERROR"; |
239 | 9336 | my $PID_file = $self ? $self->{PID_file} : $file; | 9360 | } |
240 | 9337 | PTDEBUG && _d('Checking PID file', $PID_file); | 9361 | if ( -t STDERR ) { |
241 | 9338 | if ( $PID_file && -f $PID_file ) { | 9362 | PTDEBUG && _d('No log file and STDERR is a terminal;', |
242 | 9339 | my $pid; | 9363 | 'redirecting to /dev/null'); |
243 | 9340 | eval { | 9364 | close STDERR; |
244 | 9341 | chomp($pid = (slurp_file($PID_file) || '')); | 9365 | open STDERR, '>', '/dev/null' |
245 | 9342 | }; | 9366 | or die "Cannot reopen STDERR to /dev/null: $OS_ERROR"; |
246 | 9343 | if ( $EVAL_ERROR ) { | 9367 | } |
247 | 9344 | die "The PID file $PID_file already exists but it cannot be read: " | 9368 | } |
248 | 9345 | . $EVAL_ERROR; | 9369 | |
249 | 9346 | } | 9370 | $OUTPUT_AUTOFLUSH = 1; |
250 | 9347 | PTDEBUG && _d('PID file exists; it contains PID', $pid); | 9371 | } |
251 | 9348 | if ( $pid ) { | 9372 | |
252 | 9349 | my $pid_is_alive = kill 0, $pid; | 9373 | PTDEBUG && _d('Daemon running'); |
253 | 9374 | return; | ||
254 | 9375 | } | ||
255 | 9376 | |||
256 | 9377 | sub _make_pid_file { | ||
257 | 9378 | my ($self, %args) = @_; | ||
258 | 9379 | my @required_args = qw(pid pid_file); | ||
259 | 9380 | foreach my $arg ( @required_args ) { | ||
260 | 9381 | die "I need a $arg argument" unless $args{$arg}; | ||
261 | 9382 | }; | ||
262 | 9383 | my $pid = $args{pid}; | ||
263 | 9384 | my $pid_file = $args{pid_file}; | ||
264 | 9385 | |||
265 | 9386 | eval { | ||
266 | 9387 | sysopen(PID_FH, $pid_file, O_RDWR|O_CREAT|O_EXCL) or die $OS_ERROR; | ||
267 | 9388 | print PID_FH $PID, "\n"; | ||
268 | 9389 | close PID_FH; | ||
269 | 9390 | }; | ||
270 | 9391 | if ( my $e = $EVAL_ERROR ) { | ||
271 | 9392 | if ( $e =~ m/file exists/i ) { | ||
272 | 9393 | my $old_pid = $self->_check_pid_file( | ||
273 | 9394 | pid_file => $pid_file, | ||
274 | 9395 | pid => $PID, | ||
275 | 9396 | ); | ||
276 | 9397 | if ( $old_pid ) { | ||
277 | 9398 | warn "Overwriting PID file $pid_file because PID $old_pid " | ||
278 | 9399 | . "is not running.\n"; | ||
279 | 9400 | } | ||
280 | 9401 | $self->_update_pid_file( | ||
281 | 9402 | pid => $PID, | ||
282 | 9403 | pid_file => $pid_file | ||
283 | 9404 | ); | ||
284 | 9405 | } | ||
285 | 9406 | else { | ||
286 | 9407 | die "Error creating PID file $pid_file: $e\n"; | ||
287 | 9408 | } | ||
288 | 9409 | } | ||
289 | 9410 | |||
290 | 9411 | return; | ||
291 | 9412 | } | ||
292 | 9413 | |||
293 | 9414 | sub _check_pid_file { | ||
294 | 9415 | my ($self, %args) = @_; | ||
295 | 9416 | my @required_args = qw(pid_file pid); | ||
296 | 9417 | foreach my $arg ( @required_args ) { | ||
297 | 9418 | die "I need a $arg argument" unless $args{$arg}; | ||
298 | 9419 | }; | ||
299 | 9420 | my $pid_file = $args{pid_file}; | ||
300 | 9421 | my $pid = $args{pid}; | ||
301 | 9422 | |||
302 | 9423 | PTDEBUG && _d('Checking if PID in', $pid_file, 'is running'); | ||
303 | 9424 | |||
304 | 9425 | if ( ! -f $pid_file ) { | ||
305 | 9426 | PTDEBUG && _d('PID file', $pid_file, 'does not exist'); | ||
306 | 9427 | return; | ||
307 | 9428 | } | ||
308 | 9429 | |||
309 | 9430 | open my $fh, '<', $pid_file | ||
310 | 9431 | or die "Error opening $pid_file: $OS_ERROR"; | ||
311 | 9432 | my $existing_pid = do { local $/; <$fh> }; | ||
312 | 9433 | chomp($existing_pid) if $existing_pid; | ||
313 | 9434 | close $fh | ||
314 | 9435 | or die "Error closing $pid_file: $OS_ERROR"; | ||
315 | 9436 | |||
316 | 9437 | if ( $existing_pid ) { | ||
317 | 9438 | if ( $existing_pid == $pid ) { | ||
318 | 9439 | warn "The current PID $pid already holds the PID file $pid_file\n"; | ||
319 | 9440 | return; | ||
320 | 9441 | } | ||
321 | 9442 | else { | ||
322 | 9443 | PTDEBUG && _d('Checking if PID', $existing_pid, 'is running'); | ||
323 | 9444 | my $pid_is_alive = kill 0, $existing_pid; | ||
324 | 9350 | if ( $pid_is_alive ) { | 9445 | if ( $pid_is_alive ) { |
336 | 9351 | die "The PID file $PID_file already exists " | 9446 | die "PID file $pid_file exists and PID $existing_pid is running\n"; |
337 | 9352 | . " and the PID that it contains, $pid, is running"; | 9447 | } |
327 | 9353 | } | ||
328 | 9354 | else { | ||
329 | 9355 | warn "Overwriting PID file $PID_file because the PID that it " | ||
330 | 9356 | . "contains, $pid, is not running"; | ||
331 | 9357 | } | ||
332 | 9358 | } | ||
333 | 9359 | else { | ||
334 | 9360 | die "The PID file $PID_file already exists but it does not " | ||
335 | 9361 | . "contain a PID"; | ||
338 | 9362 | } | 9448 | } |
339 | 9363 | } | 9449 | } |
340 | 9364 | else { | 9450 | else { |
383 | 9365 | PTDEBUG && _d('No PID file'); | 9451 | die "PID file $pid_file exists but it is empty. Remove the file " |
384 | 9366 | } | 9452 | . "if the process is no longer running.\n"; |
385 | 9367 | return; | 9453 | } |
386 | 9368 | } | 9454 | |
387 | 9369 | 9455 | return $existing_pid; | |
388 | 9370 | sub make_PID_file { | 9456 | } |
389 | 9371 | my ( $self ) = @_; | 9457 | |
390 | 9372 | if ( exists $self->{child} ) { | 9458 | sub _update_pid_file { |
391 | 9373 | die "Do not call Daemon::make_PID_file() for daemonized scripts"; | 9459 | my ($self, %args) = @_; |
392 | 9374 | } | 9460 | my @required_args = qw(pid pid_file); |
393 | 9375 | $self->_make_PID_file(); | 9461 | foreach my $arg ( @required_args ) { |
394 | 9376 | $self->{PID_owner} = $PID; | 9462 | die "I need a $arg argument" unless $args{$arg}; |
395 | 9377 | return; | 9463 | }; |
396 | 9378 | } | 9464 | my $pid = $args{pid}; |
397 | 9379 | 9465 | my $pid_file = $args{pid_file}; | |
398 | 9380 | sub _make_PID_file { | 9466 | |
399 | 9381 | my ( $self ) = @_; | 9467 | open my $fh, '>', $pid_file |
400 | 9382 | 9468 | or die "Cannot open $pid_file: $OS_ERROR"; | |
401 | 9383 | my $PID_file = $self->{PID_file}; | 9469 | print { $fh } $pid, "\n" |
402 | 9384 | if ( !$PID_file ) { | 9470 | or die "Cannot print to $pid_file: $OS_ERROR"; |
403 | 9385 | PTDEBUG && _d('No PID file to create'); | 9471 | close $fh |
404 | 9386 | return; | 9472 | or warn "Cannot close $pid_file: $OS_ERROR"; |
405 | 9387 | } | 9473 | |
406 | 9388 | 9474 | return; | |
407 | 9389 | $self->check_PID_file(); | 9475 | } |
408 | 9390 | 9476 | ||
409 | 9391 | open my $PID_FH, '>', $PID_file | 9477 | sub remove_pid_file { |
410 | 9392 | or die "Cannot open PID file $PID_file: $OS_ERROR"; | 9478 | my ($self, $pid_file) = @_; |
411 | 9393 | print $PID_FH $PID | 9479 | $pid_file ||= $self->{pid_file}; |
412 | 9394 | or die "Cannot print to PID file $PID_file: $OS_ERROR"; | 9480 | if ( $pid_file && -f $pid_file ) { |
413 | 9395 | close $PID_FH | 9481 | unlink $self->{pid_file} |
414 | 9396 | or die "Cannot close PID file $PID_file: $OS_ERROR"; | 9482 | or warn "Cannot remove PID file $pid_file: $OS_ERROR"; |
373 | 9397 | |||
374 | 9398 | PTDEBUG && _d('Created PID file:', $self->{PID_file}); | ||
375 | 9399 | return; | ||
376 | 9400 | } | ||
377 | 9401 | |||
378 | 9402 | sub _remove_PID_file { | ||
379 | 9403 | my ( $self ) = @_; | ||
380 | 9404 | if ( $self->{PID_file} && -f $self->{PID_file} ) { | ||
381 | 9405 | unlink $self->{PID_file} | ||
382 | 9406 | or warn "Cannot remove PID file $self->{PID_file}: $OS_ERROR"; | ||
415 | 9407 | PTDEBUG && _d('Removed PID file'); | 9483 | PTDEBUG && _d('Removed PID file'); |
416 | 9408 | } | 9484 | } |
417 | 9409 | else { | 9485 | else { |
418 | @@ -9413,20 +9489,15 @@ | |||
419 | 9413 | } | 9489 | } |
420 | 9414 | 9490 | ||
421 | 9415 | sub DESTROY { | 9491 | sub DESTROY { |
423 | 9416 | my ( $self ) = @_; | 9492 | my ($self) = @_; |
424 | 9417 | 9493 | ||
426 | 9418 | $self->_remove_PID_file() if ($self->{PID_owner} || 0) == $PID; | 9494 | if ( $self->{pid_file_owner} == $PID ) { |
427 | 9495 | $self->remove_pid_file(); | ||
428 | 9496 | } | ||
429 | 9419 | 9497 | ||
430 | 9420 | return; | 9498 | return; |
431 | 9421 | } | 9499 | } |
432 | 9422 | 9500 | ||
433 | 9423 | sub slurp_file { | ||
434 | 9424 | my ($file) = @_; | ||
435 | 9425 | return unless $file; | ||
436 | 9426 | open my $fh, "<", $file or die "Cannot open $file: $OS_ERROR"; | ||
437 | 9427 | return do { local $/; <$fh> }; | ||
438 | 9428 | } | ||
439 | 9429 | |||
440 | 9430 | sub _d { | 9501 | sub _d { |
441 | 9431 | my ($package, undef, $line) = caller 0; | 9502 | my ($package, undef, $line) = caller 0; |
442 | 9432 | @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; } | 9503 | @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; } |
443 | @@ -11479,25 +11550,23 @@ | |||
444 | 11479 | # ########################################################################### | 11550 | # ########################################################################### |
445 | 11480 | 11551 | ||
446 | 11481 | # ########################################################################### | 11552 | # ########################################################################### |
448 | 11482 | # HTTPMicro package | 11553 | # HTTP::Micro package |
449 | 11483 | # This package is a copy without comments from the original. The original | 11554 | # This package is a copy without comments from the original. The original |
450 | 11484 | # with comments and its test file can be found in the Bazaar repository at, | 11555 | # with comments and its test file can be found in the Bazaar repository at, |
453 | 11485 | # lib/HTTPMicro.pm | 11556 | # lib/HTTP/Micro.pm |
454 | 11486 | # t/lib/HTTPMicro.t | 11557 | # t/lib/HTTP/Micro.t |
455 | 11487 | # See https://launchpad.net/percona-toolkit for more information. | 11558 | # See https://launchpad.net/percona-toolkit for more information. |
456 | 11488 | # ########################################################################### | 11559 | # ########################################################################### |
457 | 11489 | { | 11560 | { |
463 | 11490 | 11561 | package HTTP::Micro; | |
464 | 11491 | package HTTPMicro; | 11562 | |
465 | 11492 | BEGIN { | 11563 | our $VERSION = '0.01'; |
466 | 11493 | $HTTPMicro::VERSION = '0.001'; | 11564 | |
462 | 11494 | } | ||
467 | 11495 | use strict; | 11565 | use strict; |
470 | 11496 | use warnings; | 11566 | use warnings FATAL => 'all'; |
471 | 11497 | 11567 | use English qw(-no_match_vars); | |
472 | 11498 | use Carp (); | 11568 | use Carp (); |
473 | 11499 | 11569 | ||
474 | 11500 | |||
475 | 11501 | my @attributes; | 11570 | my @attributes; |
476 | 11502 | BEGIN { | 11571 | BEGIN { |
477 | 11503 | @attributes = qw(agent timeout); | 11572 | @attributes = qw(agent timeout); |
478 | @@ -11568,7 +11637,7 @@ | |||
479 | 11568 | headers => {}, | 11637 | headers => {}, |
480 | 11569 | }; | 11638 | }; |
481 | 11570 | 11639 | ||
483 | 11571 | my $handle = HTTPMicro::Handle->new(timeout => $self->{timeout}); | 11640 | my $handle = HTTP::Micro::Handle->new(timeout => $self->{timeout}); |
484 | 11572 | 11641 | ||
485 | 11573 | $handle->connect($scheme, $host, $port); | 11642 | $handle->connect($scheme, $host, $port); |
486 | 11574 | 11643 | ||
487 | @@ -11633,320 +11702,325 @@ | |||
488 | 11633 | return ($scheme, $host, $port, $path_query); | 11702 | return ($scheme, $host, $port, $path_query); |
489 | 11634 | } | 11703 | } |
490 | 11635 | 11704 | ||
805 | 11636 | package | 11705 | } # HTTP::Micro |
806 | 11637 | HTTPMicro::Handle; # hide from PAUSE/indexers | 11706 | |
807 | 11638 | use strict; | 11707 | { |
808 | 11639 | use warnings; | 11708 | package HTTP::Micro::Handle; |
809 | 11640 | 11709 | ||
810 | 11641 | use Carp qw[croak]; | 11710 | use strict; |
811 | 11642 | use Errno qw[EINTR EPIPE]; | 11711 | use warnings FATAL => 'all'; |
812 | 11643 | use IO::Socket qw[SOCK_STREAM]; | 11712 | use English qw(-no_match_vars); |
813 | 11644 | 11713 | ||
814 | 11645 | sub BUFSIZE () { 32768 } | 11714 | use Carp qw(croak); |
815 | 11646 | 11715 | use Errno qw(EINTR EPIPE); | |
816 | 11647 | my $Printable = sub { | 11716 | use IO::Socket qw(SOCK_STREAM); |
817 | 11648 | local $_ = shift; | 11717 | |
818 | 11649 | s/\r/\\r/g; | 11718 | sub BUFSIZE () { 32768 } |
819 | 11650 | s/\n/\\n/g; | 11719 | |
820 | 11651 | s/\t/\\t/g; | 11720 | my $Printable = sub { |
821 | 11652 | s/([^\x20-\x7E])/sprintf('\\x%.2X', ord($1))/ge; | 11721 | local $_ = shift; |
822 | 11653 | $_; | 11722 | s/\r/\\r/g; |
823 | 11654 | }; | 11723 | s/\n/\\n/g; |
824 | 11655 | 11724 | s/\t/\\t/g; | |
825 | 11656 | sub new { | 11725 | s/([^\x20-\x7E])/sprintf('\\x%.2X', ord($1))/ge; |
826 | 11657 | my ($class, %args) = @_; | 11726 | $_; |
827 | 11658 | return bless { | 11727 | }; |
828 | 11659 | rbuf => '', | 11728 | |
829 | 11660 | timeout => 60, | 11729 | sub new { |
830 | 11661 | max_line_size => 16384, | 11730 | my ($class, %args) = @_; |
831 | 11662 | %args | 11731 | return bless { |
832 | 11663 | }, $class; | 11732 | rbuf => '', |
833 | 11664 | } | 11733 | timeout => 60, |
834 | 11665 | 11734 | max_line_size => 16384, | |
835 | 11666 | my $ssl_verify_args = { | 11735 | %args |
836 | 11667 | check_cn => "when_only", | 11736 | }, $class; |
837 | 11668 | wildcards_in_alt => "anywhere", | 11737 | } |
838 | 11669 | wildcards_in_cn => "anywhere" | 11738 | |
839 | 11670 | }; | 11739 | my $ssl_verify_args = { |
840 | 11671 | 11740 | check_cn => "when_only", | |
841 | 11672 | sub connect { | 11741 | wildcards_in_alt => "anywhere", |
842 | 11673 | @_ == 4 || croak(q/Usage: $handle->connect(scheme, host, port)/); | 11742 | wildcards_in_cn => "anywhere" |
843 | 11674 | my ($self, $scheme, $host, $port) = @_; | 11743 | }; |
844 | 11675 | 11744 | ||
845 | 11676 | if ( $scheme eq 'https' ) { | 11745 | sub connect { |
846 | 11677 | eval "require IO::Socket::SSL" | 11746 | @_ == 4 || croak(q/Usage: $handle->connect(scheme, host, port)/); |
847 | 11678 | unless exists $INC{'IO/Socket/SSL.pm'}; | 11747 | my ($self, $scheme, $host, $port) = @_; |
848 | 11679 | croak(qq/IO::Socket::SSL must be installed for https support\n/) | 11748 | |
849 | 11680 | unless $INC{'IO/Socket/SSL.pm'}; | 11749 | if ( $scheme eq 'https' ) { |
850 | 11681 | } | 11750 | eval "require IO::Socket::SSL" |
851 | 11682 | elsif ( $scheme ne 'http' ) { | 11751 | unless exists $INC{'IO/Socket/SSL.pm'}; |
852 | 11683 | croak(qq/Unsupported URL scheme '$scheme'\n/); | 11752 | croak(qq/IO::Socket::SSL must be installed for https support\n/) |
853 | 11684 | } | 11753 | unless $INC{'IO/Socket/SSL.pm'}; |
854 | 11685 | 11754 | } | |
855 | 11686 | $self->{fh} = 'IO::Socket::INET'->new( | 11755 | elsif ( $scheme ne 'http' ) { |
856 | 11687 | PeerHost => $host, | 11756 | croak(qq/Unsupported URL scheme '$scheme'\n/); |
857 | 11688 | PeerPort => $port, | 11757 | } |
858 | 11689 | Proto => 'tcp', | 11758 | |
859 | 11690 | Type => SOCK_STREAM, | 11759 | $self->{fh} = IO::Socket::INET->new( |
860 | 11691 | Timeout => $self->{timeout} | 11760 | PeerHost => $host, |
861 | 11692 | ) or croak(qq/Could not connect to '$host:$port': $@/); | 11761 | PeerPort => $port, |
862 | 11693 | 11762 | Proto => 'tcp', | |
863 | 11694 | binmode($self->{fh}) | 11763 | Type => SOCK_STREAM, |
864 | 11695 | or croak(qq/Could not binmode() socket: '$!'/); | 11764 | Timeout => $self->{timeout} |
865 | 11696 | 11765 | ) or croak(qq/Could not connect to '$host:$port': $@/); | |
866 | 11697 | if ( $scheme eq 'https') { | 11766 | |
867 | 11698 | IO::Socket::SSL->start_SSL($self->{fh}); | 11767 | binmode($self->{fh}) |
868 | 11699 | ref($self->{fh}) eq 'IO::Socket::SSL' | 11768 | or croak(qq/Could not binmode() socket: '$!'/); |
869 | 11700 | or die(qq/SSL connection failed for $host\n/); | 11769 | |
870 | 11701 | if ( $self->{fh}->can("verify_hostname") ) { | 11770 | if ( $scheme eq 'https') { |
871 | 11702 | $self->{fh}->verify_hostname( $host, $ssl_verify_args ); | 11771 | IO::Socket::SSL->start_SSL($self->{fh}); |
872 | 11703 | } | 11772 | ref($self->{fh}) eq 'IO::Socket::SSL' |
873 | 11704 | else { | 11773 | or die(qq/SSL connection failed for $host\n/); |
874 | 11705 | my $fh = $self->{fh}; | 11774 | if ( $self->{fh}->can("verify_hostname") ) { |
875 | 11706 | _verify_hostname_of_cert($host, _peer_certificate($fh), $ssl_verify_args) | 11775 | $self->{fh}->verify_hostname( $host, $ssl_verify_args ); |
876 | 11707 | or die(qq/SSL certificate not valid for $host\n/); | 11776 | } |
877 | 11708 | } | 11777 | else { |
878 | 11709 | } | 11778 | my $fh = $self->{fh}; |
879 | 11710 | 11779 | _verify_hostname_of_cert($host, _peer_certificate($fh), $ssl_verify_args) | |
880 | 11711 | $self->{host} = $host; | 11780 | or die(qq/SSL certificate not valid for $host\n/); |
881 | 11712 | $self->{port} = $port; | 11781 | } |
882 | 11713 | 11782 | } | |
883 | 11714 | return $self; | 11783 | |
884 | 11715 | } | 11784 | $self->{host} = $host; |
885 | 11716 | 11785 | $self->{port} = $port; | |
886 | 11717 | sub close { | 11786 | |
887 | 11718 | @_ == 1 || croak(q/Usage: $handle->close()/); | 11787 | return $self; |
888 | 11719 | my ($self) = @_; | 11788 | } |
889 | 11720 | CORE::close($self->{fh}) | 11789 | |
890 | 11721 | or croak(qq/Could not close socket: '$!'/); | 11790 | sub close { |
891 | 11722 | } | 11791 | @_ == 1 || croak(q/Usage: $handle->close()/); |
892 | 11723 | 11792 | my ($self) = @_; | |
893 | 11724 | sub write { | 11793 | CORE::close($self->{fh}) |
894 | 11725 | @_ == 2 || croak(q/Usage: $handle->write(buf)/); | 11794 | or croak(qq/Could not close socket: '$!'/); |
895 | 11726 | my ($self, $buf) = @_; | 11795 | } |
896 | 11727 | 11796 | ||
897 | 11728 | my $len = length $buf; | 11797 | sub write { |
898 | 11729 | my $off = 0; | 11798 | @_ == 2 || croak(q/Usage: $handle->write(buf)/); |
899 | 11730 | 11799 | my ($self, $buf) = @_; | |
900 | 11731 | local $SIG{PIPE} = 'IGNORE'; | 11800 | |
901 | 11732 | 11801 | my $len = length $buf; | |
902 | 11733 | while () { | 11802 | my $off = 0; |
903 | 11734 | $self->can_write | 11803 | |
904 | 11735 | or croak(q/Timed out while waiting for socket to become ready for writing/); | 11804 | local $SIG{PIPE} = 'IGNORE'; |
905 | 11736 | my $r = syswrite($self->{fh}, $buf, $len, $off); | 11805 | |
906 | 11737 | if (defined $r) { | 11806 | while () { |
907 | 11738 | $len -= $r; | 11807 | $self->can_write |
908 | 11739 | $off += $r; | 11808 | or croak(q/Timed out while waiting for socket to become ready for writing/); |
909 | 11740 | last unless $len > 0; | 11809 | my $r = syswrite($self->{fh}, $buf, $len, $off); |
910 | 11741 | } | 11810 | if (defined $r) { |
911 | 11742 | elsif ($! == EPIPE) { | 11811 | $len -= $r; |
912 | 11743 | croak(qq/Socket closed by remote server: $!/); | 11812 | $off += $r; |
913 | 11744 | } | 11813 | last unless $len > 0; |
914 | 11745 | elsif ($! != EINTR) { | 11814 | } |
915 | 11746 | croak(qq/Could not write to socket: '$!'/); | 11815 | elsif ($! == EPIPE) { |
916 | 11747 | } | 11816 | croak(qq/Socket closed by remote server: $!/); |
917 | 11748 | } | 11817 | } |
918 | 11749 | return $off; | 11818 | elsif ($! != EINTR) { |
919 | 11750 | } | 11819 | croak(qq/Could not write to socket: '$!'/); |
920 | 11751 | 11820 | } | |
921 | 11752 | sub read { | 11821 | } |
922 | 11753 | @_ == 2 || @_ == 3 || croak(q/Usage: $handle->read(len)/); | 11822 | return $off; |
923 | 11754 | my ($self, $len) = @_; | 11823 | } |
924 | 11755 | 11824 | ||
925 | 11756 | my $buf = ''; | 11825 | sub read { |
926 | 11757 | my $got = length $self->{rbuf}; | 11826 | @_ == 2 || @_ == 3 || croak(q/Usage: $handle->read(len)/); |
927 | 11758 | 11827 | my ($self, $len) = @_; | |
928 | 11759 | if ($got) { | 11828 | |
929 | 11760 | my $take = ($got < $len) ? $got : $len; | 11829 | my $buf = ''; |
930 | 11761 | $buf = substr($self->{rbuf}, 0, $take, ''); | 11830 | my $got = length $self->{rbuf}; |
931 | 11762 | $len -= $take; | 11831 | |
932 | 11763 | } | 11832 | if ($got) { |
933 | 11764 | 11833 | my $take = ($got < $len) ? $got : $len; | |
934 | 11765 | while ($len > 0) { | 11834 | $buf = substr($self->{rbuf}, 0, $take, ''); |
935 | 11766 | $self->can_read | 11835 | $len -= $take; |
936 | 11767 | or croak(q/Timed out while waiting for socket to become ready for reading/); | 11836 | } |
937 | 11768 | my $r = sysread($self->{fh}, $buf, $len, length $buf); | 11837 | |
938 | 11769 | if (defined $r) { | 11838 | while ($len > 0) { |
939 | 11770 | last unless $r; | 11839 | $self->can_read |
940 | 11771 | $len -= $r; | 11840 | or croak(q/Timed out while waiting for socket to become ready for reading/); |
941 | 11772 | } | 11841 | my $r = sysread($self->{fh}, $buf, $len, length $buf); |
942 | 11773 | elsif ($! != EINTR) { | 11842 | if (defined $r) { |
943 | 11774 | croak(qq/Could not read from socket: '$!'/); | 11843 | last unless $r; |
944 | 11775 | } | 11844 | $len -= $r; |
945 | 11776 | } | 11845 | } |
946 | 11777 | if ($len) { | 11846 | elsif ($! != EINTR) { |
947 | 11778 | croak(q/Unexpected end of stream/); | 11847 | croak(qq/Could not read from socket: '$!'/); |
948 | 11779 | } | 11848 | } |
949 | 11780 | return $buf; | 11849 | } |
950 | 11781 | } | 11850 | if ($len) { |
951 | 11782 | 11851 | croak(q/Unexpected end of stream/); | |
952 | 11783 | sub readline { | 11852 | } |
953 | 11784 | @_ == 1 || croak(q/Usage: $handle->readline()/); | 11853 | return $buf; |
954 | 11785 | my ($self) = @_; | 11854 | } |
955 | 11786 | 11855 | ||
956 | 11787 | while () { | 11856 | sub readline { |
957 | 11788 | if ($self->{rbuf} =~ s/\A ([^\x0D\x0A]* \x0D?\x0A)//x) { | 11857 | @_ == 1 || croak(q/Usage: $handle->readline()/); |
958 | 11789 | return $1; | 11858 | my ($self) = @_; |
959 | 11790 | } | 11859 | |
960 | 11791 | $self->can_read | 11860 | while () { |
961 | 11792 | or croak(q/Timed out while waiting for socket to become ready for reading/); | 11861 | if ($self->{rbuf} =~ s/\A ([^\x0D\x0A]* \x0D?\x0A)//x) { |
962 | 11793 | my $r = sysread($self->{fh}, $self->{rbuf}, BUFSIZE, length $self->{rbuf}); | 11862 | return $1; |
963 | 11794 | if (defined $r) { | 11863 | } |
964 | 11795 | last unless $r; | 11864 | $self->can_read |
965 | 11796 | } | 11865 | or croak(q/Timed out while waiting for socket to become ready for reading/); |
966 | 11797 | elsif ($! != EINTR) { | 11866 | my $r = sysread($self->{fh}, $self->{rbuf}, BUFSIZE, length $self->{rbuf}); |
967 | 11798 | croak(qq/Could not read from socket: '$!'/); | 11867 | if (defined $r) { |
968 | 11799 | } | 11868 | last unless $r; |
969 | 11800 | } | 11869 | } |
970 | 11801 | croak(q/Unexpected end of stream while looking for line/); | 11870 | elsif ($! != EINTR) { |
971 | 11802 | } | 11871 | croak(qq/Could not read from socket: '$!'/); |
972 | 11803 | 11872 | } | |
973 | 11804 | sub read_header_lines { | 11873 | } |
974 | 11805 | @_ == 1 || @_ == 2 || croak(q/Usage: $handle->read_header_lines([headers])/); | 11874 | croak(q/Unexpected end of stream while looking for line/); |
975 | 11806 | my ($self, $headers) = @_; | 11875 | } |
976 | 11807 | $headers ||= {}; | 11876 | |
977 | 11808 | my $lines = 0; | 11877 | sub read_header_lines { |
978 | 11809 | my $val; | 11878 | @_ == 1 || @_ == 2 || croak(q/Usage: $handle->read_header_lines([headers])/); |
979 | 11810 | 11879 | my ($self, $headers) = @_; | |
980 | 11811 | while () { | 11880 | $headers ||= {}; |
981 | 11812 | my $line = $self->readline; | 11881 | my $lines = 0; |
982 | 11813 | 11882 | my $val; | |
983 | 11814 | if ($line =~ /\A ([^\x00-\x1F\x7F:]+) : [\x09\x20]* ([^\x0D\x0A]*)/x) { | 11883 | |
984 | 11815 | my ($field_name) = lc $1; | 11884 | while () { |
985 | 11816 | $val = \($headers->{$field_name} = $2); | 11885 | my $line = $self->readline; |
986 | 11817 | } | 11886 | |
987 | 11818 | elsif ($line =~ /\A [\x09\x20]+ ([^\x0D\x0A]*)/x) { | 11887 | if ($line =~ /\A ([^\x00-\x1F\x7F:]+) : [\x09\x20]* ([^\x0D\x0A]*)/x) { |
988 | 11819 | $val | 11888 | my ($field_name) = lc $1; |
989 | 11820 | or croak(q/Unexpected header continuation line/); | 11889 | $val = \($headers->{$field_name} = $2); |
990 | 11821 | next unless length $1; | 11890 | } |
991 | 11822 | $$val .= ' ' if length $$val; | 11891 | elsif ($line =~ /\A [\x09\x20]+ ([^\x0D\x0A]*)/x) { |
992 | 11823 | $$val .= $1; | 11892 | $val |
993 | 11824 | } | 11893 | or croak(q/Unexpected header continuation line/); |
994 | 11825 | elsif ($line =~ /\A \x0D?\x0A \z/x) { | 11894 | next unless length $1; |
995 | 11826 | last; | 11895 | $$val .= ' ' if length $$val; |
996 | 11827 | } | 11896 | $$val .= $1; |
997 | 11828 | else { | 11897 | } |
998 | 11829 | croak(q/Malformed header line: / . $Printable->($line)); | 11898 | elsif ($line =~ /\A \x0D?\x0A \z/x) { |
999 | 11830 | } | 11899 | last; |
1000 | 11831 | } | 11900 | } |
1001 | 11832 | return $headers; | 11901 | else { |
1002 | 11833 | } | 11902 | croak(q/Malformed header line: / . $Printable->($line)); |
1003 | 11834 | 11903 | } | |
1004 | 11835 | sub write_header_lines { | 11904 | } |
1005 | 11836 | (@_ == 2 && ref $_[1] eq 'HASH') || croak(q/Usage: $handle->write_header_lines(headers)/); | 11905 | return $headers; |
1006 | 11837 | my($self, $headers) = @_; | 11906 | } |
1007 | 11838 | 11907 | ||
1008 | 11839 | my $buf = ''; | 11908 | sub write_header_lines { |
1009 | 11840 | while (my ($k, $v) = each %$headers) { | 11909 | (@_ == 2 && ref $_[1] eq 'HASH') || croak(q/Usage: $handle->write_header_lines(headers)/); |
1010 | 11841 | my $field_name = lc $k; | 11910 | my($self, $headers) = @_; |
1011 | 11842 | $field_name =~ /\A [\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7A\x7C\x7E]+ \z/x | 11911 | |
1012 | 11843 | or croak(q/Invalid HTTP header field name: / . $Printable->($field_name)); | 11912 | my $buf = ''; |
1013 | 11844 | $field_name =~ s/\b(\w)/\u$1/g; | 11913 | while (my ($k, $v) = each %$headers) { |
1014 | 11845 | $buf .= "$field_name: $v\x0D\x0A"; | 11914 | my $field_name = lc $k; |
1015 | 11846 | } | 11915 | $field_name =~ /\A [\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7A\x7C\x7E]+ \z/x |
1016 | 11847 | $buf .= "\x0D\x0A"; | 11916 | or croak(q/Invalid HTTP header field name: / . $Printable->($field_name)); |
1017 | 11848 | return $self->write($buf); | 11917 | $field_name =~ s/\b(\w)/\u$1/g; |
1018 | 11849 | } | 11918 | $buf .= "$field_name: $v\x0D\x0A"; |
1019 | 11850 | 11919 | } | |
1020 | 11851 | sub read_content_body { | 11920 | $buf .= "\x0D\x0A"; |
1021 | 11852 | @_ == 3 || @_ == 4 || croak(q/Usage: $handle->read_content_body(callback, response, [read_length])/); | 11921 | return $self->write($buf); |
1022 | 11853 | my ($self, $cb, $response, $len) = @_; | 11922 | } |
1023 | 11854 | $len ||= $response->{headers}{'content-length'}; | 11923 | |
1024 | 11855 | 11924 | sub read_content_body { | |
1025 | 11856 | croak("No content-length in the returned response, and this " | 11925 | @_ == 3 || @_ == 4 || croak(q/Usage: $handle->read_content_body(callback, response, [read_length])/); |
1026 | 11857 | . "UA doesn't implement chunking") unless defined $len; | 11926 | my ($self, $cb, $response, $len) = @_; |
1027 | 11858 | 11927 | $len ||= $response->{headers}{'content-length'}; | |
1028 | 11859 | while ($len > 0) { | 11928 | |
1029 | 11860 | my $read = ($len > BUFSIZE) ? BUFSIZE : $len; | 11929 | croak("No content-length in the returned response, and this " |
1030 | 11861 | $cb->($self->read($read), $response); | 11930 | . "UA doesn't implement chunking") unless defined $len; |
1031 | 11862 | $len -= $read; | 11931 | |
1032 | 11863 | } | 11932 | while ($len > 0) { |
1033 | 11864 | 11933 | my $read = ($len > BUFSIZE) ? BUFSIZE : $len; | |
1034 | 11865 | return; | 11934 | $cb->($self->read($read), $response); |
1035 | 11866 | } | 11935 | $len -= $read; |
1036 | 11867 | 11936 | } | |
1037 | 11868 | sub write_content_body { | 11937 | |
1038 | 11869 | @_ == 2 || croak(q/Usage: $handle->write_content_body(request)/); | 11938 | return; |
1039 | 11870 | my ($self, $request) = @_; | 11939 | } |
1040 | 11871 | my ($len, $content_length) = (0, $request->{headers}{'content-length'}); | 11940 | |
1041 | 11872 | 11941 | sub write_content_body { | |
1042 | 11873 | $len += $self->write($request->{content}); | 11942 | @_ == 2 || croak(q/Usage: $handle->write_content_body(request)/); |
1043 | 11874 | 11943 | my ($self, $request) = @_; | |
1044 | 11875 | $len == $content_length | 11944 | my ($len, $content_length) = (0, $request->{headers}{'content-length'}); |
1045 | 11876 | or croak(qq/Content-Length missmatch (got: $len expected: $content_length)/); | 11945 | |
1046 | 11877 | 11946 | $len += $self->write($request->{content}); | |
1047 | 11878 | return $len; | 11947 | |
1048 | 11879 | } | 11948 | $len == $content_length |
1049 | 11880 | 11949 | or croak(qq/Content-Length missmatch (got: $len expected: $content_length)/); | |
1050 | 11881 | sub read_response_header { | 11950 | |
1051 | 11882 | @_ == 1 || croak(q/Usage: $handle->read_response_header()/); | 11951 | return $len; |
1052 | 11883 | my ($self) = @_; | 11952 | } |
1053 | 11884 | 11953 | ||
1054 | 11885 | my $line = $self->readline; | 11954 | sub read_response_header { |
1055 | 11886 | 11955 | @_ == 1 || croak(q/Usage: $handle->read_response_header()/); | |
1056 | 11887 | $line =~ /\A (HTTP\/(0*\d+\.0*\d+)) [\x09\x20]+ ([0-9]{3}) [\x09\x20]+ ([^\x0D\x0A]*) \x0D?\x0A/x | 11956 | my ($self) = @_; |
1057 | 11888 | or croak(q/Malformed Status-Line: / . $Printable->($line)); | 11957 | |
1058 | 11889 | 11958 | my $line = $self->readline; | |
1059 | 11890 | my ($protocol, $version, $status, $reason) = ($1, $2, $3, $4); | 11959 | |
1060 | 11891 | 11960 | $line =~ /\A (HTTP\/(0*\d+\.0*\d+)) [\x09\x20]+ ([0-9]{3}) [\x09\x20]+ ([^\x0D\x0A]*) \x0D?\x0A/x | |
1061 | 11892 | return { | 11961 | or croak(q/Malformed Status-Line: / . $Printable->($line)); |
1062 | 11893 | status => $status, | 11962 | |
1063 | 11894 | reason => $reason, | 11963 | my ($protocol, $version, $status, $reason) = ($1, $2, $3, $4); |
1064 | 11895 | headers => $self->read_header_lines, | 11964 | |
1065 | 11896 | protocol => $protocol, | 11965 | return { |
1066 | 11897 | }; | 11966 | status => $status, |
1067 | 11898 | } | 11967 | reason => $reason, |
1068 | 11899 | 11968 | headers => $self->read_header_lines, | |
1069 | 11900 | sub write_request_header { | 11969 | protocol => $protocol, |
1070 | 11901 | @_ == 4 || croak(q/Usage: $handle->write_request_header(method, request_uri, headers)/); | 11970 | }; |
1071 | 11902 | my ($self, $method, $request_uri, $headers) = @_; | 11971 | } |
1072 | 11903 | 11972 | ||
1073 | 11904 | return $self->write("$method $request_uri HTTP/1.1\x0D\x0A") | 11973 | sub write_request_header { |
1074 | 11905 | + $self->write_header_lines($headers); | 11974 | @_ == 4 || croak(q/Usage: $handle->write_request_header(method, request_uri, headers)/); |
1075 | 11906 | } | 11975 | my ($self, $method, $request_uri, $headers) = @_; |
1076 | 11907 | 11976 | ||
1077 | 11908 | sub _do_timeout { | 11977 | return $self->write("$method $request_uri HTTP/1.1\x0D\x0A") |
1078 | 11909 | my ($self, $type, $timeout) = @_; | 11978 | + $self->write_header_lines($headers); |
1079 | 11910 | $timeout = $self->{timeout} | 11979 | } |
1080 | 11911 | unless defined $timeout && $timeout >= 0; | 11980 | |
1081 | 11912 | 11981 | sub _do_timeout { | |
1082 | 11913 | my $fd = fileno $self->{fh}; | 11982 | my ($self, $type, $timeout) = @_; |
1083 | 11914 | defined $fd && $fd >= 0 | 11983 | $timeout = $self->{timeout} |
1084 | 11915 | or croak(q/select(2): 'Bad file descriptor'/); | 11984 | unless defined $timeout && $timeout >= 0; |
1085 | 11916 | 11985 | ||
1086 | 11917 | my $initial = time; | 11986 | my $fd = fileno $self->{fh}; |
1087 | 11918 | my $pending = $timeout; | 11987 | defined $fd && $fd >= 0 |
1088 | 11919 | my $nfound; | 11988 | or croak(q/select(2): 'Bad file descriptor'/); |
1089 | 11920 | 11989 | ||
1090 | 11921 | vec(my $fdset = '', $fd, 1) = 1; | 11990 | my $initial = time; |
1091 | 11922 | 11991 | my $pending = $timeout; | |
1092 | 11923 | while () { | 11992 | my $nfound; |
1093 | 11924 | $nfound = ($type eq 'read') | 11993 | |
1094 | 11925 | ? select($fdset, undef, undef, $pending) | 11994 | vec(my $fdset = '', $fd, 1) = 1; |
1095 | 11926 | : select(undef, $fdset, undef, $pending) ; | 11995 | |
1096 | 11927 | if ($nfound == -1) { | 11996 | while () { |
1097 | 11928 | $! == EINTR | 11997 | $nfound = ($type eq 'read') |
1098 | 11929 | or croak(qq/select(2): '$!'/); | 11998 | ? select($fdset, undef, undef, $pending) |
1099 | 11930 | redo if !$timeout || ($pending = $timeout - (time - $initial)) > 0; | 11999 | : select(undef, $fdset, undef, $pending) ; |
1100 | 11931 | $nfound = 0; | 12000 | if ($nfound == -1) { |
1101 | 11932 | } | 12001 | $! == EINTR |
1102 | 11933 | last; | 12002 | or croak(qq/select(2): '$!'/); |
1103 | 11934 | } | 12003 | redo if !$timeout || ($pending = $timeout - (time - $initial)) > 0; |
1104 | 11935 | $! = 0; | 12004 | $nfound = 0; |
1105 | 11936 | return $nfound; | 12005 | } |
1106 | 11937 | } | 12006 | last; |
1107 | 11938 | 12007 | } | |
1108 | 11939 | sub can_read { | 12008 | $! = 0; |
1109 | 11940 | @_ == 1 || @_ == 2 || croak(q/Usage: $handle->can_read([timeout])/); | 12009 | return $nfound; |
1110 | 11941 | my $self = shift; | 12010 | } |
1111 | 11942 | return $self->_do_timeout('read', @_) | 12011 | |
1112 | 11943 | } | 12012 | sub can_read { |
1113 | 11944 | 12013 | @_ == 1 || @_ == 2 || croak(q/Usage: $handle->can_read([timeout])/); | |
1114 | 11945 | sub can_write { | 12014 | my $self = shift; |
1115 | 11946 | @_ == 1 || @_ == 2 || croak(q/Usage: $handle->can_write([timeout])/); | 12015 | return $self->_do_timeout('read', @_) |
1116 | 11947 | my $self = shift; | 12016 | } |
1117 | 11948 | return $self->_do_timeout('write', @_) | 12017 | |
1118 | 11949 | } | 12018 | sub can_write { |
1119 | 12019 | @_ == 1 || @_ == 2 || croak(q/Usage: $handle->can_write([timeout])/); | ||
1120 | 12020 | my $self = shift; | ||
1121 | 12021 | return $self->_do_timeout('write', @_) | ||
1122 | 12022 | } | ||
1123 | 12023 | } # HTTP::Micro::Handle | ||
1124 | 11950 | 12024 | ||
1125 | 11951 | my $prog = <<'EOP'; | 12025 | my $prog = <<'EOP'; |
1126 | 11952 | BEGIN { | 12026 | BEGIN { |
1127 | @@ -11967,6 +12041,7 @@ | |||
1128 | 11967 | } | 12041 | } |
1129 | 11968 | } | 12042 | } |
1130 | 11969 | { | 12043 | { |
1131 | 12044 | use Carp qw(croak); | ||
1132 | 11970 | my %dispatcher = ( | 12045 | my %dispatcher = ( |
1133 | 11971 | issuer => sub { Net::SSLeay::X509_NAME_oneline( Net::SSLeay::X509_get_issuer_name( shift )) }, | 12046 | issuer => sub { Net::SSLeay::X509_NAME_oneline( Net::SSLeay::X509_get_issuer_name( shift )) }, |
1134 | 11972 | subject => sub { Net::SSLeay::X509_NAME_oneline( Net::SSLeay::X509_get_subject_name( shift )) }, | 12047 | subject => sub { Net::SSLeay::X509_NAME_oneline( Net::SSLeay::X509_get_subject_name( shift )) }, |
1135 | @@ -12122,9 +12197,8 @@ | |||
1136 | 12122 | } | 12197 | } |
1137 | 12123 | 12198 | ||
1138 | 12124 | 1; | 12199 | 1; |
1139 | 12125 | } | ||
1140 | 12126 | # ########################################################################### | 12200 | # ########################################################################### |
1142 | 12127 | # End HTTPMicro package | 12201 | # End HTTP::Micro package |
1143 | 12128 | # ########################################################################### | 12202 | # ########################################################################### |
1144 | 12129 | 12203 | ||
1145 | 12130 | # ########################################################################### | 12204 | # ########################################################################### |
1146 | @@ -12158,7 +12232,7 @@ | |||
1147 | 12158 | 12232 | ||
1148 | 12159 | eval { | 12233 | eval { |
1149 | 12160 | require Percona::Toolkit; | 12234 | require Percona::Toolkit; |
1151 | 12161 | require HTTPMicro; | 12235 | require HTTP::Micro; |
1152 | 12162 | }; | 12236 | }; |
1153 | 12163 | 12237 | ||
1154 | 12164 | { | 12238 | { |
1155 | @@ -12389,7 +12463,7 @@ | |||
1156 | 12389 | my $url = $args{url}; | 12463 | my $url = $args{url}; |
1157 | 12390 | my $instances = $args{instances}; | 12464 | my $instances = $args{instances}; |
1158 | 12391 | 12465 | ||
1160 | 12392 | my $ua = $args{ua} || HTTPMicro->new( timeout => 3 ); | 12466 | my $ua = $args{ua} || HTTP::Micro->new( timeout => 3 ); |
1161 | 12393 | 12467 | ||
1162 | 12394 | my $response = $ua->request('GET', $url); | 12468 | my $response = $ua->request('GET', $url); |
1163 | 12395 | PTDEBUG && _d('Server response:', Dumper($response)); | 12469 | PTDEBUG && _d('Server response:', Dumper($response)); |
1164 | @@ -13965,17 +14039,12 @@ | |||
1165 | 13965 | # ######################################################################## | 14039 | # ######################################################################## |
1166 | 13966 | # Daemonize now that everything is setup and ready to work. | 14040 | # Daemonize now that everything is setup and ready to work. |
1167 | 13967 | # ######################################################################## | 14041 | # ######################################################################## |
1179 | 13968 | my $daemon; | 14042 | my $daemon = Daemon->new( |
1180 | 13969 | if ( $o->get('daemonize') ) { | 14043 | daemonize => $o->get('daemonize'), |
1181 | 13970 | $daemon = new Daemon(o=>$o); | 14044 | pid_file => $o->get('pid'), |
1182 | 13971 | $daemon->daemonize(); | 14045 | log_file => $o->get('log'), |
1183 | 13972 | PTDEBUG && _d('I am a daemon now'); | 14046 | ); |
1184 | 13973 | } | 14047 | $daemon->run(); |
1174 | 13974 | elsif ( $o->get('pid') ) { | ||
1175 | 13975 | # We're not daemoninzing, it just handles PID stuff. | ||
1176 | 13976 | $daemon = new Daemon(o=>$o); | ||
1177 | 13977 | $daemon->make_PID_file(); | ||
1178 | 13978 | } | ||
1185 | 13979 | 14048 | ||
1186 | 13980 | # ######################################################################## | 14049 | # ######################################################################## |
1187 | 13981 | # Do the version-check | 14050 | # Do the version-check |
1188 | 13982 | 14051 | ||
1189 | === modified file 'lib/HTTP/Micro.pm' | |||
1190 | --- lib/HTTP/Micro.pm 2013-02-05 17:22:31 +0000 | |||
1191 | +++ lib/HTTP/Micro.pm 2013-08-03 19:47:33 +0000 | |||
1192 | @@ -708,5 +708,5 @@ | |||
1193 | 708 | 708 | ||
1194 | 709 | 1; | 709 | 1; |
1195 | 710 | # ########################################################################### | 710 | # ########################################################################### |
1197 | 711 | # End HTTPMicro package | 711 | # End HTTP::Micro package |
1198 | 712 | # ########################################################################### | 712 | # ########################################################################### |
1199 | 713 | 713 | ||
1200 | === modified file 'lib/QueryParser.pm' | |||
1201 | --- lib/QueryParser.pm 2013-01-03 00:19:16 +0000 | |||
1202 | +++ lib/QueryParser.pm 2013-08-03 19:47:33 +0000 | |||
1203 | @@ -98,7 +98,7 @@ | |||
1204 | 98 | 98 | ||
1205 | 99 | # These keywords may appear between UPDATE or SELECT and the table refs. | 99 | # These keywords may appear between UPDATE or SELECT and the table refs. |
1206 | 100 | # They need to be removed so that they are not mistaken for tables. | 100 | # They need to be removed so that they are not mistaken for tables. |
1208 | 101 | $query =~ s/ (?:LOW_PRIORITY|IGNORE|STRAIGHT_JOIN)//ig; | 101 | $query =~ s/(?:LOW_PRIORITY|IGNORE|STRAIGHT_JOIN|DELAYED)\s+/ /ig; |
1209 | 102 | 102 | ||
1210 | 103 | # Another special case: LOCK TABLES tbl [[AS] alias] READ|WRITE, etc. | 103 | # Another special case: LOCK TABLES tbl [[AS] alias] READ|WRITE, etc. |
1211 | 104 | # We strip the LOCK TABLES stuff and append "FROM" to fake a SELECT | 104 | # We strip the LOCK TABLES stuff and append "FROM" to fake a SELECT |
1212 | @@ -110,9 +110,21 @@ | |||
1213 | 110 | $query = "FROM $query"; | 110 | $query = "FROM $query"; |
1214 | 111 | } | 111 | } |
1215 | 112 | 112 | ||
1219 | 113 | $query =~ s/\\["']//g; # quoted strings | 113 | $query =~ s/\\["']//g; # quoted strings |
1220 | 114 | $query =~ s/".*?"/?/sg; # quoted strings | 114 | $query =~ s/".*?"/?/sg; # quoted strings |
1221 | 115 | $query =~ s/'.*?'/?/sg; # quoted strings | 115 | $query =~ s/'.*?'/?/sg; # quoted strings |
1222 | 116 | |||
1223 | 117 | # INSERT and REPLACE without INTO | ||
1224 | 118 | # https://bugs.launchpad.net/percona-toolkit/+bug/984053 | ||
1225 | 119 | if ( $query =~ m/\A\s*(?:INSERT|REPLACE)(?!\s+INTO)/i ) { | ||
1226 | 120 | # Add INTO so the reset of the code work as usual. | ||
1227 | 121 | $query =~ s/\A\s*((?:INSERT|REPLACE))\s+/$1 INTO /i; | ||
1228 | 122 | } | ||
1229 | 123 | |||
1230 | 124 | if ( $query =~ m/\A\s*LOAD DATA/i ) { | ||
1231 | 125 | my ($tbl) = $query =~ m/INTO TABLE\s+(\S+)/i; | ||
1232 | 126 | return $tbl; | ||
1233 | 127 | } | ||
1234 | 116 | 128 | ||
1235 | 117 | my @tables; | 129 | my @tables; |
1236 | 118 | foreach my $tbls ( $query =~ m/$tbl_regex/gio ) { | 130 | foreach my $tbls ( $query =~ m/$tbl_regex/gio ) { |
1237 | 119 | 131 | ||
1238 | === modified file 'lib/QueryRewriter.pm' | |||
1239 | --- lib/QueryRewriter.pm 2013-06-27 18:54:53 +0000 | |||
1240 | +++ lib/QueryRewriter.pm 2013-08-03 19:47:33 +0000 | |||
1241 | @@ -246,6 +246,13 @@ | |||
1242 | 246 | $query =~ m/\A\s*UNLOCK TABLES/i && return "UNLOCK"; | 246 | $query =~ m/\A\s*UNLOCK TABLES/i && return "UNLOCK"; |
1243 | 247 | $query =~ m/\A\s*xa\s+(\S+)/i && return "XA_$1"; | 247 | $query =~ m/\A\s*xa\s+(\S+)/i && return "XA_$1"; |
1244 | 248 | 248 | ||
1245 | 249 | if ( $query =~ m/\A\s*LOAD/i ) { | ||
1246 | 250 | my ($tbl) = $query =~ m/INTO TABLE\s+(\S+)/i; | ||
1247 | 251 | $tbl ||= ''; | ||
1248 | 252 | $tbl =~ s/`//g; | ||
1249 | 253 | return "LOAD DATA $tbl"; | ||
1250 | 254 | } | ||
1251 | 255 | |||
1252 | 249 | if ( $query =~ m/\Aadministrator command:/ ) { | 256 | if ( $query =~ m/\Aadministrator command:/ ) { |
1253 | 250 | $query =~ s/administrator command:/ADMIN/; | 257 | $query =~ s/administrator command:/ADMIN/; |
1254 | 251 | $query = uc $query; | 258 | $query = uc $query; |
1255 | @@ -386,6 +393,9 @@ | |||
1256 | 386 | map { $verbs =~ s/$_/$alias_for{$_}/ } keys %alias_for; | 393 | map { $verbs =~ s/$_/$alias_for{$_}/ } keys %alias_for; |
1257 | 387 | $query = $verbs; | 394 | $query = $verbs; |
1258 | 388 | } | 395 | } |
1259 | 396 | elsif ( $verbs && $verbs =~ m/^LOAD DATA/ ) { | ||
1260 | 397 | return $verbs; | ||
1261 | 398 | } | ||
1262 | 389 | else { | 399 | else { |
1263 | 390 | # For everything else, distill the tables. | 400 | # For everything else, distill the tables. |
1264 | 391 | my @tables = $self->__distill_tables($query, $table, %args); | 401 | my @tables = $self->__distill_tables($query, $table, %args); |
1265 | 392 | 402 | ||
1266 | === modified file 'lib/VersionCheck.pm' | |||
1267 | --- lib/VersionCheck.pm 2013-06-17 06:23:11 +0000 | |||
1268 | +++ lib/VersionCheck.pm 2013-08-03 19:47:33 +0000 | |||
1269 | @@ -45,7 +45,7 @@ | |||
1270 | 45 | 45 | ||
1271 | 46 | eval { | 46 | eval { |
1272 | 47 | require Percona::Toolkit; | 47 | require Percona::Toolkit; |
1274 | 48 | require HTTPMicro; | 48 | require HTTP::Micro; |
1275 | 49 | }; | 49 | }; |
1276 | 50 | 50 | ||
1277 | 51 | # Return the version check file used to keep track of | 51 | # Return the version check file used to keep track of |
1278 | @@ -335,7 +335,7 @@ | |||
1279 | 335 | my $instances = $args{instances}; | 335 | my $instances = $args{instances}; |
1280 | 336 | 336 | ||
1281 | 337 | # Optional args | 337 | # Optional args |
1283 | 338 | my $ua = $args{ua} || HTTPMicro->new( timeout => 3 ); | 338 | my $ua = $args{ua} || HTTP::Micro->new( timeout => 3 ); |
1284 | 339 | 339 | ||
1285 | 340 | # GET https://upgrade.percona.com, the server will return | 340 | # GET https://upgrade.percona.com, the server will return |
1286 | 341 | # a plaintext list of items/programs it wants the tool | 341 | # a plaintext list of items/programs it wants the tool |
1287 | 342 | 342 | ||
1288 | === modified file 't/lib/QueryParser.t' | |||
1289 | --- t/lib/QueryParser.t 2012-08-16 22:18:14 +0000 | |||
1290 | +++ t/lib/QueryParser.t 2013-08-03 19:47:33 +0000 | |||
1291 | @@ -828,6 +828,12 @@ | |||
1292 | 828 | [qw(t1 t2)], 'get_tables works for lowercased LOCK TABLES', | 828 | [qw(t1 t2)], 'get_tables works for lowercased LOCK TABLES', |
1293 | 829 | ); | 829 | ); |
1294 | 830 | 830 | ||
1295 | 831 | is_deeply( | ||
1296 | 832 | [ $qp->get_tables("LOAD DATA INFILE '/tmp/foo.txt' INTO TABLE db.tbl") ], | ||
1297 | 833 | [qw(db.tbl)], | ||
1298 | 834 | "LOAD DATA db.tbl" | ||
1299 | 835 | ); | ||
1300 | 836 | |||
1301 | 831 | # ############################################################################# | 837 | # ############################################################################# |
1302 | 832 | # Done. | 838 | # Done. |
1303 | 833 | # ############################################################################# | 839 | # ############################################################################# |
1304 | 834 | 840 | ||
1305 | === modified file 't/lib/QueryRewriter.t' | |||
1306 | --- t/lib/QueryRewriter.t 2013-06-27 18:53:06 +0000 | |||
1307 | +++ t/lib/QueryRewriter.t 2013-08-03 19:47:33 +0000 | |||
1308 | @@ -1412,6 +1412,34 @@ | |||
1309 | 1412 | 'distills SELECT with REPLACE function (issue 1176)' | 1412 | 'distills SELECT with REPLACE function (issue 1176)' |
1310 | 1413 | ); | 1413 | ); |
1311 | 1414 | 1414 | ||
1312 | 1415 | # LOAD DATA | ||
1313 | 1416 | # https://bugs.launchpad.net/percona-toolkit/+bug/821692 | ||
1314 | 1417 | # INSERT and REPLACE without INTO | ||
1315 | 1418 | # https://bugs.launchpad.net/percona-toolkit/+bug/984053 | ||
1316 | 1419 | is( | ||
1317 | 1420 | $qr->distill("LOAD DATA LOW_PRIORITY LOCAL INFILE 'file' INTO TABLE tbl"), | ||
1318 | 1421 | "LOAD DATA tbl", | ||
1319 | 1422 | "distill LOAD DATA (bug 821692)" | ||
1320 | 1423 | ); | ||
1321 | 1424 | |||
1322 | 1425 | is( | ||
1323 | 1426 | $qr->distill("LOAD DATA LOW_PRIORITY LOCAL INFILE 'file' INTO TABLE `tbl`"), | ||
1324 | 1427 | "LOAD DATA tbl", | ||
1325 | 1428 | "distill LOAD DATA (bug 821692)" | ||
1326 | 1429 | ); | ||
1327 | 1430 | |||
1328 | 1431 | is( | ||
1329 | 1432 | $qr->distill("insert ignore_bar (id) values (4029731)"), | ||
1330 | 1433 | "INSERT ignore_bar", | ||
1331 | 1434 | "distill INSERT without INTO (bug 984053)" | ||
1332 | 1435 | ); | ||
1333 | 1436 | |||
1334 | 1437 | is( | ||
1335 | 1438 | $qr->distill("replace ignore_bar (id) values (4029731)"), | ||
1336 | 1439 | "REPLACE ignore_bar", | ||
1337 | 1440 | "distill REPLACE without INTO (bug 984053)" | ||
1338 | 1441 | ); | ||
1339 | 1442 | |||
1340 | 1415 | # ############################################################################# | 1443 | # ############################################################################# |
1341 | 1416 | # Done. | 1444 | # Done. |
1342 | 1417 | # ############################################################################# | 1445 | # ############################################################################# |
1343 | 1418 | 1446 | ||
1344 | === modified file 't/lib/samples/slowlogs/slow051.txt' | |||
1345 | --- t/lib/samples/slowlogs/slow051.txt 2011-06-24 17:22:06 +0000 | |||
1346 | +++ t/lib/samples/slowlogs/slow051.txt 2013-08-03 19:47:33 +0000 | |||
1347 | @@ -1,6 +1,6 @@ | |||
1348 | 1 | # Time: 071218 11:48:27 | 1 | # Time: 071218 11:48:27 |
1349 | 2 | # Query_time: 0.000012 Lock_time: 0.000000 Rows_sent: 0 Rows_examined: 0 | 2 | # Query_time: 0.000012 Lock_time: 0.000000 Rows_sent: 0 Rows_examined: 0 |
1351 | 3 | LOAD DATA INFILE '/tmp/foo.txt' INTO db.tbl; | 3 | LOAD DATA INFILE '/tmp/foo.txt' INTO TABLE db.tbl; |
1352 | 4 | # Time: 071218 11:48:37 | 4 | # Time: 071218 11:48:37 |
1353 | 5 | # Query_time: 0.000012 Lock_time: 0.000000 Rows_sent: 0 Rows_examined: 0 | 5 | # Query_time: 0.000012 Lock_time: 0.000000 Rows_sent: 0 Rows_examined: 0 |
1355 | 6 | LOAD DATA INFILE '/tmp/bar.txt' INTO db.tbl; | 6 | LOAD DATA INFILE '/tmp/bar.txt' INTO TABLE db.tbl; |
1356 | 7 | 7 | ||
1357 | === added file 't/lib/samples/slowlogs/slow058.txt' | |||
1358 | --- t/lib/samples/slowlogs/slow058.txt 1970-01-01 00:00:00 +0000 | |||
1359 | +++ t/lib/samples/slowlogs/slow058.txt 2013-08-03 19:47:33 +0000 | |||
1360 | @@ -0,0 +1,24 @@ | |||
1361 | 1 | # User@Host: meow[meow] @ [1.2.3.8] | ||
1362 | 2 | # Thread_id: 5 Schema: db | ||
1363 | 3 | # Query_time: 0.000002 Lock_time: 0.000000 Rows_sent: 0 Rows_examined: 0 | ||
1364 | 4 | LOAD DATA LOCAL INFILE '/tmp/foo.txt' INTO TABLE `foo`; | ||
1365 | 5 | # User@Host: meow[meow] @ [1.2.3.8] | ||
1366 | 6 | # Thread_id: 7 Schema: db | ||
1367 | 7 | # Query_time: 0.018799 Lock_time: 0.009453 Rows_sent: 0 Rows_examined: 0 | ||
1368 | 8 | INSERT `foo` VALUES("bar"); | ||
1369 | 9 | # User@Host: meow[meow] @ [1.2.3.8] | ||
1370 | 10 | # Thread_id: 7 Schema: db | ||
1371 | 11 | # Query_time: 0.018799 Lock_time: 0.009453 Rows_sent: 0 Rows_examined: 0 | ||
1372 | 12 | REPLACE `foo` VALUES("bar"); | ||
1373 | 13 | # User@Host: meow[meow] @ [1.2.3.8] | ||
1374 | 14 | # Thread_id: 5 Schema: db | ||
1375 | 15 | # Query_time: 0.000002 Lock_time: 0.000000 Rows_sent: 0 Rows_examined: 0 | ||
1376 | 16 | load data local infile '/tmp/foo.txt' into table `foo`; | ||
1377 | 17 | # User@Host: meow[meow] @ [1.2.3.8] | ||
1378 | 18 | # Thread_id: 7 Schema: db | ||
1379 | 19 | # Query_time: 0.018799 Lock_time: 0.009453 Rows_sent: 0 Rows_examined: 0 | ||
1380 | 20 | insert `foo` values("bar"); | ||
1381 | 21 | # User@Host: meow[meow] @ [1.2.3.8] | ||
1382 | 22 | # Thread_id: 7 Schema: db | ||
1383 | 23 | # Query_time: 0.018799 Lock_time: 0.009453 Rows_sent: 0 Rows_examined: 0 | ||
1384 | 24 | replace `foo` values("bar"); | ||
1385 | 0 | 25 | ||
1386 | === modified file 't/pt-query-digest/binlog_analyses.t' | |||
1387 | --- t/pt-query-digest/binlog_analyses.t 2012-11-21 16:58:40 +0000 | |||
1388 | +++ t/pt-query-digest/binlog_analyses.t 2013-08-03 19:47:33 +0000 | |||
1389 | @@ -28,7 +28,7 @@ | |||
1390 | 28 | "t/pt-query-digest/samples/binlog001.txt" | 28 | "t/pt-query-digest/samples/binlog001.txt" |
1391 | 29 | ), | 29 | ), |
1392 | 30 | 'Analysis for binlog001', | 30 | 'Analysis for binlog001', |
1394 | 31 | ); | 31 | ) or diag($test_diff); |
1395 | 32 | 32 | ||
1396 | 33 | ok( | 33 | ok( |
1397 | 34 | no_diff( | 34 | no_diff( |
1398 | @@ -36,7 +36,7 @@ | |||
1399 | 36 | "t/pt-query-digest/samples/binlog002.txt" | 36 | "t/pt-query-digest/samples/binlog002.txt" |
1400 | 37 | ), | 37 | ), |
1401 | 38 | 'Analysis for binlog002', | 38 | 'Analysis for binlog002', |
1403 | 39 | ); | 39 | ) or diag($test_diff); |
1404 | 40 | 40 | ||
1405 | 41 | # ############################################################################# | 41 | # ############################################################################# |
1406 | 42 | # Done. | 42 | # Done. |
1407 | 43 | 43 | ||
1408 | === modified file 't/pt-query-digest/daemon.t' | |||
1409 | --- t/pt-query-digest/daemon.t 2012-06-03 19:14:30 +0000 | |||
1410 | +++ t/pt-query-digest/daemon.t 2013-08-03 19:47:33 +0000 | |||
1411 | @@ -32,8 +32,8 @@ | |||
1412 | 32 | $output = `$trunk/bin/pt-query-digest $trunk/commont/t/samples/slow002.txt --pid $pid_file 2>&1`; | 32 | $output = `$trunk/bin/pt-query-digest $trunk/commont/t/samples/slow002.txt --pid $pid_file 2>&1`; |
1413 | 33 | like( | 33 | like( |
1414 | 34 | $output, | 34 | $output, |
1417 | 35 | qr{PID file $pid_file already exists}, | 35 | qr{PID file $pid_file exists}, |
1418 | 36 | 'Dies if PID file already exists (--pid without --daemonize) (issue 391)' | 36 | 'Dies if PID file exists (--pid without --daemonize) (issue 391)' |
1419 | 37 | ); | 37 | ); |
1420 | 38 | `rm $pid_file >/dev/null 2>&1`; | 38 | `rm $pid_file >/dev/null 2>&1`; |
1421 | 39 | 39 | ||
1422 | 40 | 40 | ||
1423 | === modified file 't/pt-query-digest/json.t' | |||
1424 | --- t/pt-query-digest/json.t 2013-07-01 20:59:12 +0000 | |||
1425 | +++ t/pt-query-digest/json.t 2013-08-03 19:47:33 +0000 | |||
1426 | @@ -25,7 +25,7 @@ | |||
1427 | 25 | ok( | 25 | ok( |
1428 | 26 | no_diff( | 26 | no_diff( |
1429 | 27 | sub { pt_query_digest::main(@args, "$sample/slowlogs/empty") }, | 27 | sub { pt_query_digest::main(@args, "$sample/slowlogs/empty") }, |
1431 | 28 | "t/pt-query-digest/samples/empty_report.txt", | 28 | "t/pt-query-digest/samples/empty_json_report.txt", |
1432 | 29 | ), | 29 | ), |
1433 | 30 | 'json output for empty log' | 30 | 'json output for empty log' |
1434 | 31 | ) or diag($test_diff); | 31 | ) or diag($test_diff); |
1435 | 32 | 32 | ||
1436 | === modified file 't/pt-query-digest/samples/binlog002.txt' | |||
1437 | --- t/pt-query-digest/samples/binlog002.txt 2013-01-11 16:45:20 +0000 | |||
1438 | +++ t/pt-query-digest/samples/binlog002.txt 2013-08-03 19:47:33 +0000 | |||
1439 | @@ -89,6 +89,9 @@ | |||
1440 | 89 | # 100ms | 89 | # 100ms |
1441 | 90 | # 1s | 90 | # 1s |
1442 | 91 | # 10s+ | 91 | # 10s+ |
1443 | 92 | # Tables | ||
1444 | 93 | # SHOW TABLE STATUS FROM `d` LIKE 'foo'\G | ||
1445 | 94 | # SHOW CREATE TABLE `d`.`foo`\G | ||
1446 | 92 | insert foo values (1) /*... omitted ...*/\G | 95 | insert foo values (1) /*... omitted ...*/\G |
1447 | 93 | 96 | ||
1448 | 94 | # Profile | 97 | # Profile |
1449 | @@ -96,4 +99,4 @@ | |||
1450 | 96 | # ==== ================== ============= ===== ====== ===== =============== | 99 | # ==== ================== ============= ===== ====== ===== =============== |
1451 | 97 | # 1 0xF25D6D5AC7C18FF3 0.0000 0.0% 1 0.0000 0.00 CREATE DATABASE d | 100 | # 1 0xF25D6D5AC7C18FF3 0.0000 0.0% 1 0.0000 0.00 CREATE DATABASE d |
1452 | 98 | # 2 0x03409022EB8A4AE7 0.0000 0.0% 1 0.0000 0.00 CREATE TABLE foo | 101 | # 2 0x03409022EB8A4AE7 0.0000 0.0% 1 0.0000 0.00 CREATE TABLE foo |
1454 | 99 | # 3 0xF579EC4A9633EEA0 0.0000 0.0% 1 0.0000 0.00 INSERT | 102 | # 3 0xF579EC4A9633EEA0 0.0000 0.0% 1 0.0000 0.00 INSERT foo |
1455 | 100 | 103 | ||
1456 | === added file 't/pt-query-digest/samples/empty_json_report.txt' | |||
1457 | === modified file 't/pt-query-digest/samples/empty_report.txt' | |||
1458 | --- t/pt-query-digest/samples/empty_report.txt 2013-07-01 20:38:34 +0000 | |||
1459 | +++ t/pt-query-digest/samples/empty_report.txt 2013-08-03 19:47:33 +0000 | |||
1460 | @@ -0,0 +1,2 @@ | |||
1461 | 1 | |||
1462 | 2 | # No events processed. | ||
1463 | 0 | 3 | ||
1464 | === modified file 't/pt-query-digest/samples/slow051.txt' | |||
1465 | --- t/pt-query-digest/samples/slow051.txt 2013-01-11 16:45:20 +0000 | |||
1466 | +++ t/pt-query-digest/samples/slow051.txt 2013-08-03 19:47:33 +0000 | |||
1467 | @@ -1,5 +1,5 @@ | |||
1468 | 1 | 1 | ||
1470 | 2 | # Query 1: 0.20 QPS, 0.00x concurrency, ID 0xD989521B246E945B at byte 146 | 2 | # Query 1: 0.20 QPS, 0.00x concurrency, ID 0x14354E1D979884B4 at byte 152 |
1471 | 3 | # This item is included in the report because it matches --limit. | 3 | # This item is included in the report because it matches --limit. |
1472 | 4 | # Scores: V/M = 0.00 | 4 | # Scores: V/M = 0.00 |
1473 | 5 | # Time range: 2007-12-18 11:48:27 to 11:48:37 | 5 | # Time range: 2007-12-18 11:48:27 to 11:48:37 |
1474 | @@ -10,7 +10,7 @@ | |||
1475 | 10 | # Lock time 0 0 0 0 0 0 0 0 | 10 | # Lock time 0 0 0 0 0 0 0 0 |
1476 | 11 | # Rows sent 0 0 0 0 0 0 0 0 | 11 | # Rows sent 0 0 0 0 0 0 0 0 |
1477 | 12 | # Rows examine 0 0 0 0 0 0 0 0 | 12 | # Rows examine 0 0 0 0 0 0 0 0 |
1479 | 13 | # Query size 100 86 43 43 43 43 0 43 | 13 | # Query size 100 98 49 49 49 49 0 49 |
1480 | 14 | # Query_time distribution | 14 | # Query_time distribution |
1481 | 15 | # 1us | 15 | # 1us |
1482 | 16 | # 10us ################################################################ | 16 | # 10us ################################################################ |
1483 | @@ -23,9 +23,9 @@ | |||
1484 | 23 | # Tables | 23 | # Tables |
1485 | 24 | # SHOW TABLE STATUS FROM `db` LIKE 'tbl'\G | 24 | # SHOW TABLE STATUS FROM `db` LIKE 'tbl'\G |
1486 | 25 | # SHOW CREATE TABLE `db`.`tbl`\G | 25 | # SHOW CREATE TABLE `db`.`tbl`\G |
1488 | 26 | LOAD DATA INFILE '/tmp/bar.txt' INTO db.tbl\G | 26 | LOAD DATA INFILE '/tmp/bar.txt' INTO TABLE db.tbl\G |
1489 | 27 | 27 | ||
1490 | 28 | # Profile | 28 | # Profile |
1491 | 29 | # Rank Query ID Response time Calls R/Call V/M Item | 29 | # Rank Query ID Response time Calls R/Call V/M Item |
1494 | 30 | # ==== ================== ============= ===== ====== ===== ====== | 30 | # ==== ================== ============= ===== ====== ===== =============== |
1495 | 31 | # 1 0xD989521B246E945B 0.0000 100.0% 2 0.0000 0.00 db.tbl | 31 | # 1 0x14354E1D979884B4 0.0000 100.0% 2 0.0000 0.00 LOAD DATA db.tbl |
1496 | 32 | 32 | ||
1497 | === added file 't/pt-query-digest/samples/slow058.txt' | |||
1498 | --- t/pt-query-digest/samples/slow058.txt 1970-01-01 00:00:00 +0000 | |||
1499 | +++ t/pt-query-digest/samples/slow058.txt 2013-08-03 19:47:33 +0000 | |||
1500 | @@ -0,0 +1,94 @@ | |||
1501 | 1 | |||
1502 | 2 | # Query 1: 0 QPS, 0x concurrency, ID 0x471A0C4BD7A4EE34 at byte 730 ______ | ||
1503 | 3 | # This item is included in the report because it matches --limit. | ||
1504 | 4 | # Scores: V/M = 0.00 | ||
1505 | 5 | # Attribute pct total min max avg 95% stddev median | ||
1506 | 6 | # ============ === ======= ======= ======= ======= ======= ======= ======= | ||
1507 | 7 | # Count 33 2 | ||
1508 | 8 | # Exec time 49 38ms 19ms 19ms 19ms 19ms 0 19ms | ||
1509 | 9 | # Lock time 50 19ms 9ms 9ms 9ms 9ms 0 9ms | ||
1510 | 10 | # Rows sent 0 0 0 0 0 0 0 0 | ||
1511 | 11 | # Rows examine 0 0 0 0 0 0 0 0 | ||
1512 | 12 | # Query size 24 52 26 26 26 26 0 26 | ||
1513 | 13 | # String: | ||
1514 | 14 | # Databases db | ||
1515 | 15 | # Hosts | ||
1516 | 16 | # Users meow | ||
1517 | 17 | # Query_time distribution | ||
1518 | 18 | # 1us | ||
1519 | 19 | # 10us | ||
1520 | 20 | # 100us | ||
1521 | 21 | # 1ms | ||
1522 | 22 | # 10ms ################################################################ | ||
1523 | 23 | # 100ms | ||
1524 | 24 | # 1s | ||
1525 | 25 | # 10s+ | ||
1526 | 26 | # Tables | ||
1527 | 27 | # SHOW TABLE STATUS FROM `db` LIKE 'foo'\G | ||
1528 | 28 | # SHOW CREATE TABLE `db`.`foo`\G | ||
1529 | 29 | insert `foo` values("bar")\G | ||
1530 | 30 | |||
1531 | 31 | # Query 2: 0 QPS, 0x concurrency, ID 0xF33473286088142B at byte 898 ______ | ||
1532 | 32 | # This item is included in the report because it matches --limit. | ||
1533 | 33 | # Scores: V/M = 0.00 | ||
1534 | 34 | # Attribute pct total min max avg 95% stddev median | ||
1535 | 35 | # ============ === ======= ======= ======= ======= ======= ======= ======= | ||
1536 | 36 | # Count 33 2 | ||
1537 | 37 | # Exec time 49 38ms 19ms 19ms 19ms 19ms 0 19ms | ||
1538 | 38 | # Lock time 50 19ms 9ms 9ms 9ms 9ms 0 9ms | ||
1539 | 39 | # Rows sent 0 0 0 0 0 0 0 0 | ||
1540 | 40 | # Rows examine 0 0 0 0 0 0 0 0 | ||
1541 | 41 | # Query size 25 54 27 27 27 27 0 27 | ||
1542 | 42 | # String: | ||
1543 | 43 | # Databases db | ||
1544 | 44 | # Hosts | ||
1545 | 45 | # Users meow | ||
1546 | 46 | # Query_time distribution | ||
1547 | 47 | # 1us | ||
1548 | 48 | # 10us | ||
1549 | 49 | # 100us | ||
1550 | 50 | # 1ms | ||
1551 | 51 | # 10ms ################################################################ | ||
1552 | 52 | # 100ms | ||
1553 | 53 | # 1s | ||
1554 | 54 | # 10s+ | ||
1555 | 55 | # Tables | ||
1556 | 56 | # SHOW TABLE STATUS FROM `db` LIKE 'foo'\G | ||
1557 | 57 | # SHOW CREATE TABLE `db`.`foo`\G | ||
1558 | 58 | replace `foo` values("bar")\G | ||
1559 | 59 | |||
1560 | 60 | # Query 3: 0 QPS, 0x concurrency, ID 0xEBAC9C76529E62CE at byte 534 ______ | ||
1561 | 61 | # This item is included in the report because it matches --limit. | ||
1562 | 62 | # Scores: V/M = 0.00 | ||
1563 | 63 | # Attribute pct total min max avg 95% stddev median | ||
1564 | 64 | # ============ === ======= ======= ======= ======= ======= ======= ======= | ||
1565 | 65 | # Count 33 2 | ||
1566 | 66 | # Exec time 0 4us 2us 2us 2us 2us 0 2us | ||
1567 | 67 | # Lock time 0 0 0 0 0 0 0 0 | ||
1568 | 68 | # Rows sent 0 0 0 0 0 0 0 0 | ||
1569 | 69 | # Rows examine 0 0 0 0 0 0 0 0 | ||
1570 | 70 | # Query size 50 108 54 54 54 54 0 54 | ||
1571 | 71 | # String: | ||
1572 | 72 | # Databases db | ||
1573 | 73 | # Hosts | ||
1574 | 74 | # Users meow | ||
1575 | 75 | # Query_time distribution | ||
1576 | 76 | # 1us ################################################################ | ||
1577 | 77 | # 10us | ||
1578 | 78 | # 100us | ||
1579 | 79 | # 1ms | ||
1580 | 80 | # 10ms | ||
1581 | 81 | # 100ms | ||
1582 | 82 | # 1s | ||
1583 | 83 | # 10s+ | ||
1584 | 84 | # Tables | ||
1585 | 85 | # SHOW TABLE STATUS FROM `db` LIKE 'foo'\G | ||
1586 | 86 | # SHOW CREATE TABLE `db`.`foo`\G | ||
1587 | 87 | load data local infile '/tmp/foo.txt' into table `foo`\G | ||
1588 | 88 | |||
1589 | 89 | # Profile | ||
1590 | 90 | # Rank Query ID Response time Calls R/Call V/M Item | ||
1591 | 91 | # ==== ================== ============= ===== ====== ===== ============= | ||
1592 | 92 | # 1 0x471A0C4BD7A4EE34 0.0376 50.0% 2 0.0188 0.00 INSERT foo | ||
1593 | 93 | # 2 0xF33473286088142B 0.0376 50.0% 2 0.0188 0.00 REPLACE foo | ||
1594 | 94 | # 3 0xEBAC9C76529E62CE 0.0000 0.0% 2 0.0000 0.00 LOAD DATA foo | ||
1595 | 0 | 95 | ||
1596 | === modified file 't/pt-query-digest/slowlog_analyses.t' | |||
1597 | --- t/pt-query-digest/slowlog_analyses.t 2013-06-26 23:16:15 +0000 | |||
1598 | +++ t/pt-query-digest/slowlog_analyses.t 2013-08-03 19:47:33 +0000 | |||
1599 | @@ -343,7 +343,7 @@ | |||
1600 | 343 | "t/pt-query-digest/samples/slow051.txt", | 343 | "t/pt-query-digest/samples/slow051.txt", |
1601 | 344 | ), | 344 | ), |
1602 | 345 | 'Analysis for slow051 (issue 918)', | 345 | 'Analysis for slow051 (issue 918)', |
1604 | 346 | ); | 346 | ) or diag($test_diff); |
1605 | 347 | 347 | ||
1606 | 348 | # ############################################################################# | 348 | # ############################################################################# |
1607 | 349 | # Issue 1124: Make mk-query-digest profile include variance-to-mean ratio | 349 | # Issue 1124: Make mk-query-digest profile include variance-to-mean ratio |
1608 | @@ -394,9 +394,10 @@ | |||
1609 | 394 | ); | 394 | ); |
1610 | 395 | 395 | ||
1611 | 396 | # ############################################################################# | 396 | # ############################################################################# |
1613 | 397 | # Bug 1176010: pt-query-digest should know how to group quoted and unquoted database names | 397 | # Bug 1176010: pt-query-digest should know how to group quoted and unquoted |
1614 | 398 | # database names | ||
1615 | 398 | # https://bugs.launchpad.net/percona-toolkit/+bug/1176010 | 399 | # https://bugs.launchpad.net/percona-toolkit/+bug/1176010 |
1617 | 399 | ############################################################################# | 400 | # ############################################################################# |
1618 | 400 | ok( | 401 | ok( |
1619 | 401 | no_diff( | 402 | no_diff( |
1620 | 402 | sub { pt_query_digest::main(@args, $sample.'slow057.txt', | 403 | sub { pt_query_digest::main(@args, $sample.'slow057.txt', |
1621 | @@ -407,6 +408,22 @@ | |||
1622 | 407 | ) or diag($test_diff); | 408 | ) or diag($test_diff); |
1623 | 408 | 409 | ||
1624 | 409 | # ############################################################################# | 410 | # ############################################################################# |
1625 | 411 | # https://bugs.launchpad.net/percona-toolkit/+bug/821692 | ||
1626 | 412 | # pt-query-digest doesn't distill LOAD DATA correctly | ||
1627 | 413 | # https://bugs.launchpad.net/percona-toolkit/+bug/984053 | ||
1628 | 414 | # pt-query-digest doesn't distill INSERT/REPLACE without INTO correctly | ||
1629 | 415 | # ############################################################################# | ||
1630 | 416 | ok( | ||
1631 | 417 | no_diff( | ||
1632 | 418 | sub { pt_query_digest::main($sample.'slow058.txt', | ||
1633 | 419 | '--report-format', 'query_report,profile', '--limit', '100%', | ||
1634 | 420 | )}, | ||
1635 | 421 | "t/pt-query-digest/samples/slow058.txt", | ||
1636 | 422 | ), | ||
1637 | 423 | 'Analysis for slow058 (bug 821692, bug 984053)' | ||
1638 | 424 | ) or diag($test_diff); | ||
1639 | 425 | |||
1640 | 426 | # ############################################################################# | ||
1641 | 410 | # Done. | 427 | # Done. |
1642 | 411 | # ############################################################################# | 428 | # ############################################################################# |
1643 | 412 | done_testing; | 429 | done_testing; |
1644 | 413 | 430 | ||
1645 | === modified file 'util/update-modules' | |||
1646 | --- util/update-modules 2013-01-17 22:09:52 +0000 | |||
1647 | +++ util/update-modules 2013-08-03 19:47:33 +0000 | |||
1648 | @@ -91,7 +91,7 @@ | |||
1649 | 91 | 91 | ||
1650 | 92 | $BRANCH/util/extract-package $pkg $pkg_file | grep -v '^ *#' >> $tmp_file | 92 | $BRANCH/util/extract-package $pkg $pkg_file | grep -v '^ *#' >> $tmp_file |
1651 | 93 | 93 | ||
1653 | 94 | if [ "$tool_lang" = "perl" ]; then | 94 | if [ "$tool_lang" = "perl" -a $pkg != "HTTP::Micro" ]; then |
1654 | 95 | echo "}" >> $tmp_file | 95 | echo "}" >> $tmp_file |
1655 | 96 | fi | 96 | fi |
1656 | 97 | 97 |