From 5e79afa8e0c3305cf376d7bfe53a29d27478ffbb Mon Sep 17 00:00:00 2001 From: Andriy Utkin Date: Wed, 26 Jun 2024 13:41:15 +0100 Subject: [PATCH 01/62] Set thread names --- include/proxysql_utils.h | 9 +++++++++ lib/ClickHouse_Server.cpp | 1 + lib/GTID_Server_Data.cpp | 1 + lib/MySQL_HostGroups_Manager.cpp | 1 + lib/MySQL_Monitor.cpp | 13 +++++++++++++ lib/MySQL_Session.cpp | 1 + lib/MySQL_Thread.cpp | 4 ++++ lib/ProxySQL_Admin.cpp | 1 + lib/ProxySQL_Cluster.cpp | 1 + lib/ProxySQL_RESTAPI_Server.cpp | 1 + lib/Query_Cache.cpp | 1 + lib/Query_Processor.cpp | 3 +++ src/SQLite3_Server.cpp | 2 ++ src/main.cpp | 2 ++ 14 files changed, 41 insertions(+) diff --git a/include/proxysql_utils.h b/include/proxysql_utils.h index 2e127e57c4..187a7c0f1e 100644 --- a/include/proxysql_utils.h +++ b/include/proxysql_utils.h @@ -11,6 +11,7 @@ #include #include #include +#include #include "sqlite3db.h" @@ -258,4 +259,12 @@ void close_all_non_term_fd(std::vector excludeFDs); */ std::pair get_dollar_quote_error(const char* version); +static inline void set_thread_name(const char name[16]) { +#if defined(__linux__) || defined(__FreeBSD__) + int rc; + rc = pthread_setname_np(pthread_self(), name); + assert(!rc); +#endif +} + #endif diff --git a/lib/ClickHouse_Server.cpp b/lib/ClickHouse_Server.cpp index db35d65635..fff779f0bc 100644 --- a/lib/ClickHouse_Server.cpp +++ b/lib/ClickHouse_Server.cpp @@ -1475,6 +1475,7 @@ static void * sqlite3server_main_loop(void *arg) pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + set_thread_name("ClickHouseMain"); while (glovars.shutdown==0 && *shutdown==0) { int *client; diff --git a/lib/GTID_Server_Data.cpp b/lib/GTID_Server_Data.cpp index d721bfd1b0..5fa90b7bdd 100644 --- a/lib/GTID_Server_Data.cpp +++ b/lib/GTID_Server_Data.cpp @@ -442,6 +442,7 @@ void addGtid(const gtid_t& gtid, gtid_set_t& gtid_executed) { void * GTID_syncer_run() { //struct ev_loop * gtid_ev_loop; //gtid_ev_loop = NULL; + set_thread_name("GTID"); MyHGM->gtid_ev_loop = ev_loop_new (EVBACKEND_POLL | EVFLAG_NOENV); if (MyHGM->gtid_ev_loop == NULL) { proxy_error("could not initialise GTID sync loop\n"); diff --git a/lib/MySQL_HostGroups_Manager.cpp b/lib/MySQL_HostGroups_Manager.cpp index 37c075c6b1..04b64939ba 100644 --- a/lib/MySQL_HostGroups_Manager.cpp +++ b/lib/MySQL_HostGroups_Manager.cpp @@ -85,6 +85,7 @@ static int wait_for_mysql(MYSQL *mysql, int status) { //static void * HGCU_thread_run() { static void * HGCU_thread_run() { PtrArray *conn_array=new PtrArray(); + set_thread_name("MyHGCU"); while(1) { MySQL_Connection *myconn= NULL; myconn = (MySQL_Connection *)MyHGM->queue.remove(); diff --git a/lib/MySQL_Monitor.cpp b/lib/MySQL_Monitor.cpp index 4d5d9bc95f..fd35843bf3 100644 --- a/lib/MySQL_Monitor.cpp +++ b/lib/MySQL_Monitor.cpp @@ -68,6 +68,9 @@ class ConsumerThread : public Thread { thrn=_n; } void* run() { + char thr_name[16]; + snprintf(thr_name, sizeof(thr_name), "%.12s%03d", typeid(T).name(), thrn); + set_thread_name(thr_name); // Remove 1 item at a time and process it. Blocks if no items are // available to process. for (int i = 0; (thrn ? i < thrn : 1); i++) { @@ -729,6 +732,7 @@ void * monitor_connect_pthread(void *arg) { bool cache=false; mallctl("thread.tcache.enabled", NULL, NULL, &cache, sizeof(bool)); #endif + set_thread_name("MonitorConnect"); while (GloMTH==NULL) { usleep(50000); } @@ -742,6 +746,7 @@ void * monitor_ping_pthread(void *arg) { bool cache=false; mallctl("thread.tcache.enabled", NULL, NULL, &cache, sizeof(bool)); #endif + set_thread_name("MonitorPing"); while (GloMTH==NULL) { usleep(50000); } @@ -755,6 +760,7 @@ void * monitor_read_only_pthread(void *arg) { bool cache=false; mallctl("thread.tcache.enabled", NULL, NULL, &cache, sizeof(bool)); #endif + set_thread_name("MonitorReadOnly"); while (GloMTH==NULL) { usleep(50000); } @@ -768,6 +774,7 @@ void * monitor_group_replication_pthread(void *arg) { bool cache=false; mallctl("thread.tcache.enabled", NULL, NULL, &cache, sizeof(bool)); #endif + set_thread_name("MonitorGR"); while (GloMTH==NULL) { usleep(50000); } @@ -782,6 +789,7 @@ void * monitor_galera_pthread(void *arg) { bool cache=false; mallctl("thread.tcache.enabled", NULL, NULL, &cache, sizeof(bool)); #endif + set_thread_name("MonitorGalera"); while (GloMTH==NULL) { usleep(50000); } @@ -795,6 +803,7 @@ void * monitor_aws_aurora_pthread(void *arg) { // bool cache=false; // mallctl("thread.tcache.enabled", NULL, NULL, &cache, sizeof(bool)); //#endif + set_thread_name("MonitorAurora"); while (GloMTH==NULL) { usleep(50000); } @@ -808,6 +817,7 @@ void * monitor_replication_lag_pthread(void *arg) { bool cache=false; mallctl("thread.tcache.enabled", NULL, NULL, &cache, sizeof(bool)); #endif + set_thread_name("MonitReplicLag"); while (GloMTH==NULL) { usleep(50000); } @@ -821,6 +831,7 @@ void* monitor_dns_cache_pthread(void* arg) { bool cache = false; mallctl("thread.tcache.enabled", NULL, NULL, &cache, sizeof(bool)); #endif + set_thread_name("MonitorDNSCache"); while (GloMTH == NULL) { usleep(50000); } @@ -3996,6 +4007,7 @@ struct mon_thread_info_t { void* monitor_GR_thread_HG(void *arg) { uint32_t wr_hg = *(static_cast(arg)); + set_thread_name("MonitorGRwrHG"); proxy_info("Started Monitor thread for Group Replication writer HG %u\n", wr_hg); // Quick exit during shutdown/restart @@ -5854,6 +5866,7 @@ void * monitor_AWS_Aurora_thread_HG(void *arg) { unsigned int min_lag_ms = 0; unsigned int lag_num_checks = 1; //unsigned int i = 0; + set_thread_name("MonitorAuroraHG"); proxy_info("Started Monitor thread for AWS Aurora writer HG %u\n", wHG); unsigned int MySQL_Monitor__thread_MySQL_Thread_Variables_version; diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index ae306e36e4..94ba263d84 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -264,6 +264,7 @@ void* kill_query_thread(void *arg) { KillArgs *ka=(KillArgs *)arg; //! It initializes a new MySQL_Thread object to handle MySQL-related operations. std::unique_ptr mysql_thr(new MySQL_Thread()); + set_thread_name("KillQuery"); //! Retrieves the current time and refreshes thread variables. mysql_thr->curtime=monotonic_time(); mysql_thr->refresh_variables(); diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp index 8d2d3e7e21..0810685a63 100644 --- a/lib/MySQL_Thread.cpp +++ b/lib/MySQL_Thread.cpp @@ -2386,6 +2386,7 @@ void MySQL_Threads_Handler::init(unsigned int num, size_t stack) { * @return A pointer to the created MySQL thread. */ proxysql_mysql_thread_t * MySQL_Threads_Handler::create_thread(unsigned int tn, void *(*start_routine) (void *), bool idles) { + char thr_name[16]; if (idles==false) { if (pthread_create(&mysql_threads[tn].thread_id, &attr, start_routine , &mysql_threads[tn]) != 0 ) { // LCOV_EXCL_START @@ -2393,6 +2394,8 @@ proxysql_mysql_thread_t * MySQL_Threads_Handler::create_thread(unsigned int tn, assert(0); // LCOV_EXCL_STOP } + snprintf(thr_name, sizeof(thr_name), "MySQLWorker%d", tn); + pthread_setname_np(mysql_threads[tn].thread_id, thr_name); #ifdef IDLE_THREADS } else { if (GloVars.global.idle_threads) { @@ -2402,6 +2405,7 @@ proxysql_mysql_thread_t * MySQL_Threads_Handler::create_thread(unsigned int tn, assert(0); // LCOV_EXCL_STOP } + snprintf(thr_name, sizeof(thr_name), "MySQLIdle%d", tn); } #endif // IDLE_THREADS } diff --git a/lib/ProxySQL_Admin.cpp b/lib/ProxySQL_Admin.cpp index 7308f84a89..34da224b44 100644 --- a/lib/ProxySQL_Admin.cpp +++ b/lib/ProxySQL_Admin.cpp @@ -5682,6 +5682,7 @@ static void * admin_main_loop(void *arg) int *callback_func=((struct _main_args *)arg)->callback_func; volatile int *shutdown=((struct _main_args *)arg)->shutdown; char *socket_names[MAX_ADMIN_LISTENERS]; + set_thread_name("Admin"); for (i=0;istart(true); return NULL; diff --git a/lib/Query_Cache.cpp b/lib/Query_Cache.cpp index e79e34a7ab..002031499a 100644 --- a/lib/Query_Cache.cpp +++ b/lib/Query_Cache.cpp @@ -792,6 +792,7 @@ void * Query_Cache::purgeHash_thread(void *) { unsigned int MySQL_Monitor__thread_MySQL_Thread_Variables_version; MySQL_Thread * mysql_thr = new MySQL_Thread(); MySQL_Monitor__thread_MySQL_Thread_Variables_version=GloMTH->get_global_version(); + set_thread_name("QueryCachePurge"); mysql_thr->refresh_variables(); max_memory_size = (uint64_t) mysql_thread___query_cache_size_MB*1024*1024; while (shutdown==0) { diff --git a/lib/Query_Processor.cpp b/lib/Query_Processor.cpp index 2918104821..b385f35748 100644 --- a/lib/Query_Processor.cpp +++ b/lib/Query_Processor.cpp @@ -770,6 +770,7 @@ void * get_query_digests_total_size_parallel(void *_arg) { unsigned long long i = 0; unsigned long long m = arg->m; unsigned long long ret = 0; + set_thread_name("GetQueryDigeTota"); for (std::unordered_map::iterator it=arg->gu->begin(); it!=arg->gu->end(); ++it) { if ((i%DIGEST_STATS_FAST_THREADS)==m) { QP_query_digest_stats *qds=(QP_query_digest_stats *)it->second; @@ -805,6 +806,7 @@ void * get_query_digests_parallel(void *_arg) { unsigned long long i = 0; unsigned long long m = arg->m; unsigned long long ret = 0; + set_thread_name("GetQueryDigests"); if (arg->free_me) { if (arg->defer_free) { size_t map_size = arg->gu->size(); @@ -852,6 +854,7 @@ void * purge_query_digests_parallel(void *_arg) { unsigned long long i = 0; unsigned long long r = 0; unsigned long long m = arg->m; + set_thread_name("PurgeQueryDigest"); for (std::unordered_map::iterator it=arg->gu->begin(); it!=arg->gu->end(); ++it) { if ((i%DIGEST_STATS_FAST_THREADS)==m) { QP_query_digest_stats *qds=(QP_query_digest_stats *)it->second; diff --git a/src/SQLite3_Server.cpp b/src/SQLite3_Server.cpp index d4b678366b..591ed18c29 100644 --- a/src/SQLite3_Server.cpp +++ b/src/SQLite3_Server.cpp @@ -1021,6 +1021,7 @@ static void *child_mysql(void *arg) { int client = *(int *)arg; + set_thread_name("SQLiteChildMySQL"); GloMTH->wrlock(); { char *s=GloMTH->get_variable((char *)"server_capabilities"); @@ -1133,6 +1134,7 @@ static void * sqlite3server_main_loop(void *arg) pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + set_thread_name("SQLite3_Main"); while (glovars.shutdown==0 && *shutdown==0) { int *client; diff --git a/src/main.cpp b/src/main.cpp index f234b72dc5..45cbc94756 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -78,6 +78,7 @@ static pthread_mutex_t *lockarray; static void * waitpid_thread(void *arg) { pid_t *cpid_ptr=(pid_t *)arg; int status; + set_thread_name("waitpid"); waitpid(*cpid_ptr, &status, 0); free(cpid_ptr); return NULL; @@ -195,6 +196,7 @@ static char * main_check_latest_version() { * @return NULL. */ void * main_check_latest_version_thread(void *arg) { + set_thread_name("CheckLatestVers"); // Fetch the latest version information char * latest_version = main_check_latest_version(); // we check for potential invalid data , see issue #4042 From 474d662f52ba6381e82e78d8dcddfdd4ff92077b Mon Sep 17 00:00:00 2001 From: Andriy Utkin Date: Thu, 4 Jul 2024 00:18:40 +0100 Subject: [PATCH 02/62] Use 15 chars max for thread name --- lib/Query_Processor.cpp | 4 ++-- src/SQLite3_Server.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Query_Processor.cpp b/lib/Query_Processor.cpp index b385f35748..491d2008c1 100644 --- a/lib/Query_Processor.cpp +++ b/lib/Query_Processor.cpp @@ -770,7 +770,7 @@ void * get_query_digests_total_size_parallel(void *_arg) { unsigned long long i = 0; unsigned long long m = arg->m; unsigned long long ret = 0; - set_thread_name("GetQueryDigeTota"); + set_thread_name("GetQueryDigeTot"); for (std::unordered_map::iterator it=arg->gu->begin(); it!=arg->gu->end(); ++it) { if ((i%DIGEST_STATS_FAST_THREADS)==m) { QP_query_digest_stats *qds=(QP_query_digest_stats *)it->second; @@ -854,7 +854,7 @@ void * purge_query_digests_parallel(void *_arg) { unsigned long long i = 0; unsigned long long r = 0; unsigned long long m = arg->m; - set_thread_name("PurgeQueryDigest"); + set_thread_name("PurgeQueryDgest"); for (std::unordered_map::iterator it=arg->gu->begin(); it!=arg->gu->end(); ++it) { if ((i%DIGEST_STATS_FAST_THREADS)==m) { QP_query_digest_stats *qds=(QP_query_digest_stats *)it->second; diff --git a/src/SQLite3_Server.cpp b/src/SQLite3_Server.cpp index 591ed18c29..e388e6f2d9 100644 --- a/src/SQLite3_Server.cpp +++ b/src/SQLite3_Server.cpp @@ -1021,7 +1021,7 @@ static void *child_mysql(void *arg) { int client = *(int *)arg; - set_thread_name("SQLiteChildMySQL"); + set_thread_name("SQLiteChldMySQL"); GloMTH->wrlock(); { char *s=GloMTH->get_variable((char *)"server_capabilities"); From af2e22334988aebdaa3203d0f9b0b0f2f841ea9d Mon Sep 17 00:00:00 2001 From: Andriy Utkin Date: Thu, 4 Jul 2024 00:19:04 +0100 Subject: [PATCH 03/62] ConsumerThread: parametrize thread name --- lib/MySQL_Monitor.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/MySQL_Monitor.cpp b/lib/MySQL_Monitor.cpp index fd35843bf3..10f1d97fe5 100644 --- a/lib/MySQL_Monitor.cpp +++ b/lib/MySQL_Monitor.cpp @@ -63,13 +63,17 @@ template class ConsumerThread : public Thread { wqueue*>& m_queue; int thrn; + char thr_name[16]; public: - ConsumerThread(wqueue*>& queue, int _n) : m_queue(queue) { + ConsumerThread(wqueue*>& queue, int _n, char thread_name[16]=NULL) : m_queue(queue) { thrn=_n; + if (thread_name && thread_name[0]) { + snprintf(thr_name, sizeof(thr_name), "%.16s", thread_name); + } else { + snprintf(thr_name, sizeof(thr_name), "%.12s%03d", typeid(T).name(), thrn); + } } void* run() { - char thr_name[16]; - snprintf(thr_name, sizeof(thr_name), "%.12s%03d", typeid(T).name(), thrn); set_thread_name(thr_name); // Remove 1 item at a time and process it. Blocks if no items are // available to process. @@ -4994,7 +4998,7 @@ void * MySQL_Monitor::run() { } ConsumerThread **threads= (ConsumerThread **)malloc(sizeof(ConsumerThread *)*num_threads); for (unsigned int i=0;i(*queue, 0); + threads[i] = new ConsumerThread(*queue, 0, "MyMonStateData"); threads[i]->start(2048,false); } started_threads += num_threads; @@ -5064,7 +5068,7 @@ void * MySQL_Monitor::run() { threads= (ConsumerThread **)realloc(threads, sizeof(ConsumerThread *)*num_threads); started_threads += (num_threads - old_num_threads); for (unsigned int i = old_num_threads ; i < num_threads ; i++) { - threads[i] = new ConsumerThread(*queue, 0); + threads[i] = new ConsumerThread(*queue, 0, "MyMonStateData"); threads[i]->start(2048,false); } } @@ -5093,7 +5097,7 @@ void * MySQL_Monitor::run() { threads= (ConsumerThread **)realloc(threads, sizeof(ConsumerThread *)*num_threads); started_threads += new_threads; for (unsigned int i = old_num_threads ; i < num_threads ; i++) { - threads[i] = new ConsumerThread(*queue, 0); + threads[i] = new ConsumerThread(*queue, 0, "MyMonStateData"); threads[i]->start(2048,false); } } @@ -5113,7 +5117,7 @@ void * MySQL_Monitor::run() { aux_threads = qsize; started_threads += aux_threads; for (unsigned int i=0; i(*queue, 245); + threads_aux[i] = new ConsumerThread(*queue, 245, "MyMonStateData"); threads_aux[i]->start(2048,false); } for (unsigned int i=0; i Date: Wed, 7 Aug 2024 21:37:31 +0000 Subject: [PATCH 04/62] Implementation of PROXY protocol V1 This commit introduces: - class ProxyProtocolInfo() , that: - performs parsing - validates subnet - run automated tests in DEBUG build - variable mysql-proxy_protocol_networks . Accepted values: - empty string: disables PROXY protocol - '*' : allows connections from any IP - comma separated list of subnets - automated testing in DEBUG build during start - export of PROXY protocol information in internal session, using PROXY_V1 - a TAP test to verify various connections --- include/MySQL_Data_Stream.h | 2 + include/MySQL_Thread.h | 1 + include/proxy_protocol_info.h | 51 +++ include/proxysql_structs.h | 2 + lib/Makefile | 1 + lib/MySQL_Thread.cpp | 29 ++ lib/mysql_data_stream.cpp | 98 ++++++ lib/proxy_protocol_info.cpp | 382 +++++++++++++++++++++++ src/main.cpp | 16 + test/tap/tests/test_PROXY_Protocol-t.cpp | 147 +++++++++ 10 files changed, 729 insertions(+) create mode 100644 include/proxy_protocol_info.h create mode 100644 lib/proxy_protocol_info.cpp create mode 100644 test/tap/tests/test_PROXY_Protocol-t.cpp diff --git a/include/MySQL_Data_Stream.h b/include/MySQL_Data_Stream.h index 1ce5fed802..53eafe8ec3 100644 --- a/include/MySQL_Data_Stream.h +++ b/include/MySQL_Data_Stream.h @@ -5,6 +5,7 @@ #include "cpp.h" #include "MySQL_Protocol.h" +#include "proxy_protocol_info.h" #ifndef uchar typedef unsigned char uchar; @@ -140,6 +141,7 @@ class MySQL_Data_Stream char *addr; int port; } proxy_addr; + ProxyProtocolInfo * PROXY_info; unsigned int connect_tries; int query_retries_on_failure; diff --git a/include/MySQL_Thread.h b/include/MySQL_Thread.h index ddd663056d..b238915b48 100644 --- a/include/MySQL_Thread.h +++ b/include/MySQL_Thread.h @@ -460,6 +460,7 @@ class MySQL_Threads_Handler char *server_version; char *keep_multiplexing_variables; char *default_authentication_plugin; + char *proxy_protocol_networks; //unsigned int default_charset; // removed in 2.0.13 . Obsoleted previously using MySQL_Variables instead int handle_unknown_charset; int default_authentication_plugin_int; diff --git a/include/proxy_protocol_info.h b/include/proxy_protocol_info.h new file mode 100644 index 0000000000..9f35b2915b --- /dev/null +++ b/include/proxy_protocol_info.h @@ -0,0 +1,51 @@ +#ifndef PROXY_PROTOCOL_INFO_H +#define PROXY_PROTOCOL_INFO_H + +#include +#include +#include +#include + + +class ProxyProtocolInfo { +public: + char source_address[INET6_ADDRSTRLEN+1]; + char destination_address[INET6_ADDRSTRLEN+1]; + char proxy_address[INET6_ADDRSTRLEN+1]; + uint16_t source_port; + uint16_t destination_port; + uint16_t proxy_port; + + // Constructor (initializes to zeros) + ProxyProtocolInfo() { + memset(this, 0, sizeof(ProxyProtocolInfo)); + } + + // Copy constructor + ProxyProtocolInfo(const ProxyProtocolInfo& other) { + memcpy(this, &other, sizeof(ProxyProtocolInfo)); + } + + // Function to parse the PROXY protocol header (declared) + bool parseProxyProtocolHeader(const char* packet, size_t packet_length); + + bool is_in_network(const struct sockaddr* client_addr, const std::string& subnet_mask); + bool is_client_in_any_subnet(const struct sockaddr* client_addr, const char* subnet_list); + + // Copy method + ProxyProtocolInfo& copy(const ProxyProtocolInfo& other) { + if (this != &other) { + memcpy(this, &other, sizeof(ProxyProtocolInfo)); + } + return *this; + } +#ifdef DEBUG + sockaddr_in create_ipv4_addr(const std::string& ip); + sockaddr_in6 create_ipv6_addr(const std::string& ip); + void run_tests(); +#endif // DEBUG + bool is_valid_subnet_list(const char* subnet_list); + bool is_valid_subnet(const char* subnet); +}; + +#endif // PROXY_PROTOCOL_INFO_H diff --git a/include/proxysql_structs.h b/include/proxysql_structs.h index f3d322305c..6adf755e1f 100644 --- a/include/proxysql_structs.h +++ b/include/proxysql_structs.h @@ -777,6 +777,7 @@ __thread char *mysql_thread___default_schema; __thread char *mysql_thread___server_version; __thread char *mysql_thread___keep_multiplexing_variables; __thread char *mysql_thread___default_authentication_plugin; +__thread char *mysql_thread___proxy_protocol_networks; __thread char *mysql_thread___init_connect; __thread char *mysql_thread___ldap_user_variable; __thread char *mysql_thread___default_session_track_gtids; @@ -949,6 +950,7 @@ extern __thread char *mysql_thread___default_schema; extern __thread char *mysql_thread___server_version; extern __thread char *mysql_thread___keep_multiplexing_variables; extern __thread char *mysql_thread___default_authentication_plugin; +extern __thread char *mysql_thread___proxy_protocol_networks; extern __thread char *mysql_thread___init_connect; extern __thread char *mysql_thread___ldap_user_variable; extern __thread char *mysql_thread___default_session_track_gtids; diff --git a/lib/Makefile b/lib/Makefile index 325b5bd80c..88aeff654e 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -130,6 +130,7 @@ _OBJ_CXX := ProxySQL_GloVars.oo network.oo debug.oo configfile.oo Query_Cache.oo QP_rule_text.oo QP_query_digest_stats.oo \ GTID_Server_Data.oo MyHGC.oo MySrvConnList.oo MySrvList.oo MySrvC.oo \ MySQL_encode.oo MySQL_ResultSet.oo \ + proxy_protocol_info.oo \ proxysql_find_charset.oo ProxySQL_Poll.oo OBJ_CXX := $(patsubst %,$(ODIR)/%,$(_OBJ_CXX)) HEADERS := ../include/*.h ../include/*.hpp diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp index 4df3d97429..fff793a78b 100644 --- a/lib/MySQL_Thread.cpp +++ b/lib/MySQL_Thread.cpp @@ -499,6 +499,7 @@ static char * mysql_thread_variables_names[]= { (char *)"data_packets_history_size", (char *)"handle_warnings", (char *)"evaluate_replication_lag_on_servers_load", + (char *)"proxy_protocol_networks", NULL }; @@ -1119,6 +1120,7 @@ MySQL_Threads_Handler::MySQL_Threads_Handler() { variables.ssl_p2s_crl=NULL; variables.ssl_p2s_crlpath=NULL; variables.keep_multiplexing_variables=strdup((char *)"tx_isolation,transaction_isolation,version"); + variables.proxy_protocol_networks = strdup((char *)""); variables.default_authentication_plugin=strdup((char *)"mysql_native_password"); variables.default_authentication_plugin_int = 0; // mysql_native_password #ifdef DEBUG @@ -1350,6 +1352,7 @@ char * MySQL_Threads_Handler::get_variable_string(char *name) { if (!strcmp(name,"interfaces")) return strdup(variables.interfaces); if (!strcmp(name,"keep_multiplexing_variables")) return strdup(variables.keep_multiplexing_variables); if (!strcmp(name,"default_authentication_plugin")) return strdup(variables.default_authentication_plugin); + if (!strcmp(name,"proxy_protocol_networks")) return strdup(variables.proxy_protocol_networks); // LCOV_EXCL_START proxy_error("Not existing variable: %s\n", name); assert(0); return NULL; @@ -1505,6 +1508,7 @@ char * MySQL_Threads_Handler::get_variable(char *name) { // this is the public f if (!strcasecmp(name,"default_schema")) return strdup(variables.default_schema); if (!strcasecmp(name,"keep_multiplexing_variables")) return strdup(variables.keep_multiplexing_variables); if (!strcasecmp(name,"default_authentication_plugin")) return strdup(variables.default_authentication_plugin); + if (!strcasecmp(name,"proxy_protocol_networks")) return strdup(variables.proxy_protocol_networks); if (!strcasecmp(name,"interfaces")) return strdup(variables.interfaces); if (!strcasecmp(name,"server_capabilities")) { // FIXME : make it human readable @@ -1878,6 +1882,28 @@ bool MySQL_Threads_Handler::set_variable(char *name, const char *value) { // thi return false; } } + if (!strcasecmp(name,"proxy_protocol_networks")) { + bool ret = false; + if (vallen == 0) { + // accept empty string + ret = true; + } else if ( (vallen == 1) && strcmp(value,"*")==0) { + // accept `*` + ret = true; + } else { + ProxyProtocolInfo ppi; + if (ppi.is_valid_subnet_list(value) == true) { + ret = true; + } + } + if (ret == true) { + free(variables.proxy_protocol_networks); + variables.proxy_protocol_networks=strdup(value); + return true; + } else { + return true; + } + } // SSL proxy to server variables if (!strcasecmp(name,"ssl_p2s_ca")) { if (variables.ssl_p2s_ca) free(variables.ssl_p2s_ca); @@ -2703,6 +2729,7 @@ MySQL_Threads_Handler::~MySQL_Threads_Handler() { if (variables.server_version) free(variables.server_version); if (variables.keep_multiplexing_variables) free(variables.keep_multiplexing_variables); if (variables.default_authentication_plugin) free(variables.default_authentication_plugin); + if (variables.proxy_protocol_networks) free(variables.proxy_protocol_networks); if (variables.firewall_whitelist_errormsg) free(variables.firewall_whitelist_errormsg); if (variables.init_connect) free(variables.init_connect); if (variables.ldap_user_variable) free(variables.ldap_user_variable); @@ -2834,6 +2861,7 @@ MySQL_Thread::~MySQL_Thread() { if (mysql_thread___server_version) { free(mysql_thread___server_version); mysql_thread___server_version=NULL; } if (mysql_thread___keep_multiplexing_variables) { free(mysql_thread___keep_multiplexing_variables); mysql_thread___keep_multiplexing_variables=NULL; } if (mysql_thread___default_authentication_plugin) { free(mysql_thread___default_authentication_plugin); mysql_thread___default_authentication_plugin=NULL; } + if (mysql_thread___proxy_protocol_networks) { free(mysql_thread___proxy_protocol_networks); mysql_thread___proxy_protocol_networks=NULL; } if (mysql_thread___firewall_whitelist_errormsg) { free(mysql_thread___firewall_whitelist_errormsg); mysql_thread___firewall_whitelist_errormsg=NULL; } if (mysql_thread___init_connect) { free(mysql_thread___init_connect); mysql_thread___init_connect=NULL; } if (mysql_thread___ldap_user_variable) { free(mysql_thread___ldap_user_variable); mysql_thread___ldap_user_variable=NULL; } @@ -4377,6 +4405,7 @@ void MySQL_Thread::refresh_variables() { GloMyLogger->audit_set_base_filename(); // both filename and filesize are set here REFRESH_VARIABLE_CHAR(default_schema); REFRESH_VARIABLE_CHAR(keep_multiplexing_variables); + REFRESH_VARIABLE_CHAR(proxy_protocol_networks); REFRESH_VARIABLE_CHAR(default_authentication_plugin); mysql_thread___default_authentication_plugin_int = GloMTH->variables.default_authentication_plugin_int; mysql_thread___server_capabilities=GloMTH->get_variable_uint16((char *)"server_capabilities"); diff --git a/lib/mysql_data_stream.cpp b/lib/mysql_data_stream.cpp index 3ff6e5da44..9867601397 100644 --- a/lib/mysql_data_stream.cpp +++ b/lib/mysql_data_stream.cpp @@ -307,6 +307,8 @@ MySQL_Data_Stream::MySQL_Data_Stream() { proxy_addr.addr=NULL; proxy_addr.port=0; + PROXY_info = NULL; + sess=NULL; mysql_real_query.pkt.ptr=NULL; mysql_real_query.pkt.size=0; @@ -380,6 +382,10 @@ MySQL_Data_Stream::~MySQL_Data_Stream() { free(proxy_addr.addr); proxy_addr.addr=NULL; } + if (PROXY_info) { + delete PROXY_info; + PROXY_info = NULL; + } free_mysql_real_query(); @@ -1081,6 +1087,90 @@ int MySQL_Data_Stream::buffer2array() { } else { if ((queueIN.pkt.size==0) && queue_data(queueIN)>=sizeof(mysql_hdr)) { + // check if this is a PROXY protocol packet + if ( + pkts_recv==0 && // checks if no packets have been received yet + queueIN.tail == 0 && // checks if the input queue (`queueIN`) was never rotated . This check is redundant + queueIN.head > 7 && // ensures that there are at least 8 bytes in the input buffer (`queueIN.buffer`) + // This is because the PROXY protocol signature (`PROXY`) is 5 bytes long, and we need at least 3 more bytes to check for the `\r\n` delimiter. + strncmp((char *)queueIN.buffer,"PROXY ",6) == 0 // checks if the first 6 bytes of the buffer match the "PROXY " string, indicating a potential PROXY protocol packet + ) { + bool found_delimiter = false; + size_t b = 0; + const char *ptr = (char *)queueIN.buffer; + // This loop iterates through the buffer, starting from the 8th byte (index 7) until the end of the buffer (index `queueIN.head - 1`). + // The loop continues as long as the delimiter hasn't been found (`found_delimiter == false`) + // the loop looks for \r\n , the delimiter of the PROXY packet + for (size_t i = 7; found_delimiter == false && i < queueIN.head - 1; i++) { + if ( + ptr[i] == '\r' + && + ptr[i+1] == '\n' + ) { + found_delimiter = true; + b = i+2; + } + } + if (found_delimiter) { +/* + // we could return a packet, but it is actually better to handle it here + queueIN.pkt.size = b; + queueIN.pkt.ptr=l_alloc(queueIN.pkt.size); + memcpy(queueIN.pkt.ptr, queueIN.buffer, b); + PSarrayIN->add(queueIN.pkt.ptr,queueIN.pkt.size); + add_to_data_packet_history(data_packets_history_IN,queueIN.pkt.ptr,queueIN.pkt.size); +*/ + // we move forward the internal pointer. + // note that parseProxyProtocolHeader() will read from the beginning of the buffer + queue_r(queueIN, b); + + bool accept_proxy = false; // by default, we do not accept a PROXY header + const char * proxy_protocol_networks = mysql_thread___proxy_protocol_networks; + + ProxyProtocolInfo ppi; + if (strcmp(proxy_protocol_networks,"*") == 0) { // all networks are accepted + accept_proxy = true; + } else { + if (client_addr) { + if (ppi.is_client_in_any_subnet(client_addr, proxy_protocol_networks) == true) { + accept_proxy = true; + } + } + } + if (accept_proxy == true) { + if (ppi.parseProxyProtocolHeader((const char *)queueIN.buffer, b)) { + PROXY_info = new ProxyProtocolInfo(ppi); + // we take a copy of old address/port + if (addr.addr) { + strncpy(PROXY_info->proxy_address, addr.addr, INET6_ADDRSTRLEN); + free(addr.addr); + } + PROXY_info->proxy_port = addr.port; + // we override old address/port + addr.addr = strdup(PROXY_info->source_address); + addr.port = PROXY_info->source_port; + } else { + // TODO: error handling + // maybe just generate a warning + } + } else { // the PROXY header was not accepted + // TODO: error handling + // maybe just generate a warning + } + + + pkts_recv++; + queueIN.pkt.size=0; + queueIN.pkt.ptr=NULL; + return b; + } else { + // set the connection unhealthy , this will cause the session to be destroyed + if (sess) { + sess->set_unhealthy(); + } + } + return 0; // we always return + } proxy_debug(PROXY_DEBUG_PKT_ARRAY, 5, "Session=%p . Reading the header of a new packet\n", sess); memcpy(&queueIN.hdr,queue_r_ptr(queueIN),sizeof(mysql_hdr)); pkt_sid=queueIN.hdr.pkt_id; @@ -1576,6 +1666,14 @@ void MySQL_Data_Stream::get_client_myds_info_json(json& j) { jc1["client_addr"]["port"] = addr.port; jc1["proxy_addr"]["address"] = ( proxy_addr.addr ? proxy_addr.addr : "" ); jc1["proxy_addr"]["port"] = proxy_addr.port; + if (PROXY_info != NULL) { + jc1["PROXY_V1"]["source_address"] = PROXY_info->source_address; + jc1["PROXY_V1"]["destination_address"] = PROXY_info->destination_address; + jc1["PROXY_V1"]["proxy_address"] = PROXY_info->proxy_address; + jc1["PROXY_V1"]["source_port"] = PROXY_info->source_port; + jc1["PROXY_V1"]["destination_port"] = PROXY_info->destination_port; + jc1["PROXY_V1"]["proxy_port"] = PROXY_info->proxy_port; + } jc1["encrypted"] = encrypted; if (encrypted) { const SSL_CIPHER *cipher = SSL_get_current_cipher(ssl); diff --git a/lib/proxy_protocol_info.cpp b/lib/proxy_protocol_info.cpp new file mode 100644 index 0000000000..522463f643 --- /dev/null +++ b/lib/proxy_protocol_info.cpp @@ -0,0 +1,382 @@ +#include "proxy_protocol_info.h" +#include +#include +#include +#include + +static bool DEBUG_ProxyProtocolInfo = false; + +// Function to parse the PROXY protocol header +bool ProxyProtocolInfo::parseProxyProtocolHeader(const char* packet, size_t packet_length) { + // Check for minimum header length (including CRLF) + if (packet_length < 15) { + return false; // Not a valid PROXY protocol header + } + + // Create a temporary buffer on the stack + char temp_buffer[packet_length + 1]; + + // Copy the packet data + memcpy(temp_buffer, packet, packet_length); + temp_buffer[packet_length] = '\0'; // Null-terminate the buffer + + + // Verify the PROXY protocol signature + if (memcmp(temp_buffer, "PROXY", 5) != 0) { + return false; // Not a valid PROXY protocol header + } + + // Check for the space after "PROXY" + if (temp_buffer[5] != ' ') { + return false; // Invalid header format + } + + // Check for the protocol type + if (memcmp(temp_buffer + 6, "TCP4", 4) == 0 || + memcmp(temp_buffer + 6, "TCP6", 4) == 0 || + memcmp(temp_buffer + 6, "UNKNOWN", 7) == 0) { + + // Parse the header using sscanf + int result = sscanf(temp_buffer, "PROXY %*s %s %s %hu %hu\r\n", + source_address, destination_address, + &source_port, &destination_port); + + // Check if sscanf successfully parsed all fields + if (result == 4) { + return true; // Successful parsing + } else { + // Handle partial parsing or invalid format + return false; // Indicate an error + } + } + + return false; // Invalid header format +} + +/** + * Checks if a client address is within a specified subnet. + * + * @param client_addr Pointer to the client's sockaddr structure (either sockaddr_in or sockaddr_in6). + * @param subnet_mask The subnet in CIDR notation (e.g., "192.168.1.0/24" for IPv4 or "2001:db8::/32" for IPv6). + * @return True if the client address is within the specified subnet, otherwise false. + */ +bool ProxyProtocolInfo::is_in_network(const struct sockaddr* client_addr, const std::string& subnet_mask) { + // Determine address family (IPv4 or IPv6) + int family = client_addr->sa_family; + + // Parse the subnet and mask + union { + struct in_addr v4; + struct in6_addr v6; + } subnet_addr; + + uint8_t mask = 0; + char addr_str[INET6_ADDRSTRLEN]; + + if (family == AF_INET) { + if (DEBUG_ProxyProtocolInfo==true) + std::cout << "Parsing IPv4 subnet mask" << std::endl; + // Parse the IPv4 subnet mask using sscanf + if (sscanf(subnet_mask.c_str(), "%[^/]/%hhu", addr_str, &mask) != 2) { + if (DEBUG_ProxyProtocolInfo==true) + std::cout << "Invalid subnet/mask format" << std::endl; + return false; // Invalid subnet/mask format + } + if (DEBUG_ProxyProtocolInfo==true) + std::cout << "Subnet: " << addr_str << ", Mask: " << (int)mask << std::endl; + // Convert the parsed subnet address to binary format + if (inet_pton(AF_INET, addr_str, &subnet_addr.v4) != 1) { + if (DEBUG_ProxyProtocolInfo==true) + std::cout << "Invalid IPv4 address" << std::endl; + return false; // Invalid IPv4 address + } + } else if (family == AF_INET6) { + if (DEBUG_ProxyProtocolInfo==true) + std::cout << "Parsing IPv6 subnet mask" << std::endl; + // Parse the IPv6 subnet mask using sscanf + if (sscanf(subnet_mask.c_str(), "%[^/]/%hhu", addr_str, &mask) != 2) { + if (DEBUG_ProxyProtocolInfo==true) + std::cout << "Invalid subnet/mask format" << std::endl; + return false; // Invalid subnet/mask format + } + if (DEBUG_ProxyProtocolInfo==true) + std::cout << "Subnet: " << addr_str << ", Mask: " << (int)mask << std::endl; + // Convert the parsed subnet address to binary format + if (inet_pton(AF_INET6, addr_str, &subnet_addr.v6) != 1) { + if (DEBUG_ProxyProtocolInfo==true) + std::cout << "Invalid IPv6 address" << std::endl; + return false; // Invalid IPv6 address + } + } else { + if (DEBUG_ProxyProtocolInfo==true) + std::cout << "Unsupported address family" << std::endl; + return false; // Unsupported address family + } + + uint8_t network_addr[16] = {0}; + if (family == AF_INET) { + if (DEBUG_ProxyProtocolInfo==true) + std::cout << "Calculating network address for IPv4" << std::endl; + // Calculate the network address for IPv4 + uint32_t subnet = ntohl(subnet_addr.v4.s_addr) & (0xFFFFFFFF << (32 - mask)); + subnet = htonl(subnet); + if (DEBUG_ProxyProtocolInfo==true) + std::cout << "Subnet address (masked): " << inet_ntoa(*(struct in_addr*)&subnet) << std::endl; + // Copy the masked subnet address into the network_addr array + memcpy(network_addr, &subnet, sizeof(subnet)); + } else if (family == AF_INET6) { + if (DEBUG_ProxyProtocolInfo==true) + std::cout << "Calculating network address for IPv6" << std::endl; + // Calculate the network address for IPv6 + uint8_t* addr = subnet_addr.v6.s6_addr; + int bits_left = mask; + for (int i = 0; i < 16; ++i) { + if (bits_left >= 8) { + network_addr[i] = addr[i]; + bits_left -= 8; + } else if (bits_left > 0) { + network_addr[i] = addr[i] & (0xFF << (8 - bits_left)); + bits_left = 0; + } else { + network_addr[i] = 0; + } + } + if (DEBUG_ProxyProtocolInfo==true) { + char network_addr_str[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET6, network_addr, network_addr_str, INET6_ADDRSTRLEN); + std::cout << "Subnet address (masked): " << network_addr_str << std::endl; + } + } + + uint8_t client_addr_int[16] = {0}; + if (family == AF_INET) { + if (DEBUG_ProxyProtocolInfo==true) + std::cout << "Extracting client address for IPv4" << std::endl; + // Extract the client address for IPv4 + uint32_t client = ntohl(((struct sockaddr_in*)client_addr)->sin_addr.s_addr); + client = htonl(client); + if (DEBUG_ProxyProtocolInfo==true) + std::cout << "Client address: " << inet_ntoa(*(struct in_addr*)&client) << std::endl; + // Copy the client address into the client_addr_int array + memcpy(client_addr_int, &client, sizeof(client)); + } else if (family == AF_INET6) { + if (DEBUG_ProxyProtocolInfo==true) + std::cout << "Extracting client address for IPv6" << std::endl; + // Copy the client address into the client_addr_int array + memcpy(client_addr_int, ((struct sockaddr_in6*)client_addr)->sin6_addr.s6_addr, 16); + if (DEBUG_ProxyProtocolInfo==true) { + char client_addr_str[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET6, client_addr_int, client_addr_str, INET6_ADDRSTRLEN); + std::cout << "Client address: " << client_addr_str << std::endl; + } + } + + // Calculate the number of bytes to compare based on the mask + int bytes_to_compare = mask / 8; + int remaining_bits = mask % 8; + + if (DEBUG_ProxyProtocolInfo==true) + std::cout << "Comparing full bytes covered by the mask" << std::endl; + // Compare the full bytes covered by the mask + if (memcmp(network_addr, client_addr_int, bytes_to_compare) != 0) { + if (DEBUG_ProxyProtocolInfo==true) + std::cout << "Address does not match in full byte comparison" << std::endl; + return false; + } + + if (remaining_bits > 0) { + if (DEBUG_ProxyProtocolInfo==true) + std::cout << "Comparing remaining bits" << std::endl; + // Compare the remaining bits covered by the mask + uint8_t mask_byte = 0xFF << (8 - remaining_bits); + if ((network_addr[bytes_to_compare] & mask_byte) != (client_addr_int[bytes_to_compare] & mask_byte)) { + if (DEBUG_ProxyProtocolInfo==true) + std::cout << "Address does not match in remaining bits comparison" << std::endl; + return false; // Addresses don't match in remaining bits comparison + } + } + + if (DEBUG_ProxyProtocolInfo==true) + std::cout << "Client address is within the subnet" << std::endl; + return true; // Client address is within the subnet +} + +bool ProxyProtocolInfo::is_client_in_any_subnet(const struct sockaddr* client_addr, const char* subnet_list) { + // Create a copy of the subnet list to avoid modifying the original string + char* subnet_list_copy = new char[strlen(subnet_list) + 1]; + strcpy(subnet_list_copy, subnet_list); + + char* token = strtok(subnet_list_copy, ","); // Get the first subnet + while (token != NULL) { + if (DEBUG_ProxyProtocolInfo==true) + std::cout << "Checking subnet: " << token << std::endl; + if (is_in_network(client_addr, token)) { + if (DEBUG_ProxyProtocolInfo==true) + std::cout << "Client is in subnet: " << token << std::endl; + delete[] subnet_list_copy; // Deallocate the copy + return true; // Client is in at least one subnet + } + token = strtok(NULL, ","); // Get the next subnet + } + delete[] subnet_list_copy; // Deallocate the copy + return false; // Client is not in any of the subnets +} + +#ifdef DEBUG + +// Helper function to create an IPv4 sockaddr structure +sockaddr_in ProxyProtocolInfo::create_ipv4_addr(const std::string& ip) { + sockaddr_in addr; + addr.sin_family = AF_INET; + inet_pton(AF_INET, ip.c_str(), &addr.sin_addr); + return addr; +} + +// Helper function to create an IPv6 sockaddr structure +sockaddr_in6 ProxyProtocolInfo::create_ipv6_addr(const std::string& ip) { + sockaddr_in6 addr; + addr.sin6_family = AF_INET6; + inet_pton(AF_INET6, ip.c_str(), &addr.sin6_addr); + return addr; +} + +// Test cases for the is_in_network function +void ProxyProtocolInfo::run_tests() { + // IPv4 Tests + { + sockaddr_in client_addr = create_ipv4_addr("192.168.1.10"); + assert(is_in_network((sockaddr*)&client_addr, "192.168.1.0/24") == true); + assert(is_in_network((sockaddr*)&client_addr, "192.168.1.0/25") == true); + assert(is_in_network((sockaddr*)&client_addr, "192.168.1.0/26") == true); + assert(is_in_network((sockaddr*)&client_addr, "192.168.2.0/24") == false); + assert(is_in_network((sockaddr*)&client_addr, "192.168.0.0/16") == true); + assert(is_in_network((sockaddr*)&client_addr, "192.168.1.10/32") == true); + assert(is_in_network((sockaddr*)&client_addr, "192.168.1.11/32") == false); + } + + // IPv6 Tests + { + sockaddr_in6 client_addr = create_ipv6_addr("2001:db8::1"); + assert(is_in_network((sockaddr*)&client_addr, "2001:db8::/32") == true); + assert(is_in_network((sockaddr*)&client_addr, "2001:db8::/48") == true); + assert(is_in_network((sockaddr*)&client_addr, "2001:db8::/64") == true); + assert(is_in_network((sockaddr*)&client_addr, "2001:db8:0:1::/64") == false); + assert(is_in_network((sockaddr*)&client_addr, "2001:db8::1/128") == true); + assert(is_in_network((sockaddr*)&client_addr, "2001:db8::2/128") == false); + } + { + sockaddr_in6 client_addr = create_ipv6_addr("2001:db8:0:1::1"); + assert(is_in_network((sockaddr*)&client_addr, "2001:db8:0:1::/64") == true); + assert(is_in_network((sockaddr*)&client_addr, "2001:db8::/32") == true); + assert(is_in_network((sockaddr*)&client_addr, "2001:db8:0:2::/64") == false); + assert(is_in_network((sockaddr*)&client_addr, "2001:db8::1/128") == false); + assert(is_in_network((sockaddr*)&client_addr, "2001:db8:0:1::1/128") == true); + } + { + struct sockaddr_in client_addr = create_ipv4_addr("172.16.14.1"); + assert(is_client_in_any_subnet((sockaddr*)&client_addr, "172.16.0.0/16,192.168.1.0/24") == true); + assert(is_client_in_any_subnet((sockaddr*)&client_addr, "172.17.0.0/16,192.168.1.0/24") == false); + assert(is_client_in_any_subnet((sockaddr*)&client_addr, "2001:db8:0:1::/64,172.16.0.0/16,192.168.1.0/24") == true); + assert(is_client_in_any_subnet((sockaddr*)&client_addr, "2001:db8:0:1::/64,172.17.0.0/16,192.168.1.0/24") == false); + } + { + sockaddr_in6 client_addr = create_ipv6_addr("2001:db8:0:1::1"); + assert(is_client_in_any_subnet((sockaddr*)&client_addr, "2001:db8:0:1::/64,2001:db8:0:2::/64") == true); + assert(is_client_in_any_subnet((sockaddr*)&client_addr, "2001:db8:0:2::/64,2001:db8:0:1::/64") == true); + assert(is_client_in_any_subnet((sockaddr*)&client_addr, "2001:db8:0:1::/64,172.16.0.0/16") == true); + assert(is_client_in_any_subnet((sockaddr*)&client_addr, "172.16.0.0/16,2001:db8:0:1::/64") == true); + assert(is_client_in_any_subnet((sockaddr*)&client_addr, "2001:db8:0:2::/64,172.16.0.0/16") == false); + assert(is_client_in_any_subnet((sockaddr*)&client_addr, "172.16.0.0/16,2001:db8:0:2::/64") == false); + } + { + const char* subnet_list1 = "192.168.1.0/24,10.0.0.0/8,2001:0:200::/32"; + const char* subnet_list2 = "192.168.1.0/24,10.0.0.0/not_a_mask,2001:0:200::/32"; + const char* subnet_list3 = "192.168.1.0/24,invalid_ipv4,2001:0:200::/32"; + const char* subnet_list4 = ""; + + assert(is_valid_subnet_list(subnet_list1) == true); + assert(is_valid_subnet_list(subnet_list2) == false); + assert(is_valid_subnet_list(subnet_list3) == false); + assert(is_valid_subnet_list(subnet_list4) == false); + } +} + +#endif // DEBUG + +bool ProxyProtocolInfo::is_valid_subnet_list(const char* subnet_list) { + // Check if the string is empty + if (subnet_list == nullptr || *subnet_list == '\0') { + return false; // Empty string is not a valid subnet list + } + + // Create a copy of the string to avoid modifying the original + char* subnet_list_copy = new char[strlen(subnet_list) + 1]; + strcpy(subnet_list_copy, subnet_list); + + // Tokenize the string using ',' as the delimiter + char* token = strtok(subnet_list_copy, ","); + while (token != NULL) { + // Check if the token is a valid subnet + if (!is_valid_subnet(token)) { + delete[] subnet_list_copy; // Deallocate the copy + return false; // Invalid subnet found + } + token = strtok(NULL, ","); // Get the next token + } + + delete[] subnet_list_copy; // Deallocate the copy + return true; // All subnets are valid +} + + +// Helper function to verify a single subnet +bool ProxyProtocolInfo::is_valid_subnet(const char* subnet) { + // Check if the subnet is empty + if (subnet == NULL || *subnet == '\0') { + return false; // Empty subnet is not valid + } + + // Check if the subnet contains a '/' character (CIDR notation) + if (strchr(subnet, '/') == NULL) { + return false; // Missing '/' character in subnet + } + + // Check if the subnet is a valid IPv4 or IPv6 address + int family = AF_INET; // Default to IPv4 + if (strchr(subnet, ':') != NULL) { + family = AF_INET6; // IPv6 if a colon is found + } + + char addr_str[INET6_ADDRSTRLEN]; + uint8_t mask = 0; + + if (family == AF_INET) { + // Parse IPv4 subnet using sscanf + if (sscanf(subnet, "%[^/]/%hhu", addr_str, &mask) != 2) { + return false; // Invalid IPv4 subnet format + } + } else if (family == AF_INET6) { + // Parse IPv6 subnet using sscanf + if (sscanf(subnet, "%[^/]/%hhu", addr_str, &mask) != 2) { + return false; // Invalid IPv6 subnet format + } + } else { + return false; // Unsupported address family + } + + // Validate the mask value + if (mask < 0 || mask > 128) { + return false; // Invalid mask value + } + + // Check if the address is valid using inet_pton + union { + struct in_addr v4; + struct in6_addr v6; + } addr; // Create a union to hold both IPv4 and IPv6 addresses + if (inet_pton(family, addr_str, &addr) != 1) { + return false; // Invalid IP address + } + + return true; // Valid subnet +} diff --git a/src/main.cpp b/src/main.cpp index c30a6bd999..6d08340dac 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -42,6 +42,11 @@ #include +#ifdef DEBUG +#include "proxy_protocol_info.h" +#endif // DEBUG + + /* extern "C" MySQL_LDAP_Authentication * create_MySQL_LDAP_Authentication_func() { return NULL; @@ -1967,6 +1972,17 @@ int main(int argc, const char * argv[]) { if (rc) { exit(EXIT_FAILURE); } } + +#ifdef DEBUG + { + // This run some ProxyProtocolInfo tests. + // It will assert() if any test fails + ProxyProtocolInfo ppi; + ppi.run_tests(); + } +#endif // DEBUG + + { MYSQL *my = mysql_init(NULL); mysql_close(my); diff --git a/test/tap/tests/test_PROXY_Protocol-t.cpp b/test/tap/tests/test_PROXY_Protocol-t.cpp new file mode 100644 index 0000000000..14919b0d49 --- /dev/null +++ b/test/tap/tests/test_PROXY_Protocol-t.cpp @@ -0,0 +1,147 @@ +/** + * @file test_PROXY_Protocol-t.cpp + * @brief This test tries the PROXY protocol + * @details The test performs authentication using the PROXY protocol , then + * verifies PROXYSQL INTERNAL SESSION + * @date 2024-08-07 + */ + +#include +#include +#include +#include "mysql.h" + +#include "tap.h" +#include "command_line.h" +#include "utils.h" +#include "json.hpp" + +#include // For std::pair + +using std::string; +using namespace nlohmann; + +void parse_result_json_column(MYSQL_RES *result, json& j) { + if(!result) return; + MYSQL_ROW row; + + while ((row = mysql_fetch_row(result))) { + j = json::parse(row[0]); + } +} + +int connect_and_run_query(CommandLine& cl, int tests, const char *hdr) { + int ret = 0; // number of success + MYSQL* proxysql_mysql = mysql_init(NULL); + + mysql_optionsv(proxysql_mysql, MARIADB_OPT_PROXY_HEADER, hdr, strlen(hdr)); + + if (!mysql_real_connect(proxysql_mysql, cl.host, cl.username, cl.password, NULL, cl.port, NULL, 0)) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_mysql)); + return ret; + } else { + ok(true, "Successfully connected"); + ret++; + } + MYSQL_QUERY(proxysql_mysql, "PROXYSQL INTERNAL SESSION"); + json j_status {}; + MYSQL_RES* int_session_res = mysql_store_result(proxysql_mysql); + parse_result_json_column(int_session_res, j_status); + mysql_free_result(int_session_res); + bool proxy_info_found = false; + + //diag("%s",j_status.dump(1).c_str()); + + json jv1 {}; + if (j_status.find("client") != j_status.end()) { + json& j = *j_status.find("client"); + if (j.find("PROXY_V1") != j.end()) { + proxy_info_found = true; + jv1 = *j.find("PROXY_V1"); + } + } + if (tests == 2) { // we must found PROXY_V1 + ok(proxy_info_found == true, "PROXY_V1 %sfound", proxy_info_found ? "" : "not "); + if (proxy_info_found == true) { + ret++; + diag("%s",jv1.dump().c_str()); + } + } else if (tests == 1) { // PROXY_V1 should not be present + ok(proxy_info_found == false, "PROXY_V1 %sfound", proxy_info_found ? "" : "not "); + if (proxy_info_found == true) { + diag("%s",jv1.dump().c_str()); + } else { + ret++; + } + } else { + exit(exit_status()); + } + mysql_close(proxysql_mysql); + return ret; +} + +int main(int argc, char** argv) { + CommandLine cl; + + std::vector> Headers; + Headers.push_back(std::make_pair(2, "PROXY TCP4 192.168.0.1 192.168.0.11 56324 443\r\n")); + Headers.push_back(std::make_pair(1, "PROXY TCP4 192.168.0.1 192.168.0.11 56324\r\n")); + Headers.push_back(std::make_pair(0, "PROXY TCP4 192.168.0.1 192.168.0.11 56324 443")); + Headers.push_back(std::make_pair(0, "PROXY")); + Headers.push_back(std::make_pair(2, "PROXY TCP6 fe80::d6ae:52ff:fecf:9876 fe80::d6ae:52aa:fecf:1234 56324 443\r\n")); + Headers.push_back(std::make_pair(1, "PROXY TCP6 fe80::d6ae:52ff:fecf:9876 fe80::d6ae:52aa:fecf:1234 56324\r\n")); + Headers.push_back(std::make_pair(0, "PROXY TCP6 fe80::d6ae:52ff:fecf:9876 fe80::d6ae:52aa:fecf:1234 56324 443")); + + int p = 0; + // we will run the tests twice, with: + // - with mysql-proxy_protocol_networks='' + p += Headers.size(); + for (const auto& pair : Headers) { + p += ( pair.first ? 2 : 0); // PROXY_V1 should not be present + } + // - with mysql-proxy_protocol_networks='*' + p += Headers.size(); + for (const auto& pair : Headers) { + p += ( pair.first ? 2 : 0); // perform either 2 checks, or 0 + } + plan(p); + + MYSQL* proxysql_admin = mysql_init(NULL); + // Initialize connections + if (!proxysql_admin) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_admin)); + return -1; + } + + if (!mysql_real_connect(proxysql_admin, cl.host, cl.admin_username, cl.admin_password, NULL, cl.admin_port, NULL, 0)) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_admin)); + return -1; + } + + diag("Setting mysql-proxy_protocol_networks=''"); + MYSQL_QUERY(proxysql_admin, "SET mysql-proxy_protocol_networks=''"); + MYSQL_QUERY(proxysql_admin, "LOAD MYSQL VARIABLES TO RUNTIME"); + + for (const auto& pair : Headers) { + const std::string& hdr = pair.second; + diag("Testing connection with header: %s", hdr.c_str()); + int arg1 = pair.first ? 1 : 0; // if pair.first is not 0 , we will pass 1 because PROXY_V1 should not be present + int ret = connect_and_run_query(cl, arg1, hdr.c_str()); + int expected = pair.first ? 2 : 0; + ok(ret == expected , "Expected successes: %d , returned successes: %d", expected, ret); + } + + diag("Setting mysql-proxy_protocol_networks='*'"); + MYSQL_QUERY(proxysql_admin, "SET mysql-proxy_protocol_networks='*'"); + MYSQL_QUERY(proxysql_admin, "LOAD MYSQL VARIABLES TO RUNTIME"); + + for (const auto& pair : Headers) { + const std::string& hdr = pair.second; + diag("Testing connection with header: %s", hdr.c_str()); + int ret = connect_and_run_query(cl, pair.first, hdr.c_str()); + int expected = pair.first ? 2 : 0; + ok(ret == expected , "Expected successes: %d , returned successes: %d", expected, ret); + } + + return exit_status(); +} From f3ea2e613ec86d5a6cdb8171896bd2230f9e386e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Fri, 2 Aug 2024 10:01:23 +0200 Subject: [PATCH 05/62] Fix SSL error queue cleanup for backend conns The SSL error queue wasn't cleanup after an SSL related error took place in a backend connection. This would result in the propagation of the error to other conns handled by the thread, which could result in: - Incorrect destruction of connections in conn-pool. - Invalid error propagation to clients. This is a consequence of 'libmariadbclient' not performing a cleanup of this queue by itself. The situation got mitigated since the library **does** perform a cleanup of such queue during connect phase ('auth_caching_sha2_client|auth_sha256_client'), and ProxySQL does a cleanup of this queue during frontend SSL traffic. --- lib/MySQL_HostGroups_Manager.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/MySQL_HostGroups_Manager.cpp b/lib/MySQL_HostGroups_Manager.cpp index 37c075c6b1..5bf4f80c5f 100644 --- a/lib/MySQL_HostGroups_Manager.cpp +++ b/lib/MySQL_HostGroups_Manager.cpp @@ -2536,6 +2536,15 @@ MySQL_Connection * MySQL_HostGroups_Manager::get_MyConn_from_pool(unsigned int _ } void MySQL_HostGroups_Manager::destroy_MyConn_from_pool(MySQL_Connection *c, bool _lock) { + // 'libmariadbclient' only performs a cleanup of SSL error queue during connect when making use of + // 'auth_caching_sha2_client|auth_sha256_client' during connect. If any SSL errors took place during the + // previous operation, we must cleanup the queue to avoid polluting other backend conns. + int myerr=mysql_errno(c->mysql); + if (myerr >= 2000 && myerr < 3000 && c->mysql->options.use_ssl) { + proxy_debug(PROXY_DEBUG_MYSQL_CONNPOOL, 5, "Client error %d detected on SSL connection, cleaning SSL error queue\n", myerr); + ERR_clear_error(); + } + bool to_del=true; // the default, legacy behavior MySrvC *mysrvc=(MySrvC *)c->parent; if (mysrvc->get_status() == MYSQL_SERVER_STATUS_ONLINE && c->send_quit && queue.size() < __sync_fetch_and_add(&GloMTH->variables.connpoll_reset_queue_length, 0)) { From b19106a9c84c5e2219eb0f53d07d948661b35416 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Thu, 8 Aug 2024 18:30:41 +0200 Subject: [PATCH 06/62] Add reg test for frontend/backend conns SSL errors --- test/tap/tap/utils.cpp | 35 +- test/tap/tap/utils.h | 12 +- .../tests/reg_test_4556-ssl_error_queue-t.cpp | 845 ++++++++++++++++++ .../tests/reg_test_4556-ssl_error_queue-t.env | 3 + test/tap/tests/test_prometheus_metrics-t.cpp | 31 +- 5 files changed, 892 insertions(+), 34 deletions(-) create mode 100644 test/tap/tests/reg_test_4556-ssl_error_queue-t.cpp create mode 100644 test/tap/tests/reg_test_4556-ssl_error_queue-t.env diff --git a/test/tap/tap/utils.cpp b/test/tap/tap/utils.cpp index b192d9544f..b656e03aae 100644 --- a/test/tap/tap/utils.cpp +++ b/test/tap/tap/utils.cpp @@ -1586,10 +1586,16 @@ sq3_res_t sqlite3_execute_stmt(sqlite3* db, const string& query) { return res; } -json fetch_internal_session(MYSQL* proxy) { - int rc = mysql_query_t(proxy, "PROXYSQL INTERNAL SESSION"); +json fetch_internal_session(MYSQL* proxy, bool verbose) { + int rc = 0; + + if (verbose) { + rc = mysql_query_t(proxy, "PROXYSQL INTERNAL SESSION"); + } else { + rc = mysql_query(proxy, "PROXYSQL INTERNAL SESSION"); + } - if (rc ) { + if (rc) { return json {}; } else { MYSQL_RES* myres = mysql_store_result(proxy); @@ -1601,6 +1607,29 @@ json fetch_internal_session(MYSQL* proxy) { } } +map parse_prometheus_metrics(const string& s) { + vector lines { split(s, '\n') }; + map metrics_map {}; + + for (const string ln : lines) { + const vector line_values { split(ln, ' ') }; + + if (ln.empty() == false && ln[0] != '#') { + if (line_values.size() > 2) { + size_t delim_pos_st = ln.rfind("} "); + string metric_key = ln.substr(0, delim_pos_st); + string metric_val = ln.substr(delim_pos_st + 2); + + metrics_map.insert({metric_key, stod(metric_val)}); + } else { + metrics_map.insert({line_values.front(), stod(line_values.back())}); + } + } + } + + return metrics_map; +} + struct cols_table_info_t { vector names; vector widths; diff --git a/test/tap/tap/utils.h b/test/tap/tap/utils.h index d88182442b..1aeaa8e744 100644 --- a/test/tap/tap/utils.h +++ b/test/tap/tap/utils.h @@ -682,8 +682,18 @@ int64_t get_elem_idx(const T& e, const std::vector& v) { /** * @brief Returns a 'JSON' object holding 'PROXYSQL INTERNAL SESSION' contents. * @param proxy And already openned connection to ProxySQL. + * @param verbose Wether to log or not the issued queries. */ -nlohmann::json fetch_internal_session(MYSQL* proxy); +nlohmann::json fetch_internal_session(MYSQL* proxy, bool verbose=true); + +/** + * @brief Extract the metrics values from the output of: + * - The admin command 'SHOW PROMETHEUS METRICS'. + * - Querying the RESTAPI metrics endpoint. + * @param s ProxySQL prometheus exporter output. + * @return A map of metrics identifiers and values. + */ +std::map parse_prometheus_metrics(const std::string& s); /** * @brief Returns a string table representation of the supplied resultset. diff --git a/test/tap/tests/reg_test_4556-ssl_error_queue-t.cpp b/test/tap/tests/reg_test_4556-ssl_error_queue-t.cpp new file mode 100644 index 0000000000..87d334c16c --- /dev/null +++ b/test/tap/tests/reg_test_4556-ssl_error_queue-t.cpp @@ -0,0 +1,845 @@ +/** + * @file reg_test_4556-ssl_error_queue-t.cpp + * @brief Regression test for SSL error queue cleanup in frontend/backend conns. + * @details Two different kind of coherence checks are performed: + * 1. SSL errors on fronted conns don't propagate or pollute other frontend/backend conns: + * 1.1 Config ProxySQL for either perform conn retention or not (session_idle_ms). This ensure we + * test threads conn-sharing via 'idle-threads'. + * 1.2 Warm-up the conn-pool with multiple conns per-thread, test even conn distribution. + * 1.3 Force different kinds of SSL failures on frontend conns. + * 1.4 Check that exercising all the other client conns doesn't result in errors. This ensures + * the thread that received the error, is not polluting other conns while processing the queries. + * 2. SSL errors on backend conns don't propagate or pollute other frontend/backend conns: + * 2.1 Config ProxySQL with the desired PING intv, will be used to check backend conns, and '100' + * as 'free_connections_pct' to prevent early cleanups. + * 2.1 Warm-up the conn-pool creating backend conns for multiple threads. + * 2.2 Connect to MySQL, and kill a random conn count from conn-pool. + * 2.3 Let ProxySQL exercise backend conns via PING checks, ensure only killed conns died. + * 2.4 Exercise all backend conns via trxs, exhausting the conn-pool, no errors should take place. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "mysql.h" +#include "openssl/ssl.h" +#include "json.hpp" + +#include "tap.h" +#include "command_line.h" +#include "utils.h" + +using std::map; +using std::pair; +using std::string; +using std::vector; + +using nlohmann::json; + +#define TAP_NAME "TAP_SSL_ERROR_QUEUE___" + +// Check ENV for partially disable test sections +const char* TEST_FRONTEND = getenv(TAP_NAME"TEST_FRONTEND_CONNS"); +const char* TEST_CONN_DIST = getenv(TAP_NAME"TEST_CONN_DIST"); +const char* TEST_BACKEND = getenv(TAP_NAME"TEST_BACKEND_CONNS"); +const int HG_ID = get_env_int(TAP_NAME"MYSQL_SERVER_HOSTGROUP_ID", 0); +const int PER_THREAD_CONN_COUNT = get_env_int(TAP_NAME"PER_THREAD_CONN_COUNT", 20); + +/* Helper function to do the waiting for events on the socket. */ +static int wait_for_mysql(MYSQL *mysql, int status) { + struct pollfd pfd; + int timeout, res; + + pfd.fd = mysql_get_socket(mysql); + pfd.events = + (status & MYSQL_WAIT_READ ? POLLIN : 0) | + (status & MYSQL_WAIT_WRITE ? POLLOUT : 0) | + (status & MYSQL_WAIT_EXCEPT ? POLLPRI : 0); + if (status & MYSQL_WAIT_TIMEOUT) + timeout = 1000*mysql_get_timeout_value(mysql); + else + timeout = -1; + res = poll(&pfd, 1, timeout); + if (res == 0) + return MYSQL_WAIT_TIMEOUT; + else if (res < 0) + return MYSQL_WAIT_TIMEOUT; + else { + int status = 0; + if (pfd.revents & POLLIN) status |= MYSQL_WAIT_READ; + if (pfd.revents & POLLOUT) status |= MYSQL_WAIT_WRITE; + if (pfd.revents & POLLPRI) status |= MYSQL_WAIT_EXCEPT; + return status; + } +} + +// Thread Input +struct th_args__in_t { + CommandLine& cl; +}; + +// Thread Output +struct th_args__out_t { + std::string thread_addr {}; +}; + +struct th_args_t { + th_args__in_t in_args; + th_args__out_t out_args {}; +}; + +void* create_ssl_conn_and_close_socket(void* arg) { + th_args_t* th_args = static_cast(arg); + CommandLine& cl = th_args->in_args.cl; + + MYSQL* myconn = mysql_init(NULL); + mysql_ssl_set(myconn, NULL, NULL, NULL, NULL, NULL); + + if (!mysql_real_connect(myconn, cl.host, cl.username, cl.password, NULL, cl.port, NULL, CLIENT_SSL)) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(myconn)); + return NULL; + } + + json j_session = fetch_internal_session(myconn, false); + string thread_addr { j_session["thread"] }; + + th_args->out_args.thread_addr = thread_addr; + + diag("Early closing socket of first conn thread_addr=%s", thread_addr.c_str()); + close(myconn->net.fd); + + return NULL; +} + +void* create_ssl_conn_and_close_socket_async(void* arg) { + th_args_t* th_args = static_cast(arg); + CommandLine& cl = th_args->in_args.cl; + + MYSQL* myconn = mysql_init(NULL); + mysql_options(myconn, MYSQL_OPT_NONBLOCK, 0); + mysql_ssl_set(myconn, NULL, NULL, NULL, NULL, NULL); + + MYSQL* ret = nullptr; + diag("Starting async 'MySQL' connection thread=%ld", pthread_self()); + int status = mysql_real_connect_start( + &ret, myconn, cl.host, cl.username, cl.password, NULL, cl.port, NULL, CLIENT_SSL + ); + + diag("Early closing socket of non-complete async conn ret=%p status=%d", ret, status); + close(myconn->net.fd); + + return NULL; +} + +void* create_ssl_conn_inv_cert(void* arg) { + th_args_t* th_args = static_cast(arg); + CommandLine& cl = th_args->in_args.cl; + + MYSQL* myconn = mysql_init(NULL); + mysql_options(myconn, MYSQL_OPT_NONBLOCK, 0); + + char* inv_cert_path = tempnam(nullptr, "tap"); + diag("Setting invalid CERT for conn with tmp file path=%s", inv_cert_path); + mysql_ssl_set(myconn, NULL, NULL, inv_cert_path, NULL, NULL); + + MYSQL* ret = nullptr; + diag("Starting 'MySQL' connection with invalid CERT thread=%ld", pthread_self()); + + if (!mysql_real_connect(myconn, cl.host, cl.username, cl.password, NULL, cl.port, NULL, CLIENT_SSL)) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(myconn)); + return NULL; + } + + return NULL; +} + +/** + * @brief Invalid cert data to place in temporary file. + */ +const char inv_cert[] { + "-----BEGIN CERTIFICATE-----\n" + "kDeWG8U5N5v61p9QRwUutjUnRgmtYQOoe52Ib8k6KTVhSk/BsxsKNBQ2CdbjhuDl\n" + "5QIDc+5Z9FBIHFEL+jfivaA2X4jVRTZ52RPDDxqMK5Y3mTEyJZGE\n" + "-----END CERTIFICATE-----" +}; + +void* create_ssl_conn_missing_cert(void* arg) { + th_args_t* th_args = static_cast(arg); + CommandLine& cl = th_args->in_args.cl; + + MYSQL* myconn = mysql_init(NULL); + mysql_options(myconn, MYSQL_OPT_NONBLOCK, 0); + + char* inv_cert_path = tempnam(nullptr, "tap"); + FILE *tmp_file = fopen(inv_cert_path, "w"); + fprintf(tmp_file, inv_cert); + fflush(tmp_file); + + diag("Setting invalid CERT for conn with tmp file path=%s", inv_cert_path); + mysql_ssl_set(myconn, NULL, NULL, inv_cert_path, NULL, NULL); + + MYSQL* ret = nullptr; + diag("Starting 'MySQL' connection with invalid CERT thread=%ld", pthread_self()); + + if (!mysql_real_connect(myconn, cl.host, cl.username, cl.password, NULL, cl.port, NULL, CLIENT_SSL)) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(myconn)); + return NULL; + } + + fclose(tmp_file); + + return NULL; +} + +void check_threads_conns(const map>& m_th_conns, const string& th_addr) { + if (th_addr.empty()) { + diag("Checking ALL threads conns"); + } else { + diag("Checking conns filtered by thread thread_addr=%s", th_addr.c_str()); + } + + for (const pair>& p_th_conns : m_th_conns) { + if (!th_addr.empty() && p_th_conns.first != th_addr) { continue; } + + diag("Checking thread conns thread_addr=%s", p_th_conns.first.c_str()); + const vector& th_conns { p_th_conns.second }; + + for (size_t i = 0; i < th_conns.size(); i++) { + int rc = mysql_query(th_conns[i], "SELECT 1"); + + ok( + rc == 0, + "Query should execute without error rc=%d mysql_error='%s'", + rc, mysql_error(th_conns[i]) + ); + + MYSQL_RES* myres = mysql_store_result(th_conns[i]); + + ok( + myres != nullptr && mysql_errno(th_conns[i]) == 0, + "Resultset should be properly retreived myres=%p mysql_error='%s'", + myres, mysql_error(th_conns[i]) + ); + + mysql_free_result(myres); + } + } +} + +int create_conn(const CommandLine& cl) { + struct sockaddr_in server_addr; + + int sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock < 0) { + perror("Unable to create socket"); + return -1; + } + + memset(&server_addr, 0, sizeof(server_addr)); + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(uint32_t(cl.port)); + + if (inet_pton(AF_INET, cl.host, &server_addr.sin_addr) <= 0) { + perror("'inet_pton' failed"); + close(sock); + return -1; + } + + if (connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) { + perror("Unable to connect"); + close(sock); + return -1; + } + + return sock; +} + +char net_buf[4096] { 0 }; + +struct _mysql_hdr { + u_int pkt_length:24, pkt_id:8; +}; + +int read_srv_handshake(int fd) { + char* buf_pos = net_buf; + + int r = read(fd, buf_pos, sizeof(net_buf)); + if (r == -1) { + perror("'read' failed"); + return r; + } + + buf_pos += r; + + while (r > 0 && r < NET_HEADER_SIZE) { + r = read(fd, buf_pos + r, sizeof(buf_pos)); + buf_pos += r; + + if (r == -1) { + perror("'read' failed"); + return r; + } + } + + _mysql_hdr myhdr; + memcpy(&myhdr, net_buf, sizeof(_mysql_hdr)); + + while (r > 0 && r < myhdr.pkt_length) { + r = read(fd, buf_pos + r, sizeof(buf_pos)); + buf_pos += r; + + if (r == -1) { + perror("'read' failed"); + return r; + } + } + + return 0; +} + +/** + * @brief Hardcoded SSL_Request packet. + */ +unsigned char SSL_REQUEST_PKT[] = { + 0x20, 0x00, 0x00, 0x01, 0x85, 0xae, 0xff, 0x19, + 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +void* force_ssl_pre_handshake_failure(void* arg) { + th_args_t* th_args = static_cast(arg); + CommandLine& cl = th_args->in_args.cl; + + diag("Creating TCP connection to ProxySQL"); + int sock = create_conn(cl); + + diag("Reading ServerHandshake packet"); + int rc = read_srv_handshake(sock); + if (rc == -1) { + diag("Failed to read ProxySQL init hanshake"); + return NULL; + } + + diag("Sending harcoded 'SSLRequest'"); + rc = send(sock, SSL_REQUEST_PKT, sizeof(SSL_REQUEST_PKT), 0); + if (rc == -1) { + perror("'send' failed"); + return NULL; + } + + diag("Closing socket just after 'SSLRequest'"); + close(sock); + + return NULL; +} + +MYSQL* create_server_conn(CommandLine& cl) { + MYSQL* server = mysql_init(NULL); + + if ( + !mysql_real_connect( + server, + cl.mysql_host, + cl.mysql_username, + cl.mysql_password, + NULL, + cl.mysql_port, + NULL, + 0 + ) + ) { + diag( + "Failed to create conn to MySQL error=%s port=%d", + mysql_error(server), cl.mysql_port + ); + return NULL; + } + + return server; +} + +int create_test_database(CommandLine& cl, const string& name) { + MYSQL* server = create_server_conn(cl); + if (!server) { return EXIT_FAILURE; } + + const string q { "CREATE DATABASE IF NOT EXISTS " + name }; + if (mysql_query_t(server, q.c_str())) { + diag("Query failed to execute query=%s err=%s", q.c_str(), mysql_error(server)); + return EXIT_FAILURE; + } + + mysql_close(server); + return EXIT_SUCCESS; +} + +const char CONNPOOL_DB[] { "reg_test_4556" }; + +pair> warmup_conn_pool(CommandLine& cl, uint32_t CONNS_TOTAL) { + // Create database to use to flag conn-pool connections + diag("Creating testing database for connpool warming database=%s", CONNPOOL_DB); + if (create_test_database(cl, CONNPOOL_DB)) { + diag("Failed to create testing db database=%s", CONNPOOL_DB); + return { EXIT_FAILURE, {} }; + } + + diag("Elevating process limits for conns creation"); + struct rlimit limits { 0, 0 }; + getrlimit(RLIMIT_NOFILE, &limits); + diag("Old process limits rlim_cur=%ld rlim_max=%ld", limits.rlim_cur, limits.rlim_max); + if (limits.rlim_cur < CONNS_TOTAL * 2) { + diag("Updating process max FD limit"); + limits.rlim_cur = CONNS_TOTAL * 2; + setrlimit(RLIMIT_NOFILE, &limits); + } + diag("New process limits rlim_cur=%ld rlim_max=%ld", limits.rlim_cur, limits.rlim_max); + + vector conns {}; + + for (int i = 0; i < CONNS_TOTAL; i++) { + MYSQL* myconn = mysql_init(NULL); + + if (!mysql_real_connect(myconn, cl.host, cl.username, cl.password, NULL, cl.port, NULL, 0)) { + diag( + "Failed to connect addr=%s port=%d user=%s pass=%s err=%s", + cl.host, cl.port, cl.username, cl.password, mysql_error(myconn) + ); + return { EXIT_FAILURE, {} }; + } + + const vector CONN_CREATE_QUERIES { + "USE reg_test_4556", + "/* create_new_connection=1 */ DO 1" + }; + + // Make sure to fill the connection pool + for (const char* q : CONN_CREATE_QUERIES) { + if (mysql_query_t(myconn, q)) { + diag("Query failed to execute query=%s err=%s", q, mysql_error(myconn)); + return { mysql_errno(myconn), {} }; + } + } + + conns.push_back(myconn); + } + + return { EXIT_SUCCESS, conns }; +} + +map> create_conn_thread_map(vector& conns) { + map> m_thread_conns {}; + + for (MYSQL* myconn : conns) { + json j_session = fetch_internal_session(myconn, false); + string thread_addr { j_session["thread"] }; + + m_thread_conns[thread_addr].push_back(myconn); + } + + return m_thread_conns; +} + +void check_thread_conn_dist(const map>& m_thread_conns) { + if (TEST_CONN_DIST && strcasecmp(TEST_CONN_DIST, "0") == 0) { return; } + + size_t lo_count = 0; + size_t hg_count = 0; + + diag("Dumping per-thread conn count:"); + for (const pair>& thread_conns : m_thread_conns) { + if (lo_count == 0 || thread_conns.second.size() < lo_count) { + lo_count = thread_conns.second.size(); + } + if (hg_count == 0 || thread_conns.second.size() > hg_count) { + hg_count = thread_conns.second.size(); + } + fprintf(stderr, "Map entry thread=%s count=%ld\n", thread_conns.first.c_str(), thread_conns.second.size()); + } + + ok(lo_count != 0, "No thread should be left without connections lo_count=%ld", lo_count); +} + +int clean_conn_pool(MYSQL* admin) { + // 0. Ensure connection pool cleanup + MYSQL_QUERY_T(admin, "UPDATE mysql_servers SET max_connections=0"); + MYSQL_QUERY_T(admin, "LOAD MYSQL SERVERS TO RUNTIME"); + + { + MYSQL_QUERY(admin, "SELECT * FROM stats_mysql_connection_pool"); + MYSQL_RES* myres = mysql_store_result(admin); + diag("stats_mysql_connection_pool:\n%s", dump_as_table(myres).c_str()); + } + + const string COND_CONN_CLEANUP { + "SELECT IIF((SELECT SUM(ConnUsed + ConnFree) FROM stats.stats_mysql_connection_pool" + " WHERE hostgroup=" + std::to_string(HG_ID) + ")=0, 'TRUE', 'FALSE')" + }; + int w_res = wait_for_cond(admin, COND_CONN_CLEANUP, 10); + if (w_res) { + { + MYSQL_QUERY(admin, "SELECT * FROM stats_mysql_connection_pool"); + MYSQL_RES* myres = mysql_store_result(admin); + diag("stats_mysql_connection_pool:\n%s", dump_as_table(myres).c_str()); + } + + diag("Waiting for backend connections failed res:'%d'", w_res); + return EXIT_FAILURE; + } + + MYSQL_QUERY_T(admin, "UPDATE mysql_servers SET max_connections=500"); + MYSQL_QUERY_T(admin, "LOAD MYSQL SERVERS TO RUNTIME"); + + { + MYSQL_QUERY(admin, "SELECT * FROM stats_mysql_connection_pool"); + MYSQL_RES* myres = mysql_store_result(admin); + diag("stats_mysql_connection_pool:\n%s", dump_as_table(myres).c_str()); + } + + return EXIT_SUCCESS; +} + +int check_frontend_ssl_errs( + CommandLine& cl, MYSQL* admin, int64_t thread_count, int64_t idle_sess_ms, void*(*ssl_err_cb)(void*) +) { + // 0. Ensure connection pool cleanup + int clean_rc = clean_conn_pool(admin); + if (clean_rc) { + diag("Conn-pool cleanup failed; aborting futher testing"); + return EXIT_FAILURE; + } + + // 1. Configure ProxySQL forcing threads to retains conns + MYSQL_QUERY_T(admin, ("SET mysql-session_idle_ms=" + std::to_string(idle_sess_ms)).c_str()); + MYSQL_QUERY_T(admin, "LOAD MYSQL VARIABLES TO RUNTIME"); + + // 2. Create connections based on number of threads + pair> p_rc_conns {}; + { + uint32_t CONNS_TOTAL = thread_count * PER_THREAD_CONN_COUNT; + diag( + "Creating connections threads=%ld per_thread_conns=%d total=%d", + thread_count, PER_THREAD_CONN_COUNT, CONNS_TOTAL + ); + + p_rc_conns = warmup_conn_pool(cl, CONNS_TOTAL); + if (p_rc_conns.first) { return EXIT_FAILURE; } + } + + // 3. Check connection distribution on ProxySQL + map> m_thread_conns { create_conn_thread_map(p_rc_conns.second) }; + check_thread_conn_dist(m_thread_conns); + + // 4. Force a failure in a new connection; different kinds: + // - SSL failure due to pure SSL error, inv cert. + // - SSL failure due to closed socket; during query, or premature close. + { + pthread_t unexp_socket_close; + void* th_ret = nullptr; + std::unique_ptr th_args { + new th_args_t { th_args__in_t { cl }, th_args__out_t {} } + }; + + diag("Force early SSL failure in thread"); + pthread_create(&unexp_socket_close, NULL, ssl_err_cb, th_args.get()); + pthread_join(unexp_socket_close, &th_ret); + } + + // 5. Check all the others client conns in same thread are not broken (SSL err queue). + { + diag("Checking connections handled by ALL threads"); + check_threads_conns(m_thread_conns, string {}); + } + + for (MYSQL* myconn : p_rc_conns.second) { + mysql_close(myconn); + } + + return EXIT_SUCCESS; +} + +const uint32_t PING_INTV_MS { 1000 }; + +pair fetch_metric_val(CommandLine& cl, const string& metric_id) { + uint64_t curl_res_code = 0; + string curl_res_data {}; + const char URL[] { "http://localhost:6070/metrics/" }; + + diag("Fetching metric values via RESTAPI URL=%s", URL); + CURLcode code = perform_simple_get(URL, curl_res_code, curl_res_data); + + if (code != CURLE_OK || curl_res_code != 200) { + diag("Failed to fetch current metrics error=%s", curl_res_data.c_str()); + return { EXIT_FAILURE, 0 }; + } + + const map m_id_val { parse_prometheus_metrics(curl_res_data) }; + diag( + "Searching in fetched metrics metric_id=%s map_size=%ld", + metric_id.c_str(), m_id_val.size() + ); + + double error_count = 0; + + auto m_it = m_id_val.find(metric_id); + if (m_it != m_id_val.end()) { + error_count = m_it->second; + } + + return { EXIT_SUCCESS, error_count }; +} + +/** + * @brief Perform coherence checks on the backend conns. + * @details The checks are performed in the following way: + * 1. Warmup the conn-pool creating backend conns for multiple threads. + * 2. Connect to MySQL, and kill random conns from conn-pool. + * 3. Exercise all backend conns via PING checks, ensure only killed conns died. + * 4. Exercise all backend conns via trxs, exhausting the conn-pool, no errors should take place. + * @param cl Env config for conn creation. + * @param admin Already open Admin conn for ProxySQL config. + * @param thread_count Number of threads used by ProxySQL. + * @return EXIT_SUCCESS if checks could be performed, EXIT_FAILURE otherwise. + */ +int check_backend_ssl_errs(CommandLine& cl, MYSQL* admin, int64_t thread_count) { + // Ensure connection pool cleanup + int clean_rc = clean_conn_pool(admin); + if (clean_rc) { + diag("Conn-pool cleanup failed; aborting futher testing"); + return EXIT_FAILURE; + } + + // Configure ProxySQL to exercise backend connections via PING + const string ping_intv_str { std::to_string(PING_INTV_MS) }; + MYSQL_QUERY(admin, ("SET mysql-ping_interval_server_msec=" + ping_intv_str).c_str()); + // Prevent early closing of backend conns; will interfere with error counting + MYSQL_QUERY(admin, "SET mysql-free_connections_pct=100"); + MYSQL_QUERY(admin, "LOAD MYSQL VARIABLES TO RUNTIME"); + + // Create connections based on number of threads + uint32_t CONNS_TOTAL = thread_count * PER_THREAD_CONN_COUNT; + pair> p_rc_conns {}; + + diag( + "Creating connections threads=%ld per_thread_conns=%d total=%d", + thread_count, PER_THREAD_CONN_COUNT, CONNS_TOTAL + ); + + p_rc_conns = warmup_conn_pool(cl, CONNS_TOTAL); + if (p_rc_conns.first) { return EXIT_FAILURE; } + + // Create connection map for backend connetions; assuming high idle-sessions. + map> m_thread_conns { create_conn_thread_map(p_rc_conns.second) }; + + // Kill several backend connnections; check ProxySQL only destroys the relevant ones + MYSQL* server = create_server_conn(cl); + if (!server) { return EXIT_FAILURE; } + + uint32_t TO_KILL = (thread_count * 2) + rand() % 10; + uint32_t CONN_PCT = TO_KILL * 100 / CONNS_TOTAL; + diag("Random conn kill count kills=%d conn_pct=%d", TO_KILL, CONN_PCT); + + const string proc_list_q { + "SELECT ID FROM information_schema.processlist" + " WHERE DB='" + string { CONNPOOL_DB } + "'" + " ORDER BY RAND() LIMIT " + std::to_string(TO_KILL) + }; + diag("Fetching conns to be killed query=%s", proc_list_q.c_str()); + const pair> p_conns_ids { + mysql_query_ext_rows(server, proc_list_q) + }; + if (p_conns_ids.first) { + diag("Failed to fetch conns ids from processlist error=%s", mysql_error(server)); + return EXIT_FAILURE; + } + + // Fetch current connections errors to target server + const string myport { std::to_string(cl.mysql_port) }; + const string m_srv_id { + "mysql_error_total{" + "address=\"" + string {cl.mysql_host} + "\",code=\"2013\"," + "hostgroup=\"" + std::to_string(HG_ID) + "\",port=\"" + myport + "\"" + "}" + }; + + pair p_pre_count { fetch_metric_val(cl, m_srv_id) }; + if (p_pre_count.first) { return EXIT_FAILURE; } + + for (const mysql_res_row& conn_id_row : p_conns_ids.second) { + MYSQL_QUERY_T(server, string {"KILL " + conn_id_row[0]}.c_str()); + } + + // Give time for ProxySQL to detect broken connections + sleep((PING_INTV_MS / 1000 ) * 3); + + pair p_post_count { fetch_metric_val(cl, m_srv_id) }; + + ok( + p_pre_count.second + TO_KILL == p_post_count.second, + "Errors should be increased **ONLY** by killed conns pre=%lf post=%lf to_kill=%d", + p_pre_count.second, p_post_count.second, TO_KILL + ); + + // Check all conns remains viable using trxs to exhaust the conn-pool + diag("Starting trxs count=%ld", p_rc_conns.second.size()); + vector trxs_rcs {}; + for (MYSQL* mysql : p_rc_conns.second) { + int q_rc = mysql_query_t(mysql, "BEGIN"); + if (q_rc) { + diag("Trx start failed error=%s", mysql_error(mysql)); + } + trxs_rcs.push_back(q_rc); + } + + size_t failed_trxs = std::accumulate(trxs_rcs.begin(), trxs_rcs.end(), 0, + [] (size_t acc, int n) { + if (n != 0) { return acc + 1; } + else { return acc; } + } + ); + + ok(failed_trxs == 0, "No trxs should fail to start failed_trxs=%ld", failed_trxs); + + for (MYSQL* mysql : p_rc_conns.second) { + mysql_close(mysql); + } + + return EXIT_SUCCESS; +} + +const vector idle_sess_ms { + 10000 /* No session sharing on threads */, + 1 /* Session sharing between; via 'idle-threads' */ +}; + +const vector> ssl_failure_rts { + { "force_ssl_pre_handshake_failure", force_ssl_pre_handshake_failure }, + { "create_ssl_conn_inv_cert", create_ssl_conn_inv_cert }, + { "create_ssl_conn_missing_cert", create_ssl_conn_missing_cert } +}; + +int main(int argc, char** argv) { + CommandLine cl; + + if (cl.getEnv()) { + diag("Failed to get the required environmental variables."); + return EXIT_FAILURE; + } + + diag("Init rand seed with current time"); + srand(time(NULL)); + + MYSQL* admin = mysql_init(NULL); + + if (!mysql_real_connect(admin, cl.host, cl.admin_username, cl.admin_password, NULL, cl.admin_port, NULL, 0)) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(admin)); + return EXIT_FAILURE; + } + + // Disable query retry; required for further tests + MYSQL_QUERY_T(admin, "SET mysql-query_retries_on_failure=0"); + MYSQL_QUERY_T(admin, "LOAD MYSQL VARIABLES TO RUNTIME"); + + // Ensure RESTAPI is enabled for backend conn errors fetching + MYSQL_QUERY_T(admin, "SET admin-restapi_enabled=1"); + MYSQL_QUERY_T(admin, "LOAD ADMIN VARIABLES TO RUNTIME"); + + // Update default hostgroup for user with target hostgroup + MYSQL_QUERY_T(admin, + ("UPDATE mysql_users SET default_hostgroup=" + std::to_string(HG_ID) + + " WHERE username='" + cl.username + "'").c_str() + ); + MYSQL_QUERY_T(admin, "LOAD MYSQL USERS TO RUNTIME"); + + // Disable all queries rules if present; not required + MYSQL_QUERY_T(admin, "UPDATE mysql_query_rules SET active=0"); + MYSQL_QUERY_T(admin, "LOAD MYSQL QUERY RULES TO RUNTIME"); + + // Update MySQL servers config + MYSQL_QUERY_T(admin, + ("UPDATE mysql_servers SET use_ssl=1 WHERE hostgroup_id=" + std::to_string(HG_ID)).c_str() + ); + MYSQL_QUERY_T(admin, "LOAD MYSQL SERVERS TO RUNTIME"); + + const char q_thread_count[] { + "SELECT variable_value FROM global_variables WHERE variable_name='mysql-threads'" + }; + ext_val_t ext_thread_count { mysql_query_ext_val(admin, q_thread_count, int64_t(0)) }; + + if (ext_thread_count.err != EXIT_SUCCESS) { + const string err { get_ext_val_err(admin, ext_thread_count) }; + diag("Failed getting 'mysql-threads' query:`%s`, err:`%s`", q_thread_count, err.c_str()); + return EXIT_FAILURE; + } + + const long conn_queries { PER_THREAD_CONN_COUNT * ext_thread_count.val * 2 }; + const size_t end_to_end_conns_checks { conn_queries * idle_sess_ms.size() * ssl_failure_rts.size() }; + const size_t thread_conn_dist_checks { ssl_failure_rts.size() * idle_sess_ms.size() }; + + size_t frontend_conns_checks { 0 }; + size_t conns_dist_checks { 0 }; + size_t backend_conns_checks { 0 }; + + if (!TEST_FRONTEND || (TEST_FRONTEND && strcasecmp(TEST_FRONTEND, "0") != 0)) { + frontend_conns_checks = end_to_end_conns_checks; + } + if (!TEST_CONN_DIST || (TEST_CONN_DIST && strcasecmp(TEST_CONN_DIST, "0") != 0)) { + conns_dist_checks = thread_conn_dist_checks; + } + if (!TEST_BACKEND || (TEST_BACKEND && strcasecmp(TEST_BACKEND, "0") != 0)) { + backend_conns_checks = 2; + } + + plan(frontend_conns_checks + conns_dist_checks + backend_conns_checks); + + if (!frontend_conns_checks) { + goto backend_checks; + } + +frontend_checks: + diag("START: Regression testing of #4556 for frontend conns"); + for (const pair p_name_rt : ssl_failure_rts) { + const char* rt_name = p_name_rt.first.c_str(); + void*(*ssl_fail_rt)(void*) = p_name_rt.second; + + for (size_t ms_idle : idle_sess_ms) { + diag("Forcing SSL failure on fronted connection routine=%s", p_name_rt.first.c_str()); + int rc = check_frontend_ssl_errs(cl, admin, ext_thread_count.val, ms_idle, ssl_fail_rt); + if (rc) { + diag("Unable to perform check, operation failed routine=%s", p_name_rt.first.c_str()); + return EXIT_FAILURE; + } + } + } + + if (!backend_conns_checks) { + goto cleanup; + } + +backend_checks: + diag("START: Regression testing for SSL errors on backend conns"); + { + int rc = check_backend_ssl_errs(cl, admin, ext_thread_count.val); + if (rc) { + diag("Unable to perform check, operation failed"); + return EXIT_FAILURE; + } + } + +cleanup: + mysql_close(admin); + + return exit_status(); +} diff --git a/test/tap/tests/reg_test_4556-ssl_error_queue-t.env b/test/tap/tests/reg_test_4556-ssl_error_queue-t.env new file mode 100644 index 0000000000..0700ee4384 --- /dev/null +++ b/test/tap/tests/reg_test_4556-ssl_error_queue-t.env @@ -0,0 +1,3 @@ +TAP_MYSQLUSERNAME=root +TAP_MYSQLPASSWORD=root +TAP_MYSQLPORT=13306 diff --git a/test/tap/tests/test_prometheus_metrics-t.cpp b/test/tap/tests/test_prometheus_metrics-t.cpp index a9bc27df6a..82545cf6a9 100644 --- a/test/tap/tests/test_prometheus_metrics-t.cpp +++ b/test/tap/tests/test_prometheus_metrics-t.cpp @@ -39,35 +39,6 @@ int mysql_query_d(MYSQL* mysql, const char* query) { return mysql_query(mysql, query); } -/** - * @brief Extract the metrics values from the output of the admin command - * 'SHOW PROMETHEUS METRICS'. - * @param metrics_output The output of the command 'SHOW PROMETHEUS METRICS'. - * @return A map holding the metrics identifier and its current value. - */ -std::map get_metric_values(std::string metrics_output) { - std::vector output_lines { split(metrics_output, '\n') }; - std::map metrics_map {}; - - for (const std::string line : output_lines) { - const std::vector line_values { split(line, ' ') }; - - if (line.empty() == false && line[0] != '#') { - if (line_values.size() > 2) { - size_t delim_pos_st = line.rfind("} "); - string metric_key = line.substr(0, delim_pos_st); - string metric_val = line.substr(delim_pos_st + 2); - - metrics_map.insert({metric_key, std::stod(metric_val)}); - } else { - metrics_map.insert({line_values.front(), std::stod(line_values.back())}); - } - } - } - - return metrics_map; -} - int get_cur_metrics(MYSQL* admin, map& metrics_vals) { MYSQL_QUERY(admin, "SHOW PROMETHEUS METRICS\\G"); MYSQL_RES* p_resulset = mysql_store_result(admin); @@ -81,7 +52,7 @@ int get_cur_metrics(MYSQL* admin, map& metrics_vals) { } mysql_free_result(p_resulset); - metrics_vals = get_metric_values(row_value); + metrics_vals = parse_prometheus_metrics(row_value); return EXIT_SUCCESS; } From 1fdaad02828777c500d325418445f83ea3aed961 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Fri, 2 Aug 2024 14:28:41 +0200 Subject: [PATCH 07/62] Add TAP test checking thread conns distribution --- test/tap/tests/test_thread_conn_dist-t.cpp | 132 +++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 test/tap/tests/test_thread_conn_dist-t.cpp diff --git a/test/tap/tests/test_thread_conn_dist-t.cpp b/test/tap/tests/test_thread_conn_dist-t.cpp new file mode 100644 index 0000000000..047498edc0 --- /dev/null +++ b/test/tap/tests/test_thread_conn_dist-t.cpp @@ -0,0 +1,132 @@ +#include +#include +#include +#include +#include + +#include +#include + +#include "tap.h" +#include "command_line.h" +#include "utils.h" + +#include "mysql.h" +#include "json.hpp" + +using std::map; +using std::pair; +using std::string; +using std::vector; + +using nlohmann::json; + +#define TAP_NAME "TAP_THREAD_CONN_DIST___" + +const int TEST_DURATION_SEC = get_env_int(TAP_NAME"TEST_DURATION_SEC", 20); +const int ITER_CONN_COUNT = get_env_int(TAP_NAME"ITER_CONN_COUNT", 256); + +void incr_proc_limits(uint32_t MAX_CONN_COUNT) { + diag("Elevating process limits if required for conns creation"); + + struct rlimit limits { 0, 0 }; + getrlimit(RLIMIT_NOFILE, &limits); + diag("Old process limits rlim_cur=%ld rlim_max=%ld", limits.rlim_cur, limits.rlim_max); + + if (limits.rlim_cur < MAX_CONN_COUNT * 2) { + diag("Updating process max FD limit"); + limits.rlim_cur = MAX_CONN_COUNT * 2; + setrlimit(RLIMIT_NOFILE, &limits); + } + + diag("New process limits rlim_cur=%ld rlim_max=%ld", limits.rlim_cur, limits.rlim_max); +} + +pair> create_frontend_conns(CommandLine& cl, uint32_t CONNS_TOTAL) { + vector conns {}; + + for (int i = 0; i < CONNS_TOTAL; i++) { + MYSQL* myconn = mysql_init(NULL); + + if (!mysql_real_connect(myconn, cl.host, cl.username, cl.password, NULL, cl.port, NULL, 0)) { + diag( + "Failed to connect addr=%s port=%d user=%s pass=%s err=%s", + cl.host, cl.port, cl.username, cl.password, mysql_error(myconn) + ); + return { EXIT_FAILURE, {} }; + } + + conns.push_back(myconn); + } + + return { EXIT_SUCCESS, conns }; +} + +void check_thread_conn_dist(const map>& m_thread_conns) { + size_t lo_count = 0; + size_t hg_count = 0; + + diag("Dumping per-thread conn count:"); + for (const pair>& thread_conns : m_thread_conns) { + if (lo_count == 0 || thread_conns.second.size() < lo_count) { + lo_count = thread_conns.second.size(); + } + if (hg_count == 0 || thread_conns.second.size() > hg_count) { + hg_count = thread_conns.second.size(); + } + fprintf(stderr, "Map entry thread=%s count=%ld\n", thread_conns.first.c_str(), thread_conns.second.size()); + } + + ok( + hg_count / 2 < lo_count, + "Half the highest conn count shouldn't be higher than lowest conn count" + " hg_count=%ld lo_count=%ld", + hg_count, lo_count + ); +} + +void update_conn_thread_map(vector& conns, map>& m_thread_conns) { + for (MYSQL* myconn : conns) { + json j_session = fetch_internal_session(myconn, false); + string thread_addr { j_session["thread"] }; + + m_thread_conns[thread_addr].push_back(myconn); + } +} + +int main(int argc, char** argv) { + CommandLine cl; + + if (cl.getEnv()) { + diag("Failed to get the required environmental variables."); + return EXIT_FAILURE; + } + + plan(1); + + auto start = std::chrono::system_clock::now(); + std::chrono::duration elapsed {}; + + incr_proc_limits(ITER_CONN_COUNT); + + map> m_thread_conns {}; + + while (elapsed.count() < TEST_DURATION_SEC) { + pair> p_err_conns { create_frontend_conns(cl, ITER_CONN_COUNT) }; + if (p_err_conns.first) { + diag("Frontend conn creation failed; aborting further testing err=%d", p_err_conns.first); + return EXIT_FAILURE; + } + + update_conn_thread_map(p_err_conns.second, m_thread_conns); + + for (MYSQL* conn : p_err_conns.second) { + mysql_close(conn); + } + + auto it_end = std::chrono::system_clock::now(); + elapsed = it_end - start; + } + + check_thread_conn_dist(m_thread_conns); +} From 95fa15cdf99e7a984a9b0b6339fa0b3dcbf801df Mon Sep 17 00:00:00 2001 From: Rene Cannao Date: Mon, 12 Aug 2024 20:25:22 +0000 Subject: [PATCH 08/62] Better parsing of USE queries sent with COM_QUERY #4598 --- include/set_parser.h | 5 ++ lib/MySQL_Session.cpp | 41 +++++++-------- lib/set_parser.cpp | 118 ++++++++++++++++++++++++++++++++++++++++++ src/main.cpp | 7 +++ 4 files changed, 149 insertions(+), 22 deletions(-) diff --git a/include/set_parser.h b/include/set_parser.h index 5421868342..ac783f06b4 100644 --- a/include/set_parser.h +++ b/include/set_parser.h @@ -42,6 +42,11 @@ class SetParser { // First implemenation of the parser for TRANSACTION ISOLATION LEVEL and TRANSACTION READ/WRITE std::map> parse2(); std::string parse_character_set(); + std::string parse_USE_query(); +#ifdef DEBUG + // built-in testing + void test_parse_USE_query(); +#endif // DEBUG ~SetParser(); }; diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index b40d922539..42930c9b92 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -6138,30 +6138,27 @@ void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C if (session_type == PROXYSQL_SESSION_MYSQL) { __sync_fetch_and_add(&MyHGM->status.frontend_use_db, 1); string nq=string((char *)pkt->ptr+sizeof(mysql_hdr)+1,pkt->size-sizeof(mysql_hdr)-1); - RE2::GlobalReplace(&nq,(char *)"(?U)/\\*.*\\*/",(char *)" "); - char *sn_tmp = (char *)nq.c_str(); - while (sn_tmp < ( nq.c_str() + nq.length() - 4 ) && *sn_tmp == ' ') - sn_tmp++; - //char *schemaname=strdup(nq.c_str()+4); - char *schemaname=strdup(sn_tmp+3); - char *schemanameptr=trim_spaces_and_quotes_in_place(schemaname); - // handle cases like "USE `schemaname` - if(schemanameptr[0]=='`' && schemanameptr[strlen(schemanameptr)-1]=='`') { - schemanameptr[strlen(schemanameptr)-1]='\0'; - schemanameptr++; - } - client_myds->myconn->userinfo->set_schemaname(schemanameptr,strlen(schemanameptr)); - free(schemaname); - if (mirror==false) { + SetParser parser(nq); + string schemaname = parser.parse_USE_query(); + if (schemaname != "") { + client_myds->myconn->userinfo->set_schemaname((char *)schemaname.c_str(),schemaname.length()); + if (mirror==false) { + RequestEnd(NULL); + } + l_free(pkt->size,pkt->ptr); + client_myds->setDSS_STATE_QUERY_SENT_NET(); + unsigned int nTrx=NumActiveTransactions(); + uint16_t setStatus = (nTrx ? SERVER_STATUS_IN_TRANS : 0 ); + if (autocommit) setStatus |= SERVER_STATUS_AUTOCOMMIT; + client_myds->myprot.generate_pkt_OK(true,NULL,NULL,1,0,0,setStatus,0,NULL); + GloMyLogger->log_audit_entry(PROXYSQL_MYSQL_INITDB, this, NULL); + } else { + l_free(pkt->size,pkt->ptr); + client_myds->setDSS_STATE_QUERY_SENT_NET(); + std::string msg = "Unable to parse: " + nq; + client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,client_myds->pkt_sid+1,1148,(char *)"42000", msg.c_str()); RequestEnd(NULL); } - l_free(pkt->size,pkt->ptr); - client_myds->setDSS_STATE_QUERY_SENT_NET(); - unsigned int nTrx=NumActiveTransactions(); - uint16_t setStatus = (nTrx ? SERVER_STATUS_IN_TRANS : 0 ); - if (autocommit) setStatus |= SERVER_STATUS_AUTOCOMMIT; - client_myds->myprot.generate_pkt_OK(true,NULL,NULL,1,0,0,setStatus,0,NULL); - GloMyLogger->log_audit_entry(PROXYSQL_MYSQL_INITDB, this, NULL); client_myds->DSS=STATE_SLEEP; } else { l_free(pkt->size,pkt->ptr); diff --git a/lib/set_parser.cpp b/lib/set_parser.cpp index 521808d642..80370b2535 100644 --- a/lib/set_parser.cpp +++ b/lib/set_parser.cpp @@ -3,10 +3,14 @@ #include #include #include +#include +#include // for std::pair #ifdef PARSERDEBUG #include #endif +#include "pcrecpp.h" + using namespace std; @@ -506,3 +510,117 @@ std::string SetParser::parse_character_set() { return value4; } +std::string SetParser::parse_USE_query() { +#ifdef DEBUG + proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 4, "Parsing query %s\n", query.c_str()); +#endif // DEBUG + + +std::string pattern = ""; + + + +/* +// Step 1: Match for an optional multiline comment at the beginning of the input string. + * `^` : Matches the beginning of the string. + * `\s*` : Matches zero or more whitespace characters (spaces, tabs, newlines). + * `(?: ... )?` : Non-capturing group, made optional by `?`. + * `\/\*.*\*\/` : Matches a multiline C-style comment + * `\s*` : Matches zero or more whitespace characters. +*/ + pattern += R"(^\s*(?:\/\*.*\*\/\s*)?)"; + +/* +// Step 2: This part matches the "USE" keyword followed by zero or more spaces. + * `USE`: Matches the literal string "USE". + * `\s*`: Matches zero or more whitespace characters. +*/ + pattern += R"(USE\s*)"; + +/* +// Step 3: Match the optional backtick, optional space, and the dbname + * `\s+` : Matches one or more whitespace characters. + * `|` : Or operator. + * `(` : Matches a backtick character literally. + * `(`)?` : capturing group. This matches an optional opening backtick. + * `([a-zA-Z0-9_]+)` : Matches one or more alphanumeric characters or underscores (captures the dbname). + * `\1?` : Backreference to the first capturing group (the opening backtick), making the closing backtick optional. + + This part handles the following: + * Optional space or backtick : It matches either one or more spaces (`\s+`) or a backtick (`) after "USE". This allows for the optional space when the dbname is wrapped in backticks. + * Optional opening backtick : It matches an optional opening backtick. + * Capturing the dbname : It captures the actual dbname, which can consist of alphanumeric characters and underscores. + * Optional closing backtick : It matches an optional closing backtick, which must match the opening backtick if present. +*/ + pattern += R"((`|\s+)?(?:`)?([a-zA-Z0-9_]+)\1?)"; +// add an optional space + pattern += R"(\s*)"; + +/* +// Step 4: Match the optional second comment + * `(?: ... )?` : Non-capturing group, made optional by `?`. + * `\/\*.*\*\/` : Matches a multiline C-style comment . + * `#[^\n]*$` : Matches a single-line comment starting with `#` (until the end of the line). + * `-- [^\n]*$` : Matches a single-line comment starting with `-- ` (until the end of the line). +*/ + pattern += R"((?:\/\*.*\*\/|#[^\n]*$|-- [^\n]*$)?)"; + +/* +// Step 5: Match the end of the line + * `\s*`: Matches zero or more whitespace characters. + * `$` : Matches the end of the string. +*/ + pattern += R"(\s*$)"; + + + std::string dbname = ""; + std::string opening_quote; + + pcrecpp::RE_Options opt; + opt.set_caseless(true); + pcrecpp::RE re(pattern, opt); + std::string sp(query); + re.FullMatch(sp, &opening_quote, &dbname); + + return dbname; +} + + +#ifdef DEBUG +void SetParser::test_parse_USE_query() { + + // Define vector of pairs (query, expected dbname) + std::vector> testCases = { + {"USE my_database", "my_database"}, // Basic Case + {"USE my_database", "my_database"}, // Basic Case + {"USE my_database ", "my_database"}, // Basic Case + {"/* comment */USE dbname /* comment */", "dbname"}, // With Comments + {"/* comment */ USE dbname", "dbname"}, // With Comments + {"USE dbname /* comment */", "dbname"}, // With Comments + {"/* comment */USE `dbname` /* comment */", "dbname"}, // With backtick + {"/* comment */USE `dbname`/* comment */", "dbname"}, // With backtick + {"/* comment */USE`dbname` /* comment */", "dbname"}, // With backtick + {"/* comment */USE `dbname`/* comment */", "dbname"}, // With backtick + {"/* comment\nmultiline comment */USE dbname /* comment */", "dbname"}, // Multiline Comment + {"/* comment */USE dbname # comment", "dbname"}, // Hash Comment + {"/* comment */USE dbname -- comment", "dbname"}, // Double Dash Comment + {"/* comment */USE dbname # comment", "dbname"}, // Hash Comment + {"/* comment */USE dbname -- comment", "dbname"}, // Double Dash Comment + {"USE dbname # comment", "dbname"}, // Hash Comment + {"USE dbname -- comment", "dbname"}, // Double Dash Comment + {"SELECT * FROM my_table", ""}, // No match + }; + + // Run tests for each pair + for (const auto& p : testCases) { + set_query(p.first); + std::string dbname = parse_USE_query(); + if (dbname != p.second) { + // we call parse_USE_query() again just to make it easier to create a breakpoint + std::string s = parse_USE_query(); + assert(s == p.second); + } + } + +} +#endif // DEBUG diff --git a/src/main.cpp b/src/main.cpp index c30a6bd999..d98743a604 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1976,6 +1976,13 @@ int main(int argc, const char * argv[]) { // std::cerr << "Main init phase0 completed in "; #endif } +#ifdef DEBUG + { + // Automated testing + SetParser parser(""); + parser.test_parse_USE_query(); + } +#endif // DEBUG { cpu_timer t; ProxySQL_Main_process_global_variables(argc, argv); From eedb3978bfda6afb5eb24546878d9ad0c373e711 Mon Sep 17 00:00:00 2001 From: Rene Cannao Date: Tue, 13 Aug 2024 01:27:55 +0000 Subject: [PATCH 09/62] WIP: improved USE query parsing --- include/set_parser.h | 1 + lib/set_parser.cpp | 162 ++++++++++++++++++++++++++++++++++++++----- 2 files changed, 147 insertions(+), 16 deletions(-) diff --git a/include/set_parser.h b/include/set_parser.h index ac783f06b4..bd89bbab22 100644 --- a/include/set_parser.h +++ b/include/set_parser.h @@ -43,6 +43,7 @@ class SetParser { std::map> parse2(); std::string parse_character_set(); std::string parse_USE_query(); + std::string remove_comments(const std::string& q); #ifdef DEBUG // built-in testing void test_parse_USE_query(); diff --git a/lib/set_parser.cpp b/lib/set_parser.cpp index 80370b2535..e9f98129d3 100644 --- a/lib/set_parser.cpp +++ b/lib/set_parser.cpp @@ -5,9 +5,9 @@ #include #include #include // for std::pair -#ifdef PARSERDEBUG +//#ifdef PARSERDEBUG #include -#endif +//#endif #include "pcrecpp.h" @@ -515,11 +515,8 @@ std::string SetParser::parse_USE_query() { proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 4, "Parsing query %s\n", query.c_str()); #endif // DEBUG - std::string pattern = ""; - - /* // Step 1: Match for an optional multiline comment at the beginning of the input string. * `^` : Matches the beginning of the string. @@ -537,8 +534,19 @@ std::string pattern = ""; */ pattern += R"(USE\s*)"; + +/* +// Step 3: Match the optional comment between "USE" and the database name + * `(?: ... )?` : Non-capturing group, made optional by `?`. + * `\/\*.*\*\/` : Matches a multiline C-style comment . + * `#[^\n]*$` : Matches a single-line comment starting with `#` (until the end of the line). + * `-- [^\n]*$` : Matches a single-line comment starting with `-- ` (until the end of the line). +*/ + pattern += R"((?:\/\*.*\*\/|#[^\n]*$|-- [^\n]*$)?)"; + + /* -// Step 3: Match the optional backtick, optional space, and the dbname +// Step 4: Match the optional backtick, optional space, and the dbname * `\s+` : Matches one or more whitespace characters. * `|` : Or operator. * `(` : Matches a backtick character literally. @@ -552,12 +560,13 @@ std::string pattern = ""; * Capturing the dbname : It captures the actual dbname, which can consist of alphanumeric characters and underscores. * Optional closing backtick : It matches an optional closing backtick, which must match the opening backtick if present. */ - pattern += R"((`|\s+)?(?:`)?([a-zA-Z0-9_]+)\1?)"; + //pattern += R"((`|\s+)?(`)?([a-zA-Z0-9_]+)\1?)"; + pattern += R"(\s*`([a-zA-Z0-9_]+)`|\s+([a-zA-Z0-9_]+))"; // add an optional space pattern += R"(\s*)"; /* -// Step 4: Match the optional second comment +// Step 5: Match the optional second comment * `(?: ... )?` : Non-capturing group, made optional by `?`. * `\/\*.*\*\/` : Matches a multiline C-style comment . * `#[^\n]*$` : Matches a single-line comment starting with `#` (until the end of the line). @@ -566,23 +575,121 @@ std::string pattern = ""; pattern += R"((?:\/\*.*\*\/|#[^\n]*$|-- [^\n]*$)?)"; /* -// Step 5: Match the end of the line +// Step 6: Match the end of the line * `\s*`: Matches zero or more whitespace characters. * `$` : Matches the end of the string. */ pattern += R"(\s*$)"; + pattern = R"(^\s*(?:\/\*.*\*\/\s*)?USE\s*(?:\/\*.*\*\/|#[^\n]*$|-- [^\n]*$)?\s*(`(?:[a-zA-Z0-9_]+)`|\s+(?:[a-zA-Z0-9_]+))\s*(?:\/\*.*\*\/|#[^\n]*$|-- [^\n]*$)?\s*$)"; - std::string dbname = ""; +/* + std::string dbname1 = ""; + std::string dbname2 = ""; std::string opening_quote; +*/ + re2::RE2::Options opt2(RE2::Quiet); + opt2.set_case_sensitive(false); + opt2.set_longest_match(false); +/* + re2::StringPiece input(query); + re2::RE2 re(pattern, *opt2); + re2::RE2::Consume(&input, re, &dbname1); + delete opt2; +*/ +/* pcrecpp::RE_Options opt; opt.set_caseless(true); pcrecpp::RE re(pattern, opt); std::string sp(query); - re.FullMatch(sp, &opening_quote, &dbname); + re.FullMatch(sp, &dbname1); +*/ +/* + if (dbname1 != "") + return dbname1; + return dbname2; +*/ + std::string dbname = remove_comments(query); + re2::RE2 re0("^\\s*", opt2); + re2::RE2::Replace(&dbname, re0, ""); + if (dbname.size() >= 4) { + if ( + strncasecmp(dbname.c_str(), "USE ",4) == 0 + || + strncasecmp(dbname.c_str(), "USE`",4) == 0 + ) { + re2::RE2 re1("^USE\\s*", opt2); + re2::RE2::Replace(&dbname, re1, ""); + re2::RE2 re2("\\s*$", opt2); + re2::RE2::Replace(&dbname, re2, ""); + if (dbname[0] == '`') { + if (dbname[dbname.length()-1] == '`') { + return dbname; + } + } else { + return dbname; + } + } + } else { + return ""; + } - return dbname; +/* + { + // Find the first non-space character from the end + auto it = std::find_if_not(dbname.rbegin(), dbname.rend(), [](char c) { + return std::isspace(c); + }); + // Erase the characters from the first non-space character to the end + dbname.erase(it.base(), dbname.end()); + + } +*/ + return ""; +} + + +std::string SetParser::remove_comments(const std::string& q) { + std::string result = ""; + bool in_multiline_comment = false; + + for (size_t i = 0; i < query.size(); ++i) { + char current_char = query[i]; + + // Check for multiline comment start + if (current_char == '/' && i + 1 < query.size() && query[i + 1] == '*') { + in_multiline_comment = true; + i++; // Skip the '*' + continue; + } + + // Check for multiline comment end + if (in_multiline_comment && current_char == '*' && i + 1 < query.size() && query[i + 1] == '/') { + in_multiline_comment = false; + i++; // Skip the '/' + continue; + } + + // Skip characters inside multiline comment + if (in_multiline_comment) { + continue; + } + + // Check for single-line comments + if (current_char == '#' || (current_char == '-' && i + 1 < query.size() && query[i + 1] == '-')) { + // Skip until the end of the line + while (i < query.size() && query[i] != '\n') { + i++; + } + continue; + } + + // Append the character to the result if it's not a comment + result += current_char; + } + + return result; } @@ -597,10 +704,10 @@ void SetParser::test_parse_USE_query() { {"/* comment */USE dbname /* comment */", "dbname"}, // With Comments {"/* comment */ USE dbname", "dbname"}, // With Comments {"USE dbname /* comment */", "dbname"}, // With Comments - {"/* comment */USE `dbname` /* comment */", "dbname"}, // With backtick - {"/* comment */USE `dbname`/* comment */", "dbname"}, // With backtick - {"/* comment */USE`dbname` /* comment */", "dbname"}, // With backtick - {"/* comment */USE `dbname`/* comment */", "dbname"}, // With backtick + {"/* comment */USE `dbname` /* comment */", "`dbname`"}, // With backtick + {"/* comment */USE `dbname`/* comment */", "`dbname`"}, // With backtick + {"/* comment */USE`dbname` /* comment */", "`dbname`"}, // With backtick + {"/* comment */USE `dbname`/* comment */", "`dbname`"}, // With backtick {"/* comment\nmultiline comment */USE dbname /* comment */", "dbname"}, // Multiline Comment {"/* comment */USE dbname # comment", "dbname"}, // Hash Comment {"/* comment */USE dbname -- comment", "dbname"}, // Double Dash Comment @@ -609,6 +716,28 @@ void SetParser::test_parse_USE_query() { {"USE dbname # comment", "dbname"}, // Hash Comment {"USE dbname -- comment", "dbname"}, // Double Dash Comment {"SELECT * FROM my_table", ""}, // No match + {"/*+ placeholder_comment */ USE test_use_comment", "test_use_comment"}, + + {"USE /*+ placeholder_comment */ `test_use_comment-a1`", "`test_use_comment-a1`"}, + {"USE /*+ placeholder_comment */ `test_use_comment_1`", "`test_use_comment_1`"}, + {"USE/*+ placeholder_comment */ `test_use_comment_2`", "`test_use_comment_2`"}, + {"USE /*+ placeholder_comment */`test_use_comment_3`", "`test_use_comment_3`"}, + {"USE /*+ placeholder_comment */ test_use_comment_4", "test_use_comment_4"}, + {"USE/*+ placeholder_comment */ test_use_comment_5", "test_use_comment_5"}, + {"USE /*+ placeholder_comment */test_use_comment_6", "test_use_comment_6"}, + {"USE /*+ placeholder_comment */ `test_use_comment-1`", "`test_use_comment-1`"}, + {"use my_database", "my_database"}, + {"/* comment */ use dbname -- comment", "dbname"}, + {"/* comment\nmultiline comment */USE dbname /* comment\nmultiline comment */", "dbname"}, // Multiline Comment + +// db_query.push_back(std::make_tuple("`test_use_comment-2`", "USE/*+ placeholder_comment */ `test_use_comment-2`", false)); +// db_query.push_back(std::make_tuple("`test_use_comment-3`", "USE /*+ placeholder_comment */`test_use_comment-3`", true)); +// db_query.push_back(std::make_tuple("`test_use_comment-4`", "/*+ placeholder_comment */USE `test_use_comment-4`", false)); +// db_query.push_back(std::make_tuple("`test_use_comment-5`", "USE/*+ placeholder_comment */`test_use_comment-5`", false)); +// db_query.push_back(std::make_tuple("`test_use_comment-6`", "/* comment */USE`test_use_comment-6`", false)); +// db_query.push_back(std::make_tuple("`test_use_comment-7`", "USE`test_use_comment-7`", false)); + + }; // Run tests for each pair @@ -616,6 +745,7 @@ void SetParser::test_parse_USE_query() { set_query(p.first); std::string dbname = parse_USE_query(); if (dbname != p.second) { + //std::cout << dbname << " : " << query << std::endl; // we call parse_USE_query() again just to make it easier to create a breakpoint std::string s = parse_USE_query(); assert(s == p.second); From 9f0af17249964cbd945834720f579b5454e02fcb Mon Sep 17 00:00:00 2001 From: Rene Cannao Date: Tue, 13 Aug 2024 11:19:06 +0000 Subject: [PATCH 10/62] Improved USE query parsing --- lib/set_parser.cpp | 73 +++++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/lib/set_parser.cpp b/lib/set_parser.cpp index e9f98129d3..ca19cde58a 100644 --- a/lib/set_parser.cpp +++ b/lib/set_parser.cpp @@ -9,8 +9,6 @@ #include //#endif -#include "pcrecpp.h" - using namespace std; @@ -624,8 +622,14 @@ std::string pattern = ""; re2::RE2 re2("\\s*$", opt2); re2::RE2::Replace(&dbname, re2, ""); if (dbname[0] == '`') { - if (dbname[dbname.length()-1] == '`') { - return dbname; + if (dbname.length() > 2) { + if (dbname[dbname.length()-1] == '`') { + // Remove the first character + dbname.erase(0, 1); + // Remove the last character + dbname.erase(dbname.length() - 1); + return dbname; + } } } else { return dbname; @@ -698,46 +702,44 @@ void SetParser::test_parse_USE_query() { // Define vector of pairs (query, expected dbname) std::vector> testCases = { - {"USE my_database", "my_database"}, // Basic Case - {"USE my_database", "my_database"}, // Basic Case + {"USE my_database", "my_database"}, // Basic Case + {"USE my_database", "my_database"}, // Basic Case {"USE my_database ", "my_database"}, // Basic Case - {"/* comment */USE dbname /* comment */", "dbname"}, // With Comments - {"/* comment */ USE dbname", "dbname"}, // With Comments - {"USE dbname /* comment */", "dbname"}, // With Comments - {"/* comment */USE `dbname` /* comment */", "`dbname`"}, // With backtick - {"/* comment */USE `dbname`/* comment */", "`dbname`"}, // With backtick - {"/* comment */USE`dbname` /* comment */", "`dbname`"}, // With backtick - {"/* comment */USE `dbname`/* comment */", "`dbname`"}, // With backtick + {"/* comment */USE dbname /* comment */", "dbname"}, // With Comments + {"/* comment */ USE dbname", "dbname"}, // With Comments + {"USE dbname /* comment */", "dbname"}, // With Comments + {"/* comment */USE `dbname` /* comment */", "dbname"}, // With backtick + {"/* comment */USE `dbname`/* comment */", "dbname"}, // With backtick + {"/* comment */USE`dbname` /* comment */", "dbname"}, // With backtick + {"/* comment */USE `dbname`/* comment */", "dbname"}, // With backtick {"/* comment\nmultiline comment */USE dbname /* comment */", "dbname"}, // Multiline Comment - {"/* comment */USE dbname # comment", "dbname"}, // Hash Comment - {"/* comment */USE dbname -- comment", "dbname"}, // Double Dash Comment - {"/* comment */USE dbname # comment", "dbname"}, // Hash Comment - {"/* comment */USE dbname -- comment", "dbname"}, // Double Dash Comment - {"USE dbname # comment", "dbname"}, // Hash Comment - {"USE dbname -- comment", "dbname"}, // Double Dash Comment + {"/* comment */USE dbname # comment", "dbname"}, // Hash Comment + {"/* comment */USE dbname -- comment", "dbname"}, // Double Dash Comment + {"/* comment */USE dbname # comment", "dbname"}, // Hash Comment + {"/* comment */USE dbname -- comment", "dbname"}, // Double Dash Comment + {"USE dbname # comment", "dbname"}, // Hash Comment + {"USE dbname -- comment", "dbname"}, // Double Dash Comment {"SELECT * FROM my_table", ""}, // No match {"/*+ placeholder_comment */ USE test_use_comment", "test_use_comment"}, - {"USE /*+ placeholder_comment */ `test_use_comment-a1`", "`test_use_comment-a1`"}, - {"USE /*+ placeholder_comment */ `test_use_comment_1`", "`test_use_comment_1`"}, - {"USE/*+ placeholder_comment */ `test_use_comment_2`", "`test_use_comment_2`"}, - {"USE /*+ placeholder_comment */`test_use_comment_3`", "`test_use_comment_3`"}, - {"USE /*+ placeholder_comment */ test_use_comment_4", "test_use_comment_4"}, - {"USE/*+ placeholder_comment */ test_use_comment_5", "test_use_comment_5"}, - {"USE /*+ placeholder_comment */test_use_comment_6", "test_use_comment_6"}, - {"USE /*+ placeholder_comment */ `test_use_comment-1`", "`test_use_comment-1`"}, + {"USE /*+ placeholder_comment */ `test_use_comment-a1`", "test_use_comment-a1"}, + {"USE /*+ placeholder_comment */ `test_use_comment_1`", "test_use_comment_1"}, + {"USE/*+ placeholder_comment */ `test_use_comment_2`", "test_use_comment_2"}, + {"USE /*+ placeholder_comment */`test_use_comment_3`", "test_use_comment_3"}, + {"USE /*+ placeholder_comment */ test_use_comment_4", "test_use_comment_4"}, + {"USE/*+ placeholder_comment */ test_use_comment_5", "test_use_comment_5"}, + {"USE /*+ placeholder_comment */test_use_comment_6", "test_use_comment_6"}, + {"USE /*+ placeholder_comment */ `test_use_comment-1`", "test_use_comment-1"}, {"use my_database", "my_database"}, {"/* comment */ use dbname -- comment", "dbname"}, {"/* comment\nmultiline comment */USE dbname /* comment\nmultiline comment */", "dbname"}, // Multiline Comment -// db_query.push_back(std::make_tuple("`test_use_comment-2`", "USE/*+ placeholder_comment */ `test_use_comment-2`", false)); -// db_query.push_back(std::make_tuple("`test_use_comment-3`", "USE /*+ placeholder_comment */`test_use_comment-3`", true)); -// db_query.push_back(std::make_tuple("`test_use_comment-4`", "/*+ placeholder_comment */USE `test_use_comment-4`", false)); -// db_query.push_back(std::make_tuple("`test_use_comment-5`", "USE/*+ placeholder_comment */`test_use_comment-5`", false)); -// db_query.push_back(std::make_tuple("`test_use_comment-6`", "/* comment */USE`test_use_comment-6`", false)); -// db_query.push_back(std::make_tuple("`test_use_comment-7`", "USE`test_use_comment-7`", false)); - - + {"USE/*+ placeholder_comment */ `test_use_comment-2`", "test_use_comment-2"}, + {"USE /*+ placeholder_comment */`test_use_comment-3`", "test_use_comment-3"}, + {"/*+ placeholder_comment */USE `test_use_comment-4`", "test_use_comment-4"}, + {"USE/*+ placeholder_comment */`test_use_comment-5`", "test_use_comment-5"}, + {"/* comment */USE`test_use_comment-6`", "test_use_comment-6"}, + {"USE`test_use_comment-7`", "test_use_comment-7"}, }; // Run tests for each pair @@ -745,7 +747,6 @@ void SetParser::test_parse_USE_query() { set_query(p.first); std::string dbname = parse_USE_query(); if (dbname != p.second) { - //std::cout << dbname << " : " << query << std::endl; // we call parse_USE_query() again just to make it easier to create a breakpoint std::string s = parse_USE_query(); assert(s == p.second); From c049c9268cca9bc404092d81adf6c8324589aad9 Mon Sep 17 00:00:00 2001 From: Rene Cannao Date: Tue, 13 Aug 2024 11:25:56 +0000 Subject: [PATCH 11/62] Cleanup code from previous commits --- lib/set_parser.cpp | 104 +-------------------------------------------- 1 file changed, 1 insertion(+), 103 deletions(-) diff --git a/lib/set_parser.cpp b/lib/set_parser.cpp index ca19cde58a..7abef9adf1 100644 --- a/lib/set_parser.cpp +++ b/lib/set_parser.cpp @@ -513,101 +513,10 @@ std::string SetParser::parse_USE_query() { proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 4, "Parsing query %s\n", query.c_str()); #endif // DEBUG -std::string pattern = ""; - -/* -// Step 1: Match for an optional multiline comment at the beginning of the input string. - * `^` : Matches the beginning of the string. - * `\s*` : Matches zero or more whitespace characters (spaces, tabs, newlines). - * `(?: ... )?` : Non-capturing group, made optional by `?`. - * `\/\*.*\*\/` : Matches a multiline C-style comment - * `\s*` : Matches zero or more whitespace characters. -*/ - pattern += R"(^\s*(?:\/\*.*\*\/\s*)?)"; - -/* -// Step 2: This part matches the "USE" keyword followed by zero or more spaces. - * `USE`: Matches the literal string "USE". - * `\s*`: Matches zero or more whitespace characters. -*/ - pattern += R"(USE\s*)"; - - -/* -// Step 3: Match the optional comment between "USE" and the database name - * `(?: ... )?` : Non-capturing group, made optional by `?`. - * `\/\*.*\*\/` : Matches a multiline C-style comment . - * `#[^\n]*$` : Matches a single-line comment starting with `#` (until the end of the line). - * `-- [^\n]*$` : Matches a single-line comment starting with `-- ` (until the end of the line). -*/ - pattern += R"((?:\/\*.*\*\/|#[^\n]*$|-- [^\n]*$)?)"; - - -/* -// Step 4: Match the optional backtick, optional space, and the dbname - * `\s+` : Matches one or more whitespace characters. - * `|` : Or operator. - * `(` : Matches a backtick character literally. - * `(`)?` : capturing group. This matches an optional opening backtick. - * `([a-zA-Z0-9_]+)` : Matches one or more alphanumeric characters or underscores (captures the dbname). - * `\1?` : Backreference to the first capturing group (the opening backtick), making the closing backtick optional. - - This part handles the following: - * Optional space or backtick : It matches either one or more spaces (`\s+`) or a backtick (`) after "USE". This allows for the optional space when the dbname is wrapped in backticks. - * Optional opening backtick : It matches an optional opening backtick. - * Capturing the dbname : It captures the actual dbname, which can consist of alphanumeric characters and underscores. - * Optional closing backtick : It matches an optional closing backtick, which must match the opening backtick if present. -*/ - //pattern += R"((`|\s+)?(`)?([a-zA-Z0-9_]+)\1?)"; - pattern += R"(\s*`([a-zA-Z0-9_]+)`|\s+([a-zA-Z0-9_]+))"; -// add an optional space - pattern += R"(\s*)"; - -/* -// Step 5: Match the optional second comment - * `(?: ... )?` : Non-capturing group, made optional by `?`. - * `\/\*.*\*\/` : Matches a multiline C-style comment . - * `#[^\n]*$` : Matches a single-line comment starting with `#` (until the end of the line). - * `-- [^\n]*$` : Matches a single-line comment starting with `-- ` (until the end of the line). -*/ - pattern += R"((?:\/\*.*\*\/|#[^\n]*$|-- [^\n]*$)?)"; - -/* -// Step 6: Match the end of the line - * `\s*`: Matches zero or more whitespace characters. - * `$` : Matches the end of the string. -*/ - pattern += R"(\s*$)"; - - pattern = R"(^\s*(?:\/\*.*\*\/\s*)?USE\s*(?:\/\*.*\*\/|#[^\n]*$|-- [^\n]*$)?\s*(`(?:[a-zA-Z0-9_]+)`|\s+(?:[a-zA-Z0-9_]+))\s*(?:\/\*.*\*\/|#[^\n]*$|-- [^\n]*$)?\s*$)"; - -/* - std::string dbname1 = ""; - std::string dbname2 = ""; - std::string opening_quote; -*/ - re2::RE2::Options opt2(RE2::Quiet); opt2.set_case_sensitive(false); opt2.set_longest_match(false); -/* - re2::StringPiece input(query); - re2::RE2 re(pattern, *opt2); - re2::RE2::Consume(&input, re, &dbname1); - delete opt2; -*/ -/* - pcrecpp::RE_Options opt; - opt.set_caseless(true); - pcrecpp::RE re(pattern, opt); - std::string sp(query); - re.FullMatch(sp, &dbname1); -*/ -/* - if (dbname1 != "") - return dbname1; - return dbname2; -*/ + std::string dbname = remove_comments(query); re2::RE2 re0("^\\s*", opt2); re2::RE2::Replace(&dbname, re0, ""); @@ -639,17 +548,6 @@ std::string pattern = ""; return ""; } -/* - { - // Find the first non-space character from the end - auto it = std::find_if_not(dbname.rbegin(), dbname.rend(), [](char c) { - return std::isspace(c); - }); - // Erase the characters from the first non-space character to the end - dbname.erase(it.base(), dbname.end()); - - } -*/ return ""; } From 5dd4327e8b89929a48b0492121531c887d54f6b1 Mon Sep 17 00:00:00 2001 From: Miro Stauder Date: Wed, 14 Aug 2024 11:10:22 +0000 Subject: [PATCH 12/62] remove empty .gcno files --- test/tap/tests/Makefile | 2 ++ test/tap/tests_with_deps/deprecate_eof_support/Makefile | 2 ++ 2 files changed, 4 insertions(+) diff --git a/test/tap/tests/Makefile b/test/tap/tests/Makefile index b404d1ad3e..be38e9ed53 100644 --- a/test/tap/tests/Makefile +++ b/test/tap/tests/Makefile @@ -203,6 +203,8 @@ tests: tests-cpp \ prepare_statement_err3024_async-t \ reg_test_mariadb_stmt_store_result_libmysql-t \ reg_test_mariadb_stmt_store_result_async-t +tests: + find -L . -type f -name '*.gcno' -empty -delete tests-cpp: $(patsubst %.cpp,%,$(wildcard *-t.cpp)) tests-php: $(patsubst %,php-%,$(wildcard *-t.php)) diff --git a/test/tap/tests_with_deps/deprecate_eof_support/Makefile b/test/tap/tests_with_deps/deprecate_eof_support/Makefile index 36b52fd9f8..c57c83a2e0 100644 --- a/test/tap/tests_with_deps/deprecate_eof_support/Makefile +++ b/test/tap/tests_with_deps/deprecate_eof_support/Makefile @@ -154,6 +154,8 @@ $(TEST_MYSQL_LDIR)/libmysqlclient.a: #tests: build_test_deps tests: $(patsubst %.cpp,%,$(wildcard *-t.cpp)) ok_packet_mixed_queries-t fwd_eof_query fwd_eof_ok_query +tests: + find -L . -type f -name '*.gcno' -empty -delete COMMONARGS = $(OPT) -Wl,-Bdynamic -ltap -lcpp_dotenv -lcurl -lre2 -lssl -lcrypto -lz -ldl -lpthread -DGITVERSION=\"$(GIT_VERSION)\" From 644dd93f8e2722cf5ac5384e5d337c927b00e6e9 Mon Sep 17 00:00:00 2001 From: Miro Stauder Date: Wed, 14 Aug 2024 12:30:18 +0000 Subject: [PATCH 13/62] list deleted .gcno files --- test/tap/tests/Makefile | 3 ++- test/tap/tests_with_deps/deprecate_eof_support/Makefile | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/test/tap/tests/Makefile b/test/tap/tests/Makefile index be38e9ed53..85d57f64cb 100644 --- a/test/tap/tests/Makefile +++ b/test/tap/tests/Makefile @@ -204,7 +204,8 @@ tests: tests-cpp \ reg_test_mariadb_stmt_store_result_libmysql-t \ reg_test_mariadb_stmt_store_result_async-t tests: - find -L . -type f -name '*.gcno' -empty -delete + @echo "Removing empty .gcno files ..." + find -L . -type f -name '*.gcno' -empty -ls -delete tests-cpp: $(patsubst %.cpp,%,$(wildcard *-t.cpp)) tests-php: $(patsubst %,php-%,$(wildcard *-t.php)) diff --git a/test/tap/tests_with_deps/deprecate_eof_support/Makefile b/test/tap/tests_with_deps/deprecate_eof_support/Makefile index c57c83a2e0..27062713e7 100644 --- a/test/tap/tests_with_deps/deprecate_eof_support/Makefile +++ b/test/tap/tests_with_deps/deprecate_eof_support/Makefile @@ -155,7 +155,8 @@ $(TEST_MYSQL_LDIR)/libmysqlclient.a: #tests: build_test_deps tests: $(patsubst %.cpp,%,$(wildcard *-t.cpp)) ok_packet_mixed_queries-t fwd_eof_query fwd_eof_ok_query tests: - find -L . -type f -name '*.gcno' -empty -delete + @echo "Removing empty .gcno files ..." + find -L . -type f -name '*.gcno' -empty -ls -delete COMMONARGS = $(OPT) -Wl,-Bdynamic -ltap -lcpp_dotenv -lcurl -lre2 -lssl -lcrypto -lz -ldl -lpthread -DGITVERSION=\"$(GIT_VERSION)\" From b2c13874fbefdf117a5e68d3f66ef3f9c62c05e3 Mon Sep 17 00:00:00 2001 From: Miro Stauder Date: Wed, 14 Aug 2024 21:11:30 +0000 Subject: [PATCH 14/62] add test groups --- test/tap/README.md | 20 +++++++++++++++++++ ...uto_increment_delay_multiplex-proxysql.sql | 4 ++++ ...ts_grp_auto_increment_delay_multiplex.bash | 13 ++++++++++++ .../pre-tests_grp_multiplexing-proxysql.sql | 4 ++++ .../pre-tests_grp_multiplexing.bash | 13 ++++++++++++ .../pre-tests_grp_query_digests-proxysql.sql | 4 ++++ .../pre-tests_grp_query_digests.bash | 13 ++++++++++++ ...rp_query_digests_keep_comment-proxysql.sql | 4 ++++ ...-tests_grp_query_digests_keep_comment.bash | 13 ++++++++++++ 9 files changed, 88 insertions(+) create mode 100644 test/tap/tests_grp_auto_increment_delay_multiplex/pre-tests_grp_auto_increment_delay_multiplex-proxysql.sql create mode 100755 test/tap/tests_grp_auto_increment_delay_multiplex/pre-tests_grp_auto_increment_delay_multiplex.bash create mode 100644 test/tap/tests_grp_multiplexing/pre-tests_grp_multiplexing-proxysql.sql create mode 100755 test/tap/tests_grp_multiplexing/pre-tests_grp_multiplexing.bash create mode 100644 test/tap/tests_grp_query_digests/pre-tests_grp_query_digests-proxysql.sql create mode 100755 test/tap/tests_grp_query_digests/pre-tests_grp_query_digests.bash create mode 100644 test/tap/tests_grp_query_digests_keep_comment/pre-tests_grp_query_digests_keep_comment-proxysql.sql create mode 100755 test/tap/tests_grp_query_digests_keep_comment/pre-tests_grp_query_digests_keep_comment.bash diff --git a/test/tap/README.md b/test/tap/README.md index 8b96dfe9a2..4b1d21722e 100644 --- a/test/tap/README.md +++ b/test/tap/README.md @@ -3,3 +3,23 @@ - `tap`: Contains TAP helper library for testing, and general utilities used across all tests. - `tests`: General test folder for either unitary or functional tests. - `tests_with_deps`: Test folder that holds all the tests that require special dependencies for being build. + +- `tests_grp_*`: tap test groups of specific tests with special configs applied via + - `pre-tests_grp_*.bash` script run before tests + - `pre-tests_grp_*.sql` script run before tests + - `post-tests_grp_*.bash` script run after tests + - `post-tests_grp_*.sql` script run after tests + +example test group `tests_grp_mytests` can be created by +``` +TG='mytests' +mkdir -p test/tap/tests_grp_$TG +cd test/tap/tests_grp_$TG +for T in $(ls -1 ../tests/); do ln -fsT ../tests/$T $T; done +cat > pre-test_grp_$TG-proxysql.sql << EOF +# run this test group with: +SET mysql-multiplexing='false'; +LOAD MYSQL VARIABLES TO RUNTIME; +SAVE MYSQL VARIABLES TO DISK; +EOF +``` diff --git a/test/tap/tests_grp_auto_increment_delay_multiplex/pre-tests_grp_auto_increment_delay_multiplex-proxysql.sql b/test/tap/tests_grp_auto_increment_delay_multiplex/pre-tests_grp_auto_increment_delay_multiplex-proxysql.sql new file mode 100644 index 0000000000..fcd19e67e2 --- /dev/null +++ b/test/tap/tests_grp_auto_increment_delay_multiplex/pre-tests_grp_auto_increment_delay_multiplex-proxysql.sql @@ -0,0 +1,4 @@ +# proxysql settings +SET mysql-auto_increment_delay_multiplex=0; +LOAD MYSQL VARIABLES TO RUNTIME; +SAVE MYSQL VARIABLES TO DISK; diff --git a/test/tap/tests_grp_auto_increment_delay_multiplex/pre-tests_grp_auto_increment_delay_multiplex.bash b/test/tap/tests_grp_auto_increment_delay_multiplex/pre-tests_grp_auto_increment_delay_multiplex.bash new file mode 100755 index 0000000000..078fc5a265 --- /dev/null +++ b/test/tap/tests_grp_auto_increment_delay_multiplex/pre-tests_grp_auto_increment_delay_multiplex.bash @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +# make sure we have correct cwd +pushd $(dirname $0) + +# symlink all files from ../tests +for T in $(ls -1 ../tests/); do +# echo "ln -fsT ../tests/$T $T" + ln -fsT ../tests/$T $T +done + +# remove irelevant +#rm -f test_*-t diff --git a/test/tap/tests_grp_multiplexing/pre-tests_grp_multiplexing-proxysql.sql b/test/tap/tests_grp_multiplexing/pre-tests_grp_multiplexing-proxysql.sql new file mode 100644 index 0000000000..db2c00892f --- /dev/null +++ b/test/tap/tests_grp_multiplexing/pre-tests_grp_multiplexing-proxysql.sql @@ -0,0 +1,4 @@ +# proxysql settings +SET mysql-multiplexing='false'; +LOAD MYSQL VARIABLES TO RUNTIME; +SAVE MYSQL VARIABLES TO DISK; diff --git a/test/tap/tests_grp_multiplexing/pre-tests_grp_multiplexing.bash b/test/tap/tests_grp_multiplexing/pre-tests_grp_multiplexing.bash new file mode 100755 index 0000000000..078fc5a265 --- /dev/null +++ b/test/tap/tests_grp_multiplexing/pre-tests_grp_multiplexing.bash @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +# make sure we have correct cwd +pushd $(dirname $0) + +# symlink all files from ../tests +for T in $(ls -1 ../tests/); do +# echo "ln -fsT ../tests/$T $T" + ln -fsT ../tests/$T $T +done + +# remove irelevant +#rm -f test_*-t diff --git a/test/tap/tests_grp_query_digests/pre-tests_grp_query_digests-proxysql.sql b/test/tap/tests_grp_query_digests/pre-tests_grp_query_digests-proxysql.sql new file mode 100644 index 0000000000..4203e49f42 --- /dev/null +++ b/test/tap/tests_grp_query_digests/pre-tests_grp_query_digests-proxysql.sql @@ -0,0 +1,4 @@ +# proxysql settings +SET mysql-query_digests=0; +LOAD MYSQL VARIABLES TO RUNTIME; +SAVE MYSQL VARIABLES TO DISK; diff --git a/test/tap/tests_grp_query_digests/pre-tests_grp_query_digests.bash b/test/tap/tests_grp_query_digests/pre-tests_grp_query_digests.bash new file mode 100755 index 0000000000..078fc5a265 --- /dev/null +++ b/test/tap/tests_grp_query_digests/pre-tests_grp_query_digests.bash @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +# make sure we have correct cwd +pushd $(dirname $0) + +# symlink all files from ../tests +for T in $(ls -1 ../tests/); do +# echo "ln -fsT ../tests/$T $T" + ln -fsT ../tests/$T $T +done + +# remove irelevant +#rm -f test_*-t diff --git a/test/tap/tests_grp_query_digests_keep_comment/pre-tests_grp_query_digests_keep_comment-proxysql.sql b/test/tap/tests_grp_query_digests_keep_comment/pre-tests_grp_query_digests_keep_comment-proxysql.sql new file mode 100644 index 0000000000..975f759d71 --- /dev/null +++ b/test/tap/tests_grp_query_digests_keep_comment/pre-tests_grp_query_digests_keep_comment-proxysql.sql @@ -0,0 +1,4 @@ +# proxysql settings +SET mysql-query_digests_keep_comment=1; +LOAD MYSQL VARIABLES TO RUNTIME; +SAVE MYSQL VARIABLES TO DISK; diff --git a/test/tap/tests_grp_query_digests_keep_comment/pre-tests_grp_query_digests_keep_comment.bash b/test/tap/tests_grp_query_digests_keep_comment/pre-tests_grp_query_digests_keep_comment.bash new file mode 100755 index 0000000000..078fc5a265 --- /dev/null +++ b/test/tap/tests_grp_query_digests_keep_comment/pre-tests_grp_query_digests_keep_comment.bash @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +# make sure we have correct cwd +pushd $(dirname $0) + +# symlink all files from ../tests +for T in $(ls -1 ../tests/); do +# echo "ln -fsT ../tests/$T $T" + ln -fsT ../tests/$T $T +done + +# remove irelevant +#rm -f test_*-t From 87711456a5db53316d62a19e49b7888ee102a928 Mon Sep 17 00:00:00 2001 From: Chrysanthemum Swingler Date: Thu, 15 Aug 2024 11:28:33 -0500 Subject: [PATCH 15/62] Update Prometheus HELP statement for proxysql_connpool_conns_status --- lib/MySQL_HostGroups_Manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/MySQL_HostGroups_Manager.cpp b/lib/MySQL_HostGroups_Manager.cpp index 5bf4f80c5f..a97c0f03c8 100644 --- a/lib/MySQL_HostGroups_Manager.cpp +++ b/lib/MySQL_HostGroups_Manager.cpp @@ -569,7 +569,7 @@ hg_metrics_map = std::make_tuple( std::make_tuple ( p_hg_dyn_gauge::connection_pool_status, "proxysql_connpool_conns_status", - "The status of the backend server (1 - ONLINE, 2 - SHUNNED, 3 - OFFLINE_SOFT, 4 - OFFLINE_HARD).", + "The status of the backend server (1 - ONLINE, 2 - SHUNNED, 3 - OFFLINE_SOFT, 4 - OFFLINE_HARD, 5 - SHUNNED_REPLICATION_LAG).", metric_tags {} ) } From 2fe6a3e71b7950ee6bd22037f04f55b2e59e9b8b Mon Sep 17 00:00:00 2001 From: Miro Stauder Date: Mon, 19 Aug 2024 08:24:16 +0000 Subject: [PATCH 16/62] add json groups --- .../pre-proxysql.sql | 4 + test/tap/groups/gen-groups-json.bash | 15 ++ test/tap/groups/groups.json | 184 ++++++++++++++++++ test/tap/groups/multiplexing/pre-proxysql.sql | 4 + .../tap/groups/query_digests/pre-proxysql.sql | 4 + .../pre-proxysql.sql | 4 + 6 files changed, 215 insertions(+) create mode 100644 test/tap/groups/auto_increment_delay_multiplex/pre-proxysql.sql create mode 100755 test/tap/groups/gen-groups-json.bash create mode 100644 test/tap/groups/groups.json create mode 100644 test/tap/groups/multiplexing/pre-proxysql.sql create mode 100644 test/tap/groups/query_digests/pre-proxysql.sql create mode 100644 test/tap/groups/query_digests_keep_comment/pre-proxysql.sql diff --git a/test/tap/groups/auto_increment_delay_multiplex/pre-proxysql.sql b/test/tap/groups/auto_increment_delay_multiplex/pre-proxysql.sql new file mode 100644 index 0000000000..fcd19e67e2 --- /dev/null +++ b/test/tap/groups/auto_increment_delay_multiplex/pre-proxysql.sql @@ -0,0 +1,4 @@ +# proxysql settings +SET mysql-auto_increment_delay_multiplex=0; +LOAD MYSQL VARIABLES TO RUNTIME; +SAVE MYSQL VARIABLES TO DISK; diff --git a/test/tap/groups/gen-groups-json.bash b/test/tap/groups/gen-groups-json.bash new file mode 100755 index 0000000000..683662e6e7 --- /dev/null +++ b/test/tap/groups/gen-groups-json.bash @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +# make sure we have correct cwd +pushd $(dirname $0) > /dev/null + + +GRPS=$(echo $(ls -d */ | tr -d / | awk '{ print "\""$1"\"," }')) + +echo "{" > groups.json +ls -1 ../tests/*-t | sed 's|../tests/||' | awk '{ print " \""$0"\" : [ \"default\", __GRPS__ ]," }' >> groups.json +ls -1 ../tests_with_deps/deprecate_eof_support/*-t | sed 's|../tests_with_deps/deprecate_eof_support/||' | awk '{ print " \""$0"\" : [ \"default\", __GRPS__ ]," }' >> groups.json +sed -i '$ s/.$//' groups.json +echo "}" >> groups.json +sed -i "s/__GRPS__/${GRPS%,}/" groups.json + diff --git a/test/tap/groups/groups.json b/test/tap/groups/groups.json new file mode 100644 index 0000000000..e5e96765af --- /dev/null +++ b/test/tap/groups/groups.json @@ -0,0 +1,184 @@ +{ + "admin-listen_on_unix-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "admin_show_create_table-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "admin_show_fields_from-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "admin_show_table_status-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "admin_various_commands2-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "admin_various_commands3-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "admin_various_commands-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "basic-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "charset_unsigned_int-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "clickhouse_php_conn-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "envvars-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "firewall_commands1-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "kill_connection2-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "kill_connection3-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "kill_connection-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "max_connections_ff-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "multiple_prepared_statements-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "mysql-fast_forward-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "mysql_hostgroup_attributes-servers_defaults-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "mysql-init_connect-1-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "mysql-init_connect-2-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "mysql-last_insert_id-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "mysql-mirror1-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "mysql_reconnect_libmariadb-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "mysql_reconnect_libmysql-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "mysql-set_transaction-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "mysql-sql_log_bin-error-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "mysql_stmt_send_long_data_large-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "mysql_stmt_send_long_data-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "mysql-test_ssl_CA-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "prepare_statement_err3024_async-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "prepare_statement_err3024_libmysql-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "prepare_statement_err3024-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_1493-mixed_compression-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_1574-mariadb_read_stmt_execute_response-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_1574-stmt_metadata-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_2793-compression-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_3184-set_wait_timeout-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_3223-restapi_return_codes-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_3247-mycli_support-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_3273_ssl_con-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_3317-lock_hostgroup_special_queries-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_3327-process_query_set_status_flags-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_3371_prepared_statement_crash-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_3427-stmt_first_comment1-param-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_3427-stmt_first_comment1-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_3427-stmt_first_comment2-param-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_3427-stmt_first_comment2-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_3434-text_stmt_mix-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_3493-USE_with_comment-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_3504-change_user-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_3546-stmt_empty_params-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_3549-autocommit_tracking-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_3585-stmt_metadata-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_3591-restapi_num_fds-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_3603-stmt_metadata-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_3606-mysql_warnings-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_3625-sqlite3_session_client_error_limit-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_3690-admin_large_pkts-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_3765_ssl_pollout-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_3838-restapi_eintr-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_3847_admin_lock-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_3992_fast_forward_malformed_packet-mysqlsh-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_3992_fast_forward_malformed_packet-pymysql-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_3992_fast_forward_malformed_packet-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_4001-restapi_scripts_num_fds-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_4055_restapi-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_4072-show-warnings-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_4158_change_user-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_4264-commit_rollback-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_4300-dollar_quote_check-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_4399-stats_mysql_query_digest-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_4402-mysql_fields-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_4556-ssl_error_queue-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_compression_split_packets-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_fast_forward_split_packet-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_mariadb_stmt_store_result_async-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_mariadb_stmt_store_result_libmysql-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_mariadb_stmt_store_result-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_sql_calc_found_rows-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test__ssl_client_busy_wait-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_stmt_resultset_err_no_rows_libmysql-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_stmt_resultset_err_no_rows_php-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "reg_test_stmt_resultset_err_no_rows-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "savepoint-3749-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "savepoint-948-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "set_character_set-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "setparser_test2-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "setparser_test3-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "setparser_test-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "set_testing-240-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "set_testing-multi-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "set_testing-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "sqlite3-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "sqlite_autocommit-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "stmt_explain-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_admin_stats-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_auth_methods-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_auto_increment_delay_multiplex-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_backend_conn_ping-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_binlog_fast_forward-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_binlog_reader-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_binlog_reader_uses_previous_hostgroup-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_cacert_load_and_verify_duration-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_change_user-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_clickhouse_server_libmysql-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_clickhouse_server-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_client_limit_error-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_cluster1-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_cluster_sync_mysql_servers-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_cluster_sync-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_com_binlog_dump_enables_fast_forward-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_com_register_slave_enables_fast_forward-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_com_reset_connection_com_change_user-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_connection_annotation-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_csharp_connector_support-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_debug_filters-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_default_conn_collation-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_default_value_transaction_isolation_attr-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_default_value_transaction_isolation-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_digest_umap_aux-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_dns_cache-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_empty_query-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_enforce_autocommit_on_reads-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_filtered_set_statements-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_firewall-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_flagOUT_weight-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_flush_logs-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_format_utils-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_greeting_capabilities-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_gtid_forwarding-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_hostgroup_attributes_online_servers-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_keep_multiplexing_variables-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_log_last_insert_id-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_max_transaction_time-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_mysql_connect_retries_delay-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_mysql_connect_retries-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_mysql_hostgroup_attributes-1-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_mysql_query_digests_stages-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_mysql_query_rules_fast_routing-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_mysqlsh-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_prepare_statement_memory_usage-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_prometheus_metrics-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_ps_async-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_ps_hg_routing-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_ps_large_result-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_ps_no_store-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_query_cache_soft_ttl_pct-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_query_rules_fast_routing_algorithm-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_query_rules_routing-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_query_timeout-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_read_only_actions_offline_hard_servers-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_rw_binary_data-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_server_sess_status-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_session_status_flags-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_set_character_results-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_set_collation-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_simple_embedded_HTTP_server-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_sqlite3_from_unixtime-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_sqlite3_pass_exts-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_sqlite3_server_and_fast_routing-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_sqlite3_server-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_ssl_connect-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_ssl_fast_forward-1-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_ssl_fast_forward-2-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_ssl_fast_forward-3-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_ssl_large_query-1-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_ssl_large_query-2-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_stats_proxysql_message_metrics-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_thread_conn_dist-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_throttle_max_bytes_per_second_to_client-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_unshun_algorithm-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_unsupported_queries-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_warnings-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "test_wexecvp_syscall_failures-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "deprecate_eof_cache-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "eof_cache_mixed_flags-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "eof_conn_options_check-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "eof_fast_forward-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "eof_mixed_flags_queries-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "eof_packet_mixed_queries-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], + "ok_packet_mixed_queries-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ] +} diff --git a/test/tap/groups/multiplexing/pre-proxysql.sql b/test/tap/groups/multiplexing/pre-proxysql.sql new file mode 100644 index 0000000000..db2c00892f --- /dev/null +++ b/test/tap/groups/multiplexing/pre-proxysql.sql @@ -0,0 +1,4 @@ +# proxysql settings +SET mysql-multiplexing='false'; +LOAD MYSQL VARIABLES TO RUNTIME; +SAVE MYSQL VARIABLES TO DISK; diff --git a/test/tap/groups/query_digests/pre-proxysql.sql b/test/tap/groups/query_digests/pre-proxysql.sql new file mode 100644 index 0000000000..4203e49f42 --- /dev/null +++ b/test/tap/groups/query_digests/pre-proxysql.sql @@ -0,0 +1,4 @@ +# proxysql settings +SET mysql-query_digests=0; +LOAD MYSQL VARIABLES TO RUNTIME; +SAVE MYSQL VARIABLES TO DISK; diff --git a/test/tap/groups/query_digests_keep_comment/pre-proxysql.sql b/test/tap/groups/query_digests_keep_comment/pre-proxysql.sql new file mode 100644 index 0000000000..975f759d71 --- /dev/null +++ b/test/tap/groups/query_digests_keep_comment/pre-proxysql.sql @@ -0,0 +1,4 @@ +# proxysql settings +SET mysql-query_digests_keep_comment=1; +LOAD MYSQL VARIABLES TO RUNTIME; +SAVE MYSQL VARIABLES TO DISK; From e1f99e8bea2a45241a2dc31dea5e84fe5f8c5d7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Mon, 19 Aug 2024 17:48:54 +0200 Subject: [PATCH 17/62] Make logging of Galera nodes status conditional to 'mysql-hostgroup_manager_verbose' - Closes #4612 --- lib/MySQL_HostGroups_Manager.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/MySQL_HostGroups_Manager.cpp b/lib/MySQL_HostGroups_Manager.cpp index a97c0f03c8..c3e048f734 100644 --- a/lib/MySQL_HostGroups_Manager.cpp +++ b/lib/MySQL_HostGroups_Manager.cpp @@ -5062,7 +5062,13 @@ bool Galera_Info::update(int b, int r, int o, int mw, int mtb, bool _a, int _w, return ret; } +/** + * @brief Dumps to stderr the current info for the monitored Galera hosts ('Galera_Hosts_Map'). + * @details No action if `mysql_thread___hostgroup_manager_verbose=0`. + */ void print_galera_nodes_last_status() { + if (!mysql_thread___hostgroup_manager_verbose) return; + std::unique_ptr result { new SQLite3_result(13) }; result->add_column_definition(SQLITE_TEXT,"hostname"); From 096709ebbd8aadcf8a5989324ff4a237eb98145f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Mon, 19 Aug 2024 17:53:15 +0200 Subject: [PATCH 18/62] Make random latency on simulated Galera conns conditional Similar to what was previously done for AWS_AURORA. Reduces noise for cluster simulations. --- src/SQLite3_Server.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/SQLite3_Server.cpp b/src/SQLite3_Server.cpp index d4b678366b..fc349702c9 100644 --- a/src/SQLite3_Server.cpp +++ b/src/SQLite3_Server.cpp @@ -930,10 +930,12 @@ void SQLite3_Server_session_handler(MySQL_Session *sess, void *_pa, PtrSize_t *p if (resultset->rows_count == 0) { PROXY_TRACE(); } +#ifdef TEST_GALERA_RANDOM if (rand() % 20 == 0) { // randomly add some latency on 5% of the traffic sleep(2); } +#endif } #endif // TEST_GALERA #ifdef TEST_GROUPREP From 77235633175513ef88df3774634a872ece0abfae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Mon, 19 Aug 2024 16:40:23 +0000 Subject: [PATCH 19/62] Adding warning in case PROXY header is not accepted --- lib/mysql_data_stream.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/mysql_data_stream.cpp b/lib/mysql_data_stream.cpp index 9867601397..1a642ccafe 100644 --- a/lib/mysql_data_stream.cpp +++ b/lib/mysql_data_stream.cpp @@ -1150,12 +1150,14 @@ int MySQL_Data_Stream::buffer2array() { addr.addr = strdup(PROXY_info->source_address); addr.port = PROXY_info->source_port; } else { - // TODO: error handling - // maybe just generate a warning + if (addr.addr) { + proxy_warning("Unable to parse PROXY header from IP %s . Skipping PROXY header\n", addr.addr); + } } } else { // the PROXY header was not accepted - // TODO: error handling - // maybe just generate a warning + if (addr.addr) { + proxy_warning("Skipping PROXY header from IP %s because not matching mysql-proxy_protocol_networks. Skipping PROXY header\n", addr.addr); + } } From dbc51ab1130315d1bb13970f7e437333bc5c0293 Mon Sep 17 00:00:00 2001 From: Miro Stauder Date: Tue, 20 Aug 2024 07:36:10 +0000 Subject: [PATCH 20/62] remove unused files --- ..._grp_auto_increment_delay_multiplex-proxysql.sql | 4 ---- ...re-tests_grp_auto_increment_delay_multiplex.bash | 13 ------------- .../pre-tests_grp_multiplexing-proxysql.sql | 4 ---- .../pre-tests_grp_multiplexing.bash | 13 ------------- .../pre-tests_grp_query_digests-proxysql.sql | 4 ---- .../pre-tests_grp_query_digests.bash | 13 ------------- ...ests_grp_query_digests_keep_comment-proxysql.sql | 4 ---- .../pre-tests_grp_query_digests_keep_comment.bash | 13 ------------- 8 files changed, 68 deletions(-) delete mode 100644 test/tap/tests_grp_auto_increment_delay_multiplex/pre-tests_grp_auto_increment_delay_multiplex-proxysql.sql delete mode 100755 test/tap/tests_grp_auto_increment_delay_multiplex/pre-tests_grp_auto_increment_delay_multiplex.bash delete mode 100644 test/tap/tests_grp_multiplexing/pre-tests_grp_multiplexing-proxysql.sql delete mode 100755 test/tap/tests_grp_multiplexing/pre-tests_grp_multiplexing.bash delete mode 100644 test/tap/tests_grp_query_digests/pre-tests_grp_query_digests-proxysql.sql delete mode 100755 test/tap/tests_grp_query_digests/pre-tests_grp_query_digests.bash delete mode 100644 test/tap/tests_grp_query_digests_keep_comment/pre-tests_grp_query_digests_keep_comment-proxysql.sql delete mode 100755 test/tap/tests_grp_query_digests_keep_comment/pre-tests_grp_query_digests_keep_comment.bash diff --git a/test/tap/tests_grp_auto_increment_delay_multiplex/pre-tests_grp_auto_increment_delay_multiplex-proxysql.sql b/test/tap/tests_grp_auto_increment_delay_multiplex/pre-tests_grp_auto_increment_delay_multiplex-proxysql.sql deleted file mode 100644 index fcd19e67e2..0000000000 --- a/test/tap/tests_grp_auto_increment_delay_multiplex/pre-tests_grp_auto_increment_delay_multiplex-proxysql.sql +++ /dev/null @@ -1,4 +0,0 @@ -# proxysql settings -SET mysql-auto_increment_delay_multiplex=0; -LOAD MYSQL VARIABLES TO RUNTIME; -SAVE MYSQL VARIABLES TO DISK; diff --git a/test/tap/tests_grp_auto_increment_delay_multiplex/pre-tests_grp_auto_increment_delay_multiplex.bash b/test/tap/tests_grp_auto_increment_delay_multiplex/pre-tests_grp_auto_increment_delay_multiplex.bash deleted file mode 100755 index 078fc5a265..0000000000 --- a/test/tap/tests_grp_auto_increment_delay_multiplex/pre-tests_grp_auto_increment_delay_multiplex.bash +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash - -# make sure we have correct cwd -pushd $(dirname $0) - -# symlink all files from ../tests -for T in $(ls -1 ../tests/); do -# echo "ln -fsT ../tests/$T $T" - ln -fsT ../tests/$T $T -done - -# remove irelevant -#rm -f test_*-t diff --git a/test/tap/tests_grp_multiplexing/pre-tests_grp_multiplexing-proxysql.sql b/test/tap/tests_grp_multiplexing/pre-tests_grp_multiplexing-proxysql.sql deleted file mode 100644 index db2c00892f..0000000000 --- a/test/tap/tests_grp_multiplexing/pre-tests_grp_multiplexing-proxysql.sql +++ /dev/null @@ -1,4 +0,0 @@ -# proxysql settings -SET mysql-multiplexing='false'; -LOAD MYSQL VARIABLES TO RUNTIME; -SAVE MYSQL VARIABLES TO DISK; diff --git a/test/tap/tests_grp_multiplexing/pre-tests_grp_multiplexing.bash b/test/tap/tests_grp_multiplexing/pre-tests_grp_multiplexing.bash deleted file mode 100755 index 078fc5a265..0000000000 --- a/test/tap/tests_grp_multiplexing/pre-tests_grp_multiplexing.bash +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash - -# make sure we have correct cwd -pushd $(dirname $0) - -# symlink all files from ../tests -for T in $(ls -1 ../tests/); do -# echo "ln -fsT ../tests/$T $T" - ln -fsT ../tests/$T $T -done - -# remove irelevant -#rm -f test_*-t diff --git a/test/tap/tests_grp_query_digests/pre-tests_grp_query_digests-proxysql.sql b/test/tap/tests_grp_query_digests/pre-tests_grp_query_digests-proxysql.sql deleted file mode 100644 index 4203e49f42..0000000000 --- a/test/tap/tests_grp_query_digests/pre-tests_grp_query_digests-proxysql.sql +++ /dev/null @@ -1,4 +0,0 @@ -# proxysql settings -SET mysql-query_digests=0; -LOAD MYSQL VARIABLES TO RUNTIME; -SAVE MYSQL VARIABLES TO DISK; diff --git a/test/tap/tests_grp_query_digests/pre-tests_grp_query_digests.bash b/test/tap/tests_grp_query_digests/pre-tests_grp_query_digests.bash deleted file mode 100755 index 078fc5a265..0000000000 --- a/test/tap/tests_grp_query_digests/pre-tests_grp_query_digests.bash +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash - -# make sure we have correct cwd -pushd $(dirname $0) - -# symlink all files from ../tests -for T in $(ls -1 ../tests/); do -# echo "ln -fsT ../tests/$T $T" - ln -fsT ../tests/$T $T -done - -# remove irelevant -#rm -f test_*-t diff --git a/test/tap/tests_grp_query_digests_keep_comment/pre-tests_grp_query_digests_keep_comment-proxysql.sql b/test/tap/tests_grp_query_digests_keep_comment/pre-tests_grp_query_digests_keep_comment-proxysql.sql deleted file mode 100644 index 975f759d71..0000000000 --- a/test/tap/tests_grp_query_digests_keep_comment/pre-tests_grp_query_digests_keep_comment-proxysql.sql +++ /dev/null @@ -1,4 +0,0 @@ -# proxysql settings -SET mysql-query_digests_keep_comment=1; -LOAD MYSQL VARIABLES TO RUNTIME; -SAVE MYSQL VARIABLES TO DISK; diff --git a/test/tap/tests_grp_query_digests_keep_comment/pre-tests_grp_query_digests_keep_comment.bash b/test/tap/tests_grp_query_digests_keep_comment/pre-tests_grp_query_digests_keep_comment.bash deleted file mode 100755 index 078fc5a265..0000000000 --- a/test/tap/tests_grp_query_digests_keep_comment/pre-tests_grp_query_digests_keep_comment.bash +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash - -# make sure we have correct cwd -pushd $(dirname $0) - -# symlink all files from ../tests -for T in $(ls -1 ../tests/); do -# echo "ln -fsT ../tests/$T $T" - ln -fsT ../tests/$T $T -done - -# remove irelevant -#rm -f test_*-t From c512f904a0e3ada4affaf9571833a662c0c608ac Mon Sep 17 00:00:00 2001 From: Miro Stauder Date: Tue, 20 Aug 2024 09:25:48 +0000 Subject: [PATCH 21/62] rename groups more decriptive --- test/tap/groups/groups.json | 364 +++++++++--------- .../pre-proxysql.sql | 0 .../pre-proxysql.sql | 0 .../pre-proxysql.sql | 0 .../pre-proxysql.sql | 0 5 files changed, 182 insertions(+), 182 deletions(-) rename test/tap/groups/{auto_increment_delay_multiplex => mysql-auto_increment_delay_multiplex=0}/pre-proxysql.sql (100%) rename test/tap/groups/{multiplexing => mysql-multiplexing=false}/pre-proxysql.sql (100%) rename test/tap/groups/{query_digests => mysql-query_digests=0}/pre-proxysql.sql (100%) rename test/tap/groups/{query_digests_keep_comment => mysql-query_digests_keep_comment=1}/pre-proxysql.sql (100%) diff --git a/test/tap/groups/groups.json b/test/tap/groups/groups.json index e5e96765af..64c1fa8d55 100644 --- a/test/tap/groups/groups.json +++ b/test/tap/groups/groups.json @@ -1,184 +1,184 @@ { - "admin-listen_on_unix-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "admin_show_create_table-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "admin_show_fields_from-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "admin_show_table_status-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "admin_various_commands2-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "admin_various_commands3-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "admin_various_commands-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "basic-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "charset_unsigned_int-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "clickhouse_php_conn-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "envvars-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "firewall_commands1-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "kill_connection2-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "kill_connection3-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "kill_connection-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "max_connections_ff-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "multiple_prepared_statements-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "mysql-fast_forward-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "mysql_hostgroup_attributes-servers_defaults-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "mysql-init_connect-1-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "mysql-init_connect-2-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "mysql-last_insert_id-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "mysql-mirror1-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "mysql_reconnect_libmariadb-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "mysql_reconnect_libmysql-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "mysql-set_transaction-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "mysql-sql_log_bin-error-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "mysql_stmt_send_long_data_large-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "mysql_stmt_send_long_data-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "mysql-test_ssl_CA-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "prepare_statement_err3024_async-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "prepare_statement_err3024_libmysql-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "prepare_statement_err3024-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_1493-mixed_compression-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_1574-mariadb_read_stmt_execute_response-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_1574-stmt_metadata-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_2793-compression-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_3184-set_wait_timeout-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_3223-restapi_return_codes-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_3247-mycli_support-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_3273_ssl_con-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_3317-lock_hostgroup_special_queries-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_3327-process_query_set_status_flags-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_3371_prepared_statement_crash-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_3427-stmt_first_comment1-param-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_3427-stmt_first_comment1-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_3427-stmt_first_comment2-param-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_3427-stmt_first_comment2-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_3434-text_stmt_mix-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_3493-USE_with_comment-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_3504-change_user-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_3546-stmt_empty_params-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_3549-autocommit_tracking-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_3585-stmt_metadata-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_3591-restapi_num_fds-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_3603-stmt_metadata-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_3606-mysql_warnings-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_3625-sqlite3_session_client_error_limit-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_3690-admin_large_pkts-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_3765_ssl_pollout-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_3838-restapi_eintr-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_3847_admin_lock-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_3992_fast_forward_malformed_packet-mysqlsh-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_3992_fast_forward_malformed_packet-pymysql-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_3992_fast_forward_malformed_packet-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_4001-restapi_scripts_num_fds-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_4055_restapi-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_4072-show-warnings-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_4158_change_user-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_4264-commit_rollback-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_4300-dollar_quote_check-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_4399-stats_mysql_query_digest-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_4402-mysql_fields-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_4556-ssl_error_queue-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_compression_split_packets-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_fast_forward_split_packet-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_mariadb_stmt_store_result_async-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_mariadb_stmt_store_result_libmysql-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_mariadb_stmt_store_result-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_sql_calc_found_rows-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test__ssl_client_busy_wait-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_stmt_resultset_err_no_rows_libmysql-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_stmt_resultset_err_no_rows_php-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "reg_test_stmt_resultset_err_no_rows-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "savepoint-3749-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "savepoint-948-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "set_character_set-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "setparser_test2-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "setparser_test3-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "setparser_test-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "set_testing-240-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "set_testing-multi-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "set_testing-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "sqlite3-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "sqlite_autocommit-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "stmt_explain-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_admin_stats-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_auth_methods-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_auto_increment_delay_multiplex-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_backend_conn_ping-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_binlog_fast_forward-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_binlog_reader-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_binlog_reader_uses_previous_hostgroup-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_cacert_load_and_verify_duration-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_change_user-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_clickhouse_server_libmysql-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_clickhouse_server-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_client_limit_error-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_cluster1-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_cluster_sync_mysql_servers-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_cluster_sync-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_com_binlog_dump_enables_fast_forward-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_com_register_slave_enables_fast_forward-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_com_reset_connection_com_change_user-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_connection_annotation-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_csharp_connector_support-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_debug_filters-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_default_conn_collation-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_default_value_transaction_isolation_attr-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_default_value_transaction_isolation-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_digest_umap_aux-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_dns_cache-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_empty_query-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_enforce_autocommit_on_reads-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_filtered_set_statements-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_firewall-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_flagOUT_weight-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_flush_logs-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_format_utils-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_greeting_capabilities-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_gtid_forwarding-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_hostgroup_attributes_online_servers-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_keep_multiplexing_variables-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_log_last_insert_id-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_max_transaction_time-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_mysql_connect_retries_delay-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_mysql_connect_retries-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_mysql_hostgroup_attributes-1-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_mysql_query_digests_stages-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_mysql_query_rules_fast_routing-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_mysqlsh-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_prepare_statement_memory_usage-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_prometheus_metrics-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_ps_async-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_ps_hg_routing-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_ps_large_result-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_ps_no_store-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_query_cache_soft_ttl_pct-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_query_rules_fast_routing_algorithm-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_query_rules_routing-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_query_timeout-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_read_only_actions_offline_hard_servers-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_rw_binary_data-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_server_sess_status-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_session_status_flags-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_set_character_results-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_set_collation-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_simple_embedded_HTTP_server-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_sqlite3_from_unixtime-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_sqlite3_pass_exts-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_sqlite3_server_and_fast_routing-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_sqlite3_server-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_ssl_connect-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_ssl_fast_forward-1-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_ssl_fast_forward-2-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_ssl_fast_forward-3-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_ssl_large_query-1-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_ssl_large_query-2-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_stats_proxysql_message_metrics-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_thread_conn_dist-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_throttle_max_bytes_per_second_to_client-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_unshun_algorithm-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_unsupported_queries-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_warnings-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "test_wexecvp_syscall_failures-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "deprecate_eof_cache-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "eof_cache_mixed_flags-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "eof_conn_options_check-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "eof_fast_forward-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "eof_mixed_flags_queries-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "eof_packet_mixed_queries-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ], - "ok_packet_mixed_queries-t" : [ "default", "auto_increment_delay_multiplex", "multiplexing", "query_digests", "query_digests_keep_comment" ] + "admin-listen_on_unix-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "admin_show_create_table-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "admin_show_fields_from-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "admin_show_table_status-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "admin_various_commands2-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "admin_various_commands3-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "admin_various_commands-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "basic-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "charset_unsigned_int-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "clickhouse_php_conn-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "envvars-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "firewall_commands1-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "kill_connection2-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "kill_connection3-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "kill_connection-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "max_connections_ff-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "multiple_prepared_statements-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "mysql-fast_forward-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "mysql_hostgroup_attributes-servers_defaults-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "mysql-init_connect-1-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "mysql-init_connect-2-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "mysql-last_insert_id-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "mysql-mirror1-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "mysql_reconnect_libmariadb-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "mysql_reconnect_libmysql-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "mysql-set_transaction-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "mysql-sql_log_bin-error-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "mysql_stmt_send_long_data_large-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "mysql_stmt_send_long_data-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "mysql-test_ssl_CA-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "prepare_statement_err3024_async-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "prepare_statement_err3024_libmysql-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "prepare_statement_err3024-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_1493-mixed_compression-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_1574-mariadb_read_stmt_execute_response-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_1574-stmt_metadata-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_2793-compression-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_3184-set_wait_timeout-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_3223-restapi_return_codes-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_3247-mycli_support-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_3273_ssl_con-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_3317-lock_hostgroup_special_queries-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_3327-process_query_set_status_flags-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_3371_prepared_statement_crash-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_3427-stmt_first_comment1-param-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_3427-stmt_first_comment1-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_3427-stmt_first_comment2-param-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_3427-stmt_first_comment2-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_3434-text_stmt_mix-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_3493-USE_with_comment-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_3504-change_user-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_3546-stmt_empty_params-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_3549-autocommit_tracking-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_3585-stmt_metadata-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_3591-restapi_num_fds-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_3603-stmt_metadata-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_3606-mysql_warnings-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_3625-sqlite3_session_client_error_limit-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_3690-admin_large_pkts-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_3765_ssl_pollout-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_3838-restapi_eintr-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_3847_admin_lock-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_3992_fast_forward_malformed_packet-mysqlsh-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_3992_fast_forward_malformed_packet-pymysql-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_3992_fast_forward_malformed_packet-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_4001-restapi_scripts_num_fds-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_4055_restapi-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_4072-show-warnings-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_4158_change_user-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_4264-commit_rollback-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_4300-dollar_quote_check-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_4399-stats_mysql_query_digest-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_4402-mysql_fields-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_4556-ssl_error_queue-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_compression_split_packets-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_fast_forward_split_packet-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_mariadb_stmt_store_result_async-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_mariadb_stmt_store_result_libmysql-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_mariadb_stmt_store_result-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_sql_calc_found_rows-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test__ssl_client_busy_wait-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_stmt_resultset_err_no_rows_libmysql-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_stmt_resultset_err_no_rows_php-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "reg_test_stmt_resultset_err_no_rows-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "savepoint-3749-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "savepoint-948-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "set_character_set-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "setparser_test2-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "setparser_test3-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "setparser_test-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "set_testing-240-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "set_testing-multi-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "set_testing-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "sqlite3-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "sqlite_autocommit-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "stmt_explain-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_admin_stats-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_auth_methods-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_auto_increment_delay_multiplex-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_backend_conn_ping-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_binlog_fast_forward-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_binlog_reader-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_binlog_reader_uses_previous_hostgroup-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_cacert_load_and_verify_duration-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_change_user-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_clickhouse_server_libmysql-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_clickhouse_server-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_client_limit_error-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_cluster1-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_cluster_sync_mysql_servers-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_cluster_sync-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_com_binlog_dump_enables_fast_forward-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_com_register_slave_enables_fast_forward-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_com_reset_connection_com_change_user-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_connection_annotation-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_csharp_connector_support-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_debug_filters-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_default_conn_collation-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_default_value_transaction_isolation_attr-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_default_value_transaction_isolation-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_digest_umap_aux-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_dns_cache-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_empty_query-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_enforce_autocommit_on_reads-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_filtered_set_statements-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_firewall-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_flagOUT_weight-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_flush_logs-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_format_utils-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_greeting_capabilities-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_gtid_forwarding-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_hostgroup_attributes_online_servers-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_keep_multiplexing_variables-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_log_last_insert_id-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_max_transaction_time-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_mysql_connect_retries_delay-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_mysql_connect_retries-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_mysql_hostgroup_attributes-1-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_mysql_query_digests_stages-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_mysql_query_rules_fast_routing-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_mysqlsh-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_prepare_statement_memory_usage-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_prometheus_metrics-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_ps_async-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_ps_hg_routing-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_ps_large_result-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_ps_no_store-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_query_cache_soft_ttl_pct-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_query_rules_fast_routing_algorithm-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_query_rules_routing-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_query_timeout-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_read_only_actions_offline_hard_servers-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_rw_binary_data-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_server_sess_status-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_session_status_flags-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_set_character_results-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_set_collation-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_simple_embedded_HTTP_server-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_sqlite3_from_unixtime-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_sqlite3_pass_exts-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_sqlite3_server_and_fast_routing-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_sqlite3_server-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_ssl_connect-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_ssl_fast_forward-1-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_ssl_fast_forward-2-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_ssl_fast_forward-3-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_ssl_large_query-1-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_ssl_large_query-2-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_stats_proxysql_message_metrics-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_thread_conn_dist-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_throttle_max_bytes_per_second_to_client-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_unshun_algorithm-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_unsupported_queries-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_warnings-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "test_wexecvp_syscall_failures-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "deprecate_eof_cache-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "eof_cache_mixed_flags-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "eof_conn_options_check-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "eof_fast_forward-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "eof_mixed_flags_queries-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "eof_packet_mixed_queries-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ], + "ok_packet_mixed_queries-t" : [ "default", "mysql-auto_increment_delay_multiplex=0", "mysql-multiplexing=false", "mysql-query_digests=0", "mysql-query_digests_keep_comment=1" ] } diff --git a/test/tap/groups/auto_increment_delay_multiplex/pre-proxysql.sql b/test/tap/groups/mysql-auto_increment_delay_multiplex=0/pre-proxysql.sql similarity index 100% rename from test/tap/groups/auto_increment_delay_multiplex/pre-proxysql.sql rename to test/tap/groups/mysql-auto_increment_delay_multiplex=0/pre-proxysql.sql diff --git a/test/tap/groups/multiplexing/pre-proxysql.sql b/test/tap/groups/mysql-multiplexing=false/pre-proxysql.sql similarity index 100% rename from test/tap/groups/multiplexing/pre-proxysql.sql rename to test/tap/groups/mysql-multiplexing=false/pre-proxysql.sql diff --git a/test/tap/groups/query_digests/pre-proxysql.sql b/test/tap/groups/mysql-query_digests=0/pre-proxysql.sql similarity index 100% rename from test/tap/groups/query_digests/pre-proxysql.sql rename to test/tap/groups/mysql-query_digests=0/pre-proxysql.sql diff --git a/test/tap/groups/query_digests_keep_comment/pre-proxysql.sql b/test/tap/groups/mysql-query_digests_keep_comment=1/pre-proxysql.sql similarity index 100% rename from test/tap/groups/query_digests_keep_comment/pre-proxysql.sql rename to test/tap/groups/mysql-query_digests_keep_comment=1/pre-proxysql.sql From ec6e461dd97117485a2ea1c4fbb074f755a26fbf Mon Sep 17 00:00:00 2001 From: Miro Stauder Date: Tue, 20 Aug 2024 11:49:13 +0000 Subject: [PATCH 22/62] build packages with versioned docker images --- docker-compose.yml | 60 +++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index f786401bff..8ba0f7c19b 100755 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,7 +20,7 @@ services: centos7_build: extends: service: _build - image: proxysql/packaging:build-centos7 + image: proxysql/packaging:build-centos7-v2.6.0 volumes: - ./docker/images/proxysql/rhel-compliant/rpmmacros/rpmbuild/:/root/rpmbuild/ - ./docker/images/proxysql/rhel-compliant/rpmmacros/.rpmmacros:/root/.rpmmacros @@ -40,7 +40,7 @@ services: centos8_build: extends: service: _build - image: proxysql/packaging:build-centos8 + image: proxysql/packaging:build-centos8-v2.6.0 volumes: - ./docker/images/proxysql/rhel-compliant/rpmmacros/rpmbuild/:/root/rpmbuild/ - ./docker/images/proxysql/rhel-compliant/rpmmacros/.rpmmacros:/root/.rpmmacros @@ -53,7 +53,7 @@ services: centos8_clang_build: extends: service: centos8_build - image: proxysql/packaging:build-clang-centos8 + image: proxysql/packaging:build-clang-centos8-v2.6.0 environment: - PKG_RELEASE=centos8-clang @@ -69,7 +69,7 @@ services: centos9_build: extends: service: _build - image: proxysql/packaging:build-centos9 + image: proxysql/packaging:build-centos9-v2.6.0 volumes: - ./docker/images/proxysql/rhel-compliant/rpmmacros/rpmbuild/:/root/rpmbuild/ - ./docker/images/proxysql/rhel-compliant/rpmmacros/.rpmmacros:/root/.rpmmacros @@ -82,7 +82,7 @@ services: centos9_clang_build: extends: service: centos9_build - image: proxysql/packaging:build-clang-centos9 + image: proxysql/packaging:build-clang-centos9-v2.6.0 environment: - PKG_RELEASE=centos9-clang @@ -98,7 +98,7 @@ services: fedora38_build: extends: service: _build - image: proxysql/packaging:build-fedora38 + image: proxysql/packaging:build-fedora38-v2.6.0 volumes: - ./docker/images/proxysql/rhel-compliant/rpmmacros/rpmbuild/:/root/rpmbuild/ - ./docker/images/proxysql/rhel-compliant/rpmmacros/.rpmmacros:/root/.rpmmacros @@ -111,7 +111,7 @@ services: fedora38_clang_build: extends: service: fedora38_build - image: proxysql/packaging:build-clang-fedora38 + image: proxysql/packaging:build-clang-fedora38-v2.6.0 environment: - PKG_RELEASE=fedora38-clang @@ -126,7 +126,7 @@ services: fedora39_build: extends: service: _build - image: proxysql/packaging:build-fedora39 + image: proxysql/packaging:build-fedora39-v2.6.0 volumes: - ./docker/images/proxysql/rhel-compliant/rpmmacros/rpmbuild/:/root/rpmbuild/ - ./docker/images/proxysql/rhel-compliant/rpmmacros/.rpmmacros:/root/.rpmmacros @@ -139,7 +139,7 @@ services: fedora39_clang_build: extends: service: fedora39_build - image: proxysql/packaging:build-clang-fedora39 + image: proxysql/packaging:build-clang-fedora39-v2.6.0 environment: - PKG_RELEASE=fedora39-clang @@ -154,7 +154,7 @@ services: fedora40_build: extends: service: _build - image: proxysql/packaging:build-fedora40 + image: proxysql/packaging:build-fedora40-v2.6.4 volumes: - ./docker/images/proxysql/rhel-compliant/rpmmacros/rpmbuild/:/root/rpmbuild/ - ./docker/images/proxysql/rhel-compliant/rpmmacros/.rpmmacros:/root/.rpmmacros @@ -167,7 +167,7 @@ services: fedora40_clang_build: extends: service: fedora40_build - image: proxysql/packaging:build-clang-fedora40 + image: proxysql/packaging:build-clang-fedora40-v2.6.4 environment: - PKG_RELEASE=fedora40-clang @@ -183,7 +183,7 @@ services: debian10_build: extends: service: _build - image: proxysql/packaging:build-debian10 + image: proxysql/packaging:build-debian10-v2.6.0 volumes: - ./docker/images/proxysql/deb-compliant/latest-package/ctl/:/root/ctl/ - ./docker/images/proxysql/deb-compliant/entrypoint/:/opt/entrypoint/ @@ -203,7 +203,7 @@ services: debian11_build: extends: service: _build - image: proxysql/packaging:build-debian11 + image: proxysql/packaging:build-debian11-v2.6.0 volumes: - ./docker/images/proxysql/deb-compliant/latest-package/ctl/:/root/ctl/ - ./docker/images/proxysql/deb-compliant/entrypoint/:/opt/entrypoint/ @@ -215,7 +215,7 @@ services: debian11_clang_build: extends: service: debian11_build - image: proxysql/packaging:build-clang-debian11 + image: proxysql/packaging:build-clang-debian11-v2.6.0 environment: - PKG_RELEASE=debian11-clang @@ -230,7 +230,7 @@ services: debian12_build: extends: service: _build - image: proxysql/packaging:build-debian12 + image: proxysql/packaging:build-debian12-v2.6.0 volumes: - ./docker/images/proxysql/deb-compliant/latest-package/ctl/:/root/ctl/ - ./docker/images/proxysql/deb-compliant/entrypoint/:/opt/entrypoint/ @@ -242,7 +242,7 @@ services: debian12_clang_build: extends: service: debian12_build - image: proxysql/packaging:build-clang-debian12 + image: proxysql/packaging:build-clang-debian12-v2.6.0 environment: - PKG_RELEASE=debian12-clang @@ -258,7 +258,7 @@ services: ubuntu16_build: extends: service: _build - image: proxysql/packaging:build-ubuntu16 + image: proxysql/packaging:build-ubuntu16-v2.6.0 volumes: - ./docker/images/proxysql/deb-compliant/pre-systemd/ctl/:/root/ctl/ - ./docker/images/proxysql/deb-compliant/entrypoint/:/opt/entrypoint/ @@ -277,7 +277,7 @@ services: ubuntu18_build: extends: service: _build - image: proxysql/packaging:build-ubuntu18 + image: proxysql/packaging:build-ubuntu18-v2.6.0 volumes: - ./docker/images/proxysql/deb-compliant/latest-package/ctl/:/root/ctl/ - ./docker/images/proxysql/deb-compliant/entrypoint/:/opt/entrypoint/ @@ -297,7 +297,7 @@ services: ubuntu20_build: extends: service: _build - image: proxysql/packaging:build-ubuntu20 + image: proxysql/packaging:build-ubuntu20-v2.6.0 volumes: - ./docker/images/proxysql/deb-compliant/latest-package/ctl/:/root/ctl/ - ./docker/images/proxysql/deb-compliant/entrypoint/:/opt/entrypoint/ @@ -309,7 +309,7 @@ services: ubuntu20_clang_build: extends: service: ubuntu20_build - image: proxysql/packaging:build-clang-ubuntu20 + image: proxysql/packaging:build-clang-ubuntu20-v2.6.0 environment: - PKG_RELEASE=ubuntu20-clang @@ -324,7 +324,7 @@ services: ubuntu22_build: extends: service: _build - image: proxysql/packaging:build-ubuntu22 + image: proxysql/packaging:build-ubuntu22-v2.6.1 volumes: - ./docker/images/proxysql/deb-compliant/latest-package/ctl/:/root/ctl/ - ./docker/images/proxysql/deb-compliant/entrypoint/:/opt/entrypoint/ @@ -336,7 +336,7 @@ services: ubuntu22_clang_build: extends: service: ubuntu22_build - image: proxysql/packaging:build-clang-ubuntu22 + image: proxysql/packaging:build-clang-ubuntu22-v2.6.1 environment: - PKG_RELEASE=ubuntu22-clang @@ -351,7 +351,7 @@ services: ubuntu24_build: extends: service: _build - image: proxysql/packaging:build-ubuntu24 + image: proxysql/packaging:build-ubuntu24-v2.6.4 volumes: - ./docker/images/proxysql/deb-compliant/latest-package/ctl/:/root/ctl/ - ./docker/images/proxysql/deb-compliant/entrypoint/:/opt/entrypoint/ @@ -363,7 +363,7 @@ services: ubuntu24_clang_build: extends: service: ubuntu24_build - image: proxysql/packaging:build-clang-ubuntu24 + image: proxysql/packaging:build-clang-ubuntu24-v2.6.4 environment: - PKG_RELEASE=ubuntu24-clang @@ -379,7 +379,7 @@ services: opensuse15_build: extends: service: _build - image: proxysql/packaging:build-opensuse15 + image: proxysql/packaging:build-opensuse15-v2.6.0 volumes: - ./docker/images/proxysql/suse-compliant/rpmmacros/rpmbuild/:/root/rpmbuild/ - ./docker/images/proxysql/suse-compliant/rpmmacros/.rpmmacros:/root/.rpmmacros @@ -392,7 +392,7 @@ services: opensuse15_clang_build: extends: service: opensuse15_build - image: proxysql/packaging:build-clang-opensuse15 + image: proxysql/packaging:build-clang-opensuse15-v2.6.0 environment: - PKG_RELEASE=opensuse15-clang @@ -408,7 +408,7 @@ services: almalinux8_build: extends: service: _build - image: proxysql/packaging:build-almalinux8 + image: proxysql/packaging:build-almalinux8-v2.6.0 volumes: - ./docker/images/proxysql/rhel-compliant/rpmmacros/rpmbuild/:/root/rpmbuild/ - ./docker/images/proxysql/rhel-compliant/rpmmacros/.rpmmacros:/root/.rpmmacros @@ -421,7 +421,7 @@ services: almalinux8_clang_build: extends: service: almalinux8_build - image: proxysql/packaging:build-clang-almalinux8 + image: proxysql/packaging:build-clang-almalinux8-v2.6.0 environment: - PKG_RELEASE=almalinux8-clang @@ -436,7 +436,7 @@ services: almalinux9_build: extends: service: _build - image: proxysql/packaging:build-almalinux9 + image: proxysql/packaging:build-almalinux9-v2.6.0 volumes: - ./docker/images/proxysql/rhel-compliant/rpmmacros/rpmbuild/:/root/rpmbuild/ - ./docker/images/proxysql/rhel-compliant/rpmmacros/.rpmmacros:/root/.rpmmacros @@ -449,7 +449,7 @@ services: almalinux9_clang_build: extends: service: almalinux9_build - image: proxysql/packaging:build-clang-almalinux9 + image: proxysql/packaging:build-clang-almalinux9-v2.6.0 environment: - PKG_RELEASE=almalinux9-clang From 8a93882d1dae98274c2f44752c10df05ce55035b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Tue, 20 Aug 2024 18:45:43 +0200 Subject: [PATCH 23/62] Fix assert on COM_CHANGE_USER with hashed pass for 'caching_sha2_password' For now, we always reply with an auth failure until 'Auth Switch Support' is added for 'caching_sha2_password'. --- lib/MySQL_Protocol.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/MySQL_Protocol.cpp b/lib/MySQL_Protocol.cpp index 5b02b562a6..5392a229eb 100644 --- a/lib/MySQL_Protocol.cpp +++ b/lib/MySQL_Protocol.cpp @@ -1208,9 +1208,19 @@ bool MySQL_Protocol::verify_user_pass( ret=true; } } else if (auth_plugin_id == 2) { // caching_sha2_password - // FIXME: not supported yet - // we assert() here because auth_plugin_id should never be 3 unless it is fully implemented - assert(0); + // ## FIXME: Current limitation + // For now, if a 'COM_CHANGE_USER' is received with a hashed 'password' for + // 'caching_sha2_password', we fail to authenticate. This is part of the broader limitation of + // 'Auth Switch' support for 'caching_sha2_password' (See + // https://proxysql.com/documentation/authentication-methods/#limitations). + // + // ## Future Fix + // The right approach is to perform an 'Auth Switch Request' or to accept the hash if the clear + // text password is already known and the hash can be verified. This processing is now performed + // in 'process_pkt_COM_CHANGE_USER', state at which it should be determine if we can accept the + // hash, or if we should prepare the state machine for a 'Auth Switch Request'. Progress for this + // is tracked in https://github.com/sysown/proxysql/issues/4618. + ret = false; } else { ret = false; } From 50a95d40807999e931842dbed516936af9a77582 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Tue, 20 Aug 2024 14:36:41 +0200 Subject: [PATCH 24/62] Fix value on first fetch for connpool prometheus metrics The initial value for metrics using 'p_update_connection_pool_update_*' helpers were missing. This only affects to the first metrics fetch, during the metric creation on the internal maps, subsequent fetches will find the already created metric and updated the value properly. As real counters are internal, this doesn't affect the correctness of the value in subsequent fetches. --- lib/MySQL_HostGroups_Manager.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/MySQL_HostGroups_Manager.cpp b/lib/MySQL_HostGroups_Manager.cpp index a97c0f03c8..416d1c181f 100644 --- a/lib/MySQL_HostGroups_Manager.cpp +++ b/lib/MySQL_HostGroups_Manager.cpp @@ -3314,12 +3314,13 @@ void MySQL_HostGroups_Manager::p_update_connection_pool_update_counter( counter_id->second->Increment(value - cur_val); } else { auto& new_counter = status.p_dyn_counter_array[idx]; - m_map.insert( + const auto& new_counter_it = m_map.insert( { endpoint_id, std::addressof(new_counter->Add(labels)) } ); + new_counter_it.first->second->Increment(value); } } @@ -3332,12 +3333,13 @@ void MySQL_HostGroups_Manager::p_update_connection_pool_update_gauge( counter_id->second->Set(value); } else { auto& new_counter = status.p_dyn_gauge_array[idx]; - m_map.insert( + const auto& new_gauge_it = m_map.insert( { endpoint_id, std::addressof(new_counter->Add(labels)) } ); + new_gauge_it.first->second->Set(value); } } From 99afddb2cc81cde9d0056dca1469fa75ce869478 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Tue, 20 Aug 2024 19:40:09 +0200 Subject: [PATCH 25/62] Improve TAP test with conn_pool metrics create/update A issue was also fixed on test utilities for metrics parsing. --- test/tap/tap/utils.cpp | 28 +- test/tap/tests/test_prometheus_metrics-t.cpp | 337 ++++++++++++++++++- 2 files changed, 350 insertions(+), 15 deletions(-) diff --git a/test/tap/tap/utils.cpp b/test/tap/tap/utils.cpp index b656e03aae..6b5865f1bf 100644 --- a/test/tap/tap/utils.cpp +++ b/test/tap/tap/utils.cpp @@ -1607,23 +1607,27 @@ json fetch_internal_session(MYSQL* proxy, bool verbose) { } } +pair split_line_by_last(const string& ln, char c) { + size_t pos = ln.find_last_of(c); + + if (pos == string::npos) { + return { ln, "" }; + } else { + const string f { ln.substr(0, pos) }; + const string s { ln.substr(pos + 1) }; + + return { f, s }; + } +} + map parse_prometheus_metrics(const string& s) { - vector lines { split(s, '\n') }; + const vector lines { split(s, '\n') }; map metrics_map {}; for (const string ln : lines) { - const vector line_values { split(ln, ' ') }; - if (ln.empty() == false && ln[0] != '#') { - if (line_values.size() > 2) { - size_t delim_pos_st = ln.rfind("} "); - string metric_key = ln.substr(0, delim_pos_st); - string metric_val = ln.substr(delim_pos_st + 2); - - metrics_map.insert({metric_key, stod(metric_val)}); - } else { - metrics_map.insert({line_values.front(), stod(line_values.back())}); - } + pair p_line_val { split_line_by_last(ln, ' ') }; + metrics_map.insert({p_line_val.first, stod(p_line_val.second)}); } } diff --git a/test/tap/tests/test_prometheus_metrics-t.cpp b/test/tap/tests/test_prometheus_metrics-t.cpp index 82545cf6a9..19fec468ec 100644 --- a/test/tap/tests/test_prometheus_metrics-t.cpp +++ b/test/tap/tests/test_prometheus_metrics-t.cpp @@ -4,16 +4,15 @@ * @date 2021-03-01 */ -#include #include #include #include #include #include -#include #include #include #include +#include #include #include "mysql.h" @@ -135,6 +134,8 @@ bool trigger_access_denied_wrong_password_total(MYSQL*, MYSQL*, const CommandLin access_denied_error = false; } + mysql_close(proxysql); + return access_denied_error; } @@ -215,6 +216,7 @@ bool get_proxysql_version_info(MYSQL*, MYSQL* admin, const CommandLine&) { MYSQL_RES* v_res = mysql_store_result(admin); vector res_rows = extract_mysql_rows(v_res); + mysql_free_result(v_res); if (res_rows.size() != 1 && res_rows[0].size() != 1) { diag("Invalid resulset received for 'SELECT @@version' at Line: %d", __LINE__); @@ -326,7 +328,306 @@ bool trigger_message_count_parse_failure(MYSQL*, MYSQL*, const CommandLine& cl) return res; } -#include +int NEW_SRV_HG = get_env_int("TAP_PROMETHEUS_METRICS__NEW_SRV_HG", 1724090); +string NEW_SRV_HG_STR { std::to_string(NEW_SRV_HG) }; + +string MY_PORT_STR {}; +string MY_HOST_STR {}; + +int find_free_slot(const std::vector& nums, int offset) { + std::set num_set(nums.begin(), nums.end()); + + if (num_set.find(offset) != num_set.end()) { + auto it = num_set.end(); + return *num_set.rbegin() + 1; + } else { + return offset; + } +} + +int upd_tg_metric_hg(MYSQL* admin) { + // Forces a metrics refresh; all hostgroups from current servers should be present + map cur_metrics {}; + int m_res = get_cur_metrics(admin, cur_metrics); + if (m_res) { + diag("Failed to fetch current metrics rc=%d", m_res); + return EXIT_FAILURE; + } + + vector str_hgs {}; + + // Build a map with the current hostgroups used + for (const pair& p_metric_val : cur_metrics) { + if (p_metric_val.first.rfind("proxysql_connpool_conns") == 0) { + const map metric_tags { extract_metric_tags(p_metric_val.first) }; + str_hgs.push_back(metric_tags.at("hostgroup")); + } + } + + vector hgs {}; + std::transform(str_hgs.begin(), str_hgs.end(), std::back_inserter(hgs), + [] (const string& s) -> int { + return std::atoi(s.c_str()); + } + ); + + // Get a new hostgroup currently not present in the map + NEW_SRV_HG = find_free_slot(hgs, NEW_SRV_HG); + NEW_SRV_HG_STR = std::to_string(NEW_SRV_HG); + + return EXIT_SUCCESS; +} + +bool trigger_conn_in_new_backend_hg(MYSQL* proxy, MYSQL* admin, const CommandLine& cl) { + MY_HOST_STR = cl.mysql_host; + MY_PORT_STR = std::to_string(cl.mysql_port); + + // Update the target hostgroup + int m_res = upd_tg_metric_hg(admin); + if (m_res) { + diag("Failed to update target conn hostgroup rc=%d", m_res); + return false; + } + + // Destroy the previous hostgroup stats + MYSQL_QUERY(admin, ("DELETE FROM mysql_servers WHERE hostgroup_id=" + NEW_SRV_HG_STR).c_str()); + MYSQL_QUERY(admin, "LOAD MYSQL SERVERS TO RUNTIME"); + + // Re-create the server + MYSQL_QUERY(admin, + ("INSERT INTO mysql_servers (hostgroup_id,hostname,port) VALUES (" + + NEW_SRV_HG_STR + ",'" + MY_HOST_STR + "'," + MY_PORT_STR + ")").c_str() + ); + MYSQL_QUERY(admin, "LOAD MYSQL SERVERS TO RUNTIME"); + + // Create backend connection; we keep the connection open intentionally (gauge) + MYSQL_QUERY(proxy, ("/* hostgroup=" + NEW_SRV_HG_STR + " */ BEGIN").c_str()); + + return true; +} + +bool trigger_conn_in_prev_backend_hg(MYSQL* proxy, MYSQL* admin, const CommandLine& cl) { + // Create backend connection; we keep the connection open intentionally (gauge) + MYSQL_QUERY(proxy, ("/* hostgroup=" + NEW_SRV_HG_STR + ";create_new_connection=1 */ BEGIN").c_str()); + return true; +} + +bool check_metric_creation( + map::const_iterator prev_metric_it_free, + map::const_iterator prev_metric_it_used, + map::const_iterator after_metric_it_free, + map::const_iterator after_metric_it_used, + const map& prev_metrics, + const map& after_metrics +) { + bool metric_found = + prev_metric_it_free == prev_metrics.end() && + prev_metric_it_used == prev_metrics.end() && + after_metric_it_free != after_metrics.end() && + after_metric_it_used != after_metrics.end(); + + ok(metric_found, "Metric was present ONLY after the action in 'SHOW PROMETHEUS METRICS'"); + + return metric_found; +} + +bool check_metric_update( + map::const_iterator prev_metric_it_free, + map::const_iterator prev_metric_it_used, + map::const_iterator after_metric_it_free, + map::const_iterator after_metric_it_used, + const map& prev_metrics, + const map& after_metrics +) { + bool metric_found = + prev_metric_it_free != prev_metrics.end() && + prev_metric_it_used != prev_metrics.end() && + after_metric_it_free != after_metrics.end() && + after_metric_it_used != after_metrics.end(); + + ok(metric_found, "Metric was present ONLY after the action in 'SHOW PROMETHEUS METRICS'"); + + return metric_found; +} + +bool (*check_metric_presence)( + map::const_iterator prev_metric_it_free, + map::const_iterator prev_metric_it_used, + map::const_iterator after_metric_it_free, + map::const_iterator after_metric_it_used, + const map& prev_metrics, + const map& after_metrics +) = check_metric_creation; + +pair> check_matching_tags( + map::const_iterator metric_key, + map> tags_chcks +) { + map metric_tags = extract_metric_tags(metric_key->first); + + // Find the matching metrics by key and using the check function for values + for (const auto& [tag, check] : tags_chcks) { + auto it = metric_tags.find(tag); + if (it == metric_tags.end() || !check(it->second)) { + return { false, {} }; + } + } + + return { true, metric_tags }; +} + +void check_conn_used_incr_on_hg( + const map& prev_metrics, const map& after_metrics +) { + map::const_iterator after_metric_it_free { after_metrics.end() }; + map::const_iterator after_metric_it_used { after_metrics.end() }; + map::const_iterator prev_metric_it_free { prev_metrics.end() }; + map::const_iterator prev_metric_it_used { prev_metrics.end() }; + + map metric_tags_used {}; + map metric_tags_free {}; + + const map> tags_chcks { + { "endpoint", [&] (const string& s) { return s == MY_HOST_STR + ":" + MY_PORT_STR; } }, + { "hostgroup", [&] (const string& s) { return s == NEW_SRV_HG_STR; } }, + { "status", [&] (const string& s) { return s == "free" || s == "used"; } }, + }; + + for (auto metric_key = after_metrics.begin(); metric_key != after_metrics.end(); metric_key++) { + if (metric_key->first.rfind("proxysql_connpool_conns") == 0) { + pair> match_res { check_matching_tags(metric_key, tags_chcks) }; + + if (match_res.first) { + if (match_res.second["status"] == "free") { + metric_tags_free = match_res.second; + after_metric_it_free = metric_key; + } else if (match_res.second["status"] == "used") { + metric_tags_used = match_res.second; + after_metric_it_used = metric_key; + } + if ( + after_metric_it_free != after_metrics.end() + && after_metric_it_used != after_metrics.end() + ) { + break; + } + } + } + } + for (auto metric_key = prev_metrics.begin(); metric_key != prev_metrics.end(); metric_key++) { + if (metric_key->first.rfind("proxysql_connpool_conns") == 0) { + pair> match_res { check_matching_tags(metric_key, tags_chcks) }; + + if (match_res.first) { + if (match_res.second["status"] == "free") { + metric_tags_free = match_res.second; + prev_metric_it_free = metric_key; + } else if (match_res.second["status"] == "used") { + metric_tags_used = match_res.second; + prev_metric_it_used = metric_key; + } + if ( + prev_metric_it_free != prev_metrics.end() + && prev_metric_it_used != prev_metrics.end() + ) { + break; + } + } + } + } + + // Check the metric presence - origin vs update + bool metric_found = check_metric_presence( + prev_metric_it_free, + prev_metric_it_used, + after_metric_it_free, + after_metric_it_used, + prev_metrics, + after_metrics + ); + + if (metric_found) { + // Fallback to zero in case of first time being triggered + double prev_metric_val = 0; + if (prev_metric_it_used != prev_metrics.end()) { + prev_metric_val = prev_metric_it_used->second; + } + + double after_metric_val = after_metric_it_used->second; + bool is_updated = fabs(prev_metric_val + 1 - after_metric_val) < 0.1; + const string tags_used { nlohmann::json(metric_tags_used).dump() }; + + ok( + metric_found && is_updated, + "Metric has a correct tags and updated value: { old_val: '%lf', new_val: '%lf', tags: '%s' }", + prev_metric_val, after_metric_val, tags_used.c_str() + ); + } else { + ok(false, "Metric has a properly updated value"); + } +} + +pair::const_iterator,map> get_metric( + const map& metrics, + const string& key, + const map> tags_chcks +) { + for (auto metric_key = metrics.begin(); metric_key != metrics.end(); metric_key++) { + if (metric_key->first.rfind(key) == 0) { + pair> match_res { check_matching_tags(metric_key, tags_chcks) }; + + if (match_res.first) { + return { metric_key, match_res.second }; + } + } + } + + return { metrics.end(), {} }; +} + +void check_conn_total_incr_on_hg( + const map& prev_metrics, const map& after_metrics +) { + + const map> tags_chcks { + { "endpoint", [&] (const string& s) { return s == MY_HOST_STR + ":" + MY_PORT_STR; } }, + { "hostgroup", [&] (const string& s) { return s == NEW_SRV_HG_STR; } }, + { "status", [&] (const string& s) { return s == "ok"; } }, + }; + + const auto& p_prev_metric_tags { get_metric(prev_metrics, "proxysql_connpool_conns", tags_chcks) }; + const auto& p_after_metric_tags { get_metric(after_metrics, "proxysql_connpool_conns", tags_chcks) }; + + // Check the metric presence - origin vs update + bool metric_found = check_metric_presence( + p_prev_metric_tags.first, + p_prev_metric_tags.first, + p_after_metric_tags.first, + p_after_metric_tags.first, + prev_metrics, + after_metrics + ); + + if (metric_found) { + // Fallback to zero in case of first time being triggered + double prev_metric_val = 0; + if (p_prev_metric_tags.first != prev_metrics.end()) { + prev_metric_val = p_prev_metric_tags.first->second; + } + + double after_metric_val = p_after_metric_tags.first->second; + bool is_updated = fabs(prev_metric_val + 1 - after_metric_val) < 0.1; + const string tags { nlohmann::json(p_after_metric_tags.second).dump() }; + + ok( + metric_found && is_updated, + "Metric has a correct tags and updated value: { old_val: '%lf', new_val: '%lf', tags: '%s' }", + prev_metric_val, after_metric_val, tags.c_str() + ); + } else { + ok(false, "Metric has a properly updated value"); + } +} void check_message_count_parse_failure(const map& prev_metrics, const map& after_metrics) { map::const_iterator after_metric_it { after_metrics.end() }; @@ -522,6 +823,16 @@ struct CHECK { bool placeholder_setup(MYSQL*, MYSQL*, const CommandLine&) { return true; } +bool setup_metric_creation_check(MYSQL*, MYSQL*, const CommandLine&) { + check_metric_presence = check_metric_creation; + return true; +} + +bool setup_metric_update_check(MYSQL*, MYSQL*, const CommandLine&) { + check_metric_presence = check_metric_update; + return true; +} + /** * @brief Map of test identifier and pair functions holding the metrics tests: * - First function of the pair uses an open connection to ProxySQL and to ProxySQL Admin to perform @@ -558,6 +869,26 @@ const vector>> metric_te "proxysql_message_count_parse_failure_inc", { placeholder_setup, trigger_message_count_parse_failure, check_message_count_parse_failure } }, + // Create a connection to a NEW backend server - proxysql_connpool_conns gauge + { + "proxysql_connpool_conns{endpoint/hostgroup/status} - Creation", + { setup_metric_creation_check, trigger_conn_in_new_backend_hg, check_conn_used_incr_on_hg } + }, + // Create a connection to the SAME (previous) backend server - proxysql_connpool_conns gauge + { + "proxysql_connpool_conns{endpoint/hostgroup/status} - Update", + { setup_metric_update_check, trigger_conn_in_prev_backend_hg, check_conn_used_incr_on_hg } + }, + // Create a connection to a NEW backend server - proxysql_connpool_conns_total counter + { + "proxysql_connpool_conns_total{endpoint/hostgroup/status} - Creation", + { setup_metric_creation_check, trigger_conn_in_new_backend_hg, check_conn_total_incr_on_hg } + }, + // Create a connection to a NEW backend server - proxysql_connpool_conns_total counter + { + "proxysql_connpool_conns_total{endpoint/hostgroup/status} - Update", + { setup_metric_update_check, trigger_conn_in_prev_backend_hg, check_conn_total_incr_on_hg } + }, }; using std::map; From 851a8850bc3f9bb9c311a42c4d2c6f04a6890784 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Thu, 22 Aug 2024 16:29:22 +0200 Subject: [PATCH 26/62] Fix regression on 'COM_CHANGE_USER' for 'mysql_native_password' - Closes #4589 Fixes handing of 'COM_CHANGE_USER' for 'mysql_native_password' when using hashed user passwords. --- lib/MySQL_Protocol.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/MySQL_Protocol.cpp b/lib/MySQL_Protocol.cpp index 5392a229eb..cd13ea68fe 100644 --- a/lib/MySQL_Protocol.cpp +++ b/lib/MySQL_Protocol.cpp @@ -1225,7 +1225,7 @@ bool MySQL_Protocol::verify_user_pass( ret = false; } } else { - if (auth_plugin_id == 2) { + if (auth_plugin_id == 0) { if (session_type == PROXYSQL_SESSION_MYSQL || session_type == PROXYSQL_SESSION_SQLITE) { ret=proxy_scramble_sha1((char *)pass,(*myds)->myconn->scramble_buff,password+1, reply); if (ret) { From f934c3a0486b17f466c905e7beea1d6ccd20446c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Thu, 22 Aug 2024 18:33:35 +0200 Subject: [PATCH 27/62] Several improvements for 'reg_test_3504-change_user-t' - Improved test documentation and logging format. - Added extra options checking invalid passwords and hashed passwords. - Improved combinations on options being check. --- .../tap/tests/reg_test_3504-change_user-t.cpp | 242 ++++++++++++------ .../reg_test_3504-change_user_helper.cpp | 14 +- 2 files changed, 168 insertions(+), 88 deletions(-) diff --git a/test/tap/tests/reg_test_3504-change_user-t.cpp b/test/tap/tests/reg_test_3504-change_user-t.cpp index 29b0bcb1fb..9b488585bf 100644 --- a/test/tap/tests/reg_test_3504-change_user-t.cpp +++ b/test/tap/tests/reg_test_3504-change_user-t.cpp @@ -1,79 +1,155 @@ /** * @file reg_test_3504-change_user-t.cpp * @brief This test checks the new implementation for 'COM_CHANGE_USER' - * introduced in issue #3504. The test connects using different authentication - * methods: 'mysql_clear_password', 'mysql_native_password' and - * 'caching_sha2_password', with and without SSL enabled. And verifies that both, - * the initial connection and the later 'mysql_change_user' are properly executed. - * Connections are performed using 'libmysqlclient' and 'libmariadb'. - * @details For making this possible the test uses two helper binaries, which - * are the ones performing the connection to ProxySQL, and communicates to - * them through a payload format that is specified in this helper tests files: - * - 'reg_test_3504-change_user_libmysql_helper.cpp' - * - 'reg_test_3504-change_user_libmariadb_helper.cpp' + * introduced in issue #3504. The test connects using different authentication methods: + * - 'mysql_clear_password' + * - 'mysql_native_password' + * - 'caching_sha2_password' + * It also checks that the following options are handled correctly: + * - With and without SSL. + * - Using same and different users. + * - Hashed and non-hashed user passwords are correctly handled. + * The test verifies that both, the initial connection and the later 'mysql_change_user' are + * properly executed. Connections are performed using 'libmysqlclient' and 'libmariadb'. + * @details For making this possible the test uses two helper binaries, which are the ones performing the + * connection to ProxySQL, and communicates to them through a payload format that is specified in this helper + * tests files: + * - 'reg_test_3504-change_user_libmysql_helper.cpp' + * - 'reg_test_3504-change_user_libmariadb_helper.cpp' */ #include #include #include #include -#include +#include #include #include #include "mysql.h" -#include "mysqld_error.h" #include "command_line.h" -#include "proxysql_utils.h" #include "json.hpp" #include "tap.h" #include "utils.h" using nlohmann::json; +using std::string; +using std::vector; + +struct test_opts { + string auth; + bool use_ssl; + bool change_user; + bool hashed_pass; + bool inv_pass; +}; -using test_opts = std::tuple; +const vector client_req_auths { + "mysql_clear_password", + "mysql_native_password", + "caching_sha2_password" +}; -const std::vector tests_defs { - std::make_tuple("mysql_clear_password", false, false), - std::make_tuple("mysql_native_password", false, false), - std::make_tuple("caching_sha2_password", false, false), +vector gen_tests_defs() { + // Gen all option permutations - SSL, different user, and hashed user passwords. + const auto flags_perms { get_all_bin_vec(4) }; - std::make_tuple("mysql_clear_password", true, false), - std::make_tuple("mysql_native_password", true, false), - std::make_tuple("caching_sha2_password", true, false), + // Use all options for each supported auth method + vector res {}; - std::make_tuple("mysql_clear_password", false, true), - std::make_tuple("mysql_native_password", false, true), - std::make_tuple("caching_sha2_password", false, true), + for (const auto& flags : flags_perms) { + for (const string& auth : client_req_auths) { + res.push_back({auth, flags[0], flags[1], flags[2], flags[3]}); + } + } - std::make_tuple("mysql_clear_password", true, true), - std::make_tuple("mysql_native_password", true, true), - std::make_tuple("caching_sha2_password", true, true), -}; + return res; +} + +const string PRIM_USER { get_env_str("TAP_CHANGE_USER__PRIM_USER", "sbtest1") }; +const string SECD_USER { get_env_str("TAP_CHANGE_USER__SECD_USER", "root") }; + +const char LOAD_USERS_TO_RUNTIME[] { "LOAD MYSQL USERS TO RUNTIME" }; + +int update_user_pass(MYSQL* admin, const string& user, const string& pass) { + int rc = mysql_query_t(admin, + ("UPDATE mysql_users SET password=" + pass + "" + " WHERE username='" + user + "'").c_str() + ); + if (rc) { + diag( + "Failed to set HASHED user pass. Aborting check user='%s' error='%s'", + user.c_str(), mysql_error(admin) + ); + } + + return rc; +} + +string gen_inv_pass(const string& pass) { + string rnd_str { random_string(rand() % 60 + 1) }; + + while (rnd_str == pass) { + rnd_str = random_string(rand() % 60 + 1); + } + + return rnd_str; +} + +const string opts_to_string(const test_opts& opts) { + nlohmann::json j_opts {}; + + j_opts["auth"] = opts.auth; + j_opts["use_ssl"] = opts.use_ssl; + j_opts["mix_users"] = opts.change_user; + j_opts["hashed_pass"] = opts.hashed_pass; + j_opts["inv_pass"] = opts.inv_pass; + + return j_opts.dump(); +} void perform_helper_test( + MYSQL* admin, const std::string& helper_path, - const test_opts& test_opts + const test_opts& opts ) { + diag("Preparing call to helper opts='%s'", opts_to_string(opts).c_str()); + std::string result {}; - std::string auth { std::get<0>(test_opts) }; - bool exp_SSL_val = std::get<1>(test_opts); - bool change_user = std::get<2>(test_opts); + + if (opts.hashed_pass) { + for (const string& user : { PRIM_USER, SECD_USER }) { + int rc = update_user_pass(admin, user, "MYSQL_NATIVE_PASSWORD('" + user + "')"); + if (rc) { return; } + } + } else { + for (const string& user : { PRIM_USER, SECD_USER }) { + int rc = update_user_pass(admin, user, "'" + user + "'"); + if (rc) { return; } + } + } + + int rc = mysql_query_t(admin, "LOAD MYSQL USERS TO RUNTIME"); + if (rc) { + diag("Failed to execute query. Aborting check error='%s'", mysql_error(admin)); + return; + } nlohmann::json input_json {}; - input_json["user"] = "sbtest1"; - input_json["pass"] = "sbtest1"; - input_json["ch_user"] = "root"; - input_json["ch_pass"] = "root"; - input_json["auth"] = auth; + input_json["user"] = PRIM_USER; + input_json["pass"] = PRIM_USER; + input_json["ch_user"] = SECD_USER; + input_json["ch_pass"] = opts.inv_pass ? gen_inv_pass(SECD_USER) : SECD_USER; + input_json["auth"] = opts.auth; input_json["charset"] = ""; input_json["port"] = 6033; - input_json["SSL"] = exp_SSL_val; - input_json["CHANGE_USER"] = change_user; + input_json["SSL"] = opts.use_ssl; + input_json["CHANGE_USER"] = opts.change_user; std::string input_str { input_json.dump() }; + diag("Calling test helper params='%s'", input_json.dump().c_str()); + std::vector v_argv { helper_path.c_str(), input_str.c_str() }; int res = execvp(helper_path, v_argv, result); @@ -86,7 +162,7 @@ void perform_helper_test( bool act_SSL_val; std::vector exp_ch_usernames {}; - if (change_user) { + if (opts.change_user) { exp_ch_usernames = { "root", "sbtest1", "root" }; } else { exp_ch_usernames = { "sbtest1", "sbtest1", "sbtest1" }; @@ -105,11 +181,11 @@ void perform_helper_test( def_auth_plugin = output_res.at("def_auth_plugin"); act_SSL_val = output_res.at("ssl_enabled"); - if (auth == "mysql_clear_password") { + if (opts.auth == "mysql_clear_password") { exp_switching_auth_type = -1; - } else if (auth == "mysql_native_password") { + } else if (opts.auth == "mysql_native_password") { exp_switching_auth_type = -1; - } else if (auth == "caching_sha2_password") { + } else if (opts.auth == "caching_sha2_password") { exp_switching_auth_type = 0; } @@ -120,28 +196,39 @@ void perform_helper_test( diag("Invalid JSON result from helper, parsing failed: '%s'", ex.what()); } - std::string exp_user_names_str = - std::accumulate(exp_ch_usernames.begin(), exp_ch_usernames.end(), std::string(), - [](const std::string& str, const std::string& splice) -> std::string { - return str + (str.length() > 0 ? "," : "") + splice; - }); - std::string act_user_names_str = - std::accumulate(act_ch_usernames.begin(), act_ch_usernames.end(), std::string(), - [](const std::string& str, const std::string& splice) -> std::string { - return str + (str.length() > 0 ? "," : "") + splice; - }); - - ok( - (exp_switching_auth_type == act_switching_auth_type) && - (exp_SSL_val == act_SSL_val) && err_msg.empty() && - exp_ch_usernames == act_ch_usernames, - "Connect and COM_CHANGE_USER should work for the supplied values.\n" - " + Expected values where: (client_auth_plugin='%s', switching_auth_type='%d', SSL='%d', usernames=['%s']),\n" - " + Actual values where: (client_auth_plugin='%s', switching_auth_type='%d', SSL='%d, usernames=['%s']').\n" - " Error message: %s.\n", - auth.c_str(), exp_switching_auth_type, exp_SSL_val, exp_user_names_str.c_str(), def_auth_plugin.c_str(), - act_switching_auth_type, act_SSL_val, act_user_names_str.c_str(), err_msg.c_str() - ); + // Failure with invalid CHANGE_USER pass only for real change user ops - src_user != tg_user. + if (!opts.inv_pass || !opts.change_user) { + std::string exp_user_names_str = + std::accumulate(exp_ch_usernames.begin(), exp_ch_usernames.end(), std::string(), + [](const std::string& str, const std::string& splice) -> std::string { + return str + (str.length() > 0 ? "," : "") + splice; + }); + std::string act_user_names_str = + std::accumulate(act_ch_usernames.begin(), act_ch_usernames.end(), std::string(), + [](const std::string& str, const std::string& splice) -> std::string { + return str + (str.length() > 0 ? "," : "") + splice; + }); + + ok( + (exp_switching_auth_type == act_switching_auth_type) && + (opts.use_ssl == act_SSL_val) && err_msg.empty() && + exp_ch_usernames == act_ch_usernames, + "Connect and COM_CHANGE_USER should work for the supplied values.\n" + " + Expected: (client_auth_plugin='%s', switching_auth_type='%d', SSL='%d', usernames=['%s']),\n" + " + Actual: (client_auth_plugin='%s', switching_auth_type='%d', SSL='%d, usernames=['%s']').\n" + " Error message: %s.", + opts.auth.c_str(), exp_switching_auth_type, opts.use_ssl, exp_user_names_str.c_str(), + def_auth_plugin.c_str(), act_switching_auth_type, act_SSL_val, act_user_names_str.c_str(), + err_msg.c_str() + ); + } else { + const string::size_type f_it { err_msg.find("Failed to change user") }; + ok( + res != 0 && !err_msg.empty() && f_it != string::npos, + "COM_CHANGE_USER should fail with 'Access denied' for invalid creds res=%d err='%s'", + res, err_msg.c_str() + ); + } } int main(int argc, char** argv) { @@ -152,24 +239,25 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } - MYSQL* proxysql_admin = mysql_init(NULL); + srand(time(NULL)); + MYSQL* admin = mysql_init(NULL); if ( !mysql_real_connect( - proxysql_admin, "127.0.0.1", cl.admin_username, cl.admin_password, - "information_schema", cl.admin_port, NULL, 0 + admin, "127.0.0.1", cl.admin_username, cl.admin_password, NULL, cl.admin_port, NULL, 0 ) ) { - fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_admin)); + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(admin)); return EXIT_FAILURE; } - MYSQL_QUERY(proxysql_admin, "SET mysql-have_ssl='true'"); - MYSQL_QUERY(proxysql_admin, "LOAD MYSQL VARIABLES TO RUNTIME"); - - // Give some time after the 'LOAD TO RUNTIME' - usleep(500 * 1000); + // TODO: This test now only checks support for 'mysql_native_password'. This should be changed once + // 'COM_CHANGE_USER' is supported for 'caching_sha2_password'. See #4618. + MYSQL_QUERY(admin, "SET mysql-default_authentication_plugin='mysql_native_password'"); + MYSQL_QUERY(admin, "SET mysql-have_ssl='true'"); + MYSQL_QUERY(admin, "LOAD MYSQL VARIABLES TO RUNTIME"); + const vector tests_defs { gen_tests_defs() }; plan(tests_defs.size() * 2); diag("Starting tests for helper 'reg_test_3504-change_user_libmysql_helper'\n"); @@ -178,7 +266,7 @@ int main(int argc, char** argv) { std::string { cl.workdir } + "reg_test_3504-change_user_libmysql_helper" }; for (const auto& test_opts : tests_defs) { - perform_helper_test(libmysql_helper_path, test_opts); + perform_helper_test(admin, libmysql_helper_path, test_opts); } std::cout << "\n"; @@ -188,10 +276,10 @@ int main(int argc, char** argv) { std::string { cl.workdir } + "reg_test_3504-change_user_libmariadb_helper" }; for (const auto& test_opts : tests_defs) { - perform_helper_test(libmariadb_helper_path, test_opts); + perform_helper_test(admin, libmariadb_helper_path, test_opts); } - mysql_close(proxysql_admin); + mysql_close(admin); return exit_status(); } diff --git a/test/tap/tests/reg_test_3504-change_user_helper.cpp b/test/tap/tests/reg_test_3504-change_user_helper.cpp index ee6ba80dbb..a6ac1ef4e2 100644 --- a/test/tap/tests/reg_test_3504-change_user_helper.cpp +++ b/test/tap/tests/reg_test_3504-change_user_helper.cpp @@ -210,10 +210,7 @@ int main(int argc, char** argv) { port, NULL, 0 ) ) { - string_format( - "Failed to connect to database: Error: %s\n", err_msg, - mysql_error(&mysql) - ); + string_format("Failed to connect to database: Error: %s", err_msg, mysql_error(&mysql)); output["err_msg"] = err_msg; res = EXIT_FAILURE; @@ -234,10 +231,7 @@ int main(int argc, char** argv) { } if (!conn_res) { - string_format( - "Failed to connect to database: Error: %s\n", err_msg, - mysql_error(&mysql) - ); + string_format("Failed to connect to database: Error: %s", err_msg, mysql_error(&mysql)); output["err_msg"] = err_msg; res = EXIT_FAILURE; @@ -282,9 +276,7 @@ int main(int argc, char** argv) { if (CHANGE_USER) { if (mysql_change_user(&mysql, user.c_str(), pass.c_str(), "information_schema")) { - string_format( - "Failed to change user. Error: %s\n", err_msg, mysql_error(&mysql) - ); + string_format("Failed to change user. Error: %s", err_msg, mysql_error(&mysql)); output["err_msg"] = err_msg; tmp_res = EXIT_FAILURE; } From 94b0da1768e18b01d82319dd349c0e73cd9b8a56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Thu, 22 Aug 2024 18:36:51 +0000 Subject: [PATCH 28/62] In SQL3_Processlist() use saved IP/port --- lib/MySQL_Thread.cpp | 102 ++++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 46 deletions(-) diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp index fff793a78b..82224c2dd4 100644 --- a/lib/MySQL_Thread.cpp +++ b/lib/MySQL_Thread.cpp @@ -5112,30 +5112,40 @@ SQLite3_result * MySQL_Threads_Handler::SQL3_Processlist() { } } - if (sess->mirror==false) { - switch (sess->client_myds->client_addr->sa_family) { - case AF_INET: { - struct sockaddr_in *ipv4 = (struct sockaddr_in *)sess->client_myds->client_addr; - inet_ntop(sess->client_myds->client_addr->sa_family, &ipv4->sin_addr, buf, INET_ADDRSTRLEN); - pta[4] = strdup(buf); - sprintf(port, "%d", ntohs(ipv4->sin_port)); - pta[5] = strdup(port); - break; - } - case AF_INET6: { - struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)sess->client_myds->client_addr; - inet_ntop(sess->client_myds->client_addr->sa_family, &ipv6->sin6_addr, buf, INET6_ADDRSTRLEN); - pta[4] = strdup(buf); - sprintf(port, "%d", ntohs(ipv6->sin6_port)); - pta[5] = strdup(port); - break; - } - default: - pta[4] = strdup("localhost"); - pta[5] = NULL; - break; - } - } else { + if (sess->mirror==false) { + switch (sess->client_myds->client_addr->sa_family) { + case AF_INET: + if (sess->client_myds->addr.addr != NULL) { + pta[4] = strdup(sess->client_myds->addr.addr); + sprintf(port, "%d", sess->client_myds->addr.port); + pta[5] = strdup(port); + } else { + struct sockaddr_in *ipv4 = (struct sockaddr_in *)sess->client_myds->client_addr; + inet_ntop(sess->client_myds->client_addr->sa_family, &ipv4->sin_addr, buf, INET_ADDRSTRLEN); + pta[4] = strdup(buf); + sprintf(port, "%d", ntohs(ipv4->sin_port)); + pta[5] = strdup(port); + } + break; + case AF_INET6: + if (sess->client_myds->addr.addr != NULL) { + pta[4] = strdup(sess->client_myds->addr.addr); + sprintf(port, "%d", sess->client_myds->addr.port); + pta[5] = strdup(port); + } else { + struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)sess->client_myds->client_addr; + inet_ntop(sess->client_myds->client_addr->sa_family, &ipv6->sin6_addr, buf, INET6_ADDRSTRLEN); + pta[4] = strdup(buf); + sprintf(port, "%d", ntohs(ipv6->sin6_port)); + pta[5] = strdup(port); + } + break; + default: + pta[4] = strdup("localhost"); + pta[5] = NULL; + break; + } + } else { pta[4] = strdup("mirror_internal"); pta[5] = NULL; } @@ -5151,28 +5161,28 @@ SQLite3_result * MySQL_Threads_Handler::SQL3_Processlist() { int rc; rc=getsockname(mc->fd, &addr, &addr_len); if (rc==0) { - switch (addr.sa_family) { - case AF_INET: { - struct sockaddr_in *ipv4 = (struct sockaddr_in *)&addr; - inet_ntop(addr.sa_family, &ipv4->sin_addr, buf, INET_ADDRSTRLEN); - pta[7] = strdup(buf); - sprintf(port, "%d", ntohs(ipv4->sin_port)); - pta[8] = strdup(port); - break; - } - case AF_INET6: { - struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&addr; - inet_ntop(addr.sa_family, &ipv6->sin6_addr, buf, INET6_ADDRSTRLEN); - pta[7] = strdup(buf); - sprintf(port, "%d", ntohs(ipv6->sin6_port)); - pta[8] = strdup(port); - break; - } - default: - pta[7] = strdup("localhost"); - pta[8] = NULL; - break; - } + switch (addr.sa_family) { + case AF_INET: { + struct sockaddr_in *ipv4 = (struct sockaddr_in *)&addr; + inet_ntop(addr.sa_family, &ipv4->sin_addr, buf, INET_ADDRSTRLEN); + pta[7] = strdup(buf); + sprintf(port, "%d", ntohs(ipv4->sin_port)); + pta[8] = strdup(port); + break; + } + case AF_INET6: { + struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&addr; + inet_ntop(addr.sa_family, &ipv6->sin6_addr, buf, INET6_ADDRSTRLEN); + pta[7] = strdup(buf); + sprintf(port, "%d", ntohs(ipv6->sin6_port)); + pta[8] = strdup(port); + break; + } + default: + pta[7] = strdup("localhost"); + pta[8] = NULL; + break; + } } else { pta[7]=NULL; pta[8]=NULL; From fe8e4d191f7414f39c6441253214efc5fb935b14 Mon Sep 17 00:00:00 2001 From: Miro Stauder Date: Tue, 27 Aug 2024 09:52:19 +0000 Subject: [PATCH 29/62] bump version to 2.6.5 at the beginning of the development cycle --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7bc4bad8e8..953ae4498a 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ O3 := -O3 -mtune=native ALL_DEBUG := $(O0) -ggdb -DDEBUG NO_DEBUG := $(O2) -ggdb DEBUG := $(ALL_DEBUG) -CURVER ?= 2.6.4 +CURVER ?= 2.6.5 #export DEBUG #export EXTRALINK export MAKE From 58fa5ee5ec176a2a5631a09f10ca53f8929c2858 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Tue, 27 Aug 2024 23:11:38 +0000 Subject: [PATCH 30/62] Use uppercase in stats_mysql_query_digest.digest This fixes a regression introduced in 14ba7475d40059468 . Up to ProxySQL 2.5.1 , stats_mysql_query_digest.digest was uppercase . From ProxySQL 2.5.2 to 2.6.4 it became lowercase . This because we switched from: sprintf(... 0x16llX ...) to: ostringstream ... << "0x" << std::hex ... --- lib/ProxySQL_Admin.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/ProxySQL_Admin.cpp b/lib/ProxySQL_Admin.cpp index 709ae3492b..be22e6f354 100644 --- a/lib/ProxySQL_Admin.cpp +++ b/lib/ProxySQL_Admin.cpp @@ -10373,11 +10373,9 @@ int ProxySQL_Admin::stats___save_mysql_query_digest_to_sqlite( while (resultset ? i != resultset->rows_count : it != digest_umap->end()) { QP_query_digest_stats *qds = (QP_query_digest_stats *)(resultset ? NULL : it->second); SQLite3_row *row = resultset ? resultset->rows[i] : NULL; - string digest_hex_str; + char digest_hex_str[20]; // 2+sizeof(unsigned long long)*2+2 if (!resultset) { - std::ostringstream digest_stream; - digest_stream << "0x" << std::hex << qds->digest; - digest_hex_str = digest_stream.str(); + sprintf(digest_hex_str, "0x%16llX", (long long unsigned int)qds->digest); } int idx=row_idx%32; if (row_idxfields[0] : qds->schemaname, -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); rc=(*proxy_sqlite3_bind_text)(statement32, (idx*14)+3, resultset ? row->fields[1] : qds->username, -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); rc=(*proxy_sqlite3_bind_text)(statement32, (idx*14)+4, resultset ? row->fields[2] : qds->client_address, -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); - rc=(*proxy_sqlite3_bind_text)(statement32, (idx*14)+5, resultset ? row->fields[3] : digest_hex_str.c_str(), -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); + rc=(*proxy_sqlite3_bind_text)(statement32, (idx*14)+5, resultset ? row->fields[3] : digest_hex_str, -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); rc=(*proxy_sqlite3_bind_text)(statement32, (idx*14)+6, resultset ? row->fields[4] : qds->get_digest_text(digest_text_umap), -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); rc=(*proxy_sqlite3_bind_int64)(statement32, (idx*14)+7, resultset ? atoll(row->fields[5]) : qds->count_star); ASSERT_SQLITE_OK(rc, statsdb); { @@ -10411,7 +10409,7 @@ int ProxySQL_Admin::stats___save_mysql_query_digest_to_sqlite( rc=(*proxy_sqlite3_bind_text)(statement1, 2, resultset ? row->fields[0] : qds->schemaname, -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); rc=(*proxy_sqlite3_bind_text)(statement1, 3, resultset ? row->fields[1] : qds->username, -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); rc=(*proxy_sqlite3_bind_text)(statement1, 4, resultset ? row->fields[2] : qds->client_address, -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); - rc=(*proxy_sqlite3_bind_text)(statement1, 5, resultset ? row->fields[3] : digest_hex_str.c_str(), -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); + rc=(*proxy_sqlite3_bind_text)(statement1, 5, resultset ? row->fields[3] : digest_hex_str, -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); rc=(*proxy_sqlite3_bind_text)(statement1, 6, resultset ? row->fields[4] : qds->get_digest_text(digest_text_umap), -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); rc=(*proxy_sqlite3_bind_int64)(statement1, 7, resultset ? atoll(row->fields[5]) : qds->count_star); ASSERT_SQLITE_OK(rc, statsdb); { From 6f671eed805097ab4b2a76779b829f094ac1215e Mon Sep 17 00:00:00 2001 From: Miro Stauder Date: Wed, 28 Aug 2024 08:58:20 +0000 Subject: [PATCH 31/62] bump version to 2.7.0 at the beginning of the development cycle --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7bc4bad8e8..3f54cf76c6 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ O3 := -O3 -mtune=native ALL_DEBUG := $(O0) -ggdb -DDEBUG NO_DEBUG := $(O2) -ggdb DEBUG := $(ALL_DEBUG) -CURVER ?= 2.6.4 +CURVER ?= 2.7.0 #export DEBUG #export EXTRALINK export MAKE From 645963af8e8d6efb723952c8226b4412f288c8a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Thu, 29 Aug 2024 09:08:39 +0000 Subject: [PATCH 32/62] Removing trailing semicolon from `USE` #4628 Trailing semicolon are now removed. This commit also ensure that an error is returned if `USE` is part of a multi-statement. --- include/set_parser.h | 2 +- lib/MySQL_Session.cpp | 6 +++++- lib/set_parser.cpp | 30 +++++++++++++++++++++--------- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/include/set_parser.h b/include/set_parser.h index bd89bbab22..73ff9e085f 100644 --- a/include/set_parser.h +++ b/include/set_parser.h @@ -42,7 +42,7 @@ class SetParser { // First implemenation of the parser for TRANSACTION ISOLATION LEVEL and TRANSACTION READ/WRITE std::map> parse2(); std::string parse_character_set(); - std::string parse_USE_query(); + std::string parse_USE_query(std::string& errmsg); std::string remove_comments(const std::string& q); #ifdef DEBUG // built-in testing diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 42930c9b92..815cd65fa9 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -6139,7 +6139,8 @@ void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C __sync_fetch_and_add(&MyHGM->status.frontend_use_db, 1); string nq=string((char *)pkt->ptr+sizeof(mysql_hdr)+1,pkt->size-sizeof(mysql_hdr)-1); SetParser parser(nq); - string schemaname = parser.parse_USE_query(); + string errmsg = ""; + string schemaname = parser.parse_USE_query(errmsg); if (schemaname != "") { client_myds->myconn->userinfo->set_schemaname((char *)schemaname.c_str(),schemaname.length()); if (mirror==false) { @@ -6156,6 +6157,9 @@ void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C l_free(pkt->size,pkt->ptr); client_myds->setDSS_STATE_QUERY_SENT_NET(); std::string msg = "Unable to parse: " + nq; + if (errmsg != "") { + msg = errmsg + ": " + nq; + } client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,client_myds->pkt_sid+1,1148,(char *)"42000", msg.c_str()); RequestEnd(NULL); } diff --git a/lib/set_parser.cpp b/lib/set_parser.cpp index 7abef9adf1..983897a70e 100644 --- a/lib/set_parser.cpp +++ b/lib/set_parser.cpp @@ -11,6 +11,7 @@ using namespace std; +#define MULTI_STATEMENTS_USE "Unable to parse multi-statements command with USE statement" static void remove_quotes(string& v) { if (v.length() > 2) { @@ -508,7 +509,7 @@ std::string SetParser::parse_character_set() { return value4; } -std::string SetParser::parse_USE_query() { +std::string SetParser::parse_USE_query(std::string& errmsg) { #ifdef DEBUG proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 4, "Parsing query %s\n", query.c_str()); #endif // DEBUG @@ -518,6 +519,7 @@ std::string SetParser::parse_USE_query() { opt2.set_longest_match(false); std::string dbname = remove_comments(query); + dbname.erase(dbname.find_last_not_of(" ;") + 1); // remove trailing spaces and semicolumns re2::RE2 re0("^\\s*", opt2); re2::RE2::Replace(&dbname, re0, ""); if (dbname.size() >= 4) { @@ -537,18 +539,22 @@ std::string SetParser::parse_USE_query() { dbname.erase(0, 1); // Remove the last character dbname.erase(dbname.length() - 1); - return dbname; } } - } else { - return dbname; } + } else { + dbname = ""; } } else { - return ""; + dbname = ""; + } + + if (dbname.find_first_of(';') != std::string::npos) { + errmsg = MULTI_STATEMENTS_USE; + dbname = ""; } - return ""; + return dbname; } @@ -638,18 +644,24 @@ void SetParser::test_parse_USE_query() { {"USE/*+ placeholder_comment */`test_use_comment-5`", "test_use_comment-5"}, {"/* comment */USE`test_use_comment-6`", "test_use_comment-6"}, {"USE`test_use_comment-7`", "test_use_comment-7"}, + {"USE test_use_comment-7 ;", "test_use_comment-7"}, + {"USE`test_use_comment-2` ; ", "test_use_comment-2"}, + {"USE`test_use_comment-2` ; -- comment", "test_use_comment-2"}, + {"USE test_use_comment-7 /* comment */ ; ", "test_use_comment-7"}, + {"USE /* comment */ test_use_comment-7 ; ", "test_use_comment-7"}, + {"USE dbame ; SELECT 1", ""}, }; // Run tests for each pair for (const auto& p : testCases) { set_query(p.first); - std::string dbname = parse_USE_query(); + std::string errmsg = ""; + std::string dbname = parse_USE_query(errmsg); if (dbname != p.second) { // we call parse_USE_query() again just to make it easier to create a breakpoint - std::string s = parse_USE_query(); + std::string s = parse_USE_query(errmsg); assert(s == p.second); } } - } #endif // DEBUG From c76dda60d582016e83a2027dfd0e10b6fc0ee873 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Thu, 29 Aug 2024 10:28:55 +0000 Subject: [PATCH 33/62] Add check before trying to remove trailing spaces or semicolon --- lib/MySQL_Session.cpp | 5 ++++- lib/set_parser.cpp | 15 ++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 815cd65fa9..e4ba12f440 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -6479,7 +6479,10 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C RE2::GlobalReplace(&nq,(char *)"^/\\*!\\d\\d\\d\\d\\d SET(.*)\\*/",(char *)"SET\\1"); RE2::GlobalReplace(&nq,(char *)"(?U)/\\*.*\\*/",(char *)""); // remove trailing space and semicolon if present. See issue#4380 - nq.erase(nq.find_last_not_of(" ;") + 1); + size_t pos = nq.find_last_not_of(" ;"); + if (pos != nq.npos) { + nq.erase(pos + 1); // remove trailing spaces and semicolumns + } /* // we do not threat SET SQL_LOG_BIN as a special case if (match_regexes && match_regexes[0]->match(dig)) { diff --git a/lib/set_parser.cpp b/lib/set_parser.cpp index 983897a70e..2d28da923a 100644 --- a/lib/set_parser.cpp +++ b/lib/set_parser.cpp @@ -119,7 +119,10 @@ VALGRIND_ENABLE_ERROR_REPORTING; } else if (strcasecmp("transaction_read_only", value4.c_str()) == 0) { value4 = "tx_read_only"; } - value5.erase(value5.find_last_not_of(" \n\r\t,")+1); + size_t pos = value5.find_last_not_of(" \n\r\t,"); + if (pos != value5.npos) { + value5.erase(pos+1); + } key = value4; if (value5 == "''" || value5 == "\"\"") { op.push_back(""); @@ -405,7 +408,10 @@ VALGRIND_ENABLE_ERROR_REPORTING; } else if (strcasecmp("transaction_read_only", value4.c_str()) == 0) { value4 = "tx_read_only"; } - value5.erase(value5.find_last_not_of(" \n\r\t,")+1); + size_t pos = value5.find_last_not_of(" \n\r\t,"); + if (pos != value5.npos) { + value5.erase(pos+1); + } key = value4; if (value5 == "''" || value5 == "\"\"") { op.push_back(""); @@ -519,7 +525,10 @@ std::string SetParser::parse_USE_query(std::string& errmsg) { opt2.set_longest_match(false); std::string dbname = remove_comments(query); - dbname.erase(dbname.find_last_not_of(" ;") + 1); // remove trailing spaces and semicolumns + size_t pos = dbname.find_last_not_of(" ;"); + if (pos != dbname.npos) { + dbname.erase(pos + 1); // remove trailing spaces and semicolumns + } re2::RE2 re0("^\\s*", opt2); re2::RE2::Replace(&dbname, re0, ""); if (dbname.size() >= 4) { From 3b7fc71a488d99aa1099ac37439069f0f6d3613b Mon Sep 17 00:00:00 2001 From: Miro Stauder Date: Mon, 2 Sep 2024 16:12:26 +0000 Subject: [PATCH 34/62] bump version to 2.7.0 at the beginning of the development cycle --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 953ae4498a..3f54cf76c6 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ O3 := -O3 -mtune=native ALL_DEBUG := $(O0) -ggdb -DDEBUG NO_DEBUG := $(O2) -ggdb DEBUG := $(ALL_DEBUG) -CURVER ?= 2.6.5 +CURVER ?= 2.7.0 #export DEBUG #export EXTRALINK export MAKE From a9a21da2add0281843ff32e90ddda2e6cc262a25 Mon Sep 17 00:00:00 2001 From: Miro Stauder Date: Mon, 2 Sep 2024 19:51:08 +0200 Subject: [PATCH 35/62] Update CI-builds.yml --- .github/workflows/CI-builds.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI-builds.yml b/.github/workflows/CI-builds.yml index 020606da9f..997dc71549 100644 --- a/.github/workflows/CI-builds.yml +++ b/.github/workflows/CI-builds.yml @@ -1,13 +1,15 @@ name: CI-builds +env: + MAIN: refs/heads/${{ github.event.repository.default_branch }} on: push: - branches: [ "v2.x" ] + branches: [ $MAIN ] paths-ignore: - '.github/**' - '**.md' pull_request: - branches: [ "v2.x" ] + branches: [ $MAIN ] paths-ignore: - '.github/**' - '**.md' From 1a6200860e09d921fa98d3204cd029131fbd57b7 Mon Sep 17 00:00:00 2001 From: Miro Stauder Date: Mon, 2 Sep 2024 20:33:12 +0200 Subject: [PATCH 36/62] Update CI-builds.yml --- .github/workflows/CI-builds.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CI-builds.yml b/.github/workflows/CI-builds.yml index 997dc71549..3b7f9a7d63 100644 --- a/.github/workflows/CI-builds.yml +++ b/.github/workflows/CI-builds.yml @@ -1,15 +1,13 @@ name: CI-builds -env: - MAIN: refs/heads/${{ github.event.repository.default_branch }} on: push: - branches: [ $MAIN ] + branches: [ "v2.7" ] paths-ignore: - '.github/**' - '**.md' pull_request: - branches: [ $MAIN ] + branches: [ "v2.7" ] paths-ignore: - '.github/**' - '**.md' From 0d9e1ac0d11d8dd42d0d0aa3225c8fb38175d2b8 Mon Sep 17 00:00:00 2001 From: Miro Stauder Date: Wed, 4 Sep 2024 11:27:12 +0000 Subject: [PATCH 37/62] bump version to 2.7.1 at the beginning of the development cycle --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 3f54cf76c6..dd6b8c4453 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ O3 := -O3 -mtune=native ALL_DEBUG := $(O0) -ggdb -DDEBUG NO_DEBUG := $(O2) -ggdb DEBUG := $(ALL_DEBUG) -CURVER ?= 2.7.0 +CURVER ?= 2.7.1 #export DEBUG #export EXTRALINK export MAKE From 4247a890e8bb8d59034d79e4444ee03ec5ceb479 Mon Sep 17 00:00:00 2001 From: Miro Stauder Date: Thu, 5 Sep 2024 10:50:41 +0200 Subject: [PATCH 38/62] update GH actions triggers --- .github/workflows/CI-3p-django-framework.yml | 4 ++-- .github/workflows/CI-3p-laravel-framework.yml | 4 ++-- .github/workflows/CI-3p-mariadb-connector-c.yml | 4 ++-- .github/workflows/CI-3p-mysql-connector-j.yml | 4 ++-- .github/workflows/CI-3p-php-pdo-mysql.yml | 4 ++-- .github/workflows/CI-3p-sqlalchemy.yml | 4 ++-- .github/workflows/CI-basictests.yml | 4 ++-- .github/workflows/CI-builds.yml | 4 ++-- .github/workflows/CI-codeql.yml | 4 ++-- .github/workflows/CI-maketest.yml | 4 ++-- .github/workflows/CI-package-build.yml | 2 +- .github/workflows/CI-repltests.yml | 4 ++-- .github/workflows/CI-selftests.yml | 4 ++-- .github/workflows/CI-shuntest.yml | 4 ++-- .github/workflows/CI-taptests-asan.yml | 4 ++-- .github/workflows/CI-taptests-groups.yml | 4 ++-- .github/workflows/CI-taptests-ssl.yml | 4 ++-- .github/workflows/CI-taptests.yml | 4 ++-- 18 files changed, 35 insertions(+), 35 deletions(-) diff --git a/.github/workflows/CI-3p-django-framework.yml b/.github/workflows/CI-3p-django-framework.yml index 8c50f9cf5b..4fd9340531 100644 --- a/.github/workflows/CI-3p-django-framework.yml +++ b/.github/workflows/CI-3p-django-framework.yml @@ -2,12 +2,12 @@ name: CI-3p-django-framework on: push: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' pull_request: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' diff --git a/.github/workflows/CI-3p-laravel-framework.yml b/.github/workflows/CI-3p-laravel-framework.yml index fb6f3a8c70..b3f6460090 100644 --- a/.github/workflows/CI-3p-laravel-framework.yml +++ b/.github/workflows/CI-3p-laravel-framework.yml @@ -2,12 +2,12 @@ name: CI-3p-laravel-framework on: push: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' pull_request: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' diff --git a/.github/workflows/CI-3p-mariadb-connector-c.yml b/.github/workflows/CI-3p-mariadb-connector-c.yml index 048f94f899..d1843cebf7 100644 --- a/.github/workflows/CI-3p-mariadb-connector-c.yml +++ b/.github/workflows/CI-3p-mariadb-connector-c.yml @@ -2,12 +2,12 @@ name: CI-3p-mariadb-connector-c on: push: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' pull_request: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' diff --git a/.github/workflows/CI-3p-mysql-connector-j.yml b/.github/workflows/CI-3p-mysql-connector-j.yml index d327a9f506..865d7b8bf4 100644 --- a/.github/workflows/CI-3p-mysql-connector-j.yml +++ b/.github/workflows/CI-3p-mysql-connector-j.yml @@ -2,12 +2,12 @@ name: CI-3p-mysql-connector-j on: push: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' pull_request: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' diff --git a/.github/workflows/CI-3p-php-pdo-mysql.yml b/.github/workflows/CI-3p-php-pdo-mysql.yml index 207ff1bdb9..529b425ef5 100644 --- a/.github/workflows/CI-3p-php-pdo-mysql.yml +++ b/.github/workflows/CI-3p-php-pdo-mysql.yml @@ -2,12 +2,12 @@ name: CI-3p-php-pdo-mysql on: push: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' pull_request: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' diff --git a/.github/workflows/CI-3p-sqlalchemy.yml b/.github/workflows/CI-3p-sqlalchemy.yml index 335fb88bac..2579536018 100644 --- a/.github/workflows/CI-3p-sqlalchemy.yml +++ b/.github/workflows/CI-3p-sqlalchemy.yml @@ -2,12 +2,12 @@ name: CI-3p-sqlalchemy on: push: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' pull_request: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' diff --git a/.github/workflows/CI-basictests.yml b/.github/workflows/CI-basictests.yml index 9ff6bc13e2..4eb8b93128 100644 --- a/.github/workflows/CI-basictests.yml +++ b/.github/workflows/CI-basictests.yml @@ -2,12 +2,12 @@ name: CI-basictests on: push: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' pull_request: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' diff --git a/.github/workflows/CI-builds.yml b/.github/workflows/CI-builds.yml index 3b7f9a7d63..954bacf8c5 100644 --- a/.github/workflows/CI-builds.yml +++ b/.github/workflows/CI-builds.yml @@ -2,12 +2,12 @@ name: CI-builds on: push: - branches: [ "v2.7" ] +# branches: [ "v2.7" ] paths-ignore: - '.github/**' - '**.md' pull_request: - branches: [ "v2.7" ] +# branches: [ "v2.7" ] paths-ignore: - '.github/**' - '**.md' diff --git a/.github/workflows/CI-codeql.yml b/.github/workflows/CI-codeql.yml index b283cb7bee..09c7fb6cd6 100644 --- a/.github/workflows/CI-codeql.yml +++ b/.github/workflows/CI-codeql.yml @@ -2,12 +2,12 @@ name: CI-CodeQL on: push: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' pull_request: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' diff --git a/.github/workflows/CI-maketest.yml b/.github/workflows/CI-maketest.yml index 5194374f8a..df9f1cd560 100644 --- a/.github/workflows/CI-maketest.yml +++ b/.github/workflows/CI-maketest.yml @@ -2,12 +2,12 @@ name: CI-maketest on: push: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' pull_request: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' diff --git a/.github/workflows/CI-package-build.yml b/.github/workflows/CI-package-build.yml index 2b68ee483c..bdc0115011 100644 --- a/.github/workflows/CI-package-build.yml +++ b/.github/workflows/CI-package-build.yml @@ -2,7 +2,7 @@ name: CI-Package-Build on: push: - branches: [ "v2.x" ] +# branches: [ "v[0-9]+.x?[0-9]*.?x?[0-9]*" ] paths-ignore: - '.github/**' - '**.md' diff --git a/.github/workflows/CI-repltests.yml b/.github/workflows/CI-repltests.yml index c4d2adbb05..a4d3633ba1 100644 --- a/.github/workflows/CI-repltests.yml +++ b/.github/workflows/CI-repltests.yml @@ -2,12 +2,12 @@ name: CI-repltests on: push: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' pull_request: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' diff --git a/.github/workflows/CI-selftests.yml b/.github/workflows/CI-selftests.yml index 93f96712c7..d8f90d912a 100644 --- a/.github/workflows/CI-selftests.yml +++ b/.github/workflows/CI-selftests.yml @@ -2,12 +2,12 @@ name: CI-selftests on: push: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' pull_request: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' diff --git a/.github/workflows/CI-shuntest.yml b/.github/workflows/CI-shuntest.yml index 724eec8467..71e4818dde 100644 --- a/.github/workflows/CI-shuntest.yml +++ b/.github/workflows/CI-shuntest.yml @@ -2,12 +2,12 @@ name: CI-shuntest on: push: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' pull_request: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' diff --git a/.github/workflows/CI-taptests-asan.yml b/.github/workflows/CI-taptests-asan.yml index fd819701ae..437ae09a7f 100644 --- a/.github/workflows/CI-taptests-asan.yml +++ b/.github/workflows/CI-taptests-asan.yml @@ -2,12 +2,12 @@ name: CI-taptests-asan on: push: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' pull_request: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' diff --git a/.github/workflows/CI-taptests-groups.yml b/.github/workflows/CI-taptests-groups.yml index b3cc108e8f..f41dbb12ff 100644 --- a/.github/workflows/CI-taptests-groups.yml +++ b/.github/workflows/CI-taptests-groups.yml @@ -2,12 +2,12 @@ name: CI-taptests-groups on: push: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' pull_request: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' diff --git a/.github/workflows/CI-taptests-ssl.yml b/.github/workflows/CI-taptests-ssl.yml index 0c903a72d1..47efc386fd 100644 --- a/.github/workflows/CI-taptests-ssl.yml +++ b/.github/workflows/CI-taptests-ssl.yml @@ -2,12 +2,12 @@ name: CI-taptests-ssl on: push: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' pull_request: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' diff --git a/.github/workflows/CI-taptests.yml b/.github/workflows/CI-taptests.yml index b9531eb825..de07a39151 100644 --- a/.github/workflows/CI-taptests.yml +++ b/.github/workflows/CI-taptests.yml @@ -2,12 +2,12 @@ name: CI-taptests on: push: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' pull_request: - branches: [ "v2.x" ] +# branches: [ "v2.x" ] paths-ignore: - '.github/**' - '**.md' From 74949687337f88522c446f9a9e1ceda413722d42 Mon Sep 17 00:00:00 2001 From: Miro Stauder Date: Thu, 5 Sep 2024 08:53:38 +0000 Subject: [PATCH 39/62] add fedora41 builds --- Makefile | 2 +- docker-compose.yml | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 3f54cf76c6..54df9047a7 100644 --- a/Makefile +++ b/Makefile @@ -308,7 +308,7 @@ amd64-packages: amd64-centos amd64-ubuntu amd64-debian amd64-fedora amd64-opensu amd64-almalinux: almalinux8 almalinux8-clang almalinux8-dbg almalinux9 almalinux9-clang almalinux9-dbg amd64-centos: centos7 centos7-dbg centos8 centos8-clang centos8-dbg centos9 centos9-clang centos9-dbg amd64-debian: debian10 debian10-dbg debian11 debian11-clang debian11-dbg debian12 debian12-clang debian12-dbg -amd64-fedora: fedora38 fedora38-clang fedora38-dbg fedora39 fedora39-clang fedora39-dbg fedora40 fedora40-clang fedora40-dbg +amd64-fedora: fedora38 fedora38-clang fedora38-dbg fedora39 fedora39-clang fedora39-dbg fedora40 fedora40-clang fedora40-dbg fedora41 fedora41-clang fedora41-dbg amd64-opensuse: opensuse15 opensuse15-clang opensuse15-dbg amd64-ubuntu: ubuntu16 ubuntu16-dbg ubuntu18 ubuntu18-dbg ubuntu20 ubuntu20-clang ubuntu20-dbg ubuntu22 ubuntu22-clang ubuntu22-dbg ubuntu24 ubuntu24-clang ubuntu24-dbg diff --git a/docker-compose.yml b/docker-compose.yml index 8ba0f7c19b..1539461c6c 100755 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -178,6 +178,34 @@ services: - PKG_RELEASE=dbg-fedora40 - PROXYSQL_BUILD_TYPE=debug +#################################################################################################### + fedora41_build: + extends: + service: _build + image: proxysql/packaging:build-fedora41-v2.7.1 + volumes: + - ./docker/images/proxysql/rhel-compliant/rpmmacros/rpmbuild/:/root/rpmbuild/ + - ./docker/images/proxysql/rhel-compliant/rpmmacros/.rpmmacros:/root/.rpmmacros + - ./docker/images/proxysql/rhel-compliant/entrypoint/:/opt/entrypoint/ + - ./:/opt/proxysql/ + environment: + - PKG_RELEASE=fedora41 + - PROXYSQL_BUILD_TYPE=clickhouse + + fedora41_clang_build: + extends: + service: fedora41_build + image: proxysql/packaging:build-clang-fedora41-v2.7.1 + environment: + - PKG_RELEASE=fedora41-clang + + fedora41_dbg_build: + extends: + service: fedora41_build + environment: + - PKG_RELEASE=dbg-fedora41 + - PROXYSQL_BUILD_TYPE=debug + #################################################################################################### #################################################################################################### debian10_build: From 8c271cd2059f829082425f86de868cb9aa8c5a47 Mon Sep 17 00:00:00 2001 From: Miro Stauder Date: Thu, 5 Sep 2024 08:54:28 +0000 Subject: [PATCH 40/62] apply clang fix to all clang versions --- src/Makefile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Makefile b/src/Makefile index 4a3b1dab45..3b238e0361 100644 --- a/src/Makefile +++ b/src/Makefile @@ -118,11 +118,11 @@ STDCPP := -std=c++$(shell echo $(CPLUSPLUS) | cut -c3-4) -DCXX$(shell echo $(CPL ### handle clang issue https://bugs.llvm.org/show_bug.cgi?id=16404 CLANGFIX := ifeq ($(CXX),clang++) - CLANG_VERSION := $(shell clang -dumpversion | tr '.' ' ' | awk '{ printf("%04d.%04d.%04d", $$1, $$2, $$3) }') - CLANG_MIN_VER := $(shell echo 14.0 | tr '.' ' ' | awk '{ printf("%04d.%04d.%04d", $$1, $$2, $$3) }') -ifneq ($(CLANG_MIN_VER),$(firstword $(sort $(CLANG_VERSION) $(CLANG_MIN_VER)))) - CLANGFIX := --rtlib=compiler-rt --unwindlib=libgcc -endif +# CLANG_VERSION := $(shell clang -dumpversion | tr '.' ' ' | awk '{ printf("%04d.%04d.%04d", $$1, $$2, $$3) }') +# CLANG_MIN_VER := $(shell echo 14.0 | tr '.' ' ' | awk '{ printf("%04d.%04d.%04d", $$1, $$2, $$3) }') +#ifneq ($(CLANG_MIN_VER),$(firstword $(sort $(CLANG_VERSION) $(CLANG_MIN_VER)))) + CLANGFIX := --rtlib=compiler-rt --unwindlib=libgcc +#endif endif PSQLCH := From d0182601e1aa434a4d4adc34b34a0eb3963a178b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Tue, 17 Sep 2024 18:57:19 +0000 Subject: [PATCH 41/62] Speed up packing time --- Makefile | 6 ++++++ .../proxysql/deb-compliant/entrypoint/entrypoint.bash | 8 ++++---- .../proxysql/rhel-compliant/entrypoint/entrypoint.bash | 8 ++++---- .../rhel-compliant/rhel6/entrypoint/entrypoint.bash | 8 ++++---- .../proxysql/suse-compliant/entrypoint/entrypoint.bash | 8 ++++---- test/tap/tap/Makefile | 3 +++ 6 files changed, 25 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index 056159d046..831da6f30f 100644 --- a/Makefile +++ b/Makefile @@ -344,6 +344,12 @@ build-%: .NOTPARALLEL: binaries/proxysql% binaries/proxysql%: + cd deps && ${MAKE} cleanall + cd lib && ${MAKE} clean + cd src && ${MAKE} clean + cd test/tap && ${MAKE} clean + cd test/deps && ${MAKE} cleanall + find . -not -path "./binaries/*" -not -path "./.git/*" -exec touch -h --date=@`git show -s --format=%ct HEAD` {} \; @docker compose -p proxysql down -v --remove-orphans @docker compose -p proxysql up $(IMG_NAME)$(IMG_TYPE)$(IMG_COMP)_build @docker compose -p proxysql down -v --remove-orphans diff --git a/docker/images/proxysql/deb-compliant/entrypoint/entrypoint.bash b/docker/images/proxysql/deb-compliant/entrypoint/entrypoint.bash index 8ed235472b..f0c6ae079d 100755 --- a/docker/images/proxysql/deb-compliant/entrypoint/entrypoint.bash +++ b/docker/images/proxysql/deb-compliant/entrypoint/entrypoint.bash @@ -25,9 +25,9 @@ echo "==> Building" git config --system --add safe.directory '/opt/proxysql' cd /opt/proxysql echo "==> ProxySQL '$(git describe --long --abbrev=7)'" -export SOURCE_DATE_EPOCH=$(git show -s --format=%ct HEAD) -echo "==> Setting SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH}" -find /opt/proxysql -not -path "/opt/proxysql/binaries/*" -exec touch -h --date=@${SOURCE_DATE_EPOCH} {} \; +#export SOURCE_DATE_EPOCH=$(git show -s --format=%ct HEAD) +#echo "==> Setting SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH}" +#find /opt/proxysql -not -path "/opt/proxysql/binaries/*" -exec touch -h --date=@${SOURCE_DATE_EPOCH} {} \; if [[ -z ${PROXYSQL_BUILD_TYPE:-} ]] ; then deps_target="build_deps" @@ -36,7 +36,7 @@ else deps_target="build_deps_$PROXYSQL_BUILD_TYPE" build_target="$PROXYSQL_BUILD_TYPE" fi -${MAKE} cleanbuild +#${MAKE} cleanbuild ${MAKE} ${MAKEOPT} "${deps_target}" if [[ -z ${build_target} ]] ; then diff --git a/docker/images/proxysql/rhel-compliant/entrypoint/entrypoint.bash b/docker/images/proxysql/rhel-compliant/entrypoint/entrypoint.bash index f1c639f930..619e5878cc 100755 --- a/docker/images/proxysql/rhel-compliant/entrypoint/entrypoint.bash +++ b/docker/images/proxysql/rhel-compliant/entrypoint/entrypoint.bash @@ -25,9 +25,9 @@ echo "==> Building" git config --system --add safe.directory '/opt/proxysql' cd /opt/proxysql echo "==> ProxySQL '$(git describe --long --abbrev=7)'" -export SOURCE_DATE_EPOCH=$(git show -s --format=%ct HEAD) -echo "==> Setting SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH}" -find /opt/proxysql -not -path "/opt/proxysql/binaries/*" -exec touch -h --date=@${SOURCE_DATE_EPOCH} {} \; +#export SOURCE_DATE_EPOCH=$(git show -s --format=%ct HEAD) +#echo "==> Setting SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH}" +#find /opt/proxysql -not -path "/opt/proxysql/binaries/*" -exec touch -h --date=@${SOURCE_DATE_EPOCH} {} \; if [[ -z ${PROXYSQL_BUILD_TYPE:-} ]] ; then deps_target="build_deps" @@ -36,7 +36,7 @@ else deps_target="build_deps_$PROXYSQL_BUILD_TYPE" build_target="$PROXYSQL_BUILD_TYPE" fi -${MAKE} cleanbuild +#${MAKE} cleanbuild ${MAKE} ${MAKEOPT} "${deps_target}" if [[ -z ${build_target} ]] ; then diff --git a/docker/images/proxysql/rhel-compliant/rhel6/entrypoint/entrypoint.bash b/docker/images/proxysql/rhel-compliant/rhel6/entrypoint/entrypoint.bash index 3d372dc942..aa4babeef2 100755 --- a/docker/images/proxysql/rhel-compliant/rhel6/entrypoint/entrypoint.bash +++ b/docker/images/proxysql/rhel-compliant/rhel6/entrypoint/entrypoint.bash @@ -25,9 +25,9 @@ echo "==> Building" git config --system --add safe.directory '/opt/proxysql' cd /opt/proxysql echo "==> ProxySQL '$(git describe --long --abbrev=7)'" -export SOURCE_DATE_EPOCH=$(git show -s --format=%ct HEAD) -echo "==> Setting SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH}" -find /opt/proxysql -not -path "/opt/proxysql/binaries/*" -exec touch -h --date=@${SOURCE_DATE_EPOCH} {} \; +#export SOURCE_DATE_EPOCH=$(git show -s --format=%ct HEAD) +#echo "==> Setting SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH}" +#find /opt/proxysql -not -path "/opt/proxysql/binaries/*" -exec touch -h --date=@${SOURCE_DATE_EPOCH} {} \; if [[ -z ${PROXYSQL_BUILD_TYPE:-} ]] ; then deps_target="build_deps" @@ -36,7 +36,7 @@ else deps_target="build_deps_$PROXYSQL_BUILD_TYPE" build_target="$PROXYSQL_BUILD_TYPE" fi -${MAKE} cleanbuild +#${MAKE} cleanbuild ${MAKE} ${MAKEOPT} "${deps_target}" if [[ -z ${build_target} ]] ; then diff --git a/docker/images/proxysql/suse-compliant/entrypoint/entrypoint.bash b/docker/images/proxysql/suse-compliant/entrypoint/entrypoint.bash index 109b2a27de..cecea77ee9 100755 --- a/docker/images/proxysql/suse-compliant/entrypoint/entrypoint.bash +++ b/docker/images/proxysql/suse-compliant/entrypoint/entrypoint.bash @@ -25,9 +25,9 @@ echo "==> Building" git config --system --add safe.directory '/opt/proxysql' cd /opt/proxysql echo "==> ProxySQL '$(git describe --long --abbrev=7)'" -export SOURCE_DATE_EPOCH=$(git show -s --format=%ct HEAD) -echo "==> Setting SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH}" -find /opt/proxysql -not -path "/opt/proxysql/binaries/*" -exec touch -h --date=@${SOURCE_DATE_EPOCH} {} \; +#export SOURCE_DATE_EPOCH=$(git show -s --format=%ct HEAD) +#echo "==> Setting SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH}" +#find /opt/proxysql -not -path "/opt/proxysql/binaries/*" -exec touch -h --date=@${SOURCE_DATE_EPOCH} {} \; if [[ -z ${PROXYSQL_BUILD_TYPE:-} ]] ; then deps_target="build_deps" @@ -36,7 +36,7 @@ else deps_target="build_deps_$PROXYSQL_BUILD_TYPE" build_target="$PROXYSQL_BUILD_TYPE" fi -${MAKE} cleanbuild +#${MAKE} cleanbuild ${MAKE} ${MAKEOPT} "${deps_target}" if [[ -z ${build_target} ]] ; then diff --git a/test/tap/tap/Makefile b/test/tap/tap/Makefile index 1f724aee77..aa7fb3486f 100644 --- a/test/tap/tap/Makefile +++ b/test/tap/tap/Makefile @@ -180,3 +180,6 @@ clean: find . -name '*.o' -delete || true find . -name '*.so' -delete || true find . -name '*.so.*' -delete || true + cd cpp-dotenv/static && rm -rf cpp-dotenv-*/ || true + cd cpp-dotenv/dynamic && rm -rf cpp-dotenv-*/ || true + From d8678836fcbb2d26ff3669ff5cf95dc7fd2032e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Wed, 18 Sep 2024 09:55:00 +0000 Subject: [PATCH 42/62] Fix bug #4646 Closes #4646 --- lib/ProxySQL_Admin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ProxySQL_Admin.cpp b/lib/ProxySQL_Admin.cpp index efd6d5ba27..f80826327d 100644 --- a/lib/ProxySQL_Admin.cpp +++ b/lib/ProxySQL_Admin.cpp @@ -10376,7 +10376,7 @@ int ProxySQL_Admin::stats___save_mysql_query_digest_to_sqlite( SQLite3_row *row = resultset ? resultset->rows[i] : NULL; char digest_hex_str[20]; // 2+sizeof(unsigned long long)*2+2 if (!resultset) { - sprintf(digest_hex_str, "0x%16llX", (long long unsigned int)qds->digest); + sprintf(digest_hex_str, "0x%016llX", (long long unsigned int)qds->digest); } int idx=row_idx%32; if (row_idx Date: Thu, 19 Sep 2024 23:49:33 +0500 Subject: [PATCH 43/62] DNS Cache Fixes * If a MySQL connection fails or times out for a specific hostname, the corresponding DNS record will be removed from DNS Cache. This ensures that outdated DNS records are not retained. (Rest of the DNS resolution process remains unchanged) * DNS cache functionality will automatically be disabled when ProxySQL is run with the -M or --no-monitor option. --- include/MySQL_Monitor.hpp | 6 +++++- include/MySQL_Session.h | 2 ++ include/ProxySQL_Cluster.hpp | 1 + lib/MySQL_Monitor.cpp | 30 ++++++++++++++++++++++++++++-- lib/MySQL_Session.cpp | 29 ++++++++++++++++++++++------- lib/ProxySQL_Cluster.cpp | 9 +++++++++ lib/mysql_connection.cpp | 10 +++++++++- 7 files changed, 76 insertions(+), 11 deletions(-) diff --git a/include/MySQL_Monitor.hpp b/include/MySQL_Monitor.hpp index 08901f5616..513d043dca 100644 --- a/include/MySQL_Monitor.hpp +++ b/include/MySQL_Monitor.hpp @@ -398,7 +398,9 @@ struct DNS_Cache_Record { class DNS_Cache { public: - DNS_Cache() : enabled(true) { + // By default, the DNS cache is disabled. + // This handles the case when ProxySQL is executed with the -M/--no-monitor option. + DNS_Cache() : enabled(false) { int rc = pthread_rwlock_init(&rwlock_, NULL); assert(rc == 0); } @@ -445,6 +447,7 @@ class MySQL_Monitor { static std::string dns_lookup(const std::string& hostname, bool return_hostname_if_lookup_fails = true, size_t* ip_count = NULL); static std::string dns_lookup(const char* hostname, bool return_hostname_if_lookup_fails = true, size_t* ip_count = NULL); static bool update_dns_cache_from_mysql_conn(const MYSQL* mysql); + static void remove_dns_record_from_dns_cache(const std::string& hostname); static void trigger_dns_cache_update(); void process_discovered_topology(const std::string& originating_server_hostname, const vector& discovered_servers, int reader_hostgroup); @@ -457,6 +460,7 @@ class MySQL_Monitor { void drop_tables_defs(std::vector *tables_defs); void check_and_build_standard_tables(SQLite3DB *db, std::vector *tables_defs); static bool _dns_cache_update(const std::string& hostname, std::vector&& ip_address); + static void _remove_dns_record_from_dns_cache(const std::string& hostname); public: pthread_mutex_t group_replication_mutex; // for simplicity, a mutex instead of a rwlock diff --git a/include/MySQL_Session.h b/include/MySQL_Session.h index 2a593d3ce5..fc7327b69c 100644 --- a/include/MySQL_Session.h +++ b/include/MySQL_Session.h @@ -473,6 +473,8 @@ class KillArgs { KillArgs(char *u, char *p, char *h, unsigned int P, unsigned int _hid, unsigned long i, int kt, int _use_ssl, MySQL_Thread* _mt, char *ip); ~KillArgs(); const char* get_host_address() const; + void resolve_hostname(); + void remove_dns_record(); private: char* ip_addr; diff --git a/include/ProxySQL_Cluster.hpp b/include/ProxySQL_Cluster.hpp index 05621f543e..0f37559f5e 100644 --- a/include/ProxySQL_Cluster.hpp +++ b/include/ProxySQL_Cluster.hpp @@ -104,6 +104,7 @@ class ProxySQL_Node_Address { ~ProxySQL_Node_Address(); const char* get_host_address() const; void resolve_hostname(); + void remove_dns_record(); private: char* ip_addr; }; diff --git a/lib/MySQL_Monitor.cpp b/lib/MySQL_Monitor.cpp index a0cd601221..f95167b912 100644 --- a/lib/MySQL_Monitor.cpp +++ b/lib/MySQL_Monitor.cpp @@ -1549,6 +1549,10 @@ bool MySQL_Monitor_State_Data::create_new_connection() { myrc=mysql_real_connect(mysql, "localhost", mysql_thread___monitor_username, mysql_thread___monitor_password, NULL, 0, hostname, 0); } if (myrc==NULL) { + // port == 0 means we are connecting to a unix socket + if (port) { + MySQL_Monitor::remove_dns_record_from_dns_cache(hostname); + } mysql_error_msg=strdup(mysql_error(mysql)); int myerrno=mysql_errno(mysql); MyHGM->p_update_mysql_error_counter(p_mysql_error_type::proxysql, hostgroup_id, hostname, port, myerrno); @@ -6653,6 +6657,15 @@ bool MySQL_Monitor::update_dns_cache_from_mysql_conn(const MYSQL* mysql) return result; } +void MySQL_Monitor::remove_dns_record_from_dns_cache(const std::string& hostname) { + + // if IP was provided, no need to update dns cache + if (hostname.empty() || validate_ip(hostname)) + return; + + _remove_dns_record_from_dns_cache(hostname); +} + bool MySQL_Monitor::_dns_cache_update(const std::string &hostname, std::vector&& ip_address) { static thread_local std::shared_ptr dns_cache_thread; @@ -6669,6 +6682,18 @@ bool MySQL_Monitor::_dns_cache_update(const std::string &hostname, std::vector dns_cache_thread; + + if (!dns_cache_thread && GloMyMon) + dns_cache_thread = GloMyMon->dns_cache; + + if (dns_cache_thread) { + dns_cache_thread->remove(trim(hostname)); + proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Direct DNS cache record removed. (Hostname:[%s])\n", hostname.c_str()); + } +} + void MySQL_Monitor::trigger_dns_cache_update() { if (GloMyMon) { GloMyMon->force_dns_cache_update = true; @@ -6697,7 +6722,7 @@ bool DNS_Cache::add(const std::string& hostname, std::vector&& ips) bool DNS_Cache::add_if_not_exist(const std::string& hostname, std::vector&& ips) { if (!enabled) return false; - + bool item_added = false; int rc = pthread_rwlock_wrlock(&rwlock_); assert(rc == 0); if (records.find(hostname) == records.end()) { @@ -6705,11 +6730,12 @@ bool DNS_Cache::add_if_not_exist(const std::string& hostname, std::vectordns_cache_record_updated, 1); return true; diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index e4ba12f440..894caeb616 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -209,13 +209,7 @@ bool Session_Regex::match(char *m) { KillArgs::KillArgs(char* u, char* p, char* h, unsigned int P, unsigned int _hid, unsigned long i, int kt, int _use_ssl, MySQL_Thread* _mt) : KillArgs(u, p, h, P, _hid, i, kt, _use_ssl, _mt, NULL) { // resolving DNS if available in Cache - if (h && P) { - const std::string& ip = MySQL_Monitor::dns_lookup(h, false); - - if (ip.empty() == false) { - ip_addr = strdup(ip.c_str()); - } - } + resolve_hostname(); } KillArgs::KillArgs(char* u, char* p, char* h, unsigned int P, unsigned int _hid, unsigned long i, int kt, int _use_ssl, MySQL_Thread *_mt, char *ip) { @@ -250,6 +244,25 @@ const char* KillArgs::get_host_address() const { return host_address; } +void KillArgs::resolve_hostname() { + if (ip_addr) { + free(ip_addr); + ip_addr = NULL; + } + if (hostname && port) { + const std::string& ip = MySQL_Monitor::dns_lookup(hostname, false); + + if (ip.empty() == false) { + ip_addr = strdup(ip.c_str()); + } + } +} + +void KillArgs::remove_dns_record() { + if (hostname && port) { + MySQL_Monitor::remove_dns_record_from_dns_cache(hostname); + } +} /** * @brief Thread function to kill a query or connection on a MySQL server. @@ -324,6 +337,8 @@ void* kill_query_thread(void *arg) { ret=mysql_real_connect(mysql,"localhost",ka->username,ka->password,NULL,0,ka->hostname,0); } if (!ret) { + ka->remove_dns_record(); + //ka->resolve_hostname(); int myerr = mysql_errno(mysql); if (ssl_params != NULL && myerr == 2026) { proxy_error("Failed to connect to server %s:%d to run KILL %s %lu. SSL Params: %s , %s , %s , %s , %s , %s , %s , %s\n", diff --git a/lib/ProxySQL_Cluster.cpp b/lib/ProxySQL_Cluster.cpp index 61d3cba703..8f6d71ab55 100644 --- a/lib/ProxySQL_Cluster.cpp +++ b/lib/ProxySQL_Cluster.cpp @@ -241,6 +241,7 @@ void * ProxySQL_Cluster_Monitor_thread(void *args) { } } else { proxy_warning("Cluster: unable to connect to peer %s:%d . Error: %s\n", node->hostname, node->port, mysql_error(conn)); + node->remove_dns_record(); node->resolve_hostname(); mysql_close(conn); conn = mysql_init(NULL); @@ -4481,3 +4482,11 @@ void ProxySQL_Node_Address::resolve_hostname() { } } } + +void ProxySQL_Node_Address::remove_dns_record() { + // make sure hostname is not NULL and port is not 0 (UNIX socket) + if (hostname && port) { + MySQL_Monitor::remove_dns_record_from_dns_cache(hostname); + } +} + diff --git a/lib/mysql_connection.cpp b/lib/mysql_connection.cpp index 8ae6a85f5c..97936f4ec5 100644 --- a/lib/mysql_connection.cpp +++ b/lib/mysql_connection.cpp @@ -1278,11 +1278,19 @@ MDB_ASYNC_ST MySQL_Connection::handler(short event) { //} MySQL_Monitor::update_dns_cache_from_mysql_conn(mysql); break; - case ASYNC_CONNECT_FAILED: + case ASYNC_CONNECT_FAILED: + // port == 0 means we are connecting to a unix socket + if (parent->port) { + MySQL_Monitor::remove_dns_record_from_dns_cache(parent->address); + } MyHGM->p_update_mysql_error_counter(p_mysql_error_type::mysql, parent->myhgc->hid, parent->address, parent->port, mysql_errno(mysql)); parent->connect_error(mysql_errno(mysql)); break; case ASYNC_CONNECT_TIMEOUT: + // port == 0 means we are connecting to a unix socket + if (parent->port) { + MySQL_Monitor::remove_dns_record_from_dns_cache(parent->address); + } //proxy_error("Connect timeout on %s:%d : %llu - %llu = %llu\n", parent->address, parent->port, myds->sess->thread->curtime , myds->wait_until, myds->sess->thread->curtime - myds->wait_until); proxy_error("Connect timeout on %s:%d : exceeded by %lluus\n", parent->address, parent->port, myds->sess->thread->curtime - myds->wait_until); MyHGM->p_update_mysql_error_counter(p_mysql_error_type::mysql, parent->myhgc->hid, parent->address, parent->port, mysql_errno(mysql)); From c8ea95564cb4a2e5f8cc795ef87961930be8355f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Thu, 19 Sep 2024 22:57:23 +0000 Subject: [PATCH 44/62] reload of TLS certificates after a crash #4658 Closes #4658 --- src/main.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 382b42363a..85efe4f201 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1474,6 +1474,9 @@ bool ProxySQL_daemonize_phase3() { proxy_info("ProxySQL SHA1 checksum: %s\n", binary_sha1); } call_execute_on_exit_failure(); + // automatic reload of TLS certificates after a crash , see #4658 + std::string msg; + ProxySQL_create_or_load_TLS(false, msg); parent_close_error_log(); return false; } From 061198dda146477d1577a5f8c9aa2d2b05de1fa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Thu, 19 Sep 2024 23:01:43 +0000 Subject: [PATCH 45/62] Honor --initial after a crash , see #4659 Closes #4659 --- src/main.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 85efe4f201..9dd86b8045 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1477,6 +1477,13 @@ bool ProxySQL_daemonize_phase3() { // automatic reload of TLS certificates after a crash , see #4658 std::string msg; ProxySQL_create_or_load_TLS(false, msg); + // Honor --initial after a crash , see #4659 + if (GloVars.__cmd_proxysql_initial==true) { + std::cerr << "Renaming database file " << GloVars.admindb << endl; + char *newpath=(char *)malloc(strlen(GloVars.admindb)+8); + sprintf(newpath,"%s.bak",GloVars.admindb); + rename(GloVars.admindb,newpath); // FIXME: should we check return value, or ignore whatever it successed or not? + } parent_close_error_log(); return false; } From 774b405a74f3bd2b8527cd1f8d2c661f53ffd973 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Thu, 19 Sep 2024 23:13:03 +0000 Subject: [PATCH 46/62] Make call_execute_on_exit_failure() more verbose --- src/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 9dd86b8045..76f02a073b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1380,15 +1380,15 @@ bool ProxySQL_daemonize_phase2() { * @note This function does not return if an error occurs; it exits the process. */ void call_execute_on_exit_failure() { + // Log a message indicating the attempt to call the external script + proxy_info("Trying to call external script after exit failure: %s\n", GloVars.execute_on_exit_failure ? GloVars.execute_on_exit_failure : "(null)"); + // Check if the global variable execute_on_exit_failure is NULL if (GloVars.execute_on_exit_failure == NULL) { // Exit the function if the variable is not set return; } - // Log a message indicating the attempt to call the external script - proxy_error("Trying to call external script after exit failure: %s\n", GloVars.execute_on_exit_failure); - // Fork a child process pid_t cpid; cpid = fork(); From d7529496c406832332806e34e596821351fbce55 Mon Sep 17 00:00:00 2001 From: Miro Stauder Date: Tue, 24 Sep 2024 16:57:33 +0000 Subject: [PATCH 47/62] bump version to 2.7.2 at the beginning of the development cycle --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 831da6f30f..d77c5f25f7 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ O3 := -O3 -mtune=native ALL_DEBUG := $(O0) -ggdb -DDEBUG NO_DEBUG := $(O2) -ggdb DEBUG := $(ALL_DEBUG) -CURVER ?= 2.7.1 +CURVER ?= 2.7.2 #export DEBUG #export EXTRALINK export MAKE From 6c02789591874bac9c1b58642f563ca43df9e973 Mon Sep 17 00:00:00 2001 From: Miro Stauder Date: Wed, 25 Sep 2024 00:13:48 +0200 Subject: [PATCH 48/62] update triggers --- .github/workflows/CI-3p-django-framework.yml | 17 ++++------------- .github/workflows/CI-3p-laravel-framework.yml | 15 +++------------ .github/workflows/CI-3p-mariadb-connector-c.yml | 15 +++------------ .github/workflows/CI-3p-mysql-connector-j.yml | 15 +++------------ .github/workflows/CI-3p-php-pdo-mysql.yml | 15 +++------------ .github/workflows/CI-3p-sqlalchemy.yml | 15 +++------------ .github/workflows/CI-basictests.yml | 15 +++------------ .github/workflows/CI-builds.yml | 4 ++-- .github/workflows/CI-codeql.yml | 15 +++------------ .github/workflows/CI-maketest.yml | 15 +++------------ .github/workflows/CI-package-build.yml | 12 ++++++------ .github/workflows/CI-repltests.yml | 15 +++------------ .github/workflows/CI-selftests.yml | 15 +++------------ .github/workflows/CI-shuntest.yml | 15 +++------------ .github/workflows/CI-taptests-asan.yml | 15 +++------------ .github/workflows/CI-taptests-groups.yml | 15 +++------------ .github/workflows/CI-taptests-ssl.yml | 15 +++------------ .github/workflows/CI-taptests.yml | 15 +++------------ 18 files changed, 57 insertions(+), 201 deletions(-) diff --git a/.github/workflows/CI-3p-django-framework.yml b/.github/workflows/CI-3p-django-framework.yml index 4fd9340531..717dd0d58e 100644 --- a/.github/workflows/CI-3p-django-framework.yml +++ b/.github/workflows/CI-3p-django-framework.yml @@ -1,20 +1,11 @@ name: CI-3p-django-framework on: - push: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' - pull_request: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' -# schedule: -# - cron: '15 13 * * 3' workflow_dispatch: - + workflow_run: + workflows: [ CI-builds ] + types: [ completed ] + concurrency: group: ${{ github.workflow }}-${{ github.ref_name }} cancel-in-progress: true diff --git a/.github/workflows/CI-3p-laravel-framework.yml b/.github/workflows/CI-3p-laravel-framework.yml index b3f6460090..72aba7dd40 100644 --- a/.github/workflows/CI-3p-laravel-framework.yml +++ b/.github/workflows/CI-3p-laravel-framework.yml @@ -1,19 +1,10 @@ name: CI-3p-laravel-framework on: - push: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' - pull_request: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' -# schedule: -# - cron: '15 13 * * 3' workflow_dispatch: + workflow_run: + workflows: [ CI-builds ] + types: [ completed ] concurrency: group: ${{ github.workflow }}-${{ github.ref_name }} diff --git a/.github/workflows/CI-3p-mariadb-connector-c.yml b/.github/workflows/CI-3p-mariadb-connector-c.yml index d1843cebf7..3aa4757d43 100644 --- a/.github/workflows/CI-3p-mariadb-connector-c.yml +++ b/.github/workflows/CI-3p-mariadb-connector-c.yml @@ -1,19 +1,10 @@ name: CI-3p-mariadb-connector-c on: - push: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' - pull_request: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' -# schedule: -# - cron: '15 13 * * 3' workflow_dispatch: + workflow_run: + workflows: [ CI-builds ] + types: [ completed ] concurrency: group: ${{ github.workflow }}-${{ github.ref_name }} diff --git a/.github/workflows/CI-3p-mysql-connector-j.yml b/.github/workflows/CI-3p-mysql-connector-j.yml index 865d7b8bf4..f4d49a57aa 100644 --- a/.github/workflows/CI-3p-mysql-connector-j.yml +++ b/.github/workflows/CI-3p-mysql-connector-j.yml @@ -1,19 +1,10 @@ name: CI-3p-mysql-connector-j on: - push: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' - pull_request: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' -# schedule: -# - cron: '15 13 * * 3' workflow_dispatch: + workflow_run: + workflows: [ CI-builds ] + types: [ completed ] concurrency: group: ${{ github.workflow }}-${{ github.ref_name }} diff --git a/.github/workflows/CI-3p-php-pdo-mysql.yml b/.github/workflows/CI-3p-php-pdo-mysql.yml index 529b425ef5..1f1a7a96e1 100644 --- a/.github/workflows/CI-3p-php-pdo-mysql.yml +++ b/.github/workflows/CI-3p-php-pdo-mysql.yml @@ -1,19 +1,10 @@ name: CI-3p-php-pdo-mysql on: - push: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' - pull_request: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' -# schedule: -# - cron: '15 13 * * 3' workflow_dispatch: + workflow_run: + workflows: [ CI-builds ] + types: [ completed ] concurrency: group: ${{ github.workflow }}-${{ github.ref_name }} diff --git a/.github/workflows/CI-3p-sqlalchemy.yml b/.github/workflows/CI-3p-sqlalchemy.yml index 2579536018..18e6948c77 100644 --- a/.github/workflows/CI-3p-sqlalchemy.yml +++ b/.github/workflows/CI-3p-sqlalchemy.yml @@ -1,19 +1,10 @@ name: CI-3p-sqlalchemy on: - push: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' - pull_request: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' -# schedule: -# - cron: '15 13 * * 3' workflow_dispatch: + workflow_run: + workflows: [ CI-builds ] + types: [ completed ] concurrency: group: ${{ github.workflow }}-${{ github.ref_name }} diff --git a/.github/workflows/CI-basictests.yml b/.github/workflows/CI-basictests.yml index 4eb8b93128..72213b2e91 100644 --- a/.github/workflows/CI-basictests.yml +++ b/.github/workflows/CI-basictests.yml @@ -1,19 +1,10 @@ name: CI-basictests on: - push: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' - pull_request: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' -# schedule: -# - cron: '15 13 * * 3' workflow_dispatch: + workflow_run: + workflows: [ CI-builds ] + types: [ completed ] concurrency: group: ${{ github.workflow }}-${{ github.ref_name }} diff --git a/.github/workflows/CI-builds.yml b/.github/workflows/CI-builds.yml index 954bacf8c5..dd888278ad 100644 --- a/.github/workflows/CI-builds.yml +++ b/.github/workflows/CI-builds.yml @@ -2,12 +2,12 @@ name: CI-builds on: push: -# branches: [ "v2.7" ] +# branches: [ 'v[0-9]+.x','v[0-9]+.[0-9]+','v[0-9]+.[0-9]+.[0-9]+' ] paths-ignore: - '.github/**' - '**.md' pull_request: -# branches: [ "v2.7" ] +# branches: [ 'v[0-9]+.x','v[0-9]+.[0-9]+','v[0-9]+.[0-9]+.[0-9]+' ] paths-ignore: - '.github/**' - '**.md' diff --git a/.github/workflows/CI-codeql.yml b/.github/workflows/CI-codeql.yml index 09c7fb6cd6..bad85f96b5 100644 --- a/.github/workflows/CI-codeql.yml +++ b/.github/workflows/CI-codeql.yml @@ -1,19 +1,10 @@ name: CI-CodeQL on: - push: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' - pull_request: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' -# schedule: -# - cron: '15 13 * * 3' workflow_dispatch: + workflow_run: + workflows: [ CI-builds ] + types: [ completed ] concurrency: group: ${{ github.workflow }}-${{ github.ref_name }} diff --git a/.github/workflows/CI-maketest.yml b/.github/workflows/CI-maketest.yml index df9f1cd560..ec8e9d57f7 100644 --- a/.github/workflows/CI-maketest.yml +++ b/.github/workflows/CI-maketest.yml @@ -1,19 +1,10 @@ name: CI-maketest on: - push: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' - pull_request: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' -# schedule: -# - cron: '15 13 * * 3' workflow_dispatch: + workflow_run: + workflows: [ CI-builds ] + types: [ completed ] concurrency: group: ${{ github.workflow }}-${{ github.ref_name }} diff --git a/.github/workflows/CI-package-build.yml b/.github/workflows/CI-package-build.yml index bdc0115011..ba90e2b4d2 100644 --- a/.github/workflows/CI-package-build.yml +++ b/.github/workflows/CI-package-build.yml @@ -2,15 +2,15 @@ name: CI-Package-Build on: push: -# branches: [ "v[0-9]+.x?[0-9]*.?x?[0-9]*" ] + branches: [ 'v[0-9]+.x','v[0-9]+.[0-9]+','v[0-9]+.[0-9]+.[0-9]+' ] + paths-ignore: + - '.github/**' + - '**.md' + pull_request: + branches: [ 'v[0-9]+.x','v[0-9]+.[0-9]+','v[0-9]+.[0-9]+.[0-9]+' ] paths-ignore: - '.github/**' - '**.md' -# pull_request: -# branches: [ "v2.x" ] -# paths-ignore: -# - '.github/**' -# - '**.md' # schedule: # - cron: '15 13 * * 3' workflow_dispatch: diff --git a/.github/workflows/CI-repltests.yml b/.github/workflows/CI-repltests.yml index a4d3633ba1..199a8df1d9 100644 --- a/.github/workflows/CI-repltests.yml +++ b/.github/workflows/CI-repltests.yml @@ -1,19 +1,10 @@ name: CI-repltests on: - push: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' - pull_request: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' -# schedule: -# - cron: '15 13 * * 3' workflow_dispatch: + workflow_run: + workflows: [ CI-builds ] + types: [ completed ] concurrency: group: ${{ github.workflow }}-${{ github.ref_name }} diff --git a/.github/workflows/CI-selftests.yml b/.github/workflows/CI-selftests.yml index d8f90d912a..44c163c745 100644 --- a/.github/workflows/CI-selftests.yml +++ b/.github/workflows/CI-selftests.yml @@ -1,19 +1,10 @@ name: CI-selftests on: - push: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' - pull_request: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' -# schedule: -# - cron: '15 13 * * 3' workflow_dispatch: + workflow_run: + workflows: [ CI-builds ] + types: [ completed ] concurrency: group: ${{ github.workflow }}-${{ github.ref_name }} diff --git a/.github/workflows/CI-shuntest.yml b/.github/workflows/CI-shuntest.yml index 71e4818dde..f5999b652a 100644 --- a/.github/workflows/CI-shuntest.yml +++ b/.github/workflows/CI-shuntest.yml @@ -1,19 +1,10 @@ name: CI-shuntest on: - push: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' - pull_request: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' -# schedule: -# - cron: '15 13 * * 3' workflow_dispatch: + workflow_run: + workflows: [ CI-builds ] + types: [ completed ] concurrency: group: ${{ github.workflow }}-${{ github.ref_name }} diff --git a/.github/workflows/CI-taptests-asan.yml b/.github/workflows/CI-taptests-asan.yml index 437ae09a7f..b84a62870a 100644 --- a/.github/workflows/CI-taptests-asan.yml +++ b/.github/workflows/CI-taptests-asan.yml @@ -1,19 +1,10 @@ name: CI-taptests-asan on: - push: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' - pull_request: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' -# schedule: -# - cron: '15 13 * * 3' workflow_dispatch: + workflow_run: + workflows: [ CI-builds ] + types: [ completed ] concurrency: group: ${{ github.workflow }}-${{ github.ref_name }} diff --git a/.github/workflows/CI-taptests-groups.yml b/.github/workflows/CI-taptests-groups.yml index f41dbb12ff..13b0a22eda 100644 --- a/.github/workflows/CI-taptests-groups.yml +++ b/.github/workflows/CI-taptests-groups.yml @@ -1,19 +1,10 @@ name: CI-taptests-groups on: - push: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' - pull_request: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' -# schedule: -# - cron: '15 13 * * 3' workflow_dispatch: + workflow_run: + workflows: [ CI-builds ] + types: [ completed ] concurrency: group: ${{ github.workflow }}-${{ github.ref_name }} diff --git a/.github/workflows/CI-taptests-ssl.yml b/.github/workflows/CI-taptests-ssl.yml index 47efc386fd..cc5f2b40f5 100644 --- a/.github/workflows/CI-taptests-ssl.yml +++ b/.github/workflows/CI-taptests-ssl.yml @@ -1,19 +1,10 @@ name: CI-taptests-ssl on: - push: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' - pull_request: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' -# schedule: -# - cron: '15 13 * * 3' workflow_dispatch: + workflow_run: + workflows: [ CI-builds ] + types: [ completed ] concurrency: group: ${{ github.workflow }}-${{ github.ref_name }} diff --git a/.github/workflows/CI-taptests.yml b/.github/workflows/CI-taptests.yml index de07a39151..b24e07247a 100644 --- a/.github/workflows/CI-taptests.yml +++ b/.github/workflows/CI-taptests.yml @@ -1,19 +1,10 @@ name: CI-taptests on: - push: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' - pull_request: -# branches: [ "v2.x" ] - paths-ignore: - - '.github/**' - - '**.md' -# schedule: -# - cron: '15 13 * * 3' workflow_dispatch: + workflow_run: + workflows: [ CI-builds ] + types: [ completed ] concurrency: group: ${{ github.workflow }}-${{ github.ref_name }} From 34055ce99e7d7819e7015ea00a8487ecb1f27a22 Mon Sep 17 00:00:00 2001 From: Miro Stauder Date: Thu, 26 Sep 2024 22:47:58 +0200 Subject: [PATCH 49/62] pass github context to scripts --- .github/workflows/CI-3p-django-framework.yml | 5 ++++- .github/workflows/CI-3p-laravel-framework.yml | 5 ++++- .github/workflows/CI-3p-mariadb-connector-c.yml | 5 ++++- .github/workflows/CI-3p-mysql-connector-j.yml | 5 ++++- .github/workflows/CI-3p-php-pdo-mysql.yml | 5 ++++- .github/workflows/CI-3p-sqlalchemy.yml | 5 ++++- .github/workflows/CI-basictests.yml | 3 ++- .github/workflows/CI-builds.yml | 3 ++- .github/workflows/CI-codeql.yml | 3 ++- .github/workflows/CI-maketest.yml | 4 +++- .github/workflows/CI-package-build.yml | 3 ++- .github/workflows/CI-repltests.yml | 3 ++- .github/workflows/CI-selftests.yml | 3 ++- .github/workflows/CI-shuntest.yml | 3 ++- .github/workflows/CI-taptests-asan.yml | 3 ++- .github/workflows/CI-taptests-groups.yml | 4 +++- .github/workflows/CI-taptests-ssl.yml | 3 ++- .github/workflows/CI-taptests.yml | 4 +++- 18 files changed, 51 insertions(+), 18 deletions(-) diff --git a/.github/workflows/CI-3p-django-framework.yml b/.github/workflows/CI-3p-django-framework.yml index 717dd0d58e..3dbdc670e3 100644 --- a/.github/workflows/CI-3p-django-framework.yml +++ b/.github/workflows/CI-3p-django-framework.yml @@ -14,4 +14,7 @@ jobs: run: uses: sysown/proxysql/.github/workflows/ci-3p-django-framework.yml@GH-Actions secrets: inherit - + with: + trigger: ${{ toJson(github) }} + infradb: ${{ vars.MATRIX_3P_SQLALCHEMY_infradb_mysql }} + connector: ${{ vars.MATRIX_3P_SQLALCHEMY_connector_mysql }} diff --git a/.github/workflows/CI-3p-laravel-framework.yml b/.github/workflows/CI-3p-laravel-framework.yml index 72aba7dd40..798b7248ba 100644 --- a/.github/workflows/CI-3p-laravel-framework.yml +++ b/.github/workflows/CI-3p-laravel-framework.yml @@ -14,4 +14,7 @@ jobs: run: uses: sysown/proxysql/.github/workflows/ci-3p-laravel-framework.yml@GH-Actions secrets: inherit - + with: + trigger: ${{ toJson(github) }} + infradb: ${{ vars.MATRIX_3P_SQLALCHEMY_infradb_mysql }} + connector: ${{ vars.MATRIX_3P_SQLALCHEMY_connector_mysql }} diff --git a/.github/workflows/CI-3p-mariadb-connector-c.yml b/.github/workflows/CI-3p-mariadb-connector-c.yml index 3aa4757d43..63f0091426 100644 --- a/.github/workflows/CI-3p-mariadb-connector-c.yml +++ b/.github/workflows/CI-3p-mariadb-connector-c.yml @@ -14,4 +14,7 @@ jobs: run: uses: sysown/proxysql/.github/workflows/ci-3p-mariadb-connector-c.yml@GH-Actions secrets: inherit - + with: + trigger: ${{ toJson(github) }} + infradb: ${{ vars.MATRIX_3P_SQLALCHEMY_infradb_mysql }} + connector: ${{ vars.MATRIX_3P_SQLALCHEMY_connector_mysql }} diff --git a/.github/workflows/CI-3p-mysql-connector-j.yml b/.github/workflows/CI-3p-mysql-connector-j.yml index f4d49a57aa..41b1cd3a32 100644 --- a/.github/workflows/CI-3p-mysql-connector-j.yml +++ b/.github/workflows/CI-3p-mysql-connector-j.yml @@ -14,4 +14,7 @@ jobs: run: uses: sysown/proxysql/.github/workflows/ci-3p-mysql-connector-j.yml@GH-Actions secrets: inherit - + with: + trigger: ${{ toJson(github) }} + infradb: ${{ vars.MATRIX_3P_SQLALCHEMY_infradb_mysql }} + connector: ${{ vars.MATRIX_3P_SQLALCHEMY_connector_mysql }} diff --git a/.github/workflows/CI-3p-php-pdo-mysql.yml b/.github/workflows/CI-3p-php-pdo-mysql.yml index 1f1a7a96e1..7404071645 100644 --- a/.github/workflows/CI-3p-php-pdo-mysql.yml +++ b/.github/workflows/CI-3p-php-pdo-mysql.yml @@ -14,4 +14,7 @@ jobs: run: uses: sysown/proxysql/.github/workflows/ci-3p-php-pdo-mysql.yml@GH-Actions secrets: inherit - + with: + trigger: ${{ toJson(github) }} + infradb: ${{ vars.MATRIX_3P_SQLALCHEMY_infradb_mysql }} + connector: ${{ vars.MATRIX_3P_SQLALCHEMY_connector_mysql }} diff --git a/.github/workflows/CI-3p-sqlalchemy.yml b/.github/workflows/CI-3p-sqlalchemy.yml index 18e6948c77..48ddca1a4d 100644 --- a/.github/workflows/CI-3p-sqlalchemy.yml +++ b/.github/workflows/CI-3p-sqlalchemy.yml @@ -14,4 +14,7 @@ jobs: run: uses: sysown/proxysql/.github/workflows/ci-3p-sqlalchemy.yml@GH-Actions secrets: inherit - + with: + trigger: ${{ toJson(github) }} + infradb: ${{ vars.MATRIX_3P_SQLALCHEMY_infradb_mysql }} + connector: ${{ vars.MATRIX_3P_SQLALCHEMY_connector_mysql }} diff --git a/.github/workflows/CI-basictests.yml b/.github/workflows/CI-basictests.yml index 72213b2e91..ecdf7d54e1 100644 --- a/.github/workflows/CI-basictests.yml +++ b/.github/workflows/CI-basictests.yml @@ -14,4 +14,5 @@ jobs: run: uses: sysown/proxysql/.github/workflows/ci-basictests.yml@GH-Actions secrets: inherit - + with: + trigger: ${{ toJson(github) }} diff --git a/.github/workflows/CI-builds.yml b/.github/workflows/CI-builds.yml index dd888278ad..433e4d6a8a 100644 --- a/.github/workflows/CI-builds.yml +++ b/.github/workflows/CI-builds.yml @@ -23,4 +23,5 @@ jobs: run: uses: sysown/proxysql/.github/workflows/ci-builds.yml@GH-Actions secrets: inherit - + with: + trigger: ${{ toJson(github) }} diff --git a/.github/workflows/CI-codeql.yml b/.github/workflows/CI-codeql.yml index bad85f96b5..e40a57e6f3 100644 --- a/.github/workflows/CI-codeql.yml +++ b/.github/workflows/CI-codeql.yml @@ -14,4 +14,5 @@ jobs: run: uses: sysown/proxysql/.github/workflows/ci-codeql.yml@GH-Actions secrets: inherit - + with: + trigger: ${{ toJson(github) }} diff --git a/.github/workflows/CI-maketest.yml b/.github/workflows/CI-maketest.yml index ec8e9d57f7..50804a6006 100644 --- a/.github/workflows/CI-maketest.yml +++ b/.github/workflows/CI-maketest.yml @@ -14,4 +14,6 @@ jobs: run: uses: sysown/proxysql/.github/workflows/ci-maketest.yml@GH-Actions secrets: inherit - + with: + trigger: ${{ toJson(github) }} + target: ${{ vars.MATRIX_MAKETEST_target }} diff --git a/.github/workflows/CI-package-build.yml b/.github/workflows/CI-package-build.yml index ba90e2b4d2..5cfa641102 100644 --- a/.github/workflows/CI-package-build.yml +++ b/.github/workflows/CI-package-build.yml @@ -23,4 +23,5 @@ jobs: run: uses: sysown/proxysql/.github/workflows/ci-package-build.yml@GH-Actions secrets: inherit - + with: + trigger: ${{ toJson(github) }} diff --git a/.github/workflows/CI-repltests.yml b/.github/workflows/CI-repltests.yml index 199a8df1d9..134a65e3f6 100644 --- a/.github/workflows/CI-repltests.yml +++ b/.github/workflows/CI-repltests.yml @@ -14,4 +14,5 @@ jobs: run: uses: sysown/proxysql/.github/workflows/ci-repltests.yml@GH-Actions secrets: inherit - + with: + trigger: ${{ toJson(github) }} diff --git a/.github/workflows/CI-selftests.yml b/.github/workflows/CI-selftests.yml index 44c163c745..b0850e2a13 100644 --- a/.github/workflows/CI-selftests.yml +++ b/.github/workflows/CI-selftests.yml @@ -14,4 +14,5 @@ jobs: run: uses: sysown/proxysql/.github/workflows/ci-selftests.yml@GH-Actions secrets: inherit - + with: + trigger: ${{ toJson(github) }} diff --git a/.github/workflows/CI-shuntest.yml b/.github/workflows/CI-shuntest.yml index f5999b652a..5c8da34e1a 100644 --- a/.github/workflows/CI-shuntest.yml +++ b/.github/workflows/CI-shuntest.yml @@ -14,4 +14,5 @@ jobs: run: uses: sysown/proxysql/.github/workflows/ci-shuntest.yml@GH-Actions secrets: inherit - + with: + trigger: ${{ toJson(github) }} diff --git a/.github/workflows/CI-taptests-asan.yml b/.github/workflows/CI-taptests-asan.yml index b84a62870a..6b6b8de859 100644 --- a/.github/workflows/CI-taptests-asan.yml +++ b/.github/workflows/CI-taptests-asan.yml @@ -14,4 +14,5 @@ jobs: run: uses: sysown/proxysql/.github/workflows/ci-taptests-asan.yml@GH-Actions secrets: inherit - + with: + trigger: ${{ toJson(github) }} diff --git a/.github/workflows/CI-taptests-groups.yml b/.github/workflows/CI-taptests-groups.yml index 13b0a22eda..3e2249ceef 100644 --- a/.github/workflows/CI-taptests-groups.yml +++ b/.github/workflows/CI-taptests-groups.yml @@ -14,4 +14,6 @@ jobs: run: uses: sysown/proxysql/.github/workflows/ci-taptests-groups.yml@GH-Actions secrets: inherit - + with: + trigger: ${{ toJson(github) }} + testgroup: ${{ vars.MATRIX_TAP_GROUPS_testgroup }} diff --git a/.github/workflows/CI-taptests-ssl.yml b/.github/workflows/CI-taptests-ssl.yml index cc5f2b40f5..ca441c4e75 100644 --- a/.github/workflows/CI-taptests-ssl.yml +++ b/.github/workflows/CI-taptests-ssl.yml @@ -14,4 +14,5 @@ jobs: run: uses: sysown/proxysql/.github/workflows/ci-taptests-ssl.yml@GH-Actions secrets: inherit - + with: + trigger: ${{ toJson(github) }} diff --git a/.github/workflows/CI-taptests.yml b/.github/workflows/CI-taptests.yml index b24e07247a..69388cd3f2 100644 --- a/.github/workflows/CI-taptests.yml +++ b/.github/workflows/CI-taptests.yml @@ -14,4 +14,6 @@ jobs: run: uses: sysown/proxysql/.github/workflows/ci-taptests.yml@GH-Actions secrets: inherit - + with: + trigger: ${{ toJson(github) }} + testgroup: ${{ vars.MATRIX_TAP_GROUPS_testgroup }} From a99f39cc5f122362ab07cbf936a413984f8c6abd Mon Sep 17 00:00:00 2001 From: Miro Stauder Date: Mon, 30 Sep 2024 20:22:33 +0200 Subject: [PATCH 50/62] show correct run-name set correct concurrency group execute on dependency success --- .github/workflows/CI-3p-django-framework.yml | 4 +++- .github/workflows/CI-3p-laravel-framework.yml | 4 +++- .github/workflows/CI-3p-mariadb-connector-c.yml | 4 +++- .github/workflows/CI-3p-mysql-connector-j.yml | 4 +++- .github/workflows/CI-3p-php-pdo-mysql.yml | 4 +++- .github/workflows/CI-3p-sqlalchemy.yml | 4 +++- .github/workflows/CI-basictests.yml | 4 +++- .github/workflows/CI-builds.yml | 6 +----- .github/workflows/CI-codeql.yml | 4 +++- .github/workflows/CI-maketest.yml | 4 +++- .github/workflows/CI-package-build.yml | 8 ++------ .github/workflows/CI-repltests.yml | 4 +++- .github/workflows/CI-selftests.yml | 4 +++- .github/workflows/CI-shuntest.yml | 4 +++- .github/workflows/CI-taptests-asan.yml | 4 +++- .github/workflows/CI-taptests-groups.yml | 4 +++- .github/workflows/CI-taptests-ssl.yml | 4 +++- .github/workflows/CI-taptests.yml | 4 +++- 18 files changed, 51 insertions(+), 27 deletions(-) diff --git a/.github/workflows/CI-3p-django-framework.yml b/.github/workflows/CI-3p-django-framework.yml index 3dbdc670e3..dc11bbdf6b 100644 --- a/.github/workflows/CI-3p-django-framework.yml +++ b/.github/workflows/CI-3p-django-framework.yml @@ -1,4 +1,5 @@ name: CI-3p-django-framework +run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} ${{ github.workflow }} ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}' on: workflow_dispatch: @@ -7,11 +8,12 @@ on: types: [ completed ] concurrency: - group: ${{ github.workflow }}-${{ github.ref_name }} + group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} cancel-in-progress: true jobs: run: + if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} uses: sysown/proxysql/.github/workflows/ci-3p-django-framework.yml@GH-Actions secrets: inherit with: diff --git a/.github/workflows/CI-3p-laravel-framework.yml b/.github/workflows/CI-3p-laravel-framework.yml index 798b7248ba..61a1fca702 100644 --- a/.github/workflows/CI-3p-laravel-framework.yml +++ b/.github/workflows/CI-3p-laravel-framework.yml @@ -1,4 +1,5 @@ name: CI-3p-laravel-framework +run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} ${{ github.workflow }} ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}' on: workflow_dispatch: @@ -7,11 +8,12 @@ on: types: [ completed ] concurrency: - group: ${{ github.workflow }}-${{ github.ref_name }} + group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} cancel-in-progress: true jobs: run: + if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} uses: sysown/proxysql/.github/workflows/ci-3p-laravel-framework.yml@GH-Actions secrets: inherit with: diff --git a/.github/workflows/CI-3p-mariadb-connector-c.yml b/.github/workflows/CI-3p-mariadb-connector-c.yml index 63f0091426..9da4830eef 100644 --- a/.github/workflows/CI-3p-mariadb-connector-c.yml +++ b/.github/workflows/CI-3p-mariadb-connector-c.yml @@ -1,4 +1,5 @@ name: CI-3p-mariadb-connector-c +run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} ${{ github.workflow }} ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}' on: workflow_dispatch: @@ -7,11 +8,12 @@ on: types: [ completed ] concurrency: - group: ${{ github.workflow }}-${{ github.ref_name }} + group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} cancel-in-progress: true jobs: run: + if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} uses: sysown/proxysql/.github/workflows/ci-3p-mariadb-connector-c.yml@GH-Actions secrets: inherit with: diff --git a/.github/workflows/CI-3p-mysql-connector-j.yml b/.github/workflows/CI-3p-mysql-connector-j.yml index 41b1cd3a32..528432d831 100644 --- a/.github/workflows/CI-3p-mysql-connector-j.yml +++ b/.github/workflows/CI-3p-mysql-connector-j.yml @@ -1,4 +1,5 @@ name: CI-3p-mysql-connector-j +run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} ${{ github.workflow }} ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}' on: workflow_dispatch: @@ -7,11 +8,12 @@ on: types: [ completed ] concurrency: - group: ${{ github.workflow }}-${{ github.ref_name }} + group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} cancel-in-progress: true jobs: run: + if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} uses: sysown/proxysql/.github/workflows/ci-3p-mysql-connector-j.yml@GH-Actions secrets: inherit with: diff --git a/.github/workflows/CI-3p-php-pdo-mysql.yml b/.github/workflows/CI-3p-php-pdo-mysql.yml index 7404071645..b79efb8c82 100644 --- a/.github/workflows/CI-3p-php-pdo-mysql.yml +++ b/.github/workflows/CI-3p-php-pdo-mysql.yml @@ -1,4 +1,5 @@ name: CI-3p-php-pdo-mysql +run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} ${{ github.workflow }} ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}' on: workflow_dispatch: @@ -7,11 +8,12 @@ on: types: [ completed ] concurrency: - group: ${{ github.workflow }}-${{ github.ref_name }} + group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} cancel-in-progress: true jobs: run: + if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} uses: sysown/proxysql/.github/workflows/ci-3p-php-pdo-mysql.yml@GH-Actions secrets: inherit with: diff --git a/.github/workflows/CI-3p-sqlalchemy.yml b/.github/workflows/CI-3p-sqlalchemy.yml index 48ddca1a4d..ed11fcb810 100644 --- a/.github/workflows/CI-3p-sqlalchemy.yml +++ b/.github/workflows/CI-3p-sqlalchemy.yml @@ -1,4 +1,5 @@ name: CI-3p-sqlalchemy +run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} ${{ github.workflow }} ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}' on: workflow_dispatch: @@ -7,11 +8,12 @@ on: types: [ completed ] concurrency: - group: ${{ github.workflow }}-${{ github.ref_name }} + group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} cancel-in-progress: true jobs: run: + if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} uses: sysown/proxysql/.github/workflows/ci-3p-sqlalchemy.yml@GH-Actions secrets: inherit with: diff --git a/.github/workflows/CI-basictests.yml b/.github/workflows/CI-basictests.yml index ecdf7d54e1..ce1f2577dc 100644 --- a/.github/workflows/CI-basictests.yml +++ b/.github/workflows/CI-basictests.yml @@ -1,4 +1,5 @@ name: CI-basictests +run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} ${{ github.workflow }} ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}' on: workflow_dispatch: @@ -7,11 +8,12 @@ on: types: [ completed ] concurrency: - group: ${{ github.workflow }}-${{ github.ref_name }} + group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} cancel-in-progress: true jobs: run: + if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} uses: sysown/proxysql/.github/workflows/ci-basictests.yml@GH-Actions secrets: inherit with: diff --git a/.github/workflows/CI-builds.yml b/.github/workflows/CI-builds.yml index 433e4d6a8a..e14f8b170c 100644 --- a/.github/workflows/CI-builds.yml +++ b/.github/workflows/CI-builds.yml @@ -1,12 +1,8 @@ name: CI-builds +run-name: '${{ github.ref_name }} ${{ github.workflow }} ${{ github.sha }}' on: push: -# branches: [ 'v[0-9]+.x','v[0-9]+.[0-9]+','v[0-9]+.[0-9]+.[0-9]+' ] - paths-ignore: - - '.github/**' - - '**.md' - pull_request: # branches: [ 'v[0-9]+.x','v[0-9]+.[0-9]+','v[0-9]+.[0-9]+.[0-9]+' ] paths-ignore: - '.github/**' diff --git a/.github/workflows/CI-codeql.yml b/.github/workflows/CI-codeql.yml index e40a57e6f3..7d50568811 100644 --- a/.github/workflows/CI-codeql.yml +++ b/.github/workflows/CI-codeql.yml @@ -1,4 +1,5 @@ name: CI-CodeQL +run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} ${{ github.workflow }} ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}' on: workflow_dispatch: @@ -7,11 +8,12 @@ on: types: [ completed ] concurrency: - group: ${{ github.workflow }}-${{ github.ref_name }} + group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} cancel-in-progress: true jobs: run: + if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} uses: sysown/proxysql/.github/workflows/ci-codeql.yml@GH-Actions secrets: inherit with: diff --git a/.github/workflows/CI-maketest.yml b/.github/workflows/CI-maketest.yml index 50804a6006..151be6db9d 100644 --- a/.github/workflows/CI-maketest.yml +++ b/.github/workflows/CI-maketest.yml @@ -1,4 +1,5 @@ name: CI-maketest +run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} ${{ github.workflow }} ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}' on: workflow_dispatch: @@ -7,11 +8,12 @@ on: types: [ completed ] concurrency: - group: ${{ github.workflow }}-${{ github.ref_name }} + group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} cancel-in-progress: true jobs: run: + if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} uses: sysown/proxysql/.github/workflows/ci-maketest.yml@GH-Actions secrets: inherit with: diff --git a/.github/workflows/CI-package-build.yml b/.github/workflows/CI-package-build.yml index 5cfa641102..2f1ab1182e 100644 --- a/.github/workflows/CI-package-build.yml +++ b/.github/workflows/CI-package-build.yml @@ -1,4 +1,5 @@ -name: CI-Package-Build +name: CI-package-build +run-name: '${{ github.ref_name }} ${{ github.workflow }} ${{ github.sha }}' on: push: @@ -6,11 +7,6 @@ on: paths-ignore: - '.github/**' - '**.md' - pull_request: - branches: [ 'v[0-9]+.x','v[0-9]+.[0-9]+','v[0-9]+.[0-9]+.[0-9]+' ] - paths-ignore: - - '.github/**' - - '**.md' # schedule: # - cron: '15 13 * * 3' workflow_dispatch: diff --git a/.github/workflows/CI-repltests.yml b/.github/workflows/CI-repltests.yml index 134a65e3f6..49e1577f65 100644 --- a/.github/workflows/CI-repltests.yml +++ b/.github/workflows/CI-repltests.yml @@ -1,4 +1,5 @@ name: CI-repltests +run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} ${{ github.workflow }} ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}' on: workflow_dispatch: @@ -7,11 +8,12 @@ on: types: [ completed ] concurrency: - group: ${{ github.workflow }}-${{ github.ref_name }} + group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} cancel-in-progress: true jobs: run: + if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} uses: sysown/proxysql/.github/workflows/ci-repltests.yml@GH-Actions secrets: inherit with: diff --git a/.github/workflows/CI-selftests.yml b/.github/workflows/CI-selftests.yml index b0850e2a13..3a0ea7fd76 100644 --- a/.github/workflows/CI-selftests.yml +++ b/.github/workflows/CI-selftests.yml @@ -1,4 +1,5 @@ name: CI-selftests +run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} ${{ github.workflow }} ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}' on: workflow_dispatch: @@ -7,11 +8,12 @@ on: types: [ completed ] concurrency: - group: ${{ github.workflow }}-${{ github.ref_name }} + group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} cancel-in-progress: true jobs: run: + if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} uses: sysown/proxysql/.github/workflows/ci-selftests.yml@GH-Actions secrets: inherit with: diff --git a/.github/workflows/CI-shuntest.yml b/.github/workflows/CI-shuntest.yml index 5c8da34e1a..89c326f644 100644 --- a/.github/workflows/CI-shuntest.yml +++ b/.github/workflows/CI-shuntest.yml @@ -1,4 +1,5 @@ name: CI-shuntest +run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} ${{ github.workflow }} ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}' on: workflow_dispatch: @@ -7,11 +8,12 @@ on: types: [ completed ] concurrency: - group: ${{ github.workflow }}-${{ github.ref_name }} + group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} cancel-in-progress: true jobs: run: + if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} uses: sysown/proxysql/.github/workflows/ci-shuntest.yml@GH-Actions secrets: inherit with: diff --git a/.github/workflows/CI-taptests-asan.yml b/.github/workflows/CI-taptests-asan.yml index 6b6b8de859..49902d1bb2 100644 --- a/.github/workflows/CI-taptests-asan.yml +++ b/.github/workflows/CI-taptests-asan.yml @@ -1,4 +1,5 @@ name: CI-taptests-asan +run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} ${{ github.workflow }} ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}' on: workflow_dispatch: @@ -7,11 +8,12 @@ on: types: [ completed ] concurrency: - group: ${{ github.workflow }}-${{ github.ref_name }} + group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} cancel-in-progress: true jobs: run: + if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} uses: sysown/proxysql/.github/workflows/ci-taptests-asan.yml@GH-Actions secrets: inherit with: diff --git a/.github/workflows/CI-taptests-groups.yml b/.github/workflows/CI-taptests-groups.yml index 3e2249ceef..1527d7d32e 100644 --- a/.github/workflows/CI-taptests-groups.yml +++ b/.github/workflows/CI-taptests-groups.yml @@ -1,4 +1,5 @@ name: CI-taptests-groups +run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} ${{ github.workflow }} ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}' on: workflow_dispatch: @@ -7,11 +8,12 @@ on: types: [ completed ] concurrency: - group: ${{ github.workflow }}-${{ github.ref_name }} + group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} cancel-in-progress: true jobs: run: + if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} uses: sysown/proxysql/.github/workflows/ci-taptests-groups.yml@GH-Actions secrets: inherit with: diff --git a/.github/workflows/CI-taptests-ssl.yml b/.github/workflows/CI-taptests-ssl.yml index ca441c4e75..be0efa3659 100644 --- a/.github/workflows/CI-taptests-ssl.yml +++ b/.github/workflows/CI-taptests-ssl.yml @@ -1,4 +1,5 @@ name: CI-taptests-ssl +run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} ${{ github.workflow }} ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}' on: workflow_dispatch: @@ -7,11 +8,12 @@ on: types: [ completed ] concurrency: - group: ${{ github.workflow }}-${{ github.ref_name }} + group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} cancel-in-progress: true jobs: run: + if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} uses: sysown/proxysql/.github/workflows/ci-taptests-ssl.yml@GH-Actions secrets: inherit with: diff --git a/.github/workflows/CI-taptests.yml b/.github/workflows/CI-taptests.yml index 69388cd3f2..289d9790e4 100644 --- a/.github/workflows/CI-taptests.yml +++ b/.github/workflows/CI-taptests.yml @@ -1,4 +1,5 @@ name: CI-taptests +run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} ${{ github.workflow }} ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}' on: workflow_dispatch: @@ -7,11 +8,12 @@ on: types: [ completed ] concurrency: - group: ${{ github.workflow }}-${{ github.ref_name }} + group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} cancel-in-progress: true jobs: run: + if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} uses: sysown/proxysql/.github/workflows/ci-taptests.yml@GH-Actions secrets: inherit with: From ba814c00852a8425944a7e883c13c02ef113ac40 Mon Sep 17 00:00:00 2001 From: Miro Stauder Date: Wed, 2 Oct 2024 15:36:44 +0200 Subject: [PATCH 51/62] add CI-trigger --- .github/workflows/CI-trigger.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/workflows/CI-trigger.yml diff --git a/.github/workflows/CI-trigger.yml b/.github/workflows/CI-trigger.yml new file mode 100644 index 0000000000..c3ea21ac78 --- /dev/null +++ b/.github/workflows/CI-trigger.yml @@ -0,0 +1,18 @@ +name: CI-trigger +run-name: '${{ github.ref_name }} ${{ github.workflow }} ${{ github.sha }}' + +on: + push: + paths-ignore: + - '.github/**' + - '**.md' + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref_name }} + cancel-in-progress: true + +jobs: + run: + uses: sysown/proxysql/.github/workflows/ci-trigger.yml@GH-Actions + secrets: inherit From d864d5dea52944968b01d6cc1732ec8b0b459331 Mon Sep 17 00:00:00 2001 From: Miro Stauder Date: Wed, 2 Oct 2024 15:37:30 +0200 Subject: [PATCH 52/62] opdate actions to use CI-trigger --- .github/workflows/CI-3p-django-framework.yml | 2 +- .github/workflows/CI-3p-laravel-framework.yml | 2 +- .github/workflows/CI-3p-mariadb-connector-c.yml | 2 +- .github/workflows/CI-3p-mysql-connector-j.yml | 2 +- .github/workflows/CI-3p-php-pdo-mysql.yml | 2 +- .github/workflows/CI-3p-sqlalchemy.yml | 2 +- .github/workflows/CI-basictests.yml | 2 +- .github/workflows/CI-builds.yml | 14 +++++--------- .github/workflows/CI-codeql.yml | 2 +- .github/workflows/CI-maketest.yml | 2 +- .github/workflows/CI-repltests.yml | 2 +- .github/workflows/CI-selftests.yml | 2 +- .github/workflows/CI-shuntest.yml | 2 +- .github/workflows/CI-taptests-asan.yml | 2 +- .github/workflows/CI-taptests-groups.yml | 2 +- .github/workflows/CI-taptests-ssl.yml | 2 +- .github/workflows/CI-taptests.yml | 2 +- 17 files changed, 21 insertions(+), 25 deletions(-) diff --git a/.github/workflows/CI-3p-django-framework.yml b/.github/workflows/CI-3p-django-framework.yml index dc11bbdf6b..fc5ae053bd 100644 --- a/.github/workflows/CI-3p-django-framework.yml +++ b/.github/workflows/CI-3p-django-framework.yml @@ -4,7 +4,7 @@ run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branc on: workflow_dispatch: workflow_run: - workflows: [ CI-builds ] + workflows: [ CI-trigger ] types: [ completed ] concurrency: diff --git a/.github/workflows/CI-3p-laravel-framework.yml b/.github/workflows/CI-3p-laravel-framework.yml index 61a1fca702..8b6cd73228 100644 --- a/.github/workflows/CI-3p-laravel-framework.yml +++ b/.github/workflows/CI-3p-laravel-framework.yml @@ -4,7 +4,7 @@ run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branc on: workflow_dispatch: workflow_run: - workflows: [ CI-builds ] + workflows: [ CI-trigger ] types: [ completed ] concurrency: diff --git a/.github/workflows/CI-3p-mariadb-connector-c.yml b/.github/workflows/CI-3p-mariadb-connector-c.yml index 9da4830eef..b01523bef6 100644 --- a/.github/workflows/CI-3p-mariadb-connector-c.yml +++ b/.github/workflows/CI-3p-mariadb-connector-c.yml @@ -4,7 +4,7 @@ run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branc on: workflow_dispatch: workflow_run: - workflows: [ CI-builds ] + workflows: [ CI-trigger ] types: [ completed ] concurrency: diff --git a/.github/workflows/CI-3p-mysql-connector-j.yml b/.github/workflows/CI-3p-mysql-connector-j.yml index 528432d831..663dd909df 100644 --- a/.github/workflows/CI-3p-mysql-connector-j.yml +++ b/.github/workflows/CI-3p-mysql-connector-j.yml @@ -4,7 +4,7 @@ run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branc on: workflow_dispatch: workflow_run: - workflows: [ CI-builds ] + workflows: [ CI-trigger ] types: [ completed ] concurrency: diff --git a/.github/workflows/CI-3p-php-pdo-mysql.yml b/.github/workflows/CI-3p-php-pdo-mysql.yml index b79efb8c82..2a3b9bea4d 100644 --- a/.github/workflows/CI-3p-php-pdo-mysql.yml +++ b/.github/workflows/CI-3p-php-pdo-mysql.yml @@ -4,7 +4,7 @@ run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branc on: workflow_dispatch: workflow_run: - workflows: [ CI-builds ] + workflows: [ CI-trigger ] types: [ completed ] concurrency: diff --git a/.github/workflows/CI-3p-sqlalchemy.yml b/.github/workflows/CI-3p-sqlalchemy.yml index ed11fcb810..7885cee44e 100644 --- a/.github/workflows/CI-3p-sqlalchemy.yml +++ b/.github/workflows/CI-3p-sqlalchemy.yml @@ -4,7 +4,7 @@ run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branc on: workflow_dispatch: workflow_run: - workflows: [ CI-builds ] + workflows: [ CI-trigger ] types: [ completed ] concurrency: diff --git a/.github/workflows/CI-basictests.yml b/.github/workflows/CI-basictests.yml index ce1f2577dc..22f9f8431d 100644 --- a/.github/workflows/CI-basictests.yml +++ b/.github/workflows/CI-basictests.yml @@ -4,7 +4,7 @@ run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branc on: workflow_dispatch: workflow_run: - workflows: [ CI-builds ] + workflows: [ CI-trigger ] types: [ completed ] concurrency: diff --git a/.github/workflows/CI-builds.yml b/.github/workflows/CI-builds.yml index e14f8b170c..a26ba0c319 100644 --- a/.github/workflows/CI-builds.yml +++ b/.github/workflows/CI-builds.yml @@ -1,18 +1,14 @@ name: CI-builds -run-name: '${{ github.ref_name }} ${{ github.workflow }} ${{ github.sha }}' +run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} ${{ github.workflow }} ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}' on: - push: -# branches: [ 'v[0-9]+.x','v[0-9]+.[0-9]+','v[0-9]+.[0-9]+.[0-9]+' ] - paths-ignore: - - '.github/**' - - '**.md' -# schedule: -# - cron: '15 13 * * 3' workflow_dispatch: + workflow_run: + workflows: [ CI-trigger ] + types: [ in_progress ] concurrency: - group: ${{ github.workflow }}-${{ github.ref_name }} + group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} cancel-in-progress: true jobs: diff --git a/.github/workflows/CI-codeql.yml b/.github/workflows/CI-codeql.yml index 7d50568811..7aa8ec268b 100644 --- a/.github/workflows/CI-codeql.yml +++ b/.github/workflows/CI-codeql.yml @@ -4,7 +4,7 @@ run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branc on: workflow_dispatch: workflow_run: - workflows: [ CI-builds ] + workflows: [ CI-trigger ] types: [ completed ] concurrency: diff --git a/.github/workflows/CI-maketest.yml b/.github/workflows/CI-maketest.yml index 151be6db9d..ce2cf6d486 100644 --- a/.github/workflows/CI-maketest.yml +++ b/.github/workflows/CI-maketest.yml @@ -4,7 +4,7 @@ run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branc on: workflow_dispatch: workflow_run: - workflows: [ CI-builds ] + workflows: [ CI-trigger ] types: [ completed ] concurrency: diff --git a/.github/workflows/CI-repltests.yml b/.github/workflows/CI-repltests.yml index 49e1577f65..f2beac23a6 100644 --- a/.github/workflows/CI-repltests.yml +++ b/.github/workflows/CI-repltests.yml @@ -4,7 +4,7 @@ run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branc on: workflow_dispatch: workflow_run: - workflows: [ CI-builds ] + workflows: [ CI-trigger ] types: [ completed ] concurrency: diff --git a/.github/workflows/CI-selftests.yml b/.github/workflows/CI-selftests.yml index 3a0ea7fd76..7511805c37 100644 --- a/.github/workflows/CI-selftests.yml +++ b/.github/workflows/CI-selftests.yml @@ -4,7 +4,7 @@ run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branc on: workflow_dispatch: workflow_run: - workflows: [ CI-builds ] + workflows: [ CI-trigger ] types: [ completed ] concurrency: diff --git a/.github/workflows/CI-shuntest.yml b/.github/workflows/CI-shuntest.yml index 89c326f644..59b59b6599 100644 --- a/.github/workflows/CI-shuntest.yml +++ b/.github/workflows/CI-shuntest.yml @@ -4,7 +4,7 @@ run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branc on: workflow_dispatch: workflow_run: - workflows: [ CI-builds ] + workflows: [ CI-trigger ] types: [ completed ] concurrency: diff --git a/.github/workflows/CI-taptests-asan.yml b/.github/workflows/CI-taptests-asan.yml index 49902d1bb2..42ef9b6db1 100644 --- a/.github/workflows/CI-taptests-asan.yml +++ b/.github/workflows/CI-taptests-asan.yml @@ -4,7 +4,7 @@ run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branc on: workflow_dispatch: workflow_run: - workflows: [ CI-builds ] + workflows: [ CI-trigger ] types: [ completed ] concurrency: diff --git a/.github/workflows/CI-taptests-groups.yml b/.github/workflows/CI-taptests-groups.yml index 1527d7d32e..cb75b6a3a3 100644 --- a/.github/workflows/CI-taptests-groups.yml +++ b/.github/workflows/CI-taptests-groups.yml @@ -4,7 +4,7 @@ run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branc on: workflow_dispatch: workflow_run: - workflows: [ CI-builds ] + workflows: [ CI-trigger ] types: [ completed ] concurrency: diff --git a/.github/workflows/CI-taptests-ssl.yml b/.github/workflows/CI-taptests-ssl.yml index be0efa3659..e4f7a92578 100644 --- a/.github/workflows/CI-taptests-ssl.yml +++ b/.github/workflows/CI-taptests-ssl.yml @@ -4,7 +4,7 @@ run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branc on: workflow_dispatch: workflow_run: - workflows: [ CI-builds ] + workflows: [ CI-trigger ] types: [ completed ] concurrency: diff --git a/.github/workflows/CI-taptests.yml b/.github/workflows/CI-taptests.yml index 289d9790e4..607f85711b 100644 --- a/.github/workflows/CI-taptests.yml +++ b/.github/workflows/CI-taptests.yml @@ -4,7 +4,7 @@ run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branc on: workflow_dispatch: workflow_run: - workflows: [ CI-builds ] + workflows: [ CI-trigger ] types: [ completed ] concurrency: From a26247362e1505efd35f3b1296533a27ce7cfb6e Mon Sep 17 00:00:00 2001 From: Miro Stauder Date: Wed, 2 Oct 2024 16:47:46 +0200 Subject: [PATCH 53/62] pass specific matrix for mysq/mariadb/pgsql --- .github/workflows/CI-3p-django-framework.yml | 20 ++++++++++++++++++- .github/workflows/CI-3p-laravel-framework.yml | 18 ++++++++++++++++- .github/workflows/CI-3p-sqlalchemy.yml | 20 ++++++++++++++++++- 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CI-3p-django-framework.yml b/.github/workflows/CI-3p-django-framework.yml index fc5ae053bd..9a4b2c0a18 100644 --- a/.github/workflows/CI-3p-django-framework.yml +++ b/.github/workflows/CI-3p-django-framework.yml @@ -12,7 +12,7 @@ concurrency: cancel-in-progress: true jobs: - run: + run-mysql: if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} uses: sysown/proxysql/.github/workflows/ci-3p-django-framework.yml@GH-Actions secrets: inherit @@ -20,3 +20,21 @@ jobs: trigger: ${{ toJson(github) }} infradb: ${{ vars.MATRIX_3P_SQLALCHEMY_infradb_mysql }} connector: ${{ vars.MATRIX_3P_SQLALCHEMY_connector_mysql }} + + run-mariadb: + if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} + uses: sysown/proxysql/.github/workflows/ci-3p-django-framework.yml@GH-Actions + secrets: inherit + with: + trigger: ${{ toJson(github) }} + infradb: ${{ vars.MATRIX_3P_SQLALCHEMY_infradb_mariadb }} + connector: ${{ vars.MATRIX_3P_SQLALCHEMY_connector_mariadb }} + + run-pgsql: + if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} + uses: sysown/proxysql/.github/workflows/ci-3p-django-framework.yml@GH-Actions + secrets: inherit + with: + trigger: ${{ toJson(github) }} + infradb: ${{ vars.MATRIX_3P_SQLALCHEMY_infradb_pgsql }} + connector: ${{ vars.MATRIX_3P_SQLALCHEMY_connector_pgsql }} diff --git a/.github/workflows/CI-3p-laravel-framework.yml b/.github/workflows/CI-3p-laravel-framework.yml index 8b6cd73228..0424349e90 100644 --- a/.github/workflows/CI-3p-laravel-framework.yml +++ b/.github/workflows/CI-3p-laravel-framework.yml @@ -12,7 +12,7 @@ concurrency: cancel-in-progress: true jobs: - run: + run-mysql: if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} uses: sysown/proxysql/.github/workflows/ci-3p-laravel-framework.yml@GH-Actions secrets: inherit @@ -20,3 +20,19 @@ jobs: trigger: ${{ toJson(github) }} infradb: ${{ vars.MATRIX_3P_SQLALCHEMY_infradb_mysql }} connector: ${{ vars.MATRIX_3P_SQLALCHEMY_connector_mysql }} + run-mariadb: + if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} + uses: sysown/proxysql/.github/workflows/ci-3p-laravel-framework.yml@GH-Actions + secrets: inherit + with: + trigger: ${{ toJson(github) }} + infradb: ${{ vars.MATRIX_3P_SQLALCHEMY_infradb_mariadb }} + connector: ${{ vars.MATRIX_3P_SQLALCHEMY_connector_mariadb }} + run-pgsql: + if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} + uses: sysown/proxysql/.github/workflows/ci-3p-laravel-framework.yml@GH-Actions + secrets: inherit + with: + trigger: ${{ toJson(github) }} + infradb: ${{ vars.MATRIX_3P_SQLALCHEMY_infradb_pgsql }} + connector: ${{ vars.MATRIX_3P_SQLALCHEMY_connector_pgsql }} diff --git a/.github/workflows/CI-3p-sqlalchemy.yml b/.github/workflows/CI-3p-sqlalchemy.yml index 7885cee44e..347338cb94 100644 --- a/.github/workflows/CI-3p-sqlalchemy.yml +++ b/.github/workflows/CI-3p-sqlalchemy.yml @@ -12,7 +12,7 @@ concurrency: cancel-in-progress: true jobs: - run: + run-mysql: if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} uses: sysown/proxysql/.github/workflows/ci-3p-sqlalchemy.yml@GH-Actions secrets: inherit @@ -20,3 +20,21 @@ jobs: trigger: ${{ toJson(github) }} infradb: ${{ vars.MATRIX_3P_SQLALCHEMY_infradb_mysql }} connector: ${{ vars.MATRIX_3P_SQLALCHEMY_connector_mysql }} + + run-mariadb: + if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} + uses: sysown/proxysql/.github/workflows/ci-3p-sqlalchemy.yml@GH-Actions + secrets: inherit + with: + trigger: ${{ toJson(github) }} + infradb: ${{ vars.MATRIX_3P_SQLALCHEMY_infradb_mariadb }} + connector: ${{ vars.MATRIX_3P_SQLALCHEMY_connector_mariadb }} + + run-pgsql: + if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} + uses: sysown/proxysql/.github/workflows/ci-3p-sqlalchemy.yml@GH-Actions + secrets: inherit + with: + trigger: ${{ toJson(github) }} + infradb: ${{ vars.MATRIX_3P_SQLALCHEMY_infradb_pgsql }} + connector: ${{ vars.MATRIX_3P_SQLALCHEMY_connector_pgsql }} From e44fa545fa3ddcce9bec1e62c994dbacd669cb25 Mon Sep 17 00:00:00 2001 From: Miro Stauder Date: Tue, 8 Oct 2024 12:31:52 +0200 Subject: [PATCH 54/62] use correct matrix vars --- .github/workflows/CI-3p-django-framework.yml | 12 ++++++------ .github/workflows/CI-3p-laravel-framework.yml | 14 ++++++++------ .github/workflows/CI-3p-mariadb-connector-c.yml | 4 ++-- .github/workflows/CI-3p-mysql-connector-j.yml | 4 ++-- .github/workflows/CI-3p-php-pdo-mysql.yml | 4 ++-- .github/workflows/CI-taptests-groups.yml | 2 +- .github/workflows/CI-taptests.yml | 2 +- 7 files changed, 22 insertions(+), 20 deletions(-) diff --git a/.github/workflows/CI-3p-django-framework.yml b/.github/workflows/CI-3p-django-framework.yml index 9a4b2c0a18..f6a268931d 100644 --- a/.github/workflows/CI-3p-django-framework.yml +++ b/.github/workflows/CI-3p-django-framework.yml @@ -18,8 +18,8 @@ jobs: secrets: inherit with: trigger: ${{ toJson(github) }} - infradb: ${{ vars.MATRIX_3P_SQLALCHEMY_infradb_mysql }} - connector: ${{ vars.MATRIX_3P_SQLALCHEMY_connector_mysql }} + infradb: ${{ vars.MATRIX_3P_DJANGO_FRAMEWORK_infradb_mysql }} + connector: ${{ vars.MATRIX_3P_DJANGO_FRAMEWORK_connector_mysql }} run-mariadb: if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} @@ -27,8 +27,8 @@ jobs: secrets: inherit with: trigger: ${{ toJson(github) }} - infradb: ${{ vars.MATRIX_3P_SQLALCHEMY_infradb_mariadb }} - connector: ${{ vars.MATRIX_3P_SQLALCHEMY_connector_mariadb }} + infradb: ${{ vars.MATRIX_3P_DJANGO_FRAMEWORK_infradb_mariadb }} + connector: ${{ vars.MATRIX_3P_DJANGO_FRAMEWORK_connector_mariadb }} run-pgsql: if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} @@ -36,5 +36,5 @@ jobs: secrets: inherit with: trigger: ${{ toJson(github) }} - infradb: ${{ vars.MATRIX_3P_SQLALCHEMY_infradb_pgsql }} - connector: ${{ vars.MATRIX_3P_SQLALCHEMY_connector_pgsql }} + infradb: ${{ vars.MATRIX_3P_DJANGO_FRAMEWORK_infradb_pgsql }} + connector: ${{ vars.MATRIX_3P_DJANGO_FRAMEWORK_connector_pgsql }} diff --git a/.github/workflows/CI-3p-laravel-framework.yml b/.github/workflows/CI-3p-laravel-framework.yml index 0424349e90..e81c2767ca 100644 --- a/.github/workflows/CI-3p-laravel-framework.yml +++ b/.github/workflows/CI-3p-laravel-framework.yml @@ -18,21 +18,23 @@ jobs: secrets: inherit with: trigger: ${{ toJson(github) }} - infradb: ${{ vars.MATRIX_3P_SQLALCHEMY_infradb_mysql }} - connector: ${{ vars.MATRIX_3P_SQLALCHEMY_connector_mysql }} + infradb: ${{ vars.MATRIX_3P_LARAVEL_FRAMEWORK_infradb_mysql }} + connector: ${{ vars.MATRIX_3P_LARAVEL_FRAMEWORK_connector_mysql }} + run-mariadb: if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} uses: sysown/proxysql/.github/workflows/ci-3p-laravel-framework.yml@GH-Actions secrets: inherit with: trigger: ${{ toJson(github) }} - infradb: ${{ vars.MATRIX_3P_SQLALCHEMY_infradb_mariadb }} - connector: ${{ vars.MATRIX_3P_SQLALCHEMY_connector_mariadb }} + infradb: ${{ vars.MATRIX_3P_LARAVEL_FRAMEWORK_infradb_mariadb }} + connector: ${{ vars.MATRIX_3P_LARAVEL_FRAMEWORK_connector_mariadb }} + run-pgsql: if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} uses: sysown/proxysql/.github/workflows/ci-3p-laravel-framework.yml@GH-Actions secrets: inherit with: trigger: ${{ toJson(github) }} - infradb: ${{ vars.MATRIX_3P_SQLALCHEMY_infradb_pgsql }} - connector: ${{ vars.MATRIX_3P_SQLALCHEMY_connector_pgsql }} + infradb: ${{ vars.MATRIX_3P_LARAVEL_FRAMEWORK_infradb_pgsql }} + connector: ${{ vars.MATRIX_3P_LARAVEL_FRAMEWORK_connector_pgsql }} diff --git a/.github/workflows/CI-3p-mariadb-connector-c.yml b/.github/workflows/CI-3p-mariadb-connector-c.yml index b01523bef6..ff91199bab 100644 --- a/.github/workflows/CI-3p-mariadb-connector-c.yml +++ b/.github/workflows/CI-3p-mariadb-connector-c.yml @@ -18,5 +18,5 @@ jobs: secrets: inherit with: trigger: ${{ toJson(github) }} - infradb: ${{ vars.MATRIX_3P_SQLALCHEMY_infradb_mysql }} - connector: ${{ vars.MATRIX_3P_SQLALCHEMY_connector_mysql }} + infradb: ${{ vars.MATRIX_3P_MARIADB_CONNECTOR_C_infradb_mysql }} + connector: ${{ vars.MATRIX_3P_MARIADB_CONNECTOR_C_connector_mysql }} diff --git a/.github/workflows/CI-3p-mysql-connector-j.yml b/.github/workflows/CI-3p-mysql-connector-j.yml index 663dd909df..588d65c9d6 100644 --- a/.github/workflows/CI-3p-mysql-connector-j.yml +++ b/.github/workflows/CI-3p-mysql-connector-j.yml @@ -18,5 +18,5 @@ jobs: secrets: inherit with: trigger: ${{ toJson(github) }} - infradb: ${{ vars.MATRIX_3P_SQLALCHEMY_infradb_mysql }} - connector: ${{ vars.MATRIX_3P_SQLALCHEMY_connector_mysql }} + infradb: ${{ vars.MATRIX_3P_MYSQL_CONNECTOR_J_infradb_mysql }} + connector: ${{ vars.MATRIX_3P_MYSQL_CONNECTOR_J_connector_mysql }} diff --git a/.github/workflows/CI-3p-php-pdo-mysql.yml b/.github/workflows/CI-3p-php-pdo-mysql.yml index 2a3b9bea4d..e8b3ece8f7 100644 --- a/.github/workflows/CI-3p-php-pdo-mysql.yml +++ b/.github/workflows/CI-3p-php-pdo-mysql.yml @@ -18,5 +18,5 @@ jobs: secrets: inherit with: trigger: ${{ toJson(github) }} - infradb: ${{ vars.MATRIX_3P_SQLALCHEMY_infradb_mysql }} - connector: ${{ vars.MATRIX_3P_SQLALCHEMY_connector_mysql }} + infradb: ${{ vars.MATRIX_3P_PHP_PDO_MYSQL_infradb_mysql }} + connector: ${{ vars.MATRIX_3P_PHP_PDO_MYSQL_connector_mysql }} diff --git a/.github/workflows/CI-taptests-groups.yml b/.github/workflows/CI-taptests-groups.yml index cb75b6a3a3..01f8ea76f0 100644 --- a/.github/workflows/CI-taptests-groups.yml +++ b/.github/workflows/CI-taptests-groups.yml @@ -18,4 +18,4 @@ jobs: secrets: inherit with: trigger: ${{ toJson(github) }} - testgroup: ${{ vars.MATRIX_TAP_GROUPS_testgroup }} + testgroup: ${{ vars.MATRIX_TAPTESTS_GROUPS_testgroup }} diff --git a/.github/workflows/CI-taptests.yml b/.github/workflows/CI-taptests.yml index 607f85711b..73b236ad70 100644 --- a/.github/workflows/CI-taptests.yml +++ b/.github/workflows/CI-taptests.yml @@ -18,4 +18,4 @@ jobs: secrets: inherit with: trigger: ${{ toJson(github) }} - testgroup: ${{ vars.MATRIX_TAP_GROUPS_testgroup }} + testgroup: ${{ vars.MATRIX_TAPTESTS_GROUPS_testgroup }} From d3e89e6b01f3cec0b319ce1a32c56939fbfcb8d2 Mon Sep 17 00:00:00 2001 From: Miro Stauder Date: Mon, 14 Oct 2024 09:59:05 +0200 Subject: [PATCH 55/62] add CI-3p-postgresql --- .github/workflows/CI-3p-postgresql.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/workflows/CI-3p-postgresql.yml diff --git a/.github/workflows/CI-3p-postgresql.yml b/.github/workflows/CI-3p-postgresql.yml new file mode 100644 index 0000000000..047e88783a --- /dev/null +++ b/.github/workflows/CI-3p-postgresql.yml @@ -0,0 +1,22 @@ +name: CI-3p-postgresql +run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} ${{ github.workflow }} ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}' + +on: + workflow_dispatch: + workflow_run: + workflows: [ CI-trigger ] + types: [ completed ] + +concurrency: + group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} + cancel-in-progress: true + +jobs: + run: + if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} + uses: sysown/proxysql/.github/workflows/ci-3p-postgresql.yml@GH-Actions + secrets: inherit + with: + trigger: ${{ toJson(github) }} + infradb: ${{ vars.MATRIX_3P_POSTGRESQL_infradb_pgsql }} + connector: ${{ vars.MATRIX_3P_POSTGRESQL_connector_pgsql }} From 72aefea1ed08a602aaaaef9dd61d76c320f1cb74 Mon Sep 17 00:00:00 2001 From: Rahim Kanji Date: Tue, 22 Oct 2024 15:23:40 +0500 Subject: [PATCH 56/62] Fixed crash caused by sending single semicolon (;) on admin interface --- lib/ProxySQL_Admin.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/ProxySQL_Admin.cpp b/lib/ProxySQL_Admin.cpp index f80826327d..4b3c3b7701 100644 --- a/lib/ProxySQL_Admin.cpp +++ b/lib/ProxySQL_Admin.cpp @@ -3761,12 +3761,20 @@ void admin_session_handler(MySQL_Session *sess, void *_pa, PtrSize_t *pkt) { if (query_no_space_length) { // fix bug #925 - while (query_no_space[query_no_space_length-1]==';' || query_no_space[query_no_space_length-1]==' ') { + while (query_no_space_length && + (query_no_space[query_no_space_length-1]==';' || query_no_space[query_no_space_length-1]==' ')) { query_no_space_length--; query_no_space[query_no_space_length]=0; } } + if (query_no_space_length == 0) { + proxy_warning("Empty query\n"); + SPA->send_MySQL_ERR(&sess->client_myds->myprot, (char*)"Empty query"); + run_query = false; + goto __run_query; + } + // add global mutex, see bug #1188 pthread_mutex_lock(&pa->sql_query_global_mutex); From 4f67794ee86502754a640118334059fcb6ef7d6b Mon Sep 17 00:00:00 2001 From: Rahim Kanji Date: Tue, 22 Oct 2024 15:24:05 +0500 Subject: [PATCH 57/62] Added TAP test --- ...mysql-reg_test_4716_single_semicolon-t.cpp | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 test/tap/tests/mysql-reg_test_4716_single_semicolon-t.cpp diff --git a/test/tap/tests/mysql-reg_test_4716_single_semicolon-t.cpp b/test/tap/tests/mysql-reg_test_4716_single_semicolon-t.cpp new file mode 100644 index 0000000000..c167b8f349 --- /dev/null +++ b/test/tap/tests/mysql-reg_test_4716_single_semicolon-t.cpp @@ -0,0 +1,64 @@ + /** + * @file mysql-reg_test_4716_single_semicolon-t.cpp + * @brief This test aims to verify that ProxySQL handles a lone semicolon (;) input + * crashing. The expected behavior is for ProxySQL to either ignore the input or return an + * appropriate error message, rather than crashing or becoming unresponsive. + */ + +#include +#include + +#include "mysql.h" +#include "command_line.h" +#include "tap.h" +#include "utils.h" + +CommandLine cl; + +enum ConnType { + ADMIN, + BACKEND +}; + +int main(int argc, char** argv) { + + std::vector queries = { ";", " ", "", "; ", " ;" }; + + plan(queries.size() + 1); // Total number of tests planned + + if (cl.getEnv()) + return exit_status(); + + // Initialize Admin connection + MYSQL* proxysql_admin = mysql_init(NULL); + if (!proxysql_admin) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_admin)); + return -1; + } + + // Connnect to ProxySQL Admin + if (!mysql_real_connect(proxysql_admin, cl.host, cl.admin_username, cl.admin_password, NULL, cl.admin_port, NULL, 0)) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_admin)); + return -1; + } + + for (const char* query : queries) { + MYSQL_QUERY_err(proxysql_admin, query); + const int _errorno = mysql_errno(proxysql_admin); + ok(_errorno > 0, "Error Code:%d, Message:%s", _errorno, mysql_error(proxysql_admin)); + } + + // Test a valid query to ensure the connection is working + if (mysql_query(proxysql_admin, "SELECT 1") == 0) { + MYSQL_RES* res = mysql_store_result(proxysql_admin); + ok(res != nullptr, "Query executed successfully. %s", mysql_error(proxysql_admin)); + mysql_free_result(res); + } + else { + ok(false, "Error executing query. %s", mysql_error(proxysql_admin)); + } + + mysql_close(proxysql_admin); + + return exit_status(); +} From 8b526c69ed245b1ad13bdf0103983b2b090f486d Mon Sep 17 00:00:00 2001 From: Rahim Kanji Date: Wed, 23 Oct 2024 13:12:11 +0500 Subject: [PATCH 58/62] Updated default value of cache_empty_result to -1, indicating that it has not been explicitly set --- include/query_processor.h | 2 +- ...xxxx_query_cache_stores_empty_result-t.cpp | 154 ++++++++++++++++++ 2 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 test/tap/tests/mysql-reg_test_xxxx_query_cache_stores_empty_result-t.cpp diff --git a/include/query_processor.h b/include/query_processor.h index 9d62330291..fd93abb719 100644 --- a/include/query_processor.h +++ b/include/query_processor.h @@ -164,7 +164,7 @@ class Query_Processor_Output { mirror_flagOUT=-1; next_query_flagIN=-1; cache_ttl=-1; - cache_empty_result=1; + cache_empty_result=-1; cache_timeout=-1; reconnect=-1; timeout=-1; diff --git a/test/tap/tests/mysql-reg_test_xxxx_query_cache_stores_empty_result-t.cpp b/test/tap/tests/mysql-reg_test_xxxx_query_cache_stores_empty_result-t.cpp new file mode 100644 index 0000000000..468502de1a --- /dev/null +++ b/test/tap/tests/mysql-reg_test_xxxx_query_cache_stores_empty_result-t.cpp @@ -0,0 +1,154 @@ + /** + * @file mysql-reg_test_4716_single_semicolon-t.cpp + * @brief This test aims to verify that ProxySQL handles a lone semicolon (;) input + * crashing. The expected behavior is for ProxySQL to either ignore the input or return an + * appropriate error message, rather than crashing or becoming unresponsive. + */ + +#include +#include + +#include "mysql.h" +#include "command_line.h" +#include "tap.h" +#include "utils.h" + +CommandLine cl; + +std::map getQueryCacheMetrics(MYSQL* proxy_admin) { + const char* query = "SELECT Variable_Name, Variable_Value FROM stats_mysql_global WHERE Variable_Name LIKE 'Query_Cache%';"; + diag("Running: %s", query); + + int query_res = mysql_query(proxy_admin, query); + if (query_res) { + BAIL_OUT("Query failed with error: %s", mysql_error(proxy_admin)); + return {}; + } + + std::map metrics{}; + MYSQL_RES* res = mysql_store_result(proxy_admin); + MYSQL_ROW row; + + while ((row = mysql_fetch_row(res))) { + metrics[row[0]] = atoi(row[1]); + } + + mysql_free_result(res); + return metrics; +} + +class TestMetrics { +public: + std::map before; + std::map after; + + void swap() { + before.swap(after); + } + + template + bool checkMetricDelta(const std::string& metric_name, int expected, BinaryOp op) { + if (before.find(metric_name) == before.end() || + after.find(metric_name) == after.end()) { + BAIL_OUT("Metric '%s' not found", metric_name.c_str()); + return false; + } + + int delta = after[metric_name] - before[metric_name]; + bool result = op(std::max(0, delta), expected); + + std::string bin_op_name = typeid(BinaryOp).name(); + bin_op_name = bin_op_name.substr(3, bin_op_name.size() - 6); + + ok(result, "Metric `%s` should be '%s' %d. Actual %d", metric_name.c_str(), bin_op_name.c_str(), expected, delta); + return result; + } +}; + + + +int main(int argc, char** argv) { + + plan(10); // Total number of tests planned + + if (cl.getEnv()) + return exit_status(); + + // Initialize Admin connection + MYSQL* proxysql_admin = mysql_init(NULL); + if (!proxysql_admin) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_admin)); + return -1; + } + + // Connnect to ProxySQL Admin + if (!mysql_real_connect(proxysql_admin, cl.host, /*cl.admin_username*/ "admin", /*cl.admin_password*/ "admin", NULL, /*cl.admin_port*/ 6032, NULL, 0)) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_admin)); + return -1; + } + + // Initialize Backend connection + MYSQL* proxysql_backend = mysql_init(NULL); + if (!proxysql_backend) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_backend)); + return -1; + } + + // Connect to Backend + if (!mysql_real_connect(proxysql_backend, cl.host, /*cl.username*/ "root", /*cl.password*/ "root", NULL, /*cl.port*/ 6033, NULL, 0)) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_backend)); + return -1; + } + + MYSQL_QUERY(proxysql_admin, "DELETE FROM mysql_query_rules"); + MYSQL_QUERY(proxysql_admin, "INSERT INTO mysql_query_rules (rule_id,active,match_digest,cache_ttl) VALUES (2,1,'^SELECT',4000)"); + MYSQL_QUERY(proxysql_admin, "LOAD MYSQL QUERY RULES TO RUNTIME"); + MYSQL_QUERY(proxysql_admin, "UPDATE global_variables SET variable_value=0 WHERE variable_name='mysql-query_cache_stores_empty_result'"); + MYSQL_QUERY(proxysql_admin, "LOAD MYSQL VARIABLES TO RUNTIME"); + + TestMetrics metrics; + + metrics.before = getQueryCacheMetrics(proxysql_admin); + + if (mysql_query(proxysql_backend, "SELECT 1 WHERE 1!=1") == 0) { + MYSQL_RES* res = mysql_store_result(proxysql_backend); + ok(res != nullptr, "Query executed successfully. %s", mysql_error(proxysql_backend)); + mysql_free_result(res); + } + else { + ok(false, "Error executing query. %s", mysql_error(proxysql_admin)); + } + + metrics.after = getQueryCacheMetrics(proxysql_admin); + + metrics.checkMetricDelta<>("Query_Cache_Memory_bytes", 0, std::equal_to()); + metrics.checkMetricDelta<>("Query_Cache_count_SET", 0, std::equal_to()); + metrics.checkMetricDelta<>("Query_Cache_bytes_IN", 0, std::equal_to()); + metrics.checkMetricDelta<>("Query_Cache_Entries", 0, std::equal_to()); + + metrics.swap(); + + MYSQL_QUERY(proxysql_admin, "UPDATE global_variables SET variable_value=1 WHERE variable_name='mysql-query_cache_stores_empty_result'"); + MYSQL_QUERY(proxysql_admin, "LOAD MYSQL VARIABLES TO RUNTIME"); + + if (mysql_query(proxysql_backend, "SELECT 1 WHERE 1!=1") == 0) { + MYSQL_RES* res = mysql_store_result(proxysql_backend); + ok(res != nullptr, "Query executed successfully. %s", mysql_error(proxysql_backend)); + mysql_free_result(res); + } + else { + ok(false, "Error executing query. %s", mysql_error(proxysql_admin)); + } + + metrics.after = getQueryCacheMetrics(proxysql_admin); + + metrics.checkMetricDelta<>("Query_Cache_Memory_bytes", 1, std::greater()); + metrics.checkMetricDelta<>("Query_Cache_count_SET", 1, std::equal_to()); + metrics.checkMetricDelta<>("Query_Cache_bytes_IN", 1, std::greater()); + metrics.checkMetricDelta<>("Query_Cache_Entries", 1, std::equal_to()); + + mysql_close(proxysql_backend); + mysql_close(proxysql_admin); + + return exit_status(); +} From 65fba5d0a6f8eb8d4bfd6cf6eaf27629759fbc97 Mon Sep 17 00:00:00 2001 From: Rahim Kanji Date: Wed, 23 Oct 2024 13:16:20 +0500 Subject: [PATCH 59/62] Added TAP test --- ...4723_query_cache_stores_empty_result-t.cpp | 168 ++++++++++++++++++ ...xxxx_query_cache_stores_empty_result-t.cpp | 154 ---------------- 2 files changed, 168 insertions(+), 154 deletions(-) create mode 100644 test/tap/tests/mysql-reg_test_4723_query_cache_stores_empty_result-t.cpp delete mode 100644 test/tap/tests/mysql-reg_test_xxxx_query_cache_stores_empty_result-t.cpp diff --git a/test/tap/tests/mysql-reg_test_4723_query_cache_stores_empty_result-t.cpp b/test/tap/tests/mysql-reg_test_4723_query_cache_stores_empty_result-t.cpp new file mode 100644 index 0000000000..c40b1646b3 --- /dev/null +++ b/test/tap/tests/mysql-reg_test_4723_query_cache_stores_empty_result-t.cpp @@ -0,0 +1,168 @@ +/** + * @file mysql-reg_test_4723_query_cache_stores_empty_result-t.cpp + * @brief This test verfies that 'mysql-query_cache_stores_empty_result' variable works as expected. + * Specifically, it ensures that when this variable is set to `0`, empty results (zero rows) + * are not cached, and when set to `1`, they are cached. + * The test verifies this behavior by comparing the metrics before and after query execution. + */ + +#include +#include + +#include "mysql.h" +#include "command_line.h" +#include "tap.h" +#include "utils.h" + +CommandLine cl; + +std::map getQueryCacheMetrics(MYSQL* proxy_admin) { + const char* query = "SELECT Variable_Name, Variable_Value FROM stats_mysql_global WHERE Variable_Name LIKE 'Query_Cache%';"; + diag("Running: %s", query); + + int query_res = mysql_query(proxy_admin, query); + if (query_res) { + BAIL_OUT("Query failed with error: %s", mysql_error(proxy_admin)); + return {}; + } + + std::map metrics{}; + MYSQL_RES* res = mysql_store_result(proxy_admin); + if (!res) { + BAIL_OUT("Failed to store result: %s", mysql_error(proxy_admin)); + return {}; + } + + MYSQL_ROW row; + while ((row = mysql_fetch_row(res))) { + metrics[row[0]] = atoi(row[1]); + } + + mysql_free_result(res); + return metrics; +} + +class TestMetrics { +public: + std::map before; + std::map after; + + void swap() { + before.swap(after); + } + + template + bool checkMetricDelta(const std::string& metric_name, int expected, BinaryOp op) { + if (before.find(metric_name) == before.end() || after.find(metric_name) == after.end()) { + diag("Metric '%s' not found in either before or after map.", metric_name.c_str()); + return false; + } + + int delta = after[metric_name] - before[metric_name]; + bool result = op(std::max(0, delta), expected); + + diag("Checking metric '%s': Expected delta %d, Actual delta %d", metric_name.c_str(), expected, delta); + ok(result, "Metric `%s` delta is correct. Expected '%d', got '%d'", metric_name.c_str(), expected, delta); + return result; + } +}; + +// Helper function for executing MySQL queries with error handling +bool exec_query(MYSQL* conn, const char* query) { + diag("Running query: %s", query); + int query_res = mysql_query(conn, query); + if (query_res) { + diag("Query failed with error: %s", mysql_error(conn)); + return false; + } + return true; +} + +int main(int argc, char** argv) { + plan(10); // Total number of tests planned + + if (cl.getEnv()) + return exit_status(); + + // Initialize and connect to ProxySQL Admin + MYSQL* proxysql_admin = mysql_init(nullptr); + if (!proxysql_admin) { + BAIL_OUT("MySQL admin init failed."); + } + + if (!mysql_real_connect(proxysql_admin, cl.host, cl.admin_username, cl.admin_password, nullptr, cl.admin_port, nullptr, 0)) { + BAIL_OUT("Failed to connect to ProxySQL Admin: %s", mysql_error(proxysql_admin)); + } + + // Initialize and connect to ProxySQL Backend + MYSQL* proxysql_backend = mysql_init(nullptr); + if (!proxysql_backend) { + BAIL_OUT("MySQL backend init failed."); + } + + if (!mysql_real_connect(proxysql_backend, cl.host, cl.username, cl.password, nullptr, cl.port, nullptr, 0)) { + BAIL_OUT("Failed to connect to ProxySQL Backend: %s", mysql_error(proxysql_backend)); + } + + // Setting up test environment + MYSQL_QUERY(proxysql_admin, "DELETE FROM mysql_query_rules"); + MYSQL_QUERY(proxysql_admin, "INSERT INTO mysql_query_rules (rule_id,active,match_digest,cache_ttl) VALUES (2,1,'^SELECT',4000)"); + MYSQL_QUERY(proxysql_admin, "LOAD MYSQL QUERY RULES TO RUNTIME"); + + // Disable query cache storing empty result + MYSQL_QUERY(proxysql_admin, "UPDATE global_variables SET variable_value=0 WHERE variable_name='mysql-query_cache_stores_empty_result'"); + MYSQL_QUERY(proxysql_admin, "LOAD MYSQL VARIABLES TO RUNTIME"); + + TestMetrics metrics; + + metrics.before = getQueryCacheMetrics(proxysql_admin); + + // Execute the test query and check the result + if (exec_query(proxysql_backend, "SELECT 1 WHERE 1!=1")) { + MYSQL_RES* res = mysql_store_result(proxysql_backend); + ok(res != nullptr, "Query executed successfully."); + mysql_free_result(res); + } + else { + ok(false, "Error executing query."); + } + + // Fetch metrics after query execution + metrics.after = getQueryCacheMetrics(proxysql_admin); + + metrics.checkMetricDelta("Query_Cache_Memory_bytes", 0, std::equal_to()); + metrics.checkMetricDelta("Query_Cache_count_SET", 0, std::equal_to()); + metrics.checkMetricDelta("Query_Cache_bytes_IN", 0, std::equal_to()); + metrics.checkMetricDelta("Query_Cache_Entries", 0, std::equal_to()); + + // Swap the before and after metrics for the next phase + metrics.swap(); + + // Enable query cache storing empty result + MYSQL_QUERY(proxysql_admin, "UPDATE global_variables SET variable_value=1 WHERE variable_name='mysql-query_cache_stores_empty_result'"); + MYSQL_QUERY(proxysql_admin, "LOAD MYSQL VARIABLES TO RUNTIME"); + + // Execute the same query again and check the result + if (exec_query(proxysql_backend, "SELECT 1 WHERE 1!=1")) { + MYSQL_RES* res = mysql_store_result(proxysql_backend); + ok(res != nullptr, "Query executed successfully."); + mysql_free_result(res); + } + else { + ok(false, "Error executing query."); + } + + // Fetch metrics again and check for expected changes + metrics.after = getQueryCacheMetrics(proxysql_admin); + + metrics.checkMetricDelta("Query_Cache_Memory_bytes", 1, std::greater()); + metrics.checkMetricDelta("Query_Cache_count_SET", 1, std::equal_to()); + metrics.checkMetricDelta("Query_Cache_bytes_IN", 1, std::greater()); + metrics.checkMetricDelta("Query_Cache_Entries", 1, std::equal_to()); + + // Close the connections + mysql_close(proxysql_backend); + mysql_close(proxysql_admin); + + return exit_status(); +} diff --git a/test/tap/tests/mysql-reg_test_xxxx_query_cache_stores_empty_result-t.cpp b/test/tap/tests/mysql-reg_test_xxxx_query_cache_stores_empty_result-t.cpp deleted file mode 100644 index 468502de1a..0000000000 --- a/test/tap/tests/mysql-reg_test_xxxx_query_cache_stores_empty_result-t.cpp +++ /dev/null @@ -1,154 +0,0 @@ - /** - * @file mysql-reg_test_4716_single_semicolon-t.cpp - * @brief This test aims to verify that ProxySQL handles a lone semicolon (;) input - * crashing. The expected behavior is for ProxySQL to either ignore the input or return an - * appropriate error message, rather than crashing or becoming unresponsive. - */ - -#include -#include - -#include "mysql.h" -#include "command_line.h" -#include "tap.h" -#include "utils.h" - -CommandLine cl; - -std::map getQueryCacheMetrics(MYSQL* proxy_admin) { - const char* query = "SELECT Variable_Name, Variable_Value FROM stats_mysql_global WHERE Variable_Name LIKE 'Query_Cache%';"; - diag("Running: %s", query); - - int query_res = mysql_query(proxy_admin, query); - if (query_res) { - BAIL_OUT("Query failed with error: %s", mysql_error(proxy_admin)); - return {}; - } - - std::map metrics{}; - MYSQL_RES* res = mysql_store_result(proxy_admin); - MYSQL_ROW row; - - while ((row = mysql_fetch_row(res))) { - metrics[row[0]] = atoi(row[1]); - } - - mysql_free_result(res); - return metrics; -} - -class TestMetrics { -public: - std::map before; - std::map after; - - void swap() { - before.swap(after); - } - - template - bool checkMetricDelta(const std::string& metric_name, int expected, BinaryOp op) { - if (before.find(metric_name) == before.end() || - after.find(metric_name) == after.end()) { - BAIL_OUT("Metric '%s' not found", metric_name.c_str()); - return false; - } - - int delta = after[metric_name] - before[metric_name]; - bool result = op(std::max(0, delta), expected); - - std::string bin_op_name = typeid(BinaryOp).name(); - bin_op_name = bin_op_name.substr(3, bin_op_name.size() - 6); - - ok(result, "Metric `%s` should be '%s' %d. Actual %d", metric_name.c_str(), bin_op_name.c_str(), expected, delta); - return result; - } -}; - - - -int main(int argc, char** argv) { - - plan(10); // Total number of tests planned - - if (cl.getEnv()) - return exit_status(); - - // Initialize Admin connection - MYSQL* proxysql_admin = mysql_init(NULL); - if (!proxysql_admin) { - fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_admin)); - return -1; - } - - // Connnect to ProxySQL Admin - if (!mysql_real_connect(proxysql_admin, cl.host, /*cl.admin_username*/ "admin", /*cl.admin_password*/ "admin", NULL, /*cl.admin_port*/ 6032, NULL, 0)) { - fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_admin)); - return -1; - } - - // Initialize Backend connection - MYSQL* proxysql_backend = mysql_init(NULL); - if (!proxysql_backend) { - fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_backend)); - return -1; - } - - // Connect to Backend - if (!mysql_real_connect(proxysql_backend, cl.host, /*cl.username*/ "root", /*cl.password*/ "root", NULL, /*cl.port*/ 6033, NULL, 0)) { - fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_backend)); - return -1; - } - - MYSQL_QUERY(proxysql_admin, "DELETE FROM mysql_query_rules"); - MYSQL_QUERY(proxysql_admin, "INSERT INTO mysql_query_rules (rule_id,active,match_digest,cache_ttl) VALUES (2,1,'^SELECT',4000)"); - MYSQL_QUERY(proxysql_admin, "LOAD MYSQL QUERY RULES TO RUNTIME"); - MYSQL_QUERY(proxysql_admin, "UPDATE global_variables SET variable_value=0 WHERE variable_name='mysql-query_cache_stores_empty_result'"); - MYSQL_QUERY(proxysql_admin, "LOAD MYSQL VARIABLES TO RUNTIME"); - - TestMetrics metrics; - - metrics.before = getQueryCacheMetrics(proxysql_admin); - - if (mysql_query(proxysql_backend, "SELECT 1 WHERE 1!=1") == 0) { - MYSQL_RES* res = mysql_store_result(proxysql_backend); - ok(res != nullptr, "Query executed successfully. %s", mysql_error(proxysql_backend)); - mysql_free_result(res); - } - else { - ok(false, "Error executing query. %s", mysql_error(proxysql_admin)); - } - - metrics.after = getQueryCacheMetrics(proxysql_admin); - - metrics.checkMetricDelta<>("Query_Cache_Memory_bytes", 0, std::equal_to()); - metrics.checkMetricDelta<>("Query_Cache_count_SET", 0, std::equal_to()); - metrics.checkMetricDelta<>("Query_Cache_bytes_IN", 0, std::equal_to()); - metrics.checkMetricDelta<>("Query_Cache_Entries", 0, std::equal_to()); - - metrics.swap(); - - MYSQL_QUERY(proxysql_admin, "UPDATE global_variables SET variable_value=1 WHERE variable_name='mysql-query_cache_stores_empty_result'"); - MYSQL_QUERY(proxysql_admin, "LOAD MYSQL VARIABLES TO RUNTIME"); - - if (mysql_query(proxysql_backend, "SELECT 1 WHERE 1!=1") == 0) { - MYSQL_RES* res = mysql_store_result(proxysql_backend); - ok(res != nullptr, "Query executed successfully. %s", mysql_error(proxysql_backend)); - mysql_free_result(res); - } - else { - ok(false, "Error executing query. %s", mysql_error(proxysql_admin)); - } - - metrics.after = getQueryCacheMetrics(proxysql_admin); - - metrics.checkMetricDelta<>("Query_Cache_Memory_bytes", 1, std::greater()); - metrics.checkMetricDelta<>("Query_Cache_count_SET", 1, std::equal_to()); - metrics.checkMetricDelta<>("Query_Cache_bytes_IN", 1, std::greater()); - metrics.checkMetricDelta<>("Query_Cache_Entries", 1, std::equal_to()); - - mysql_close(proxysql_backend); - mysql_close(proxysql_admin); - - return exit_status(); -} From 4d07b1702702269834382e20c766e237bff8886c Mon Sep 17 00:00:00 2001 From: Rahim Kanji Date: Thu, 24 Oct 2024 11:57:25 +0500 Subject: [PATCH 60/62] Updated query --- .../mysql-reg_test_4723_query_cache_stores_empty_result-t.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/tap/tests/mysql-reg_test_4723_query_cache_stores_empty_result-t.cpp b/test/tap/tests/mysql-reg_test_4723_query_cache_stores_empty_result-t.cpp index c40b1646b3..c6471e2530 100644 --- a/test/tap/tests/mysql-reg_test_4723_query_cache_stores_empty_result-t.cpp +++ b/test/tap/tests/mysql-reg_test_4723_query_cache_stores_empty_result-t.cpp @@ -118,7 +118,7 @@ int main(int argc, char** argv) { metrics.before = getQueryCacheMetrics(proxysql_admin); // Execute the test query and check the result - if (exec_query(proxysql_backend, "SELECT 1 WHERE 1!=1")) { + if (exec_query(proxysql_backend, "SELECT 1 FROM DUAL WHERE 1!=1")) { MYSQL_RES* res = mysql_store_result(proxysql_backend); ok(res != nullptr, "Query executed successfully."); mysql_free_result(res); @@ -143,7 +143,7 @@ int main(int argc, char** argv) { MYSQL_QUERY(proxysql_admin, "LOAD MYSQL VARIABLES TO RUNTIME"); // Execute the same query again and check the result - if (exec_query(proxysql_backend, "SELECT 1 WHERE 1!=1")) { + if (exec_query(proxysql_backend, "SELECT 1 FROM DUAL WHERE 1!=1")) { MYSQL_RES* res = mysql_store_result(proxysql_backend); ok(res != nullptr, "Query executed successfully."); mysql_free_result(res); From 67e45ecef29842f6ad8ff55bdfb7672be01a2f87 Mon Sep 17 00:00:00 2001 From: Rahim Kanji Date: Tue, 29 Oct 2024 12:29:42 +0500 Subject: [PATCH 61/62] Fixed admin_host --- .../mysql-reg_test_4723_query_cache_stores_empty_result-t.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/tap/tests/mysql-reg_test_4723_query_cache_stores_empty_result-t.cpp b/test/tap/tests/mysql-reg_test_4723_query_cache_stores_empty_result-t.cpp index c6471e2530..d36c5d53b0 100644 --- a/test/tap/tests/mysql-reg_test_4723_query_cache_stores_empty_result-t.cpp +++ b/test/tap/tests/mysql-reg_test_4723_query_cache_stores_empty_result-t.cpp @@ -90,7 +90,7 @@ int main(int argc, char** argv) { BAIL_OUT("MySQL admin init failed."); } - if (!mysql_real_connect(proxysql_admin, cl.host, cl.admin_username, cl.admin_password, nullptr, cl.admin_port, nullptr, 0)) { + if (!mysql_real_connect(proxysql_admin, cl.admin_host, cl.admin_username, cl.admin_password, nullptr, cl.admin_port, nullptr, 0)) { BAIL_OUT("Failed to connect to ProxySQL Admin: %s", mysql_error(proxysql_admin)); } From b84e0a6361261ac7b7bad8e736b17a807731ce6a Mon Sep 17 00:00:00 2001 From: Rahim Kanji Date: Tue, 29 Oct 2024 12:35:29 +0500 Subject: [PATCH 62/62] Fixed admin port --- test/tap/tests/mysql-reg_test_4716_single_semicolon-t.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/tap/tests/mysql-reg_test_4716_single_semicolon-t.cpp b/test/tap/tests/mysql-reg_test_4716_single_semicolon-t.cpp index c167b8f349..116debe36b 100644 --- a/test/tap/tests/mysql-reg_test_4716_single_semicolon-t.cpp +++ b/test/tap/tests/mysql-reg_test_4716_single_semicolon-t.cpp @@ -37,7 +37,7 @@ int main(int argc, char** argv) { } // Connnect to ProxySQL Admin - if (!mysql_real_connect(proxysql_admin, cl.host, cl.admin_username, cl.admin_password, NULL, cl.admin_port, NULL, 0)) { + if (!mysql_real_connect(proxysql_admin, cl.admin_host, cl.admin_username, cl.admin_password, NULL, cl.admin_port, NULL, 0)) { fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_admin)); return -1; }