From 23cab574ac7037e71093528b29e6da1d45fd8bc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20S=C3=A1nchez=20Parra?= Date: Tue, 6 Dec 2022 11:46:25 +0100 Subject: [PATCH 1/2] Add new variable 'mysql-parse_failure_logs_digest' If the variable is 'true', ProxySQL prints the digest instead of the query when it has a parse failure. --- include/MySQL_Thread.h | 1 + include/proxysql_structs.h | 2 ++ lib/MySQL_Session.cpp | 48 +++++++++++++++++++++++++++++++------- lib/MySQL_Thread.cpp | 4 ++++ 4 files changed, 46 insertions(+), 9 deletions(-) diff --git a/include/MySQL_Thread.h b/include/MySQL_Thread.h index f7a6b9b6a..d45cd1469 100644 --- a/include/MySQL_Thread.h +++ b/include/MySQL_Thread.h @@ -498,6 +498,7 @@ class MySQL_Threads_Handler bool query_digests_keep_comment; int query_digests_grouping_limit; int query_digests_groups_grouping_limit; + bool parse_failure_logs_digest; bool default_reconnect; bool have_compress; bool have_ssl; diff --git a/include/proxysql_structs.h b/include/proxysql_structs.h index 82a5ceed0..3f68ce8f7 100644 --- a/include/proxysql_structs.h +++ b/include/proxysql_structs.h @@ -823,6 +823,7 @@ __thread bool mysql_thread___query_digests_track_hostname; __thread bool mysql_thread___query_digests_keep_comment; __thread int mysql_thread___query_digests_max_digest_length; __thread int mysql_thread___query_digests_max_query_length; +__thread bool mysql_thread___parse_failure_logs_digest; __thread int mysql_thread___show_processlist_extended; __thread int mysql_thread___session_idle_ms; __thread int mysql_thread___hostgroup_manager_verbose; @@ -984,6 +985,7 @@ extern __thread bool mysql_thread___query_digests_track_hostname; extern __thread bool mysql_thread___query_digests_keep_comment; extern __thread int mysql_thread___query_digests_max_digest_length; extern __thread int mysql_thread___query_digests_max_query_length; +extern __thread bool mysql_thread___parse_failure_logs_digest; extern __thread int mysql_thread___show_processlist_extended; extern __thread int mysql_thread___session_idle_ms; extern __thread int mysql_thread___hostgroup_manager_verbose; diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index fd321ea81..6f751ded3 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -5806,7 +5806,11 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C } #endif if (index(dig,';') && (index(dig,';') != dig + strlen(dig)-1)) { - string nqn = string((char *)CurrentQuery.QueryPointer,CurrentQuery.QueryLength); + string nqn; + if (mysql_thread___parse_failure_logs_digest) + nqn = string((char *)CurrentQuery.QueryPointer,CurrentQuery.QueryLength); + else + nqn = string(CurrentQuery.get_digest_text()); proxy_warning( "Unable to parse multi-statements command with SET statement from client" " %s:%d: setting lock hostgroup. Command: %s\n", client_myds->addr.addr, @@ -5849,12 +5853,19 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Processing SET variable %s\n", var.c_str()); if (it->second.size() < 1 || it->second.size() > 2) { // error not enough arguments - string nqn = string((char *)CurrentQuery.QueryPointer,CurrentQuery.QueryLength); + string query_str = string((char *)CurrentQuery.QueryPointer,CurrentQuery.QueryLength); + string digest_str = string(CurrentQuery.get_digest_text()); + string nqn; + if (mysql_thread___parse_failure_logs_digest) + nqn = digest_str; + else + nqn = query_str; // PMC-10002: A query has failed to be parsed. This can be due a incorrect query or // due to ProxySQL not being able to properly parse it. In case the query is correct a // bug report should be filed including the offending query. proxy_error2(10002, "Unable to parse query. If correct, report it as a bug: %s\n", nqn.c_str()); - proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "Locking hostgroup for query %s\n", nqn.c_str()); + proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "Locking hostgroup for query %s\n", + query_str.c_str()); unable_to_parse_set_statement(lock_hostgroup); return false; } @@ -5878,9 +5889,17 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C || ( strcasecmp(value1.c_str(),(char *)"IFNULL") == 0 ) ) { - string nqn = string((char *)CurrentQuery.QueryPointer,CurrentQuery.QueryLength); + string query_str = string((char *)CurrentQuery.QueryPointer, + CurrentQuery.QueryLength); + string digest_str = string(CurrentQuery.get_digest_text()); + string nqn; + if (mysql_thread___parse_failure_logs_digest) + nqn = digest_str; + else + nqn = query_str; proxy_error2(10002, "Unable to parse query. If correct, report it as a bug: %s\n", nqn.c_str()); - proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "Locking hostgroup for query %s\n", nqn.c_str()); + proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, + "Locking hostgroup for query %s\n", query_str.c_str()); unable_to_parse_set_statement(lock_hostgroup); return false; } @@ -6319,7 +6338,11 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C if (kq != 0) { kq = strncmp((const char *)CurrentQuery.QueryPointer, (const char *)"/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */" , CurrentQuery.QueryLength); if (kq != 0) { - string nqn = string((char *)CurrentQuery.QueryPointer,CurrentQuery.QueryLength); + string nqn; + if (mysql_thread___parse_failure_logs_digest) + nqn = string((char *)CurrentQuery.QueryPointer,CurrentQuery.QueryLength); + else + nqn = string(CurrentQuery.get_digest_text()); proxy_error2(10002, "Unable to parse query. If correct, report it as a bug: %s\n", nqn.c_str()); return false; } @@ -7642,8 +7665,14 @@ bool MySQL_Session::known_query_for_locked_on_hostgroup(uint64_t digest) { void MySQL_Session::unable_to_parse_set_statement(bool *lock_hostgroup) { // we couldn't parse the query - string nqn = string((char *)CurrentQuery.QueryPointer,CurrentQuery.QueryLength); - proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "Locking hostgroup for query %s\n", nqn.c_str()); + string query_str = string((char *)CurrentQuery.QueryPointer,CurrentQuery.QueryLength); + string digest_str = string(CurrentQuery.get_digest_text()); + string nqn; + if (mysql_thread___parse_failure_logs_digest) + nqn = digest_str; + else + nqn = query_str; + proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "Locking hostgroup for query %s\n", query_str.c_str()); if (qpo->multiplex == -1) { // we have no rule about this SET statement. We set hostgroup locking if (locked_on_hostgroup < 0) { @@ -7671,7 +7700,8 @@ void MySQL_Session::unable_to_parse_set_statement(bool *lock_hostgroup) { } } } else { - proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "Unable to parse SET query but NOT setting lock_hostgroup %s\n", nqn.c_str()); + proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, + "Unable to parse SET query but NOT setting lock_hostgroup %s\n", query_str.c_str()); } } diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp index 63021edeb..09a072f78 100644 --- a/lib/MySQL_Thread.cpp +++ b/lib/MySQL_Thread.cpp @@ -547,6 +547,7 @@ static char * mysql_thread_variables_names[]= { (char *)"query_digests_normalize_digest_text", (char *)"query_digests_track_hostname", (char *)"query_digests_keep_comment", + (char *)"parse_failure_logs_digest", (char *)"servers_stats", (char *)"default_reconnect", #ifdef DEBUG @@ -1171,6 +1172,7 @@ MySQL_Threads_Handler::MySQL_Threads_Handler() { variables.query_digests_normalize_digest_text=false; variables.query_digests_track_hostname=false; variables.query_digests_keep_comment=false; + variables.parse_failure_logs_digest=false; variables.connpoll_reset_queue_length = 50; variables.min_num_servers_lantency_awareness = 1000; variables.aurora_max_lag_ms_only_read_from_replicas = 2; @@ -2117,6 +2119,7 @@ char ** MySQL_Threads_Handler::get_variables_list() { VariablesPointers_bool["query_digests_normalize_digest_text"] = make_tuple(&variables.query_digests_normalize_digest_text, false); VariablesPointers_bool["query_digests_track_hostname"] = make_tuple(&variables.query_digests_track_hostname, false); VariablesPointers_bool["query_digests_keep_comment"] = make_tuple(&variables.query_digests_keep_comment, false); + VariablesPointers_bool["parse_failure_logs_digest"] = make_tuple(&variables.parse_failure_logs_digest, false); VariablesPointers_bool["servers_stats"] = make_tuple(&variables.servers_stats, false); VariablesPointers_bool["sessions_sort"] = make_tuple(&variables.sessions_sort, false); VariablesPointers_bool["stats_time_backend_query"] = make_tuple(&variables.stats_time_backend_query, false); @@ -4059,6 +4062,7 @@ void MySQL_Thread::refresh_variables() { mysql_thread___query_digests_grouping_limit=(int)GloMTH->get_variable_int((char *)"query_digests_grouping_limit"); mysql_thread___query_digests_groups_grouping_limit=(int)GloMTH->get_variable_int((char *)"query_digests_groups_grouping_limit"); mysql_thread___query_digests_keep_comment=(bool)GloMTH->get_variable_int((char *)"query_digests_keep_comment"); + mysql_thread___parse_failure_logs_digest=(bool)GloMTH->get_variable_int((char *)"parse_failure_logs_digest"); variables.min_num_servers_lantency_awareness=GloMTH->get_variable_int((char *)"min_num_servers_lantency_awareness"); variables.aurora_max_lag_ms_only_read_from_replicas=GloMTH->get_variable_int((char *)"aurora_max_lag_ms_only_read_from_replicas"); variables.stats_time_backend_query=(bool)GloMTH->get_variable_int((char *)"stats_time_backend_query"); From 64670f46cc2cd3bc848bfa2a9ba887fd61fa7150 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Mon, 12 Dec 2022 03:42:50 +0000 Subject: [PATCH 2/2] Minor optimization in unable_to_parse_set_statement() --- lib/MySQL_Session.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 6f751ded3..28fd72306 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -7667,11 +7667,7 @@ void MySQL_Session::unable_to_parse_set_statement(bool *lock_hostgroup) { // we couldn't parse the query string query_str = string((char *)CurrentQuery.QueryPointer,CurrentQuery.QueryLength); string digest_str = string(CurrentQuery.get_digest_text()); - string nqn; - if (mysql_thread___parse_failure_logs_digest) - nqn = digest_str; - else - nqn = query_str; + string& nqn = ( mysql_thread___parse_failure_logs_digest == true ? digest_str : query_str ); proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "Locking hostgroup for query %s\n", query_str.c_str()); if (qpo->multiplex == -1) { // we have no rule about this SET statement. We set hostgroup locking