From 8d03589cf93d75f33092d1fd9f07251b1058bbd1 Mon Sep 17 00:00:00 2001 From: Rahim Kanji Date: Fri, 7 Jul 2023 15:06:40 +0500 Subject: [PATCH] Moved SQL_ISOLATION_LEVEL, SQL_TRANSACTION_READ, and SQL_WSREP_SYNC_WAIT to the higher bound. --- include/MySQL_Variables.h | 2 ++ include/proxysql_structs.h | 15 +++++++-------- lib/MySQL_Session.cpp | 9 +-------- lib/MySQL_Variables.cpp | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 47 insertions(+), 16 deletions(-) diff --git a/include/MySQL_Variables.h b/include/MySQL_Variables.h index e51caee16e..95381bf2da 100644 --- a/include/MySQL_Variables.h +++ b/include/MySQL_Variables.h @@ -39,11 +39,13 @@ class MySQL_Variables { bool client_set_value(MySQL_Session* session, int idx, const std::string& value); bool client_set_hash_and_value(MySQL_Session* session, int idx, const std::string& value, uint32_t hash); + void client_reset_value(MySQL_Session* session, int idx); const char* client_get_value(MySQL_Session* session, int idx) const; uint32_t client_get_hash(MySQL_Session* session, int idx) const; void server_set_value(MySQL_Session* session, int idx, const char* value); void server_set_hash_and_value(MySQL_Session* session, int idx, const char* value, uint32_t hash); + void server_reset_value(MySQL_Session* session, int idx); const char* server_get_value(MySQL_Session* session, int idx) const; inline uint32_t server_get_hash(MySQL_Session* session, int idx) const; diff --git a/include/proxysql_structs.h b/include/proxysql_structs.h index 4352380c4b..9ad6214a93 100644 --- a/include/proxysql_structs.h +++ b/include/proxysql_structs.h @@ -173,11 +173,10 @@ enum mysql_variable_name { SQL_CHARACTER_SET_CONNECTION, SQL_CHARACTER_SET_CLIENT, SQL_CHARACTER_SET_DATABASE, - SQL_ISOLATION_LEVEL, - SQL_TRANSACTION_READ, SQL_COLLATION_CONNECTION, - SQL_WSREP_SYNC_WAIT, SQL_NAME_LAST_LOW_WM, + SQL_ISOLATION_LEVEL, + SQL_TRANSACTION_READ, SQL_AURORA_READ_REPLICA_READ_COMMITTED, SQL_AUTO_INCREMENT_INCREMENT, SQL_AUTO_INCREMENT_OFFSET, @@ -223,6 +222,7 @@ enum mysql_variable_name { SQL_TMP_TABLE_SIZE, SQL_UNIQUE_CHECKS, SQL_WSREP_OSU_METHOD, + SQL_WSREP_SYNC_WAIT, SQL_NAME_LAST_HIGH_WM, }; @@ -1135,13 +1135,12 @@ mysql_variable_st mysql_tracked_variables[] { { SQL_CHARACTER_SET_CONNECTION, SETTING_VARIABLE, false, false, false, false, (char *)"character_set_connection", (char *)"character_set_connection", (char *)"utf8", false } , { SQL_CHARACTER_SET_CLIENT, SETTING_VARIABLE, false, false, false, false, (char *)"character_set_client", (char *)"character_set_client", (char *)"utf8" , false} , { SQL_CHARACTER_SET_DATABASE, SETTING_VARIABLE, false, false, false, false, (char *)"character_set_database", (char *)"character_set_database", (char *)"utf8" , false} , - { SQL_ISOLATION_LEVEL, SETTING_ISOLATION_LEVEL, false, true, false, false, (char *)"SESSION TRANSACTION ISOLATION LEVEL", (char *)"isolation_level", (char *)"READ COMMITTED" , false} , - // NOTE: we also need support for transaction_read_only session variable - { SQL_TRANSACTION_READ, SETTING_TRANSACTION_READ, false, true, false, false, (char *)"SESSION TRANSACTION READ", (char *)"transaction_read", (char *)"WRITE" , false} , { SQL_COLLATION_CONNECTION, SETTING_VARIABLE, true, false, false, false, (char *)"collation_connection", (char *)"collation_connection", (char *)"utf8_general_ci" , true} , // { SQL_NET_WRITE_TIMEOUT, SETTING_VARIABLE, false, false, true, false, (char *)"net_write_timeout", (char *)"net_write_timeout", (char *)"60" , false} , - { SQL_WSREP_SYNC_WAIT, SETTING_VARIABLE, false, false, true, false, (char *)"wsrep_sync_wait", (char *)"wsrep_sync_wait", (char *)"0" , false} , { SQL_NAME_LAST_LOW_WM, SETTING_VARIABLE, false, false, true, false, (char *)"placeholder", (char *)"placeholder", (char *)"0" , false} , // this is just a placeholder to separate the previous index from the next block + { SQL_ISOLATION_LEVEL, SETTING_ISOLATION_LEVEL, false, true, false, false, (char *)"SESSION TRANSACTION ISOLATION LEVEL", (char *)"isolation_level", (char *)"READ COMMITTED" , false} , + // NOTE: we also need support for transaction_read_only session variable + { SQL_TRANSACTION_READ, SETTING_TRANSACTION_READ, false, true, false, false, (char *)"SESSION TRANSACTION READ", (char *)"transaction_read", (char *)"WRITE" , false} , { SQL_AURORA_READ_REPLICA_READ_COMMITTED, SETTING_VARIABLE, false, false, false, true, ( char *)"aurora_read_replica_read_committed", NULL, (char *)"" , false} , { SQL_AUTO_INCREMENT_INCREMENT, SETTING_VARIABLE, false, false, true, false, (char *)"auto_increment_increment", NULL, (char *)"" , false} , { SQL_AUTO_INCREMENT_OFFSET, SETTING_VARIABLE, false, false, true, false, (char *)"auto_increment_offset", NULL, (char *)"" , false} , @@ -1190,7 +1189,7 @@ mysql_variable_st mysql_tracked_variables[] { { SQL_TMP_TABLE_SIZE, SETTING_VARIABLE, false, false, true, false, (char *)"tmp_table_size", NULL, (char *)"" , false} , { SQL_UNIQUE_CHECKS, SETTING_VARIABLE, true, false, false, true, (char *)"unique_checks", NULL, (char *)"" , false} , { SQL_WSREP_OSU_METHOD, SETTING_VARIABLE, true, false, false, false, (char *)"wsrep_osu_method", NULL, (char *)"" , false} , - + { SQL_WSREP_SYNC_WAIT, SETTING_VARIABLE, false, false, true, false, (char *)"wsrep_sync_wait", (char *)"wsrep_sync_wait", (char *)"0" , false} , /* variables that will need input validation: binlog_row_image diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 57b8255687..f7789cfee9 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -2558,14 +2558,7 @@ bool MySQL_Session::handler_again___status_SETTING_GENERIC_VARIABLE(int *_rc, co // https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Reference.html#AuroraMySQL.Reference.IsolationLevels // Basically, to change isolation level you must first set // aurora_read_replica_read_committed , and then isolation level - MySQL_Connection *beconn = mybe->server_myds->myconn; - if (beconn->var_hash[SQL_ISOLATION_LEVEL] != 0) { - beconn->var_hash[SQL_ISOLATION_LEVEL] = 0; - if (beconn->variables[SQL_ISOLATION_LEVEL].value) { - free(beconn->variables[SQL_ISOLATION_LEVEL].value); - beconn->variables[SQL_ISOLATION_LEVEL].value = NULL; - } - } + mysql_variables.server_reset_value(this, SQL_ISOLATION_LEVEL); sprintf(query,q,var_name, var_value); } else { sprintf(query,q,var_name, var_value); diff --git a/lib/MySQL_Variables.cpp b/lib/MySQL_Variables.cpp index e60c4b3abb..c1ed5685a7 100644 --- a/lib/MySQL_Variables.cpp +++ b/lib/MySQL_Variables.cpp @@ -94,6 +94,24 @@ bool MySQL_Variables::client_set_hash_and_value(MySQL_Session* session, int idx, return true; } +void MySQL_Variables::client_reset_value(MySQL_Session* session, int idx) { + if (!session || !session->client_myds || !session->client_myds->myconn) { + proxy_warning("Session validation failed\n"); + return; + } + + MySQL_Connection *client_conn = session->client_myds->myconn; + + if (client_conn->var_hash[idx] != 0) { + client_conn->var_hash[idx] = 0; + if (client_conn->variables[idx].value) { + free(client_conn->variables[idx].value); + client_conn->variables[idx].value = NULL; + } + // we now regererate dynamic_variables_idx + client_conn->reorder_dynamic_variables_idx(); + } +} void MySQL_Variables::server_set_hash_and_value(MySQL_Session* session, int idx, const char* value, uint32_t hash) { if (!session || !session->mybe || !session->mybe->server_myds || !session->mybe->server_myds->myconn || !value) { proxy_warning("Session validation failed\n"); @@ -222,6 +240,25 @@ void MySQL_Variables::server_set_value(MySQL_Session* session, int idx, const ch session->mybe->server_myds->myconn->reorder_dynamic_variables_idx(); } +void MySQL_Variables::server_reset_value(MySQL_Session* session, int idx) { + assert(session); + assert(session->mybe); + assert(session->mybe->server_myds); + assert(session->mybe->server_myds->myconn); + + MySQL_Connection *backend_conn = session->mybe->server_myds->myconn; + + if (backend_conn->var_hash[idx] != 0) { + backend_conn->var_hash[idx] = 0; + if (backend_conn->variables[idx].value) { + free(backend_conn->variables[idx].value); + backend_conn->variables[idx].value = NULL; + } + // we now regererate dynamic_variables_idx + backend_conn->reorder_dynamic_variables_idx(); + } +} + const char* MySQL_Variables::server_get_value(MySQL_Session* session, int idx) const { assert(session); assert(session->mybe);