diff --git a/include/MySQL_Thread.h b/include/MySQL_Thread.h index 0049321ec..2b60ebb03 100644 --- a/include/MySQL_Thread.h +++ b/include/MySQL_Thread.h @@ -14,6 +14,8 @@ #include "prometheus_helpers.h" +#include "set_parser.h" + #define MIN_POLL_LEN 8 #define MIN_POLL_DELETE_RATIO 8 #define MY_EPOLL_THREAD_MAXEVENTS 128 @@ -214,11 +216,15 @@ class __attribute__((aligned(64))) MySQL_Thread bool query_cache_stores_empty_result; } variables; - pthread_mutex_t thread_mutex; - MySQL_Thread(); - ~MySQL_Thread(); - MySQL_Session * create_new_session_and_client_data_stream(int _fd); - bool init(); + pthread_mutex_t thread_mutex; + + // if set_parser_algorithm == 2 , a single thr_SetParser is used + SetParser *thr_SetParser; + + MySQL_Thread(); + ~MySQL_Thread(); + MySQL_Session * create_new_session_and_client_data_stream(int _fd); + bool init(); void run___get_multiple_idle_connections(int& num_idles); void run___cleanup_mirror_queue(); void ProcessAllMyDS_BeforePoll(); @@ -538,6 +544,7 @@ class MySQL_Threads_Handler int query_processor_iterations; int query_processor_regex; int set_query_lock_on_hostgroup; + int set_parser_algorithm; int reset_connection_algorithm; int auto_increment_delay_multiplex; int auto_increment_delay_multiplex_timeout_ms; diff --git a/include/proxysql_structs.h b/include/proxysql_structs.h index d6c3b3f3e..4352380c4 100644 --- a/include/proxysql_structs.h +++ b/include/proxysql_structs.h @@ -815,6 +815,7 @@ __thread int mysql_thread___connect_timeout_server_max; __thread int mysql_thread___query_processor_iterations; __thread int mysql_thread___query_processor_regex; __thread int mysql_thread___set_query_lock_on_hostgroup; +__thread int mysql_thread___set_parser_algorithm; __thread int mysql_thread___reset_connection_algorithm; __thread uint32_t mysql_thread___server_capabilities; __thread int mysql_thread___auto_increment_delay_multiplex; @@ -981,6 +982,7 @@ extern __thread int mysql_thread___connect_timeout_server_max; extern __thread int mysql_thread___query_processor_iterations; extern __thread int mysql_thread___query_processor_regex; extern __thread int mysql_thread___set_query_lock_on_hostgroup; +extern __thread int mysql_thread___set_parser_algorithm; extern __thread int mysql_thread___reset_connection_algorithm; extern __thread uint32_t mysql_thread___server_capabilities; extern __thread int mysql_thread___auto_increment_delay_multiplex; diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index ccb62521a..57b825568 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -6,7 +6,6 @@ #include "re2/re2.h" #include "re2/regexp.h" #include "mysqld_error.h" -#include "set_parser.h" #include "MySQL_Data_Stream.h" #include "query_processor.h" @@ -6022,7 +6021,15 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Parsing SET command %s\n", nq.c_str()); proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "Parsing SET command = %s\n", nq.c_str()); SetParser parser(nq); - std::map> set = parser.parse1(); + std::map> set = {}; + if (mysql_thread___set_parser_algorithm == 1) { // legacy behavior + set = parser.parse1(); + } else if (mysql_thread___set_parser_algorithm == 2) { // we use a single SetParser per thread + thread->thr_SetParser->set_query(nq); // replace the query + set = thread->thr_SetParser->parse1v2(); // use algorithm v2 + } else { + assert(0); + } // Flag to be set if any variable within the 'SET' statement fails to be tracked, // due to being unknown or because it's an user defined variable. bool failed_to_parse_var = false; diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp index d80c6d301..a15e0ca70 100644 --- a/lib/MySQL_Thread.cpp +++ b/lib/MySQL_Thread.cpp @@ -525,6 +525,7 @@ static char * mysql_thread_variables_names[]= { (char *)"query_processor_iterations", (char *)"query_processor_regex", (char *)"set_query_lock_on_hostgroup", + (char *)"set_parser_algorithm", (char *)"reset_connection_algorithm", (char *)"auto_increment_delay_multiplex", (char *)"auto_increment_delay_multiplex_timeout_ms", @@ -1119,6 +1120,7 @@ MySQL_Threads_Handler::MySQL_Threads_Handler() { variables.query_processor_iterations=0; variables.query_processor_regex=1; variables.set_query_lock_on_hostgroup=1; + variables.set_parser_algorithm=1; // in 2.6.0 this must become 2 variables.reset_connection_algorithm=2; variables.auto_increment_delay_multiplex=5; variables.auto_increment_delay_multiplex_timeout_ms=10000; @@ -2213,6 +2215,7 @@ char ** MySQL_Threads_Handler::get_variables_list() { VariablesPointers_int["query_processor_regex"] = make_tuple(&variables.query_processor_regex, 1, 2, false); VariablesPointers_int["query_retries_on_failure"] = make_tuple(&variables.query_retries_on_failure, 0, 1000, false); VariablesPointers_int["set_query_lock_on_hostgroup"] = make_tuple(&variables.set_query_lock_on_hostgroup, 0, 1, false); + VariablesPointers_int["set_parser_algorithm"] = make_tuple(&variables.set_parser_algorithm, 1, 2, false); // throttle VariablesPointers_int["throttle_connections_per_sec_to_hostgroup"] = make_tuple(&variables.throttle_connections_per_sec_to_hostgroup, 1, 100*1000*1000, false); @@ -2835,6 +2838,10 @@ MySQL_Thread::~MySQL_Thread() { free(match_regexes); match_regexes=NULL; } + if (thr_SetParser != NULL) { + delete thr_SetParser; + thr_SetParser = NULL; + } } @@ -2941,6 +2948,7 @@ bool MySQL_Thread::init() { mypolls.add(POLLIN, pipefd[0], NULL, 0); assert(i==0); + thr_SetParser = new SetParser(""); match_regexes=(Session_Regex **)malloc(sizeof(Session_Regex *)*4); // match_regexes[0]=new Session_Regex((char *)"^SET (|SESSION |@@|@@session.)SQL_LOG_BIN( *)(:|)=( *)"); match_regexes[0] = NULL; // NOTE: historically we used match_regexes[0] for SET SQL_LOG_BIN . Not anymore @@ -3995,6 +4003,7 @@ void MySQL_Thread::refresh_variables() { mysql_thread___query_processor_iterations=GloMTH->get_variable_int((char *)"query_processor_iterations"); mysql_thread___query_processor_regex=GloMTH->get_variable_int((char *)"query_processor_regex"); mysql_thread___set_query_lock_on_hostgroup=GloMTH->get_variable_int((char *)"set_query_lock_on_hostgroup"); + mysql_thread___set_parser_algorithm=GloMTH->get_variable_int((char *)"set_parser_algorithm"); mysql_thread___reset_connection_algorithm=GloMTH->get_variable_int((char *)"reset_connection_algorithm"); mysql_thread___auto_increment_delay_multiplex=GloMTH->get_variable_int((char *)"auto_increment_delay_multiplex"); mysql_thread___auto_increment_delay_multiplex_timeout_ms=GloMTH->get_variable_int((char *)"auto_increment_delay_multiplex_timeout_ms"); diff --git a/test/tap/tests/set_testing-240-t.cpp b/test/tap/tests/set_testing-240-t.cpp index 6566e02e9..766077451 100644 --- a/test/tap/tests/set_testing-240-t.cpp +++ b/test/tap/tests/set_testing-240-t.cpp @@ -47,7 +47,7 @@ char *schema=(char *)"information_schema"; int silent = 0; int sysbench = 0; int local=0; -int queries=4000; +int queries=3000; int uniquequeries=0; int histograms=-1; @@ -480,7 +480,9 @@ int main(int argc, char *argv[]) { //queries = 3000; //queries = testCases.size(); - plan(queries * num_threads); + unsigned int p = queries * num_threads; + p *= 2; // number of algorithms + plan(p); if (strcmp(host,"localhost")==0) { local = 1; @@ -492,16 +494,25 @@ int main(int argc, char *argv[]) { uniquequeries=(int)sqrt(uniquequeries); } - pthread_t *thi=(pthread_t *)malloc(sizeof(pthread_t)*num_threads); - if (thi==NULL) - return exit_status(); - - for (unsigned int i=0; i::iterator it = vars_counters.begin(); it!=vars_counters.end(); it++) { diag("Unknown variable %s:\t Count: %d , unknown: %d", it->first.c_str(), it->second.count, it->second.unknown);