From b588798a08d55a81a697cf625be26d5085c86cde Mon Sep 17 00:00:00 2001 From: Rahim Kanji Date: Tue, 31 Oct 2023 10:39:39 +0500 Subject: [PATCH] Few fixes --- include/mysql_connection.h | 1 + lib/MySQL_Session.cpp | 35 ++++++++++++++++-------------- lib/mysql_connection.cpp | 7 ++++-- test/tap/tests/test_warnings-t.cpp | 23 ++++++++++---------- 4 files changed, 37 insertions(+), 29 deletions(-) diff --git a/include/mysql_connection.h b/include/mysql_connection.h index c783a7d64..7b796b18c 100644 --- a/include/mysql_connection.h +++ b/include/mysql_connection.h @@ -129,6 +129,7 @@ class MySQL_Connection { } statuses; unsigned long largest_query_length; + unsigned int warning_count; /** * @brief This represents the internal knowledge of ProxySQL about the connection. It keeps track of those * states which *are not reflected* into 'server_status', but are relevant for connection handling. diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index f4ef709b3..c168069b8 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -1250,6 +1250,7 @@ void MySQL_Session::generate_proxysql_internal_session_json(json &j) { j["backends"][i]["conn"]["status"]["compression"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_COMPRESSION); j["backends"][i]["conn"]["status"]["prepared_statement"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_PREPARED_STATEMENT); j["backends"][i]["conn"]["status"]["has_warnings"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_HAS_WARNINGS); + j["backends"][i]["conn"]["warning_count"] = _myconn->warning_count; j["backends"][i]["conn"]["MultiplexDisabled"] = _myconn->MultiplexDisabled(); j["backends"][i]["conn"]["ps"]["backend_stmt_to_global_ids"] = _myconn->local_stmts->backend_stmt_to_global_ids; j["backends"][i]["conn"]["ps"]["global_stmt_to_backend_ids"] = _myconn->local_stmts->global_stmt_to_backend_ids; @@ -6062,27 +6063,28 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C if ((dig_len == 22) && (strncasecmp(dig, "SHOW COUNT(*) WARNINGS", 22) == 0)) { proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Intercepted '%s'\n", dig); + std::string warning_count = "0"; if (warning_in_hg > -1) { proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Changing current_hostgroup to '%d'\n", warning_in_hg); - current_hostgroup = warning_in_hg; - //warning_in_hg = -1; - return false; + current_hostgroup = warning_in_hg; + assert(mybe && mybe->server_myds && mybe->server_myds->myconn && mybe->server_myds->myconn->mysql); + warning_count = std::to_string(mybe->server_myds->myconn->warning_count); } else { proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "No warnings were detected in the previous query. Sending an empty response.\n"); - std::unique_ptr resultset(new SQLite3_result(1)); - resultset->add_column_definition(SQLITE_TEXT, "@@session.warning_count"); - char* pta[1]; - pta[0] = (char*)"0"; - resultset->add_row(pta); - SQLite3_to_MySQL(resultset.get(), NULL, 0, &client_myds->myprot, false, (client_myds->myconn->options.client_flag & CLIENT_DEPRECATE_EOF)); - client_myds->DSS = STATE_SLEEP; - status = WAITING_CLIENT_DATA; - if (mirror == false) { - RequestEnd(NULL); - } - l_free(pkt->size, pkt->ptr); - return true; } + std::unique_ptr resultset(new SQLite3_result(1)); + resultset->add_column_definition(SQLITE_TEXT, "@@session.warning_count"); + char* pta[1]; + pta[0] = (char*)warning_count.c_str(); + resultset->add_row(pta); + SQLite3_to_MySQL(resultset.get(), NULL, 0, &client_myds->myprot, false, (client_myds->myconn->options.client_flag & CLIENT_DEPRECATE_EOF)); + client_myds->DSS = STATE_SLEEP; + status = WAITING_CLIENT_DATA; + if (mirror == false) { + RequestEnd(NULL); + } + l_free(pkt->size, pkt->ptr); + return true; } reset_warning_hostgroup_flag_and_release_connection(); @@ -8163,6 +8165,7 @@ void MySQL_Session::reset_warning_hostgroup_flag_and_release_connection() MySQL_Backend* _mybe = NULL; _mybe = find_backend(warning_in_hg); MySQL_Data_Stream* myds = _mybe->server_myds; + myds->myconn->warning_count = 0; myds->myconn->set_status(false, STATUS_MYSQL_CONNECTION_HAS_WARNINGS); if ((myds->myconn->reusable == true) && myds->myconn->IsActiveTransaction() == false && myds->myconn->MultiplexDisabled() == false) { myds->return_MySQL_Connection_To_Pool(); diff --git a/lib/mysql_connection.cpp b/lib/mysql_connection.cpp index 44a4623da..4f2235456 100644 --- a/lib/mysql_connection.cpp +++ b/lib/mysql_connection.cpp @@ -434,6 +434,7 @@ MySQL_Connection::MySQL_Connection() { query.stmt_meta=NULL; query.stmt_result=NULL; largest_query_length=0; + warning_count=0; multiplex_delayed=false; MyRS=NULL; MyRS_reuse=NULL; @@ -2575,11 +2576,12 @@ void MySQL_Connection::ProcessQueryAndSetStatusFlags(char *query_digest_text) { // checking warnings and disabling multiplexing will be effective only when the mysql-query_digests is enabled if (myds->sess->CurrentQuery.QueryParserArgs.digest_text) { if (get_status(STATUS_MYSQL_CONNECTION_HAS_WARNINGS) == false) { - if (mysql_warning_count(this->mysql) > 0) { + if (this->mysql && mysql_warning_count(this->mysql) > 0) { if (myds && myds->sess) { // 'warning_in_hg' will be used if the next query is 'SHOW WARNINGS' or // 'SHOW COUNT(*) WARNINGS' myds->sess->warning_in_hg = myds->sess->current_hostgroup; + warning_count = mysql_warning_count(this->mysql); // enabling multiplexing set_status(true, STATUS_MYSQL_CONNECTION_HAS_WARNINGS); } @@ -2595,6 +2597,7 @@ void MySQL_Connection::ProcessQueryAndSetStatusFlags(char *query_digest_text) { if (myds && myds->sess) { myds->sess->warning_in_hg = -1; } + warning_count = 0; // disabling multiplexing set_status(false, STATUS_MYSQL_CONNECTION_HAS_WARNINGS); } @@ -2828,7 +2831,7 @@ void MySQL_Connection::reset() { set_status(old_compress,STATUS_MYSQL_CONNECTION_COMPRESSION); reusable=true; options.last_set_autocommit=-1; // never sent - + warning_count=0; delete local_stmts; local_stmts=new MySQL_STMTs_local_v14(false); creation_time = monotonic_time(); diff --git a/test/tap/tests/test_warnings-t.cpp b/test/tap/tests/test_warnings-t.cpp index bb6f2e40c..9071ccccb 100644 --- a/test/tap/tests/test_warnings-t.cpp +++ b/test/tap/tests/test_warnings-t.cpp @@ -31,11 +31,7 @@ using MESSAGE = std::string; } \ } while(0) -#define MYSQL_CLEAR_RESULT(mysql) do { MYSQL_RES* mysql_result = mysql_use_result(mysql); \ - while (MYSQL_ROW row = mysql_fetch_row(mysql_result)) {} \ - mysql_free_result(mysql_result); \ - } while(0) - +#define MYSQL_CLEAR_RESULT(mysql) mysql_free_result(mysql_store_result(mysql)); enum MultiplexStatus { kNotApplicable = 0, @@ -150,15 +146,17 @@ int check_proxysql_internal_session(MYSQL* proxysql, int exp_status) { if (backend != nullptr && backend.contains("conn")) { found_backend = true; - if (backend["conn"]["MultiplexDisabled"]) { + if (backend["conn"]["MultiplexDisabled"] == true) { status |= MultiplexStatus::kMultiplexingEnabled; } - if (backend["conn"]["status"]["has_warnings"] && j_status["warning_in_hg"] != -1) { + if (backend["conn"]["status"]["has_warnings"] == true && + backend["conn"]["warning_count"] > 0 && + j_status["warning_in_hg"] != -1) { status |= MultiplexStatus::kHasWarnings; } - if (backend["conn"]["status"]["user_variable"]) { + if (backend["conn"]["status"]["user_variable"] == true) { status |= MultiplexStatus::kUserVariables; } } @@ -233,8 +231,6 @@ const std::vector multiplexing_test = { { ConnectionType::kMySQL, {"SELECT 1", true}, {WarningCheckType::kAll, 0}, (MultiplexStatus::kMultiplexingEnabled | MultiplexStatus::kUserVariables) } }; - - #define IS_BIT_MASK_SET(variable,flag) ((variable & static_cast(flag)) == static_cast(flag)) int main(int argc, char** argv) { @@ -246,7 +242,12 @@ int main(int argc, char** argv) { return -1; } - plan(9+13+4+23+9+10); + plan((7+2) + // select test: 7 warning checks, 2 multiplex status checks + (9+4) + // insert test: 9 warning checks, 4 multiplex status checks + (3+1) + // query digest test: 3 warning checks, 1 multiplex status checks + (18+5) + // query cache test: 18 warning checks, 5 multiplex status checks + (7+2) + // warning log test: 7 warning checks, 2 multiplex status checks + (7+3)); // multiplexing test: 7 warning checks, 3 multiplex status checks // Initialize Admin connection MYSQL* proxysql_admin = mysql_init(NULL);