From 54ee4e9b695c7872352e69bcd8665e77c373fc2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Mon, 13 Apr 2020 19:51:54 +0200 Subject: [PATCH] Simplified the number of session statuses * removed 14 statuses * configured the MySQL_Session status to SETTING_VARIABLE for 14 session variables * extended MySQL_Session to introduce a new variable that tracks the session variable to change * MySQL_Threads_Handler::SQL3_Processlist() can handle all variables * removed unnecessary loops * improved performance removing unnecessary function calls --- include/MySQL_Session.h | 3 +++ include/proxysql_structs.h | 52 ++++++++++++++------------------------ lib/MySQL_Session.cpp | 27 ++++++++------------ lib/MySQL_Thread.cpp | 14 ++++++++++ lib/MySQL_Variables.cpp | 19 ++++++++++---- 5 files changed, 60 insertions(+), 55 deletions(-) diff --git a/include/MySQL_Session.h b/include/MySQL_Session.h index db007f519..f3dfe5b5a 100644 --- a/include/MySQL_Session.h +++ b/include/MySQL_Session.h @@ -209,6 +209,9 @@ class MySQL_Session void *ldap_ctx; + // this variable is relevant only if status == SETTING_VARIABLE + enum variable_name changing_variable_idx; + MySQL_Session(); ~MySQL_Session(); diff --git a/include/proxysql_structs.h b/include/proxysql_structs.h index 5068e1d7c..d8c0f1c14 100644 --- a/include/proxysql_structs.h +++ b/include/proxysql_structs.h @@ -186,23 +186,9 @@ enum session_status { RESETTING_CONNECTION, SETTING_INIT_CONNECT, SETTING_LDAP_USER_VARIABLE, - SETTING_SQL_LOG_BIN, - SETTING_SQL_MODE, - SETTING_TIME_ZONE, SETTING_ISOLATION_LEVEL, SETTING_TRANSACTION_READ, - SETTING_CHARACTER_SET_RESULTS, - SETTING_CHARACTER_SET_CONNECTION, - SETTING_CHARACTER_SET_CLIENT, - SETTING_CHARACTER_SET_DATABASE, SETTING_SESSION_TRACK_GTIDS, - SETTING_SQL_AUTO_IS_NULL, - SETTING_SQL_SELECT_LIMIT, - SETTING_SQL_SAFE_UPDATES, - SETTING_COLLATION_CONNECTION, - SETTING_NET_WRITE_TIMEOUT, - SETTING_MAX_JOIN_SIZE, - SETTING_WSREP_SYNC_WAIT, SETTING_MULTI_STMT, FAST_FORWARD, PROCESSING_STMT_PREPARE, @@ -987,25 +973,25 @@ extern __thread unsigned int g_seed; // field_7: variable name as displayed in admin , WITHOUT "default_" // field_8: default value mysql_variable_st mysql_tracked_variables[] { - { SQL_CHARACTER_SET, SETTING_CHARSET, false, true, false, (char *)"CHARSET", (char *)"CHARSET", (char *)"UTF8" } , // should be before SQL_CHARACTER_SET_RESULTS - { SQL_CHARACTER_ACTION, NONE, false, false, false, (char *)"action", (char *)"action", (char *)"1" } , - { SQL_SET_NAMES, SETTING_SET_NAMES, false, false, false, (char *)"names", (char *)"names", (char *)"DEFAULT" } , - { SQL_SAFE_UPDATES, SETTING_SQL_SAFE_UPDATES , true, false, true, (char *)"sql_safe_updates", (char *)"sql_safe_updates", (char *)"OFF" } , - { SQL_SELECT_LIMIT, SETTING_SQL_SELECT_LIMIT , false, false, true, (char *)"sql_select_limit", (char *)"sql_select_limit", (char *)"DEFAULT" } , - { SQL_SQL_MODE, SETTING_SQL_MODE , true, false, true, (char *)"sql_mode" , (char *)"sql_mode" , (char *)"" } , - { SQL_TIME_ZONE, SETTING_TIME_ZONE , true, false, true, (char *)"time_zone", (char *)"time_zone", (char *)"SYSTEM" } , - { SQL_CHARACTER_SET_RESULTS, SETTING_CHARACTER_SET_RESULTS, false, false, true, (char *)"character_set_results", (char *)"character_set_results", (char *)"UTF8" } , - { SQL_CHARACTER_SET_CONNECTION, SETTING_CHARACTER_SET_CONNECTION, false, false, true, (char *)"character_set_connection", (char *)"character_set_connection", (char *)"UTF8" } , - { SQL_CHARACTER_SET_CLIENT, SETTING_CHARACTER_SET_CLIENT, false, false, true, (char *)"character_set_client", (char *)"character_set_client", (char *)"UTF8" } , - { SQL_CHARACTER_SET_DATABASE, SETTING_CHARACTER_SET_DATABASE, false, false, true, (char *)"character_set_database", (char *)"character_set_database", (char *)"UTF8" } , - { SQL_ISOLATION_LEVEL, SETTING_ISOLATION_LEVEL, false, true, true, (char *)"SESSION TRANSACTION ISOLATION LEVEL", (char *)"isolation_level", (char *)"READ COMMITTED" } , - { SQL_TRANSACTION_READ, SETTING_TRANSACTION_READ, false, true, true, (char *)"SESSION TRANSACTION READ", (char *)"transaction_read", (char *)"WRITE" } , - { SQL_SQL_AUTO_IS_NULL, SETTING_SQL_AUTO_IS_NULL, true, false, true, (char *)"sql_auto_is_null", (char *)"sql_auto_is_null", (char *)"OFF" } , - { SQL_COLLATION_CONNECTION, SETTING_COLLATION_CONNECTION, true, false, true, (char *)"COLLATION_CONNECTION", (char *)"collation_connection", (char *)"utf8_general_ci" } , - { SQL_NET_WRITE_TIMEOUT, SETTING_NET_WRITE_TIMEOUT, false, false, true, (char *)"NET_WRITE_TIMEOUT", (char *)"net_write_timeout", (char *)"60" } , - { SQL_MAX_JOIN_SIZE, SETTING_MAX_JOIN_SIZE, false, false, true, (char *)"MAX_JOIN_SIZE", (char *)"max_join_size", (char *)"18446744073709551615" } , - { SQL_LOG_BIN, SETTING_SQL_LOG_BIN, false, false, true, (char *)"SQL_LOG_BIN", (char *)"sql_log_bin", (char *)"1" } , - { SQL_WSREP_SYNC_WAIT, SETTING_WSREP_SYNC_WAIT, false, false, true, (char *)"WSREP_SYNC_WAIT", (char *)"wsrep_sync_wait", (char *)"0" } , + { SQL_CHARACTER_SET, SETTING_CHARSET, false, true, false, (char *)"CHARSET", (char *)"CHARSET", (char *)"UTF8" } , // should be before SQL_CHARACTER_SET_RESULTS + { SQL_CHARACTER_ACTION, NONE, false, false, false, (char *)"action", (char *)"action", (char *)"1" } , + { SQL_SET_NAMES, SETTING_SET_NAMES,false, false, false, (char *)"names", (char *)"names", (char *)"DEFAULT" } , + { SQL_SAFE_UPDATES, SETTING_VARIABLE, true, false, true, (char *)"sql_safe_updates", (char *)"sql_safe_updates", (char *)"OFF" } , + { SQL_SELECT_LIMIT, SETTING_VARIABLE, false, false, true, (char *)"sql_select_limit", (char *)"sql_select_limit", (char *)"DEFAULT" } , + { SQL_SQL_MODE, SETTING_VARIABLE, true, false, true, (char *)"sql_mode" , (char *)"sql_mode" , (char *)"" } , + { SQL_TIME_ZONE, SETTING_VARIABLE, true, false, true, (char *)"time_zone", (char *)"time_zone", (char *)"SYSTEM" } , + { SQL_CHARACTER_SET_RESULTS, SETTING_VARIABLE, false, false, true, (char *)"character_set_results", (char *)"character_set_results", (char *)"UTF8" } , + { SQL_CHARACTER_SET_CONNECTION, SETTING_VARIABLE, false, false, true, (char *)"character_set_connection", (char *)"character_set_connection", (char *)"UTF8" } , + { SQL_CHARACTER_SET_CLIENT, SETTING_VARIABLE, false, false, true, (char *)"character_set_client", (char *)"character_set_client", (char *)"UTF8" } , + { SQL_CHARACTER_SET_DATABASE, SETTING_VARIABLE, false, false, true, (char *)"character_set_database", (char *)"character_set_database", (char *)"UTF8" } , + { SQL_ISOLATION_LEVEL, SETTING_ISOLATION_LEVEL, false, true, true, (char *)"SESSION TRANSACTION ISOLATION LEVEL", (char *)"isolation_level", (char *)"READ COMMITTED" } , + { SQL_TRANSACTION_READ, SETTING_TRANSACTION_READ, false, true, true, (char *)"SESSION TRANSACTION READ", (char *)"transaction_read", (char *)"WRITE" } , + { SQL_SQL_AUTO_IS_NULL, SETTING_VARIABLE, true, false, true, (char *)"sql_auto_is_null", (char *)"sql_auto_is_null", (char *)"OFF" } , + { SQL_COLLATION_CONNECTION, SETTING_VARIABLE, true, false, true, (char *)"collation_connection", (char *)"collation_connection", (char *)"utf8_general_ci" } , + { SQL_NET_WRITE_TIMEOUT, SETTING_VARIABLE, false, false, true, (char *)"net_write_timeout", (char *)"net_write_timeout", (char *)"60" } , + { SQL_MAX_JOIN_SIZE, SETTING_VARIABLE, false, false, true, (char *)"max_join_size", (char *)"max_join_size", (char *)"18446744073709551615" } , + { SQL_LOG_BIN, SETTING_VARIABLE, false, false, true, (char *)"sql_log_bin", (char *)"sql_log_bin", (char *)"1" } , + { SQL_WSREP_SYNC_WAIT, SETTING_VARIABLE, false, false, true, (char *)"wsrep_sync_wait", (char *)"wsrep_sync_wait", (char *)"0" } , }; #else extern mysql_variable_st mysql_tracked_variables[]; diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 626f17dad..af5952c5d 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -3551,8 +3551,14 @@ handler_again: } for (auto i = 0; i < SQL_NAME_LAST; i++) { - if(!myconn->var_absent[i] && mysql_variables.verify_variable(this, i)) { - goto handler_again; + auto client_hash = client_myds->myconn->var_hash[i]; + if (client_hash) { + auto server_hash = myconn->var_hash[i]; + if (client_hash != server_hash) { + if(!myconn->var_absent[i] && mysql_variables.verify_variable(this, i)) { + goto handler_again; + } + } } } @@ -4081,24 +4087,11 @@ handler_again: } break; - case SETTING_SQL_MODE: - case SETTING_SQL_SELECT_LIMIT: - case SETTING_SQL_SAFE_UPDATES: - case SETTING_TIME_ZONE: - case SETTING_CHARACTER_SET_RESULTS: - case SETTING_CHARACTER_SET_CONNECTION: - case SETTING_CHARACTER_SET_CLIENT: - case SETTING_CHARACTER_SET_DATABASE: case SETTING_ISOLATION_LEVEL: case SETTING_TRANSACTION_READ: - case SETTING_SQL_AUTO_IS_NULL: - case SETTING_COLLATION_CONNECTION: - case SETTING_NET_WRITE_TIMEOUT: - case SETTING_MAX_JOIN_SIZE: case SETTING_CHARSET: - case SETTING_SQL_LOG_BIN: - case SETTING_WSREP_SYNC_WAIT: - for (auto i = 0; i < SQL_NAME_LAST; i++) { + case SETTING_VARIABLE: + { int rc = 0; if (mysql_variables.update_variable(this, status, rc)) { goto handler_again; diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp index bf0f76903..60b6a1fe8 100644 --- a/lib/MySQL_Thread.cpp +++ b/lib/MySQL_Thread.cpp @@ -5427,6 +5427,7 @@ SQLite3_result * MySQL_Threads_Handler::SQL3_Processlist() { case SETTING_INIT_CONNECT: pta[11]=strdup("Setting init connect"); break; +/* case SETTING_SQL_LOG_BIN: pta[11]=strdup("Set log bin"); break; @@ -5436,6 +5437,19 @@ SQLite3_result * MySQL_Threads_Handler::SQL3_Processlist() { case SETTING_TIME_ZONE: pta[11]=strdup("Set TZ"); break; +*/ + case SETTING_VARIABLE: + { + int idx = sess->changing_variable_idx; + if (idx < SQL_NAME_LAST) { + char buf[128]; + sprintf(buf, "Setting variable %s", mysql_tracked_variables[idx].set_variable_name); + pta[11]=strdup(buf); + } else { + pta[11]=strdup("Setting variable"); + } + } + break; case FAST_FORWARD: pta[11]=strdup("Fast forward"); break; diff --git a/lib/MySQL_Variables.cpp b/lib/MySQL_Variables.cpp index 7e55cbf50..e5dbdb230 100644 --- a/lib/MySQL_Variables.cpp +++ b/lib/MySQL_Variables.cpp @@ -185,10 +185,15 @@ uint32_t MySQL_Variables::server_get_hash(MySQL_Session* session, int idx) const bool MySQL_Variables::update_variable(MySQL_Session* session, session_status status, int &_rc) { int idx = SQL_NAME_LAST; - for (int i=0; istatus == SETTING_VARIABLE) { + // if status is SETTING_VARIABLE , what variable needs to be changed is defined in changing_variable_idx + idx = session->changing_variable_idx; + } else { + for (int i=0; iclient_myds->myconn->var_hash[idx]; auto server_hash = session->mybe->server_myds->myconn->var_hash[idx]; - ret = verifiers[idx](session, idx, client_hash, server_hash); + if (client_hash && client_hash != server_hash) { + ret = verifiers[idx](session, idx, client_hash, server_hash); + } } return ret; } @@ -417,6 +424,8 @@ inline bool verify_server_variable(MySQL_Session* session, int idx, uint32_t cli return false; } } + // this variable is relevant only if status == SETTING_VARIABLE + session->changing_variable_idx = (enum variable_name)idx; switch(session->status) { // this switch can be replaced with a simple previous_status.push(status), but it is here for readibility case PROCESSING_QUERY: session->previous_status.push(PROCESSING_QUERY);