From e91caa0bf9b54483e5ff7254f25c01d8c1d09b1e Mon Sep 17 00:00:00 2001 From: Elshad Aghazade Date: Thu, 10 Nov 2016 20:55:34 +0400 Subject: [PATCH 1/4] Read only mode I added --read-only option. If the value of this option is 1 then query parser chooses only select statements from slow log file. Updated percona_playback/query_log/query_log.cc --- percona_playback/query_log/query_log.cc | 37 ++++++++++++++++++------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/percona_playback/query_log/query_log.cc b/percona_playback/query_log/query_log.cc index 8feb860..9533a16 100644 --- a/percona_playback/query_log/query_log.cc +++ b/percona_playback/query_log/query_log.cc @@ -57,14 +57,16 @@ class ParseQueryLogFunc: public tbb::filter { ParseQueryLogFunc(FILE *input_file_, unsigned int run_count_, tbb::atomic *entries_, - tbb::atomic *queries_) + tbb::atomic *queries_, + bool p_is_ro_mode = false) : tbb::filter(true), nr_entries(entries_), nr_queries(queries_), input_file(input_file_), run_count(run_count_), next_line(NULL), - next_len(0) + next_len(0), + is_ro_mode(p_is_ro_mode) {}; void* operator() (void*); @@ -75,11 +77,13 @@ class ParseQueryLogFunc: public tbb::filter { unsigned int run_count; char *next_line; ssize_t next_len; + bool is_ro_mode; }; void* dispatch(void *input_); void* ParseQueryLogFunc::operator() (void*) { + std::vector > *entries= new std::vector >(); @@ -137,13 +141,16 @@ void* ParseQueryLogFunc::operator() (void*) { tmp_entry.reset(new QueryLogEntry()); (*this->nr_entries)++; } - + if (p[0] == '#') tmp_entry->parse_metadata(std::string(line)); else { - (*nr_queries)++; - tmp_entry->add_query_line(std::string(line)); + if((is_ro_mode && (strncmp("select", line, strlen("select")) == 0 || strncmp("SELECT", line, strlen("SELECT")) == 0)) || !is_ro_mode) + { + (*nr_queries)++; + tmp_entry->add_query_line(std::string(line)); + } do { if ((len= getline(&line, &buflen, input_file)) == -1) { @@ -156,7 +163,9 @@ void* ParseQueryLogFunc::operator() (void*) { next_len= len; break; } - tmp_entry->add_query_line(std::string(line)); + + if((is_ro_mode && (strncmp("select", line, strlen("select")) == 0 || strncmp("SELECT", line, strlen("SELECT")) == 0)) || !is_ro_mode) + tmp_entry->add_query_line(std::string(line)); } while(true); } next: @@ -333,7 +342,7 @@ class DispatchQueriesFunc : public tbb::filter { } }; -static void LogReaderThread(FILE* input_file, unsigned int run_count, struct percona_playback_run_result *r) +static void LogReaderThread(FILE* input_file, unsigned int run_count, struct percona_playback_run_result *r, bool is_ro_mode = false) { tbb::pipeline p; tbb::atomic entries; @@ -341,7 +350,7 @@ static void LogReaderThread(FILE* input_file, unsigned int run_count, struct per entries=0; queries=0; - ParseQueryLogFunc f2(input_file, run_count, &entries, &queries); + ParseQueryLogFunc f2(input_file, run_count, &entries, &queries, is_ro_mode); DispatchQueriesFunc f4; p.add_filter(f2); p.add_filter(f4); @@ -360,6 +369,7 @@ class QueryLogPlugin : public percona_playback::InputPlugin std::string file_name; unsigned int read_count; bool std_in; + bool is_ro_mode; public: QueryLogPlugin(const std::string &_name) : @@ -373,6 +383,8 @@ class QueryLogPlugin : public percona_playback::InputPlugin options.add_options() ("query-log-file", po::value(), _("Query log file")) + ("read-only", + po::value(), _("Read only mode")) ("query-log-stdin", po::value()->default_value(false)->zero_tokens(), _("Read query log from stdin")) @@ -436,6 +448,10 @@ class QueryLogPlugin : public percona_playback::InputPlugin fprintf(stderr, _("ERROR: --query-log-file is a required option.\n")); return -1; } + + // sets read only mode + if(vm.count("read-only")) + is_ro_mode = vm["read-only"].as(); return 0; } @@ -443,7 +459,7 @@ class QueryLogPlugin : public percona_playback::InputPlugin virtual void run(percona_playback_run_result &result) { FILE* input_file; - + if (std_in) { input_file = stdin; @@ -463,7 +479,8 @@ class QueryLogPlugin : public percona_playback::InputPlugin boost::thread log_reader_thread(LogReaderThread, input_file, read_count, - &result); + &result, + is_ro_mode); log_reader_thread.join(); fclose(input_file); From b5cbcdf4f48e4649ccc17f4fe87df1e5d618348c Mon Sep 17 00:00:00 2001 From: Elshad Aghazade Date: Fri, 11 Nov 2016 00:31:28 +0400 Subject: [PATCH 2/4] Duplication avoided --- percona_playback/query_log/query_log.cc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/percona_playback/query_log/query_log.cc b/percona_playback/query_log/query_log.cc index 9533a16..2d79003 100644 --- a/percona_playback/query_log/query_log.cc +++ b/percona_playback/query_log/query_log.cc @@ -146,11 +146,8 @@ void* ParseQueryLogFunc::operator() (void*) { tmp_entry->parse_metadata(std::string(line)); else { - if((is_ro_mode && (strncmp("select", line, strlen("select")) == 0 || strncmp("SELECT", line, strlen("SELECT")) == 0)) || !is_ro_mode) - { - (*nr_queries)++; - tmp_entry->add_query_line(std::string(line)); - } + (*nr_queries)++; + tmp_entry->add_query_line(std::string(line)); do { if ((len= getline(&line, &buflen, input_file)) == -1) { From 3752a9e2f1f107d47bb8d05ad28c261d8a40a95b Mon Sep 17 00:00:00 2001 From: Elshad Aghazade Date: Fri, 11 Nov 2016 00:42:36 +0400 Subject: [PATCH 3/4] Update query_log.cc I removed duplicate contitions from the line 149, because I understand that on this line parser catches only set timestamp commands. But I kept the condition at line 164 because it is important for read-only mode filtering. --- percona_playback/query_log/query_log.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/percona_playback/query_log/query_log.cc b/percona_playback/query_log/query_log.cc index 2d79003..6d0cb1e 100644 --- a/percona_playback/query_log/query_log.cc +++ b/percona_playback/query_log/query_log.cc @@ -148,6 +148,7 @@ void* ParseQueryLogFunc::operator() (void*) { { (*nr_queries)++; tmp_entry->add_query_line(std::string(line)); + do { if ((len= getline(&line, &buflen, input_file)) == -1) { @@ -160,7 +161,6 @@ void* ParseQueryLogFunc::operator() (void*) { next_len= len; break; } - if((is_ro_mode && (strncmp("select", line, strlen("select")) == 0 || strncmp("SELECT", line, strlen("SELECT")) == 0)) || !is_ro_mode) tmp_entry->add_query_line(std::string(line)); } while(true); From c1deddc822e60965cd73c28b8ef3bd2fcbbdd168 Mon Sep 17 00:00:00 2001 From: Elshad Aghazade Date: Tue, 15 Nov 2016 03:20:42 +0400 Subject: [PATCH 4/4] Update query_log.cc on 15.11.2016 --- percona_playback/query_log/query_log.cc | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/percona_playback/query_log/query_log.cc b/percona_playback/query_log/query_log.cc index 6d0cb1e..24fa20b 100644 --- a/percona_playback/query_log/query_log.cc +++ b/percona_playback/query_log/query_log.cc @@ -82,8 +82,7 @@ class ParseQueryLogFunc: public tbb::filter { void* dispatch(void *input_); -void* ParseQueryLogFunc::operator() (void*) { - +void* ParseQueryLogFunc::operator() (void*) { std::vector > *entries= new std::vector >(); @@ -141,7 +140,7 @@ void* ParseQueryLogFunc::operator() (void*) { tmp_entry.reset(new QueryLogEntry()); (*this->nr_entries)++; } - + if (p[0] == '#') tmp_entry->parse_metadata(std::string(line)); else @@ -161,7 +160,7 @@ void* ParseQueryLogFunc::operator() (void*) { next_len= len; break; } - if((is_ro_mode && (strncmp("select", line, strlen("select")) == 0 || strncmp("SELECT", line, strlen("SELECT")) == 0)) || !is_ro_mode) + if((is_ro_mode && strnicmp("select", line, strlen("select")) == 0) || !is_ro_mode) tmp_entry->add_query_line(std::string(line)); } while(true); } @@ -444,8 +443,7 @@ class QueryLogPlugin : public percona_playback::InputPlugin { fprintf(stderr, _("ERROR: --query-log-file is a required option.\n")); return -1; - } - + } // sets read only mode if(vm.count("read-only")) is_ro_mode = vm["read-only"].as(); @@ -456,7 +454,7 @@ class QueryLogPlugin : public percona_playback::InputPlugin virtual void run(percona_playback_run_result &result) { FILE* input_file; - + if (std_in) { input_file = stdin;