Merge lp:~mark-pent/percona-playback/add-select-only-option into lp:percona-playback

Proposed by Mark Pentland
Status: Needs review
Proposed branch: lp:~mark-pent/percona-playback/add-select-only-option
Merge into: lp:percona-playback
Diff against target: 206 lines (+114/-3)
4 files modified
Makefile.am (+5/-0)
percona_playback/query_log/query_log.cc (+17/-3)
percona_playback/query_log/query_log.h (+15/-0)
percona_playback/test/basic-select-only.cc (+77/-0)
To merge this branch: bzr merge lp:~mark-pent/percona-playback/add-select-only-option
Reviewer Review Type Date Requested Status
Percona core Pending
Review via email: mp+187743@code.launchpad.net

Description of the change

I have added a --query-log-select-only option to only execute SELECT statements.
Not 100% accurate (SELECT INTO) but I also use a read-only user for playback so it will catch any that slip through.
Referenced in Bug #1231391
Includes a basic test

Thanks for the good work on Percona.

Mark

To post a comment you must log in.
Revision history for this message
Stewart Smith (stewart) wrote :

This looks great! Thanks for the patch!

I'm just in the process of getting the last things done for the 0.7 release and then I'll merge this in.

One question: what is it with the "USE " query detection in this patch? Should it be a separate option?

Unmerged revisions

197. By Mark Pentland

Added --query-log-select-only option to only execute SELECT (and use) statements

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Makefile.am'
--- Makefile.am 2013-07-26 09:35:29 +0000
+++ Makefile.am 2013-09-26 12:08:23 +0000
@@ -102,6 +102,7 @@
102102
103check_PROGRAMS += \103check_PROGRAMS += \
104 percona_playback/test/basic \104 percona_playback/test/basic \
105 percona_playback/test/basic-select-only \
105 percona_playback/test/basic-stdin \106 percona_playback/test/basic-stdin \
106 percona_playback/test/basic-multiline \107 percona_playback/test/basic-multiline \
107 percona_playback/test/basic-queue-depth \108 percona_playback/test/basic-queue-depth \
@@ -118,6 +119,7 @@
118 percona_playback/test/help119 percona_playback/test/help
119120
120percona_playback_test_basic_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\"121percona_playback_test_basic_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\"
122percona_playback_test_basic_select_only_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\"
121percona_playback_test_basic_stdin_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\"123percona_playback_test_basic_stdin_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\"
122percona_playback_test_basic_multiline_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\"124percona_playback_test_basic_multiline_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\"
123percona_playback_test_basic_queue_depth_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\"125percona_playback_test_basic_queue_depth_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\"
@@ -138,6 +140,9 @@
138percona_playback_test_basic_SOURCES= percona_playback/test/basic.cc140percona_playback_test_basic_SOURCES= percona_playback/test/basic.cc
139percona_playback_test_basic_LDADD= $(LDADD) $(MYSQL_LIBS)141percona_playback_test_basic_LDADD= $(LDADD) $(MYSQL_LIBS)
140142
143percona_playback_test_basic_select_only_SOURCES= percona_playback/test/basic-select-only.cc
144percona_playback_test_basic_select_only_LDADD= $(LDADD) $(MYSQL_LIBS)
145
141percona_playback_test_basic_stdin_SOURCES= percona_playback/test/basic-stdin.cc146percona_playback_test_basic_stdin_SOURCES= percona_playback/test/basic-stdin.cc
142percona_playback_test_basic_stdin_LDADD= $(LDADD) $(MYSQL_LIBS)147percona_playback_test_basic_stdin_LDADD= $(LDADD) $(MYSQL_LIBS)
143148
144149
=== modified file 'percona_playback/query_log/query_log.cc'
--- percona_playback/query_log/query_log.cc 2013-06-07 07:04:15 +0000
+++ percona_playback/query_log/query_log.cc 2013-09-26 12:08:23 +0000
@@ -49,6 +49,7 @@
4949
50static bool g_run_set_timestamp;50static bool g_run_set_timestamp;
51static bool g_preserve_query_time;51static bool g_preserve_query_time;
52static bool g_select_only;
5253
53extern percona_playback::DispatcherPlugin *g_dispatcher_plugin;54extern percona_playback::DispatcherPlugin *g_dispatcher_plugin;
5455
@@ -131,11 +132,12 @@
131132
132 if (strncmp(p, "# User@Host", strlen("# User@Host")) == 0)133 if (strncmp(p, "# User@Host", strlen("# User@Host")) == 0)
133 {134 {
134 if (!tmp_entry->getQuery().empty())135 if ((!tmp_entry->getQuery().empty())&&(tmp_entry->should_run())) {
135 entries->push_back(tmp_entry);136 entries->push_back(tmp_entry);
137 (*this->nr_entries)++;
138 }
136 count++;139 count++;
137 tmp_entry.reset(new QueryLogEntry());140 tmp_entry.reset(new QueryLogEntry());
138 (*this->nr_entries)++;
139 }141 }
140142
141 if (p[0] == '#')143 if (p[0] == '#')
@@ -174,7 +176,7 @@
174 p= line;176 p= line;
175 }177 }
176178
177 if (!tmp_entry->getQuery().empty())179 if ((!tmp_entry->getQuery().empty())&&(tmp_entry->should_run()))
178 entries->push_back(tmp_entry);180 entries->push_back(tmp_entry);
179181
180 free(line);182 free(line);
@@ -308,6 +310,12 @@
308 return r;310 return r;
309}311}
310312
313//should this query be run? (--query-log-select-only)
314bool QueryLogEntry::should_run()
315{
316 return ( (!g_select_only) || (is_select_statement()) || (is_use_statement()) );
317}
318
311extern percona_playback::DBClientPlugin *g_dbclient_plugin;319extern percona_playback::DBClientPlugin *g_dbclient_plugin;
312320
313void* dispatch (void *input_)321void* dispatch (void *input_)
@@ -395,6 +403,12 @@
395 zero_tokens(),403 zero_tokens(),
396 _("Ensure that each query takes at least Query_time (from slow query "404 _("Ensure that each query takes at least Query_time (from slow query "
397 "log) to execute."))405 "log) to execute."))
406 ("query-log-select-only",
407 po::value<bool>(&g_select_only)->
408 default_value(false)->
409 zero_tokens(),
410 _("Only execute queries starting with 'select ' allowing for replay "
411 "on slave servers."))
398 ;412 ;
399413
400 return &options;414 return &options;
401415
=== modified file 'percona_playback/query_log/query_log.h'
--- percona_playback/query_log/query_log.h 2013-06-07 07:04:15 +0000
+++ percona_playback/query_log/query_log.h 2013-09-26 12:08:23 +0000
@@ -22,6 +22,7 @@
22#include <fstream>22#include <fstream>
23#include <string>23#include <string>
24#include <vector>24#include <vector>
25#include <boost/algorithm/string/predicate.hpp>
2526
26#include <tbb/atomic.h>27#include <tbb/atomic.h>
2728
@@ -66,6 +67,20 @@
66 {67 {
67 return (query.compare(0, 30, "# administrator command: Quit;") == 0);68 return (query.compare(0, 30, "# administrator command: Quit;") == 0);
68 }69 }
70
71 bool is_select_statement()
72 {
73 const std::string select_prefix("SELECT ");
74 return (boost::istarts_with(query, select_prefix));
75 }
76
77 bool is_use_statement()
78 {
79 const std::string use_prefix("USE ");
80 return (boost::istarts_with(query, use_prefix));
81 }
82
83 bool should_run();
6984
70 void execute(DBThread *t);85 void execute(DBThread *t);
71};86};
7287
=== added file 'percona_playback/test/basic-select-only.cc'
--- percona_playback/test/basic-select-only.cc 1970-01-01 00:00:00 +0000
+++ percona_playback/test/basic-select-only.cc 2013-09-26 12:08:23 +0000
@@ -0,0 +1,77 @@
1/* BEGIN LICENSE
2 * Copyright (C) 2011-2013 Percona Ireland Ltd.
3 * This program is free software: you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License version 2, as published
5 * by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranties of
9 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along
13 * with this program. If not, see <http://www.gnu.org/licenses/>.
14 * END LICENSE */
15
16#include "config.h"
17
18#include <iostream>
19#include <cstdio>
20#include <string>
21#include <cstring>
22#include <assert.h>
23#include <unistd.h>
24
25#include <sys/types.h>
26#include <sys/stat.h>
27#include <fcntl.h>
28#include <errno.h>
29
30#include <percona_playback/percona_playback.h>
31
32/**
33 * @TODO Actually write a real test suite here
34 */
35int main(int argc, char **argv)
36{
37 (void)argc; (void)argv;
38
39 fprintf(stderr, "Working dir: %s\n\n", get_current_dir_name());
40
41 percona_playback_st *the_percona_playback= percona_playback_create("test_Percona Playback");
42 assert(the_percona_playback);
43
44 char dbplugin_opt[] = "--db-plugin=null";
45 char stdin_opt[] = "--query-log-stdin";
46 char select_only_opt[] = "--query-log-select-only";
47
48 char *dbplugin_argv[4];
49 dbplugin_argv[0]= argv[0];
50 dbplugin_argv[1]= dbplugin_opt;
51 dbplugin_argv[2]= stdin_opt;
52 dbplugin_argv[3]= select_only_opt;
53
54 const char *query_log = SRCDIR"/percona_playback/test/basic-slow.log";
55 int fd = open(query_log, O_RDONLY);
56 if (fd < 0)
57 {
58 fprintf(stderr, "Error: open file '%s' error: %s\n", query_log, strerror(errno));
59 return -1;
60 }
61
62 if (dup2(fd, STDIN_FILENO) < 0)
63 {
64 fprintf(stderr, "Error: can't dup2 to stdin: %s\n", strerror(errno));
65 return -1;
66 }
67
68 assert(0 == percona_playback_argv(the_percona_playback, 4, dbplugin_argv));
69
70 struct percona_playback_run_result *r= percona_playback_run(the_percona_playback);
71
72 assert(r->err == 0);
73 assert(r->n_queries == 17);
74 assert(r->n_log_entries == 2);
75 percona_playback_destroy(&the_percona_playback);
76 return r->err;
77}

Subscribers

People subscribed via source and target branches

to all changes: