From c7d0c2caf69ce646426635b0da8ac85da4e74b2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20del=20Campo?= Date: Fri, 21 Dec 2018 11:12:57 +0100 Subject: [PATCH 1/8] Fixing sql states in many error messages from admin console. As the # is already included when generating the message, is not needed here, making the output in mysql show a wrong one --- lib/MySQL_Session.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index ab8158035..f0bc72cd1 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -2410,7 +2410,7 @@ __get_pkts_from_client: if (session_type != PROXYSQL_SESSION_MYSQL) { // only MySQL module supports prepared statement!! l_free(pkt.size,pkt.ptr); client_myds->setDSS_STATE_QUERY_SENT_NET(); - client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"#28000",(char *)"Command not supported"); + client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"28000",(char *)"Command not supported"); client_myds->DSS=STATE_SLEEP; status=WAITING_CLIENT_DATA; break; @@ -2471,7 +2471,7 @@ __get_pkts_from_client: if (session_type != PROXYSQL_SESSION_MYSQL) { // only MySQL module supports prepared statement!! l_free(pkt.size,pkt.ptr); client_myds->setDSS_STATE_QUERY_SENT_NET(); - client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"#28000",(char *)"Command not supported"); + client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"28000",(char *)"Command not supported"); client_myds->DSS=STATE_SLEEP; status=WAITING_CLIENT_DATA; break; @@ -2497,7 +2497,7 @@ __get_pkts_from_client: // we couldn't find it l_free(pkt.size,pkt.ptr); client_myds->setDSS_STATE_QUERY_SENT_NET(); - client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"#28000",(char *)"Prepared statement doesn't exist", true); + client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"28000",(char *)"Prepared statement doesn't exist", true); client_myds->DSS=STATE_SLEEP; status=WAITING_CLIENT_DATA; break; @@ -2515,7 +2515,7 @@ __get_pkts_from_client: if (stmt_meta==NULL) { l_free(pkt.size,pkt.ptr); client_myds->setDSS_STATE_QUERY_SENT_NET(); - client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"#28000",(char *)"Error in prepared statement execution", true); + client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"28000",(char *)"Error in prepared statement execution", true); client_myds->DSS=STATE_SLEEP; status=WAITING_CLIENT_DATA; //__sync_fetch_and_sub(&stmt_info->ref_count,1); // decrease reference count @@ -3811,12 +3811,12 @@ void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C /* FIXME: temporary */ l_free(pkt->size,pkt->ptr); client_myds->setDSS_STATE_QUERY_SENT_NET(); - client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"#28000",(char *)"Command not supported", true); + client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"28000",(char *)"Command not supported", true); client_myds->DSS=STATE_SLEEP; } else { l_free(pkt->size,pkt->ptr); client_myds->setDSS_STATE_QUERY_SENT_NET(); - client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"#28000",(char *)"Command not supported", true); + client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"28000",(char *)"Command not supported", true); client_myds->DSS=STATE_SLEEP; } } @@ -3831,7 +3831,7 @@ void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C } else { l_free(pkt->size,pkt->ptr); client_myds->setDSS_STATE_QUERY_SENT_NET(); - client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"#28000",(char *)"Command not supported"); + client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"28000",(char *)"Command not supported"); client_myds->DSS=STATE_SLEEP; } } @@ -3845,7 +3845,7 @@ void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C } else { l_free(pkt->size,pkt->ptr); client_myds->setDSS_STATE_QUERY_SENT_NET(); - client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"#28000",(char *)"Command not supported"); + client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"28000",(char *)"Command not supported"); client_myds->DSS=STATE_SLEEP; } } @@ -3853,7 +3853,7 @@ void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_PROCESS_KILL(PtrSize_t *pkt) { l_free(pkt->size,pkt->ptr); client_myds->setDSS_STATE_QUERY_SENT_NET(); - client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,9003,(char *)"#28000",(char *)"Command not supported"); + client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,9003,(char *)"28000",(char *)"Command not supported"); client_myds->DSS=STATE_SLEEP; } @@ -4590,7 +4590,7 @@ void MySQL_Session::SQLite3_to_MySQL(SQLite3_result *result, char *error, int af } else { // no result set if (error) { // there was an error - myprot->generate_pkt_ERR(true,NULL,NULL,sid,1045,(char *)"#28000",error); + myprot->generate_pkt_ERR(true,NULL,NULL,sid,1045,(char *)"28000",error); } else { // no error, DML succeeded unsigned int nTrx=NumActiveTransactions(); From f762929c94f3ba4a82658fa0503e14606ec7d6da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20del=20Campo?= Date: Thu, 27 Dec 2018 16:40:24 +0100 Subject: [PATCH 2/8] Fixed query to get available galera nodes in a hostgroup --- lib/MySQL_HostGroups_Manager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/MySQL_HostGroups_Manager.cpp b/lib/MySQL_HostGroups_Manager.cpp index 51085949a..038e0c31c 100644 --- a/lib/MySQL_HostGroups_Manager.cpp +++ b/lib/MySQL_HostGroups_Manager.cpp @@ -3697,8 +3697,8 @@ void MySQL_HostGroups_Manager::update_galera_set_offline(char *_hostname, int _p } else { // the server is already offline, but we check if needs to be taken back online SQLite3_result *numw_result = NULL; q=(char *)"SELECT 1 FROM mysql_servers WHERE hostgroup_id=%d AND status=0"; - query=(char *)malloc(strlen(q)+strlen(_hostname)+32); - sprintf(query,q,_hostname,_port); + query=(char *)malloc(strlen(q) + (sizeof(_writer_hostgroup) * 8 + 1)); + sprintf(query,q,_writer_hostgroup); mydb->execute_statement(query, &error , &cols , &affected_rows , &numw_result); free(query); if (numw_result) { From d0b898614330cbf91f7d0fe2e8a1b8263672a895 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Fri, 28 Dec 2018 23:46:25 +1100 Subject: [PATCH 3/8] Remove trailing spaces from USE command --- lib/MySQL_Session.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 7494dbdfe..1ba77dae8 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -3889,13 +3889,15 @@ 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); char *schemaname=strndup((char *)pkt->ptr+sizeof(mysql_hdr)+5,pkt->size-sizeof(mysql_hdr)-5); - char *schemanameptr=schemaname; + char *schemanameptr=trim_spaces_and_quotes_in_place(schemaname); +/* //remove leading spaces while(isspace((unsigned char)*schemanameptr)) schemanameptr++; // remove trailing semicolon , issue #915 if (schemanameptr[strlen(schemanameptr)-1]==';') { schemanameptr[strlen(schemanameptr)-1]='\0'; } +*/ // handle cases like "USE `schemaname` if(schemanameptr[0]=='`' && schemanameptr[strlen(schemanameptr)-1]=='`') { schemanameptr[strlen(schemanameptr)-1]='\0'; From 953bbac09fb63965ffeb22f634add0cb4bea74a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Mon, 7 Jan 2019 15:33:36 +0100 Subject: [PATCH 4/8] Support writer_is_also_reader=2 in Hostgroup Manager --- include/MySQL_HostGroups_Manager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/MySQL_HostGroups_Manager.h b/include/MySQL_HostGroups_Manager.h index 34f3639b0..755b99ed8 100644 --- a/include/MySQL_HostGroups_Manager.h +++ b/include/MySQL_HostGroups_Manager.h @@ -34,7 +34,7 @@ #define MYHGM_MYSQL_GROUP_REPLICATION_HOSTGROUPS "CREATE TABLE mysql_group_replication_hostgroups (writer_hostgroup INT CHECK (writer_hostgroup>=0) NOT NULL PRIMARY KEY , backup_writer_hostgroup INT CHECK (backup_writer_hostgroup>=0 AND backup_writer_hostgroup<>writer_hostgroup) NOT NULL , reader_hostgroup INT NOT NULL CHECK (reader_hostgroup<>writer_hostgroup AND backup_writer_hostgroup<>reader_hostgroup AND reader_hostgroup>0) , offline_hostgroup INT NOT NULL CHECK (offline_hostgroup<>writer_hostgroup AND offline_hostgroup<>reader_hostgroup AND backup_writer_hostgroup<>offline_hostgroup AND offline_hostgroup>=0) , active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1 , max_writers INT NOT NULL CHECK (max_writers >= 0) DEFAULT 1 , writer_is_also_reader INT CHECK (writer_is_also_reader IN (0,1)) NOT NULL DEFAULT 0 , max_transactions_behind INT CHECK (max_transactions_behind>=0) NOT NULL DEFAULT 0 , comment VARCHAR , UNIQUE (reader_hostgroup) , UNIQUE (offline_hostgroup) , UNIQUE (backup_writer_hostgroup))" -#define MYHGM_MYSQL_GALERA_HOSTGROUPS "CREATE TABLE mysql_galera_hostgroups (writer_hostgroup INT CHECK (writer_hostgroup>=0) NOT NULL PRIMARY KEY , backup_writer_hostgroup INT CHECK (backup_writer_hostgroup>=0 AND backup_writer_hostgroup<>writer_hostgroup) NOT NULL , reader_hostgroup INT NOT NULL CHECK (reader_hostgroup<>writer_hostgroup AND backup_writer_hostgroup<>reader_hostgroup AND reader_hostgroup>0) , offline_hostgroup INT NOT NULL CHECK (offline_hostgroup<>writer_hostgroup AND offline_hostgroup<>reader_hostgroup AND backup_writer_hostgroup<>offline_hostgroup AND offline_hostgroup>=0) , active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1 , max_writers INT NOT NULL CHECK (max_writers >= 0) DEFAULT 1 , writer_is_also_reader INT CHECK (writer_is_also_reader IN (0,1)) NOT NULL DEFAULT 0 , max_transactions_behind INT CHECK (max_transactions_behind>=0) NOT NULL DEFAULT 0 , comment VARCHAR , UNIQUE (reader_hostgroup) , UNIQUE (offline_hostgroup) , UNIQUE (backup_writer_hostgroup))" +#define MYHGM_MYSQL_GALERA_HOSTGROUPS "CREATE TABLE mysql_galera_hostgroups (writer_hostgroup INT CHECK (writer_hostgroup>=0) NOT NULL PRIMARY KEY , backup_writer_hostgroup INT CHECK (backup_writer_hostgroup>=0 AND backup_writer_hostgroup<>writer_hostgroup) NOT NULL , reader_hostgroup INT NOT NULL CHECK (reader_hostgroup<>writer_hostgroup AND backup_writer_hostgroup<>reader_hostgroup AND reader_hostgroup>0) , offline_hostgroup INT NOT NULL CHECK (offline_hostgroup<>writer_hostgroup AND offline_hostgroup<>reader_hostgroup AND backup_writer_hostgroup<>offline_hostgroup AND offline_hostgroup>=0) , active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1 , max_writers INT NOT NULL CHECK (max_writers >= 0) DEFAULT 1 , writer_is_also_reader INT CHECK (writer_is_also_reader IN (0,1,2)) NOT NULL DEFAULT 0 , max_transactions_behind INT CHECK (max_transactions_behind>=0) NOT NULL DEFAULT 0 , comment VARCHAR , UNIQUE (reader_hostgroup) , UNIQUE (offline_hostgroup) , UNIQUE (backup_writer_hostgroup))" typedef std::unordered_map umap_mysql_errors; From 450ed45c030d48bb316d7885788306c28145d530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Mon, 7 Jan 2019 15:35:26 +0100 Subject: [PATCH 5/8] Setting synchronous=0 on wrong schema #1842 --- 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 1163e781b..3b0b47c81 100644 --- a/lib/ProxySQL_Admin.cpp +++ b/lib/ProxySQL_Admin.cpp @@ -1906,7 +1906,7 @@ void ProxySQL_Admin::flush_configdb() { // see #923 __attach_db(admindb, configdb, (char *)"disk"); // Fully synchronous is not required. See to #1055 // https://sqlite.org/pragma.html#pragma_synchronous - configdb->execute("PRAGMA disk.synchronous=0"); + configdb->execute("PRAGMA synchronous=0"); wrunlock(); } From a143b50a7d47c0cb28be22b2c8362b5a8f591ff0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Wed, 9 Jan 2019 17:57:03 +1100 Subject: [PATCH 6/8] Fixed a memory leak If client disconnects without retrieving the resultset, the memory used by the last packet could be leaked if larger than network buffer. --- lib/mysql_data_stream.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/mysql_data_stream.cpp b/lib/mysql_data_stream.cpp index 42bf28fcf..ce142b897 100644 --- a/lib/mysql_data_stream.cpp +++ b/lib/mysql_data_stream.cpp @@ -71,6 +71,10 @@ static void __dump_pkt(const char *func, unsigned char *_ptr, unsigned int len) #define queue_destroy(_q) { \ if (_q.buffer) free(_q.buffer); \ _q.buffer=NULL; \ + if (_q.pkt.ptr) { \ + l_free(_q.pkt.size,_q.pkt.ptr); \ + queueOUT.pkt.ptr=NULL; \ + } \ } #define queue_zero(_q) { \ From 6cec5078ec22833ecbe248d5b9fe1042c6bdc877 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Wed, 19 Dec 2018 07:27:27 +0100 Subject: [PATCH 7/8] Tune shun time if ping interval is too low #1883 When shunning a node, evaluate the different between `mysql-monitor_ping_interval` and `mysql-shun_recovery_time_sec`, and postpone in the future when the server needs to be recovered --- lib/MySQL_HostGroups_Manager.cpp | 22 ++++++++++++++++++++-- lib/MySQL_Thread.cpp | 2 +- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/lib/MySQL_HostGroups_Manager.cpp b/lib/MySQL_HostGroups_Manager.cpp index 51085949a..9fe8aefcf 100644 --- a/lib/MySQL_HostGroups_Manager.cpp +++ b/lib/MySQL_HostGroups_Manager.cpp @@ -748,10 +748,16 @@ void MySrvC::connect_error(int err_num) { break; } time_t t=time(NULL); - if (t!=time_last_detected_error) { + if (t > time_last_detected_error) { time_last_detected_error=t; connect_ERR_at_time_last_detected_error=1; } else { + if (t < time_last_detected_error) { + // time_last_detected_error is in the future + // this means that monitor has a ping interval too big and tuned that in the future + return; + } + // same time int max_failures = ( mysql_thread___shun_on_failures > mysql_thread___connect_retries_on_failure ? mysql_thread___connect_retries_on_failure : mysql_thread___shun_on_failures) ; if (__sync_add_and_fetch(&connect_ERR_at_time_last_detected_error,1) >= (unsigned int)max_failures) { bool _shu=false; @@ -2076,7 +2082,7 @@ MySrvC *MyHGC::get_random_MySrvC(char * gtid_uuid, uint64_t gtid_trxid) { if (max_wait_sec < 1) { // min wait time should be at least 1 second max_wait_sec = 1; } - if ((t - mysrvc->time_last_detected_error) > max_wait_sec) { + if (t > mysrvc->time_last_detected_error && (t - mysrvc->time_last_detected_error) > max_wait_sec) { if ( (mysrvc->shunned_and_kill_all_connections==false) // it is safe to bring it back online || @@ -2988,6 +2994,18 @@ bool MySQL_HostGroups_Manager::shun_and_killall(char *hostname, int port) { default: break; } + // if Monitor is enabled and mysql-monitor_ping_interval is + // set too high, ProxySQL will unshun hosts that are not + // available. For this reason time_last_detected_error will + // be tuned in the future + if (mysql_thread___monitor_enabled) { + int a = mysql_thread___shun_recovery_time_sec; + int b = mysql_thread___monitor_ping_interval; + b = b/1000; + if (b > a) { + t = t + (b - a); + } + } mysrvc->time_last_detected_error = t; } } diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp index eee77bfa3..3e0fe08af 100644 --- a/lib/MySQL_Thread.cpp +++ b/lib/MySQL_Thread.cpp @@ -356,7 +356,7 @@ MySQL_Threads_Handler::MySQL_Threads_Handler() { variables.monitor_history=600000; variables.monitor_connect_interval=120000; variables.monitor_connect_timeout=600; - variables.monitor_ping_interval=60000; + variables.monitor_ping_interval=8000; variables.monitor_ping_max_failures=3; variables.monitor_ping_timeout=1000; variables.monitor_read_only_interval=1000; From 6bdacade784e5ebaf326be3e595c106b6c092992 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Wed, 19 Dec 2018 02:57:41 +0100 Subject: [PATCH 8/8] Added mysql-auto_increment_delay_multiplex #1828 Temporary disable multiplexing when last_insert_id is returned in OK packet. Multiplexing is disabled for mysql-auto_increment_delay_multiplex queries. mysql-auto_increment_delay_multiplex ranges from 0 to 1000000 . Default value is 5 --- include/MySQL_Thread.h | 1 + include/mysql_connection.h | 2 ++ include/proxysql_structs.h | 2 ++ lib/MySQL_Session.cpp | 5 +++++ lib/MySQL_Thread.cpp | 29 +++++++++++++++++++++++++++++ lib/mysql_connection.cpp | 2 ++ 6 files changed, 41 insertions(+) diff --git a/include/MySQL_Thread.h b/include/MySQL_Thread.h index 3ad5ba195..8d3241428 100644 --- a/include/MySQL_Thread.h +++ b/include/MySQL_Thread.h @@ -414,6 +414,7 @@ class MySQL_Threads_Handler int query_processor_iterations; int query_processor_regex; int reset_connection_algorithm; + int auto_increment_delay_multiplex; int long_query_time; int hostgroup_manager_verbose; int binlog_reader_connect_retry_msec; diff --git a/include/mysql_connection.h b/include/mysql_connection.h index f8397fb53..7b3d79bad 100644 --- a/include/mysql_connection.h +++ b/include/mysql_connection.h @@ -65,6 +65,7 @@ class MySQL_Connection { unsigned long long creation_time; unsigned long long last_time_used; unsigned long long timeout; + int auto_increment_delay_token; int fd; MySQL_STMTs_local_v14 *local_stmts; // local view of prepared statements MYSQL *mysql; @@ -180,5 +181,6 @@ class MySQL_Connection { void reset(); bool get_gtid(char *buff, uint64_t *trx_id); + void reduce_auto_increment_delay_token() { if (auto_increment_delay_token) auto_increment_delay_token--; }; }; #endif /* __CLASS_MYSQL_CONNECTION_H */ diff --git a/include/proxysql_structs.h b/include/proxysql_structs.h index ee0e7b527..8d39236ff 100644 --- a/include/proxysql_structs.h +++ b/include/proxysql_structs.h @@ -624,6 +624,7 @@ __thread int mysql_thread___connect_timeout_server_max; __thread int mysql_thread___query_processor_iterations; __thread int mysql_thread___query_processor_regex; __thread int mysql_thread___reset_connection_algorithm; +__thread int mysql_thread___auto_increment_delay_multiplex; __thread uint16_t mysql_thread___server_capabilities; __thread uint8_t mysql_thread___default_charset; __thread int mysql_thread___poll_timeout; @@ -740,6 +741,7 @@ extern __thread int mysql_thread___connect_timeout_server_max; extern __thread int mysql_thread___query_processor_iterations; extern __thread int mysql_thread___query_processor_regex; extern __thread int mysql_thread___reset_connection_algorithm; +extern __thread int mysql_thread___auto_increment_delay_multiplex; extern __thread uint16_t mysql_thread___server_capabilities; extern __thread uint8_t mysql_thread___default_charset; extern __thread int mysql_thread___poll_timeout; diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 8a70358d4..514b26a3c 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -2876,6 +2876,9 @@ handler_again: if (myconn->mysql->affected_rows) { if (myconn->mysql->affected_rows != ULLONG_MAX) { last_HG_affected_rows = current_hostgroup; + if (mysql_thread___auto_increment_delay_multiplex) { + myconn->auto_increment_delay_token = mysql_thread___auto_increment_delay_multiplex + 1; + } } } } @@ -2953,6 +2956,7 @@ handler_again: } RequestEnd(myds); + myds->myconn->reduce_auto_increment_delay_token(); if (mysql_thread___multiplexing && (myds->myconn->reusable==true) && myds->myconn->IsActiveTransaction()==false && myds->myconn->MultiplexDisabled()==false) { if (mysql_thread___connection_delay_multiplex_ms && mirror==false) { myds->wait_until=thread->curtime+mysql_thread___connection_delay_multiplex_ms*1000; @@ -3222,6 +3226,7 @@ handler_again: } RequestEnd(myds); if (myds->myconn) { + myds->myconn->reduce_auto_increment_delay_token(); if (mysql_thread___multiplexing && (myds->myconn->reusable==true) && myds->myconn->IsActiveTransaction()==false && myds->myconn->MultiplexDisabled()==false) { myds->DSS=STATE_NOT_INITIALIZED; if (mysql_thread___autocommit_false_not_reusable && myds->myconn->IsAutoCommit()==false) { diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp index 3e0fe08af..357ebd18f 100644 --- a/lib/MySQL_Thread.cpp +++ b/lib/MySQL_Thread.cpp @@ -285,6 +285,7 @@ static char * mysql_thread_variables_names[]= { (char *)"query_processor_iterations", (char *)"query_processor_regex", (char *)"reset_connection_algorithm", + (char *)"auto_increment_delay_multiplex", (char *)"long_query_time", (char *)"query_cache_size_MB", (char *)"ping_interval_server_msec", @@ -402,6 +403,7 @@ MySQL_Threads_Handler::MySQL_Threads_Handler() { variables.query_processor_iterations=0; variables.query_processor_regex=1; variables.reset_connection_algorithm=2; + variables.auto_increment_delay_multiplex=5; variables.long_query_time=1000; variables.query_cache_size_MB=256; variables.init_connect=NULL; @@ -716,6 +718,19 @@ int MySQL_Threads_Handler::get_variable_int(char *name) { if (!strcasecmp(name,"binlog_reader_connect_retry_msec")) return (int)variables.binlog_reader_connect_retry_msec; if (!strcasecmp(name,"wait_timeout")) return (int)variables.wait_timeout; if (!strcasecmp(name,"reset_connection_algorithm")) return (int)variables.reset_connection_algorithm; + if (!strcasecmp(name,"throttle_max_bytes_per_second_to_client")) return (int)variables.throttle_max_bytes_per_second_to_client; + if (!strcasecmp(name,"throttle_ratio_server_to_client")) return (int)variables.throttle_ratio_server_to_client; + if (!strcasecmp(name,"max_connections")) return (int)variables.max_connections; + if (!strcasecmp(name,"max_stmts_per_connection")) return (int)variables.max_stmts_per_connection; + if (!strcasecmp(name,"max_stmts_cache")) return (int)variables.max_stmts_cache; + if (!strcasecmp(name,"mirror_max_concurrency")) return (int)variables.mirror_max_concurrency; + if (!strcasecmp(name,"mirror_max_queue_length")) return (int)variables.mirror_max_queue_length; + if (!strcasecmp(name,"default_query_delay")) return (int)variables.default_query_delay; + if (!strcasecmp(name,"default_query_timeout")) return (int)variables.default_query_timeout; + if (!strcasecmp(name,"query_processor_iterations")) return (int)variables.query_processor_iterations; + if (!strcasecmp(name,"query_processor_regex")) return (int)variables.query_processor_regex; + if (!strcasecmp(name,"auto_increment_delay_multiplex")) return (int)variables.auto_increment_delay_multiplex; + if (!strcasecmp(name,"default_max_latency_ms")) return (int)variables.default_max_latency_ms; if (!strcasecmp(name,"long_query_time")) return (int)variables.long_query_time; if (!strcasecmp(name,"free_connections_pct")) return (int)variables.free_connections_pct; if (!strcasecmp(name,"have_compress")) return (int)variables.have_compress; @@ -1063,6 +1078,10 @@ char * MySQL_Threads_Handler::get_variable(char *name) { // this is the public f sprintf(intbuf,"%d",variables.reset_connection_algorithm); return strdup(intbuf); } + if (!strcasecmp(name,"auto_increment_delay_multiplex")) { + sprintf(intbuf,"%d",variables.auto_increment_delay_multiplex); + return strdup(intbuf); + } if (!strcasecmp(name,"default_max_latency_ms")) { sprintf(intbuf,"%d",variables.default_max_latency_ms); return strdup(intbuf); @@ -1664,6 +1683,15 @@ bool MySQL_Threads_Handler::set_variable(char *name, char *value) { // this is t return false; } } + if (!strcasecmp(name,"auto_increment_delay_multiplex")) { + int intv=atoi(value); + if (intv >= 0 && intv <= 1000000) { + variables.auto_increment_delay_multiplex=intv; + return true; + } else { + return false; + } + } if (!strcasecmp(name,"default_max_latency_ms")) { int intv=atoi(value); if (intv >= 0 && intv <= 20*24*3600*1000) { @@ -3523,6 +3551,7 @@ void MySQL_Thread::refresh_variables() { mysql_thread___query_processor_iterations=GloMTH->get_variable_int((char *)"query_processor_iterations"); mysql_thread___query_processor_regex=GloMTH->get_variable_int((char *)"query_processor_regex"); mysql_thread___reset_connection_algorithm=GloMTH->get_variable_int((char *)"reset_connection_algorithm"); + mysql_thread___auto_increment_delay_multiplex=GloMTH->get_variable_int((char *)"auto_increment_delay_multiplex"); mysql_thread___default_max_latency_ms=GloMTH->get_variable_int((char *)"default_max_latency_ms"); mysql_thread___long_query_time=GloMTH->get_variable_int((char *)"long_query_time"); mysql_thread___query_cache_size_MB=GloMTH->get_variable_int((char *)"query_cache_size_MB"); diff --git a/lib/mysql_connection.cpp b/lib/mysql_connection.cpp index b51374b97..f1600eb99 100644 --- a/lib/mysql_connection.cpp +++ b/lib/mysql_connection.cpp @@ -219,6 +219,7 @@ MySQL_Connection::MySQL_Connection() { MyRS_reuse=NULL; unknown_transaction_status = false; creation_time=0; + auto_increment_delay_token = 0; processing_multi_statement=false; proxy_debug(PROXY_DEBUG_MYSQL_CONNPOOL, 4, "Creating new MySQL_Connection %p\n", this); local_stmts=new MySQL_STMTs_local_v14(false); // false by default, it is a backend @@ -1626,6 +1627,7 @@ bool MySQL_Connection::MultiplexDisabled() { if (status_flags & (STATUS_MYSQL_CONNECTION_TRANSACTION|STATUS_MYSQL_CONNECTION_USER_VARIABLE|STATUS_MYSQL_CONNECTION_PREPARED_STATEMENT|STATUS_MYSQL_CONNECTION_LOCK_TABLES|STATUS_MYSQL_CONNECTION_TEMPORARY_TABLE|STATUS_MYSQL_CONNECTION_GET_LOCK|STATUS_MYSQL_CONNECTION_NO_MULTIPLEX|STATUS_MYSQL_CONNECTION_SQL_LOG_BIN0|STATUS_MYSQL_CONNECTION_FOUND_ROWS) ) { ret=true; } + if (auto_increment_delay_token) return true; return ret; }