Merge lp:~percona-toolkit-dev/percona-toolkit/pt-upgrade-fails-on-SELECT-INTO-queries-1421781 into lp:~percona-toolkit-dev/percona-toolkit/release-2.2.14

Proposed by Frank Cizmich
Status: Merged
Approved by: Daniel Nichter
Approved revision: 615
Merged at revision: 616
Proposed branch: lp:~percona-toolkit-dev/percona-toolkit/pt-upgrade-fails-on-SELECT-INTO-queries-1421781
Merge into: lp:~percona-toolkit-dev/percona-toolkit/release-2.2.14
Diff against target: 136 lines (+84/-4)
4 files modified
bin/pt-upgrade (+11/-3)
lib/ResultWriter.pm (+3/-1)
t/pt-upgrade/issue_1421781.t (+66/-0)
t/pt-upgrade/samples/select_into.log (+4/-0)
To merge this branch: bzr merge lp:~percona-toolkit-dev/percona-toolkit/pt-upgrade-fails-on-SELECT-INTO-queries-1421781
Reviewer Review Type Date Requested Status
Daniel Nichter Approve
Review via email: mp+254640@code.launchpad.net

Description of the change

Proplem:

pt-upgrade fails when log contains queries of the form:
SELECT...INTO

This is because the tool treats it as a regular select that returns rows, so it performs first the execute(), which works fine, but then fails when attempting to fetch() since DBI considers the operation already over.

Solution:

Filter these out via regex. (excludes the three forms , OUTFILE, DUMPFILE and @variable)

Notes:
- changes made in 2 place: module ResultWriter and tool's main()
- also created test case

To post a comment you must log in.
Revision history for this message
Daniel Nichter (daniel-nichter) wrote :

Would be good to document that these queries are skipped/ignored.

Revision history for this message
Daniel Nichter (daniel-nichter) :
review: Needs Information
615. By Frank Cizmich

Added info in doc. Minor test tweak

Revision history for this message
Daniel Nichter (daniel-nichter) wrote :

"but dump output to a file or variable)" needs a period. :-) Otherwise code is fine.

review: Approve
616. By Frank Cizmich

minor typo

Revision history for this message
Frank Cizmich (frank-cizmich) wrote :

Added period. (Inside the parentheses like in this case.)

In other cases it would go outside, (like here for example).

:-)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/pt-upgrade'
2--- bin/pt-upgrade 2015-01-23 10:19:56 +0000
3+++ bin/pt-upgrade 2015-04-07 20:07:53 +0000
4@@ -6304,7 +6304,11 @@
5 else {
6 my $rows;
7 if ( my $sth = $results->{sth} ) {
8- if ( $event->{arg} =~ m/(?:^\s*SELECT|(?:\*\/\s*SELECT))/i ) {
9+ # Only fetch rows of select statements
10+ # *except* when they are directed INTO
11+ # a file or a variable. (issue lp:1421781)
12+ if ( $event->{arg} =~ m/(?:^\s*SELECT|(?:\*\/\s*SELECT))/i
13+ && $event->{arg} !~ /INTO\s*(?:OUTFILE|DUMPFILE|@)/ ) {
14 $rows = $sth->fetchall_arrayref();
15 }
16 eval {
17@@ -10120,9 +10124,11 @@
18 ignore_warnings => $ignore_warnings,
19 );
20
21- # Only SELECT statements return rows.
22+ # Only SELECT statements return rows, *except* when they are directed
23+ # INTO a file or a variable.
24 my $row_diffs;
25- if ( $event->{arg} =~ m/(?:^\s*SELECT|(?:\*\/\s*SELECT))/i ) {
26+ if ( $event->{arg} =~ m/(?:^\s*SELECT|(?:\*\/\s*SELECT))/i
27+ && $event->{arg} !~ m/INTO\s*(?:OUTFILE|DUMPFILE|@)/i ) {
28 $row_diffs = diff_rows(
29 sth1 => $results1->{sth},
30 sth2 => $results2->{sth},
31@@ -10608,6 +10614,8 @@
32 =head2 READ-ONLY
33
34 By default, pt-upgrade only executes C<SELECT> and C<SET> statements.
35+(This does not include 'SELECT...INTO' statements, which do not return
36+rows but dump output to a file or variable.)
37 If you're using recreatable test or development servers and wish to
38 compare write statements too (e.g. C<INSERT>, C<UPDATE>, C<DELETE>),
39 then specify C<--no-read-only>. If using a binary log, you must
40
41=== modified file 'lib/ResultWriter.pm'
42--- lib/ResultWriter.pm 2013-02-20 16:37:43 +0000
43+++ lib/ResultWriter.pm 2015-04-07 20:07:53 +0000
44@@ -128,9 +128,11 @@
45 }
46 else {
47 # Save rows, if any (i.e. if it's a SELECT statement).
48+ # *except* if it's a SELECT...INTO (issue lp:1421781)
49 my $rows;
50 if ( my $sth = $results->{sth} ) {
51- if ( $event->{arg} =~ m/(?:^\s*SELECT|(?:\*\/\s*SELECT))/i ) {
52+ if ( $event->{arg} =~ m/(?:^\s*SELECT|(?:\*\/\s*SELECT))/i
53+ && $event->{arg} !~ /INTO\s*(?:OUTFILE|DUMPFILE|@)/ ) {
54 $rows = $sth->fetchall_arrayref();
55 }
56 eval {
57
58=== added file 't/pt-upgrade/issue_1421781.t'
59--- t/pt-upgrade/issue_1421781.t 1970-01-01 00:00:00 +0000
60+++ t/pt-upgrade/issue_1421781.t 2015-04-07 20:07:53 +0000
61@@ -0,0 +1,66 @@
62+#!/usr/bin/env perl
63+
64+BEGIN {
65+ die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n"
66+ unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH};
67+ unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib";
68+};
69+
70+use strict;
71+use warnings FATAL => 'all';
72+use English qw(-no_match_vars);
73+use Test::More;
74+use File::Basename;
75+use File::Temp qw(tempdir);
76+
77+$ENV{PERCONA_TOOLKIT_TEST_USE_DSN_NAMES} = 1;
78+$ENV{PRETTY_RESULTS} = 1;
79+
80+use PerconaTest;
81+use Sandbox;
82+require "$trunk/bin/pt-upgrade";
83+
84+my $dp = new DSNParser(opts=>$dsn_opts);
85+my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
86+my $dbh1 = $sb->get_dbh_for('host1');
87+
88+
89+if ( !$dbh1 ) {
90+ plan skip_all => 'Cannot connect to sandbox host1';
91+}
92+
93+my $host1_dsn = $sb->dsn_for('host1');
94+my $tmpdir = tempdir("/tmp/pt-upgrade.$PID.XXXXXX", CLEANUP => 1);
95+my $samples = "$trunk/t/pt-upgrade/samples";
96+my $lib_samples = "$trunk/t/lib/samples";
97+my $exit_status = 0;
98+my $output;
99+
100+# #############################################################################
101+# genlog
102+# #############################################################################
103+
104+`rm -f /tmp/test_select_into_*.log`;
105+
106+$output = output(
107+ sub {
108+ $exit_status = pt_upgrade::main($host1_dsn, '--save-results', $tmpdir,
109+ qw(--type rawlog),
110+ "$samples/select_into.log",
111+ )},
112+ stderr => 1,
113+);
114+
115+is(
116+ $exit_status,
117+ 0,
118+ "Does not fail on SELECT...INTO statements"
119+);
120+
121+
122+# #############################################################################
123+# Done.
124+# #############################################################################
125+$sb->wipe_clean($dbh1);
126+ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
127+done_testing;
128
129=== added file 't/pt-upgrade/samples/select_into.log'
130--- t/pt-upgrade/samples/select_into.log 1970-01-01 00:00:00 +0000
131+++ t/pt-upgrade/samples/select_into.log 2015-04-07 20:07:53 +0000
132@@ -0,0 +1,4 @@
133+SELECT 1 INTO @foo;
134+SELECT * FROM sakila.actor INTO OUTFILE '/tmp/test_select_into_1.log';
135+SELECT actor_id,first_name FROM sakila.actor LIMIT 1 INTO DUMPFILE '/tmp/test_select_into_2.log';
136+

Subscribers

People subscribed via source and target branches

to all changes: