From d0d7018e341ed4ddb01898742cefefae65085b63 Mon Sep 17 00:00:00 2001 From: val Date: Wed, 8 Apr 2020 14:19:06 +0000 Subject: [PATCH] rollback session_track_gtids --- include/MySQL_Session.h | 3 ++ include/MySQL_Thread.h | 2 + include/mysql_connection.h | 3 ++ include/proxysql_structs.h | 4 +- lib/MySQL_Session.cpp | 98 ++++++++++++++++++++++++++++++++++++-- lib/MySQL_Thread.cpp | 38 +++++++++++++++ lib/MySQL_Variables.cpp | 1 - lib/mysql_connection.cpp | 14 ++++++ 8 files changed, 156 insertions(+), 7 deletions(-) diff --git a/include/MySQL_Session.h b/include/MySQL_Session.h index 5b1a51d6c..f158d197d 100644 --- a/include/MySQL_Session.h +++ b/include/MySQL_Session.h @@ -111,11 +111,14 @@ class MySQL_Session bool handler_again___verify_init_connect(); bool handler_again___verify_ldap_user_variable(); bool handler_again___verify_backend_autocommit(); + bool handler_again___verify_backend_session_track_gtids(); bool handler_again___verify_backend_multi_statement(); + bool handler_again___verify_backend__generic_variable(uint32_t *be_int, char **be_var, char *def, uint32_t *fe_int, char *fe_var, enum session_status next_sess_status); bool handler_again___verify_backend_user_schema(); bool handler_again___status_SETTING_INIT_CONNECT(int *); bool handler_again___status_SETTING_LDAP_USER_VARIABLE(int *); bool handler_again___status_SETTING_SQL_MODE(int *); + bool handler_again___status_SETTING_SESSION_TRACK_GTIDS(int *); bool handler_again___status_CHANGING_SCHEMA(int *); bool handler_again___status_CONNECTING_SERVER(int *); bool handler_again___status_CHANGING_USER_SERVER(int *); diff --git a/include/MySQL_Thread.h b/include/MySQL_Thread.h index 07becbefd..f5d38b8b7 100644 --- a/include/MySQL_Thread.h +++ b/include/MySQL_Thread.h @@ -19,6 +19,7 @@ #define MYSQL_DEFAULT_TX_ISOLATION "READ-COMMITTED" +#define MYSQL_DEFAULT_SESSION_TRACK_GTIDS "OFF" #define MYSQL_DEFAULT_COLLATION_CONNECTION "" #define MYSQL_DEFAULT_NET_WRITE_TIMEOUT "60" #define MYSQL_DEFAULT_MAX_JOIN_SIZE "18446744073709551615" @@ -361,6 +362,7 @@ class MySQL_Threads_Handler char *ldap_user_variable; char *add_ldap_user_comment; char *default_tx_isolation; + char *default_session_track_gtids; char *default_variables[SQL_NAME_LAST]; char *firewall_whitelist_errormsg; #ifdef DEBUG diff --git a/include/mysql_connection.h b/include/mysql_connection.h index af13e9423..74b11c90b 100644 --- a/include/mysql_connection.h +++ b/include/mysql_connection.h @@ -59,14 +59,17 @@ class MySQL_Connection { public: struct { char *server_version; + uint32_t session_track_gtids_int; uint32_t max_allowed_pkt; uint32_t server_capabilities; uint32_t client_flag; unsigned int compression_min_length; char *init_connect; bool init_connect_sent; + char * session_track_gtids; char *ldap_user_variable; char *ldap_user_variable_value; + bool session_track_gtids_sent; bool ldap_user_variable_sent; uint8_t protocol_version; int8_t last_set_autocommit; diff --git a/include/proxysql_structs.h b/include/proxysql_structs.h index 22a8aa196..5068e1d7c 100644 --- a/include/proxysql_structs.h +++ b/include/proxysql_structs.h @@ -160,7 +160,6 @@ enum variable_name { SQL_CHARACTER_SET_DATABASE, SQL_ISOLATION_LEVEL, SQL_TRANSACTION_READ, - SQL_SESSION_TRACK_GTIDS, SQL_SQL_AUTO_IS_NULL, SQL_COLLATION_CONNECTION, SQL_NET_WRITE_TIMEOUT, @@ -696,6 +695,7 @@ __thread char *mysql_thread___keep_multiplexing_variables; __thread char *mysql_thread___init_connect; __thread char *mysql_thread___ldap_user_variable; __thread char *mysql_thread___default_tx_isolation; +__thread char *mysql_thread___default_session_track_gtids; __thread char *mysql_thread___firewall_whitelist_errormsg; __thread int mysql_thread___max_allowed_packet; __thread bool mysql_thread___automatic_detect_sqli; @@ -840,6 +840,7 @@ extern __thread char *mysql_thread___keep_multiplexing_variables; extern __thread char *mysql_thread___init_connect; extern __thread char *mysql_thread___ldap_user_variable; extern __thread char *mysql_thread___default_tx_isolation; +extern __thread char *mysql_thread___default_session_track_gtids; extern __thread char *mysql_thread___firewall_whitelist_errormsg; extern __thread int mysql_thread___max_allowed_packet; extern __thread bool mysql_thread___automatic_detect_sqli; @@ -999,7 +1000,6 @@ mysql_variable_st mysql_tracked_variables[] { { 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_SESSION_TRACK_GTIDS, SETTING_SESSION_TRACK_GTIDS, false, false, true, (char *)"session_track_gtids" , (char *)"session_track_gtids" , (char *)"OFF" } , { 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" } , diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 4be0de336..09b9f072a 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -958,6 +958,7 @@ void MySQL_Session::generate_proxysql_internal_session_json(json &j) { j["client"]["DSS"] = client_myds->DSS; j["default_schema"] = ( default_schema ? default_schema : "" ); j["transaction_persistent"] = transaction_persistent; + j["conn"]["session_track_gtids"] = ( client_myds->myconn->options.session_track_gtids ? client_myds->myconn->options.session_track_gtids : "") ; for (auto idx = 0; idx < SQL_NAME_LAST; idx++) { if(mysql_tracked_variables[idx].special_handling) { client_myds->myconn->variables[idx].fill_client_internal_session(j, idx); @@ -1008,6 +1009,7 @@ void MySQL_Session::generate_proxysql_internal_session_json(json &j) { j["backends"][i]["conn"]["myconnpoll_get"] = _myconn->statuses.myconnpoll_get; j["backends"][i]["conn"]["myconnpoll_put"] = _myconn->statuses.myconnpoll_put; //j["backend"][i]["conn"]["charset"] = _myds->myconn->options.charset; // not used for backend + j["backends"][i]["conn"]["session_track_gtids"] = ( _myconn->options.session_track_gtids ? _myconn->options.session_track_gtids : "") ; j["backends"][i]["conn"]["init_connect"] = ( _myconn->options.init_connect ? _myconn->options.init_connect : ""); j["backends"][i]["conn"]["init_connect_sent"] = _myds->myconn->options.init_connect_sent; j["backends"][i]["conn"]["autocommit"] = ( _myds->myconn->options.autocommit ? "ON" : "OFF" ); @@ -1575,6 +1577,54 @@ void MySQL_Session::handler_again___new_thread_to_kill_connection() { // true should jump to handler_again #define NEXT_IMMEDIATE_NEW(new_st) do { set_status(new_st); return true; } while (0) +bool MySQL_Session::handler_again___verify_backend__generic_variable(uint32_t *be_int, char **be_var, char *def, uint32_t *fe_int, char *fe_var, enum session_status next_sess_status) { + // be_int = backend int (hash) + // be_var = backend value + // def = default + // fe_int = frontend int (has) + // fe_var = frontend value + if (*be_int == 0) { + // it is the first time we use this backend. Set value to default + if (*be_var) { + free(*be_var); + *be_var = NULL; + } + *be_var = strdup(def); + uint32_t tmp_int = SpookyHash::Hash32(*be_var, strlen(*be_var), 10); + *be_int = tmp_int; + } + if (*fe_int) { + if (*fe_int != *be_int) { + { + *be_int = *fe_int; + if (*be_var) { + free(*be_var); + *be_var = NULL; + } + if (fe_var) { + *be_var = strdup(fe_var); + } + } + switch(status) { // this switch can be replaced with a simple previous_status.push(status), but it is here for readibility + case PROCESSING_QUERY: + previous_status.push(PROCESSING_QUERY); + break; + case PROCESSING_STMT_PREPARE: + previous_status.push(PROCESSING_STMT_PREPARE); + break; + case PROCESSING_STMT_EXECUTE: + previous_status.push(PROCESSING_STMT_EXECUTE); + break; + default: + assert(0); + break; + } + NEXT_IMMEDIATE_NEW(next_sess_status); + } + } + return false; +} + bool MySQL_Session::handler_again___verify_backend_multi_statement() { if ((client_myds->myconn->options.client_flag & CLIENT_MULTI_STATEMENTS) != (mybe->server_myds->myconn->options.client_flag & CLIENT_MULTI_STATEMENTS)) { @@ -1629,6 +1679,20 @@ bool MySQL_Session::handler_again___verify_init_connect() { return false; } +bool MySQL_Session::handler_again___verify_backend_session_track_gtids() { + bool ret = false; + proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Session %p , client: %s , backend: %s\n", this, client_myds->myconn->options.session_track_gtids, mybe->server_myds->myconn->options.session_track_gtids); + ret = handler_again___verify_backend__generic_variable( + &mybe->server_myds->myconn->options.session_track_gtids_int, + &mybe->server_myds->myconn->options.session_track_gtids, + mysql_thread___default_session_track_gtids, + &client_myds->myconn->options.session_track_gtids_int, + client_myds->myconn->options.session_track_gtids, + SETTING_SESSION_TRACK_GTIDS + ); + return ret; +} + bool MySQL_Session::handler_again___verify_ldap_user_variable() { bool ret = false; if (mybe->server_myds->myconn->options.ldap_user_variable_sent==false) { @@ -2200,6 +2264,13 @@ bool MySQL_Session::handler_again___status_SETTING_MULTI_STMT(int *_rc) { return ret; } +bool MySQL_Session::handler_again___status_SETTING_SESSION_TRACK_GTIDS(int *_rc) { + bool ret=false; + assert(mybe->server_myds->myconn); + ret = handler_again___status_SETTING_GENERIC_VARIABLE(_rc, (char *)"SESSION_TRACK_GTIDS", mybe->server_myds->myconn->options.session_track_gtids, true); + return ret; +} + bool MySQL_Session::handler_again___status_CHANGING_SCHEMA(int *_rc) { bool ret=false; //fprintf(stderr,"CHANGING_SCHEMA\n"); @@ -3404,6 +3475,10 @@ handler_again: goto handler_again; } + if (handler_again___verify_backend_session_track_gtids()) { + goto 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; @@ -3911,6 +3986,19 @@ handler_again: } break; + case SETTING_SESSION_TRACK_GTIDS: + { + int rc=0; + if (handler_again___status_SETTING_SESSION_TRACK_GTIDS(&rc)) + goto handler_again; // we changed status + if (rc==-1) { // we have an error we can't handle + handler_ret = -1; + return handler_ret; + } + } + break; + + case SETTING_SQL_MODE: case SETTING_SQL_SELECT_LIMIT: case SETTING_SQL_SAFE_UPDATES: @@ -3921,7 +4009,6 @@ handler_again: case SETTING_CHARACTER_SET_DATABASE: case SETTING_ISOLATION_LEVEL: case SETTING_TRANSACTION_READ: - case SETTING_SESSION_TRACK_GTIDS: case SETTING_SQL_AUTO_IS_NULL: case SETTING_COLLATION_CONNECTION: case SETTING_NET_WRITE_TIMEOUT: @@ -5001,10 +5088,13 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C if ((strcasecmp(value1.c_str(),"OWN_GTID")==0) || (strcasecmp(value1.c_str(),"OFF")==0)) { proxy_debug(PROXY_DEBUG_MYSQL_COM, 7, "Processing SET session_track_gtids value %s\n", value1.c_str()); uint32_t session_track_gtids_int=SpookyHash::Hash32(value1.c_str(),value1.length(),10); - if (mysql_variables.client_get_hash(this, SQL_SESSION_TRACK_GTIDS) != session_track_gtids_int) { - if (!mysql_variables.client_set_value(this, SQL_SESSION_TRACK_GTIDS, value1.c_str())) - return false; + if (client_myds->myconn->options.session_track_gtids_int != session_track_gtids_int) { + client_myds->myconn->options.session_track_gtids_int = session_track_gtids_int; + if (client_myds->myconn->options.session_track_gtids) { + free(client_myds->myconn->options.session_track_gtids); + } proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Changing connection session_track_gtids to %s\n", value1.c_str()); + client_myds->myconn->options.session_track_gtids=strdup(value1.c_str()); } exit_after_SetParse = true; } else { diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp index 6d1a1491a..750ba8002 100644 --- a/lib/MySQL_Thread.cpp +++ b/lib/MySQL_Thread.cpp @@ -481,6 +481,7 @@ static char * mysql_thread_variables_names[]= { (char *)"ldap_user_variable", (char *)"add_ldap_user_comment", (char *)"default_tx_isolation", + (char *)"default_session_track_gtids", (char *)"connpoll_reset_queue_length", (char *)"min_num_servers_lantency_awareness", (char *)"aurora_max_lag_ms_only_read_from_replicas", @@ -589,6 +590,7 @@ MySQL_Threads_Handler::MySQL_Threads_Handler() { variables.default_variables[i]=strdup(mysql_tracked_variables[i].default_value); } variables.default_tx_isolation=strdup((char *)MYSQL_DEFAULT_TX_ISOLATION); + variables.default_session_track_gtids=strdup((char *)MYSQL_DEFAULT_SESSION_TRACK_GTIDS); variables.ping_interval_server_msec=10000; variables.ping_timeout_server=200; variables.default_schema=strdup((char *)"information_schema"); @@ -806,6 +808,12 @@ char * MySQL_Threads_Handler::get_variable_string(char *name) { } return strdup(variables.default_tx_isolation); } + if (!strcmp(name,"default_session_track_gtids")) { + if (variables.default_session_track_gtids==NULL) { + variables.default_session_track_gtids=strdup((char *)MYSQL_DEFAULT_SESSION_TRACK_GTIDS); + } + return strdup(variables.default_session_track_gtids); + } if (!strcmp(name,"default_schema")) return strdup(variables.default_schema); } if (!strcmp(name,"server_version")) return strdup(variables.server_version); @@ -1080,6 +1088,12 @@ char * MySQL_Threads_Handler::get_variable(char *name) { // this is the public f } return strdup(variables.default_tx_isolation); } + if (!strcasecmp(name,"default_session_track_gtids")) { + if (variables.default_session_track_gtids==NULL) { + variables.default_session_track_gtids=strdup((char *)MYSQL_DEFAULT_SESSION_TRACK_GTIDS); + } + return strdup(variables.default_session_track_gtids); + } for (int i=0; ifd=sess->client_myds->fd; // 20141011 sess->client_myds->myprot.init(&sess->client_myds, sess->client_myds->myconn->userinfo, sess); + uint32_t session_track_gtids_int=SpookyHash::Hash32(mysql_thread___default_session_track_gtids,strlen(mysql_thread___default_session_track_gtids),10); + sess->client_myds->myconn->options.session_track_gtids_int = session_track_gtids_int; + if (sess->client_myds->myconn->options.session_track_gtids) { + free(sess->client_myds->myconn->options.session_track_gtids); + } + sess->client_myds->myconn->options.session_track_gtids=strdup(mysql_thread___default_session_track_gtids); for (int i=0; iget_variable_string((char *)"add_ldap_user_comment"); if (mysql_thread___default_tx_isolation) free(mysql_thread___default_tx_isolation); mysql_thread___default_tx_isolation=GloMTH->get_variable_string((char *)"default_tx_isolation"); + if (mysql_thread___default_session_track_gtids) free(mysql_thread___default_session_track_gtids); + mysql_thread___default_session_track_gtids=GloMTH->get_variable_string((char *)"default_session_track_gtids"); for (int i=0; i