Adding variable mysql-set_parser_algorithm

Variable mysql-set_parser_algorithm defines which algorithm is used by SetParser
for the parsing of SET statements.
If value is 1: parse1() is used
If value is 2: parse1v2() is used

parse1v2() allows also the using a single SetParser per MySQL_Thread to
process all SET statements. Regex is compiled only once.

set_testing-240-t was also modified to test both algorithms
pull/4274/head
René Cannaò 3 years ago
parent 38724bb401
commit 37f8a50b90

@ -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;

@ -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;

@ -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<std::string, std::vector<std::string>> set = parser.parse1();
std::map<std::string, std::vector<std::string>> 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;

@ -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");

@ -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<num_threads; i++) {
if ( pthread_create(&thi[i], NULL, my_conn_thread , NULL) != 0 )
perror("Thread creation");
}
for (unsigned int i=0; i<num_threads; i++) {
pthread_join(thi[i], NULL);
for (int algo = 1; algo <= 2; algo++ ) {
connect_phase_completed = 0;
query_phase_completed = 0;
std::string qu = "SET mysql-set_parser_algorithm=" + std::to_string(algo);
diag("Setting: %s", qu.c_str());
MYSQL_QUERY(proxysql_admin, qu.c_str());
MYSQL_QUERY(proxysql_admin, "LOAD MYSQL VARIABLES TO RUNTIME");
pthread_t *thi=(pthread_t *)malloc(sizeof(pthread_t)*num_threads);
if (thi==NULL)
return exit_status();
for (unsigned int i=0; i<num_threads; i++) {
if ( pthread_create(&thi[i], NULL, my_conn_thread , NULL) != 0 )
perror("Thread creation");
}
for (unsigned int i=0; i<num_threads; i++) {
pthread_join(thi[i], NULL);
}
free(thi);
}
for (std::unordered_map<std::string,var_counter>::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);

Loading…
Cancel
Save