From 112d525c4dbbe5847acf1d8877b9c739ec51fd05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Tue, 18 Aug 2015 18:39:50 +0000 Subject: [PATCH 01/16] Bugfix: PROXYSQL STOP wasn't closing the listener --- include/MySQL_Thread.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/MySQL_Thread.h b/include/MySQL_Thread.h index b6f6f8c77..74a5310bd 100644 --- a/include/MySQL_Thread.h +++ b/include/MySQL_Thread.h @@ -210,6 +210,7 @@ class iface_info { ~iface_info() { free(iface); free(address); + close(fd); } }; From ea1cb87b0e1273a9e2ba08db93f520ed36026860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Tue, 18 Aug 2015 20:10:16 +0000 Subject: [PATCH 02/16] Improved handling of PROXYSQL STOP and PROXYSQL START Not perfect implementation . See issue #336 for more details --- include/MySQL_Thread.h | 1 + lib/MySQL_Thread.cpp | 23 +++++++++++++++++------ lib/ProxySQL_Admin.cpp | 2 ++ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/include/MySQL_Thread.h b/include/MySQL_Thread.h index 74a5310bd..83b6ecf63 100644 --- a/include/MySQL_Thread.h +++ b/include/MySQL_Thread.h @@ -313,6 +313,7 @@ class MySQL_Threads_Handler int listener_del(const char *iface); int listener_del(const char *address, int port); void start_listeners(); + void stop_listeners(); void signal_all_threads(unsigned char _c=0); SQLite3_result * SQL3_Processlist(); bool kill_session(uint32_t _thread_session_id); diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp index 43103e392..8d4e48e66 100644 --- a/lib/MySQL_Thread.cpp +++ b/lib/MySQL_Thread.cpp @@ -286,7 +286,7 @@ int MySQL_Threads_Handler::listener_del(const char *iface) { } for (i=0;imypolls.pending_listener_del,0)); + while(__sync_fetch_and_add(&thr->mypolls.pending_listener_del,0)); } MLM->del(idx); shutdown(fd,SHUT_RDWR); @@ -1003,6 +1003,17 @@ void MySQL_Threads_Handler::start_listeners() { free_tokenizer( &tok ); } +void MySQL_Threads_Handler::stop_listeners() { + if (variables.interfaces==NULL || strlen(variables.interfaces)==0) + return; + tokenizer_t tok = tokenizer( variables.interfaces, ";", TOKENIZER_NO_EMPTIES ); + const char* token; + for (token = tokenize( &tok ); token; token = tokenize( &tok )) { + listener_del((char *)token); + } + free_tokenizer( &tok ); +} + MySQL_Threads_Handler::~MySQL_Threads_Handler() { if (variables.connect_timeout_server_error) free(variables.connect_timeout_server_error); if (variables.default_schema) free(variables.default_schema); @@ -1289,11 +1300,6 @@ void MySQL_Thread::run() { } - while ((n=__sync_add_and_fetch(&mypolls.pending_listener_del,0))) { // spin here - poll_listener_del(n); - assert(__sync_bool_compare_and_swap(&mypolls.pending_listener_del,n,0)); - } - //this is the only portion of code not protected by a global mutex //proxy_debug(PROXY_DEBUG_NET,5,"Calling poll with timeout %d\n", ( mypolls.poll_timeout ? mypolls.poll_timeout : mysql_thread___poll_timeout ) ); proxy_debug(PROXY_DEBUG_NET,5,"Calling poll with timeout %d\n", ( mypolls.poll_timeout ? ( mypolls.poll_timeout/1000 > (unsigned int) mysql_thread___poll_timeout ? mypolls.poll_timeout/1000 : mysql_thread___poll_timeout ) : mysql_thread___poll_timeout ) ); @@ -1301,6 +1307,11 @@ void MySQL_Thread::run() { rc=poll(mypolls.fds,mypolls.len, ( mypolls.poll_timeout ? ( mypolls.poll_timeout/1000 < (unsigned int) mysql_thread___poll_timeout ? mypolls.poll_timeout/1000 : mysql_thread___poll_timeout ) : mysql_thread___poll_timeout ) ); proxy_debug(PROXY_DEBUG_NET,5,"%s\n", "Returning poll"); + while ((n=__sync_add_and_fetch(&mypolls.pending_listener_del,0))) { // spin here + poll_listener_del(n); + assert(__sync_bool_compare_and_swap(&mypolls.pending_listener_del,n,0)); + } + curtime=monotonic_time(); spin_wrlock(&thread_mutex); diff --git a/lib/ProxySQL_Admin.cpp b/lib/ProxySQL_Admin.cpp index 4fba9e6fe..da5b18a15 100644 --- a/lib/ProxySQL_Admin.cpp +++ b/lib/ProxySQL_Admin.cpp @@ -309,6 +309,8 @@ bool admin_handler_command_proxysql(char *query_no_space, unsigned int query_no_ if (query_no_space_length==strlen("PROXYSQL STOP") && !strncasecmp("PROXYSQL STOP",query_no_space, query_no_space_length)) { proxy_info("Received PROXYSQL STOP command\n"); + GloMTH->signal_all_threads(10); + GloMTH->stop_listeners(); __sync_bool_compare_and_swap(&glovars.shutdown,0,1); glovars.reload=2; return false; From 0eac78991e09d704c125833f474f9a9bd28253f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Tue, 18 Aug 2015 21:39:41 +0000 Subject: [PATCH 03/16] iImplementation of mysql-wait_timeout (issue #321) and others Also implemented mysql-max_transaction_time : like mysql-wait_timeout , but for transactions --- include/MySQL_Session.h | 2 ++ include/MySQL_Thread.h | 1 + include/proxysql_structs.h | 2 ++ lib/MySQL_Session.cpp | 25 +++++++++++++++++++++++++ lib/MySQL_Thread.cpp | 26 ++++++++++++++++++++++++++ 5 files changed, 56 insertions(+) diff --git a/include/MySQL_Session.h b/include/MySQL_Session.h index b9790f807..56d5b3830 100644 --- a/include/MySQL_Session.h +++ b/include/MySQL_Session.h @@ -158,6 +158,8 @@ class MySQL_Session void SQLite3_to_MySQL(SQLite3_result *, char *, int , MySQL_Protocol *); void MySQL_Result_to_MySQL_wire(MYSQL *mysql, MYSQL_RES *result, MySQL_Protocol *myprot); SQLite3_result * SQL3_Session_status(); + unsigned int NumActiveTransactions(); + unsigned long long IdleTime(); void reset_all_backends(); void writeout(); diff --git a/include/MySQL_Thread.h b/include/MySQL_Thread.h index 83b6ecf63..efc2293a3 100644 --- a/include/MySQL_Thread.h +++ b/include/MySQL_Thread.h @@ -271,6 +271,7 @@ class MySQL_Threads_Handler bool default_reconnect; bool have_compress; int max_transaction_time; + int wait_timeout; int max_connections; int default_query_delay; int default_query_timeout; diff --git a/include/proxysql_structs.h b/include/proxysql_structs.h index d82379452..77fc200b4 100644 --- a/include/proxysql_structs.h +++ b/include/proxysql_structs.h @@ -668,6 +668,7 @@ MySQL_HostGroups_Manager *MyHGM; __thread char *mysql_thread___default_schema; __thread char *mysql_thread___server_version; __thread int mysql_thread___max_transaction_time; +__thread int mysql_thread___wait_timeout; __thread int mysql_thread___max_connections; __thread int mysql_thread___default_query_delay; __thread int mysql_thread___default_query_timeout; @@ -717,6 +718,7 @@ extern MySQL_HostGroups_Manager *MyHGM; extern __thread char *mysql_thread___default_schema; extern __thread char *mysql_thread___server_version; extern __thread int mysql_thread___max_transaction_time; +extern __thread int mysql_thread___wait_timeout; extern __thread int mysql_thread___max_connections; extern __thread int mysql_thread___default_query_delay; extern __thread int mysql_thread___default_query_timeout; diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 4052c6ca4..d1afde641 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -2401,3 +2401,28 @@ void MySQL_Session::destroy_MySQL_Connection(MySQL_Data_Stream *myds) { MyHGM->destroy_MyConn_from_pool(myconn); } */ + +unsigned int MySQL_Session::NumActiveTransactions() { + unsigned int ret=0; + if (mybes==0) return ret; + MySQL_Backend *_mybe; + unsigned int i; + for (i=0; i < mybes->len; i++) { + _mybe=(MySQL_Backend *)mybes->index(i); + if (_mybe->server_myds) + if (_mybe->server_myds->myconn) + if (_mybe->server_myds->myconn->IsActiveTransaction()) + ret++; + } + return ret; +} + +unsigned long long MySQL_Session::IdleTime() { + if (client_myds==0) return 0; + if (status!=WAITING_CLIENT_DATA) return 0; + int idx=client_myds->poll_fds_idx; + unsigned long long last_sent=thread->mypolls.last_sent[idx]; + unsigned long long last_recv=thread->mypolls.last_recv[idx]; + unsigned long long last_time=(last_sent > last_recv ? last_sent : last_recv); + return thread->curtime - last_time; +} diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp index 8d4e48e66..e8e547c86 100644 --- a/lib/MySQL_Thread.cpp +++ b/lib/MySQL_Thread.cpp @@ -156,6 +156,7 @@ static char * mysql_thread_variables_names[]= { (char *)"monitor_query_timeout", (char *)"monitor_timer_cached", (char *)"max_transaction_time", + (char *)"wait_timeout", (char *)"max_connections", (char *)"default_query_delay", (char *)"default_query_timeout", @@ -213,6 +214,7 @@ MySQL_Threads_Handler::MySQL_Threads_Handler() { variables.monitor_query_status=strdup((char *)"SELECT * FROM INFORMATION_SCHEMA.GLOBAL_STATUS"); variables.monitor_timer_cached=true; variables.max_transaction_time=4*3600*1000; + variables.wait_timeout=8*3600*1000; variables.max_connections=10*1000; variables.default_query_delay=0; variables.default_query_timeout=24*3600*1000; @@ -355,6 +357,7 @@ int MySQL_Threads_Handler::get_variable_int(char *name) { if (!strcasecmp(name,"connect_timeout_server_max")) return (int)variables.connect_timeout_server_max; if (!strcasecmp(name,"connect_retries_delay")) return (int)variables.connect_retries_delay; if (!strcasecmp(name,"max_transaction_time")) return (int)variables.max_transaction_time; + if (!strcasecmp(name,"wait_timeout")) return (int)variables.wait_timeout; if (!strcasecmp(name,"max_connections")) return (int)variables.max_connections; if (!strcasecmp(name,"default_query_delay")) return (int)variables.default_query_delay; if (!strcasecmp(name,"default_query_timeout")) return (int)variables.default_query_timeout; @@ -457,6 +460,10 @@ char * MySQL_Threads_Handler::get_variable(char *name) { // this is the public f sprintf(intbuf,"%d",variables.max_transaction_time); return strdup(intbuf); } + if (!strcasecmp(name,"wait_timeout")) { + sprintf(intbuf,"%d",variables.wait_timeout); + return strdup(intbuf); + } if (!strcasecmp(name,"max_connections")) { sprintf(intbuf,"%d",variables.max_connections); return strdup(intbuf); @@ -659,6 +666,15 @@ bool MySQL_Threads_Handler::set_variable(char *name, char *value) { // this is t return false; } } + if (!strcasecmp(name,"wait_timeout")) { + int intv=atoi(value); + if (intv >= 1000 && intv <= 20*24*3600*1000) { + variables.wait_timeout=intv; + return true; + } else { + return false; + } + } if (!strcasecmp(name,"free_connections_pct")) { int intv=atoi(value); if (intv >= 0 && intv <= 100) { @@ -1473,6 +1489,15 @@ void MySQL_Thread::process_all_sessions() { } for (n=0; nlen; n++) { MySQL_Session *sess=(MySQL_Session *)mysql_sessions->index(n); + unsigned long long sess_time = sess->IdleTime(); + unsigned int numTrx = sess->NumActiveTransactions(); + if (numTrx) { + // the session has idle transactions, kill it + if (sess_time/1000 > (unsigned long long)mysql_thread___max_transaction_time) sess->killed=true; + } else { + // the session is idle, kill it + if (sess_time/1000 > (unsigned long long)mysql_thread___wait_timeout) sess->killed=true; + } if (sess->healthy==0) { unregister_session(n); n--; @@ -1505,6 +1530,7 @@ void MySQL_Thread::refresh_variables() { GloMTH->wrlock(); __thread_MySQL_Thread_Variables_version=__global_MySQL_Thread_Variables_version; mysql_thread___max_transaction_time=GloMTH->get_variable_int((char *)"max_transaction_time"); + mysql_thread___wait_timeout=GloMTH->get_variable_int((char *)"wait_timeout"); mysql_thread___max_connections=GloMTH->get_variable_int((char *)"max_connections"); mysql_thread___default_query_delay=GloMTH->get_variable_int((char *)"default_query_delay"); mysql_thread___default_query_timeout=GloMTH->get_variable_int((char *)"default_query_timeout"); From 8f4b75a2a249a61a93b1facb8e70c1081790c7f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Tue, 18 Aug 2015 21:54:58 +0000 Subject: [PATCH 04/16] Bugfix: running statistics while MySQL module is down causes segfault --- lib/MySQL_Thread.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp index e8e547c86..ed7ac6ec0 100644 --- a/lib/MySQL_Thread.cpp +++ b/lib/MySQL_Thread.cpp @@ -1981,8 +1981,11 @@ unsigned long long MySQL_Threads_Handler::get_total_queries() { unsigned long long q=0; unsigned int i; for (i=0;istatus_variables.queries,0); + if (mysql_threads && mysql_threads[i]) { + MySQL_Thread *thr=(MySQL_Thread *)mysql_threads[i].worker; + if (thr) + q+=__sync_fetch_and_add(&thr->status_variables.queries,0); + } } return q; } @@ -1991,8 +1994,11 @@ unsigned long long MySQL_Threads_Handler::get_slow_queries() { unsigned long long q=0; unsigned int i; for (i=0;istatus_variables.queries_slow,0); + if (mysql_threads && mysql_threads[i]) { + MySQL_Thread *thr=(MySQL_Thread *)mysql_threads[i].worker; + if (thr) + q+=__sync_fetch_and_add(&thr->status_variables.queries_slow,0); + } } return q; } From 471520934d6fac4060987e94db07b7e0c9b30e65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Tue, 18 Aug 2015 21:57:49 +0000 Subject: [PATCH 05/16] Typo --- lib/MySQL_Thread.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp index ed7ac6ec0..f14836c31 100644 --- a/lib/MySQL_Thread.cpp +++ b/lib/MySQL_Thread.cpp @@ -1981,7 +1981,7 @@ unsigned long long MySQL_Threads_Handler::get_total_queries() { unsigned long long q=0; unsigned int i; for (i=0;istatus_variables.queries,0); @@ -1994,7 +1994,7 @@ unsigned long long MySQL_Threads_Handler::get_slow_queries() { unsigned long long q=0; unsigned int i; for (i=0;istatus_variables.queries_slow,0); From 42fbbe6fc81b6f603bfc75845327b4aad6b216ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Tue, 18 Aug 2015 23:24:52 +0000 Subject: [PATCH 06/16] Implemented PROXYSQL PAUSE and PROXYSQL RESUME (issue #337) Enhancement: admin_handler_command_proxysql is now protected with a mutex --- lib/MySQL_Thread.cpp | 8 ++++++- lib/ProxySQL_Admin.cpp | 53 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp index f14836c31..213cbf5b7 100644 --- a/lib/MySQL_Thread.cpp +++ b/lib/MySQL_Thread.cpp @@ -668,7 +668,7 @@ bool MySQL_Threads_Handler::set_variable(char *name, char *value) { // this is t } if (!strcasecmp(name,"wait_timeout")) { int intv=atoi(value); - if (intv >= 1000 && intv <= 20*24*3600*1000) { + if (intv >= 0 && intv <= 20*24*3600*1000) { variables.wait_timeout=intv; return true; } else { @@ -1315,6 +1315,12 @@ void MySQL_Thread::run() { // } } + if (mysql_thread___wait_timeout==0) { + // we should be going into PAUSE mode + if (mypolls.poll_timeout==0 || mypolls.poll_timeout > 100000) { + mypolls.poll_timeout=100000; + } + } //this is the only portion of code not protected by a global mutex //proxy_debug(PROXY_DEBUG_NET,5,"Calling poll with timeout %d\n", ( mypolls.poll_timeout ? mypolls.poll_timeout : mysql_thread___poll_timeout ) ); diff --git a/lib/ProxySQL_Admin.cpp b/lib/ProxySQL_Admin.cpp index da5b18a15..475d2535f 100644 --- a/lib/ProxySQL_Admin.cpp +++ b/lib/ProxySQL_Admin.cpp @@ -35,6 +35,8 @@ static volatile bool nostart_=false; static int __admin_refresh_interval=0; +static bool proxysql_mysql_paused=false; +static int old_wait_timeout; extern MySQL_Authentication *GloMyAuth; extern ProxySQL_Admin *GloAdmin; @@ -316,6 +318,55 @@ bool admin_handler_command_proxysql(char *query_no_space, unsigned int query_no_ return false; } + if (query_no_space_length==strlen("PROXYSQL PAUSE") && !strncasecmp("PROXYSQL PAUSE",query_no_space, query_no_space_length)) { + proxy_info("Received PROXYSQL PAUSE command\n"); + ProxySQL_Admin *SPA=(ProxySQL_Admin *)pa; + if (nostart_) { + if (__sync_fetch_and_add(&GloVars.global.nostart,0)) { + SPA->send_MySQL_ERR(&sess->client_myds->myprot, (char *)"ProxySQL MySQL module not running, impossible to pause"); + return false; + } + } + if (proxysql_mysql_paused==false) { + old_wait_timeout=GloMTH->get_variable_int((char *)"wait_timeout"); + GloMTH->set_variable((char *)"wait_timeout",(char *)"0"); + GloMTH->commit(); + // to speed up this process we first change wait_timeout to 0 + // MySQL_thread will call poll() with a maximum timeout of 100ms + GloMTH->signal_all_threads(0); + GloMTH->stop_listeners(); + proxysql_mysql_paused=true; + SPA->send_MySQL_OK(&sess->client_myds->myprot, NULL); + } else { + SPA->send_MySQL_ERR(&sess->client_myds->myprot, (char *)"ProxySQL MySQL module is already paused, impossible to pause"); + } + return false; + } + + if (query_no_space_length==strlen("PROXYSQL RESUME") && !strncasecmp("PROXYSQL RESUME",query_no_space, query_no_space_length)) { + proxy_info("Received PROXYSQL RESUME command\n"); + ProxySQL_Admin *SPA=(ProxySQL_Admin *)pa; + if (nostart_) { + if (__sync_fetch_and_add(&GloVars.global.nostart,0)) { + SPA->send_MySQL_ERR(&sess->client_myds->myprot, (char *)"ProxySQL MySQL module not running, impossible to resume"); + return false; + } + } + if (proxysql_mysql_paused==true) { + // to speed up the process we add the listeners while poll() is called with a maximum timeout of of 100ms + GloMTH->start_listeners(); + char buf[32]; + sprintf(buf,"%d",old_wait_timeout); + GloMTH->set_variable((char *)"wait_timeout",buf); + GloMTH->commit(); + proxysql_mysql_paused=false; + SPA->send_MySQL_OK(&sess->client_myds->myprot, NULL); + } else { + SPA->send_MySQL_ERR(&sess->client_myds->myprot, (char *)"ProxySQL MySQL module is not paused, impossible to resume"); + } + return false; + } + if (query_no_space_length==strlen("PROXYSQL SHUTDOWN") && !strncasecmp("PROXYSQL SHUTDOWN",query_no_space, query_no_space_length)) { proxy_info("Received PROXYSQL SHUTDOWN command\n"); __sync_bool_compare_and_swap(&glovars.shutdown,0,1); @@ -947,7 +998,9 @@ void admin_session_handler(MySQL_Session *sess, ProxySQL_Admin *pa, PtrSize_t *p if (sess->stats==false) { if ((query_no_space_length>8) && (!strncasecmp("PROXYSQL ", query_no_space, 8))) { proxy_debug(PROXY_DEBUG_ADMIN, 4, "Received PROXYSQL command\n"); + pthread_mutex_lock(&admin_mutex); run_query=admin_handler_command_proxysql(query_no_space, query_no_space_length, sess, pa); + pthread_mutex_unlock(&admin_mutex); goto __run_query; } if ((query_no_space_length>5) && ( (!strncasecmp("SAVE ", query_no_space, 5)) || (!strncasecmp("LOAD ", query_no_space, 5))) ) { From 43c9d6751675b81b8f2a0055d14e7afde9039592 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Tue, 18 Aug 2015 23:29:45 +0000 Subject: [PATCH 07/16] Faster PROXYSQL STOP using the same technique used in #337 --- lib/ProxySQL_Admin.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/ProxySQL_Admin.cpp b/lib/ProxySQL_Admin.cpp index 475d2535f..c17e164f1 100644 --- a/lib/ProxySQL_Admin.cpp +++ b/lib/ProxySQL_Admin.cpp @@ -311,10 +311,19 @@ bool admin_handler_command_proxysql(char *query_no_space, unsigned int query_no_ if (query_no_space_length==strlen("PROXYSQL STOP") && !strncasecmp("PROXYSQL STOP",query_no_space, query_no_space_length)) { proxy_info("Received PROXYSQL STOP command\n"); - GloMTH->signal_all_threads(10); + // to speed up this process we first change wait_timeout to 0 + // MySQL_thread will call poll() with a maximum timeout of 100ms + old_wait_timeout=GloMTH->get_variable_int((char *)"wait_timeout"); + GloMTH->set_variable((char *)"wait_timeout",(char *)"0"); + GloMTH->commit(); + GloMTH->signal_all_threads(0); GloMTH->stop_listeners(); - __sync_bool_compare_and_swap(&glovars.shutdown,0,1); + char buf[32]; + sprintf(buf,"%d",old_wait_timeout); + GloMTH->set_variable((char *)"wait_timeout",buf); + GloMTH->commit(); glovars.reload=2; + __sync_bool_compare_and_swap(&glovars.shutdown,0,1); return false; } From b9c4548ab7cb4577208100c332db18d575dd6398 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Wed, 19 Aug 2015 07:18:38 +0000 Subject: [PATCH 08/16] Implementation of mysql status table named stats_mysql_global (issue #328) Status variables implemented so far: - Client_Connections_aborted - Client_Connections_connected - Client_Connections_created - Questions - Slow_queries Also created alias command SHOW MYSQL STATUS --- include/MySQL_HostGroups_Manager.h | 2 ++ include/MySQL_Thread.h | 1 + include/proxysql_admin.h | 1 + lib/MySQL_HostGroups_Manager.cpp | 2 ++ lib/MySQL_Session.cpp | 2 ++ lib/MySQL_Thread.cpp | 44 ++++++++++++++++++++++++++++++ lib/ProxySQL_Admin.cpp | 38 ++++++++++++++++++++++++++ 7 files changed, 90 insertions(+) diff --git a/include/MySQL_HostGroups_Manager.h b/include/MySQL_HostGroups_Manager.h index d0c90df84..3dea64619 100644 --- a/include/MySQL_HostGroups_Manager.h +++ b/include/MySQL_HostGroups_Manager.h @@ -90,6 +90,8 @@ class MySQL_HostGroups_Manager { public: struct { + unsigned long client_connections_aborted; + unsigned long client_connections_created; int client_connections; unsigned long myconnpoll_get; unsigned long myconnpoll_get_ok; diff --git a/include/MySQL_Thread.h b/include/MySQL_Thread.h index efc2293a3..4f261a461 100644 --- a/include/MySQL_Thread.h +++ b/include/MySQL_Thread.h @@ -317,6 +317,7 @@ class MySQL_Threads_Handler void stop_listeners(); void signal_all_threads(unsigned char _c=0); SQLite3_result * SQL3_Processlist(); + SQLite3_result * SQL3_GlobalStatus(); bool kill_session(uint32_t _thread_session_id); unsigned long long get_total_queries(); unsigned long long get_slow_queries(); diff --git a/include/proxysql_admin.h b/include/proxysql_admin.h index 54b0d3249..3ddf98d14 100644 --- a/include/proxysql_admin.h +++ b/include/proxysql_admin.h @@ -125,6 +125,7 @@ class ProxySQL_Admin { void stats___mysql_commands_counters(); void stats___mysql_processlist(); void stats___mysql_connection_pool(); + void stats___mysql_global(); int Read_Global_Variables_from_configfile(const char *prefix); int Read_MySQL_Users_from_configfile(); diff --git a/lib/MySQL_HostGroups_Manager.cpp b/lib/MySQL_HostGroups_Manager.cpp index 8af544218..2ac69d2aa 100644 --- a/lib/MySQL_HostGroups_Manager.cpp +++ b/lib/MySQL_HostGroups_Manager.cpp @@ -185,6 +185,8 @@ class MyHGC { // MySQL Host Group Container MySQL_HostGroups_Manager::MySQL_HostGroups_Manager() { status.client_connections=0; + status.client_connections_aborted=0; + status.client_connections_created=0; status.myconnpoll_get=0; status.myconnpoll_get_ok=0; status.myconnpoll_get_ping=0; diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index d1afde641..26feeb827 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -1797,6 +1797,7 @@ void MySQL_Session::handler___status_CONNECTING_CLIENT___STATE_SERVER_HANDSHAKE( *wrong_pass=true; client_myds->setDSS_STATE_QUERY_SENT_NET(); client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,2,1040,(char *)"#HY000", (char *)"Too many connections"); + __sync_add_and_fetch(&MyHGM->status.client_connections_aborted,1); client_myds->DSS=STATE_SLEEP; } else { client_myds->myprot.generate_pkt_OK(true,NULL,NULL,2,0,0,0,0,NULL); @@ -1837,6 +1838,7 @@ void MySQL_Session::handler___status_CONNECTING_CLIENT___STATE_SERVER_HANDSHAKE( char *_s=(char *)malloc(strlen(client_myds->myconn->userinfo->username)+100); sprintf(_s,"Access denied for user '%s' (using password: %s)", client_myds->myconn->userinfo->username, (client_myds->myconn->userinfo->password ? "YES" : "NO")); client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,2,1045,(char *)"#28000", _s); + __sync_add_and_fetch(&MyHGM->status.client_connections_aborted,1); free(_s); client_myds->DSS=STATE_SLEEP; //return -1; diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp index 213cbf5b7..87e1858ef 100644 --- a/lib/MySQL_Thread.cpp +++ b/lib/MySQL_Thread.cpp @@ -1672,6 +1672,7 @@ void MySQL_Thread::listener_handle_new_connection(MySQL_Data_Stream *myds, unsig MySQL_Session *sess=create_new_session_and_client_data_stream(c); //sess->myprot_client.generate_pkt_initial_handshake(sess->client_myds,true,NULL,NULL); //sess->myprot_client.generate_pkt_initial_handshake(true,NULL,NULL); + __sync_add_and_fetch(&MyHGM->status.client_connections_created,1); if (__sync_add_and_fetch(&MyHGM->status.client_connections,1) > mysql_thread___max_connections) { sess->max_connections_reached=true; } @@ -1792,6 +1793,49 @@ SQLite3_result * MySQL_Threads_Handler::SQL3_Threads_status(MySQL_Session *sess) return result; } +SQLite3_result * MySQL_Threads_Handler::SQL3_GlobalStatus() { + const int colnum=2; + char buf[256]; + char **pta=(char **)malloc(sizeof(char *)*colnum); + proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 4, "Dumping MySQL Global Status\n"); + SQLite3_result *result=new SQLite3_result(colnum); + result->add_column_definition(SQLITE_TEXT,"Variable_Name"); + result->add_column_definition(SQLITE_TEXT,"Variable_Value"); + // NOTE: as there is no string copy, we do NOT free pta[0] and pta[1] + { // Connections created + pta[0]=(char *)"Client_Connections_aborted"; + sprintf(buf,"%lu",MyHGM->status.client_connections_aborted); + pta[1]=buf; + result->add_row(pta); + } + { // Connections + pta[0]=(char *)"Client_Connections_connected"; + sprintf(buf,"%d",MyHGM->status.client_connections); + pta[1]=buf; + result->add_row(pta); + } + { // Connections created + pta[0]=(char *)"Client_Connections_created"; + sprintf(buf,"%lu",MyHGM->status.client_connections_created); + pta[1]=buf; + result->add_row(pta); + } + { // Queries + pta[0]=(char *)"Questions"; + sprintf(buf,"%llu",get_total_queries()); + pta[1]=buf; + result->add_row(pta); + } + { // Slow queries + pta[0]=(char *)"Slow_queries"; + sprintf(buf,"%llu",get_slow_queries()); + pta[1]=buf; + result->add_row(pta); + } + free(pta); + return result; +} + SQLite3_result * MySQL_Threads_Handler::SQL3_Processlist() { const int colnum=14; proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 4, "Dumping MySQL Processlist\n"); diff --git a/lib/ProxySQL_Admin.cpp b/lib/ProxySQL_Admin.cpp index c17e164f1..8b124a88e 100644 --- a/lib/ProxySQL_Admin.cpp +++ b/lib/ProxySQL_Admin.cpp @@ -68,6 +68,8 @@ pthread_mutex_t admin_mutex = PTHREAD_MUTEX_INITIALIZER; #define STATS_SQLITE_TABLE_MYSQL_QUERY_DIGEST_RESET "CREATE TABLE stats_mysql_query_digest_reset (schemaname VARCHAR NOT NULL , username VARCHAR NOT NULL , digest VARCHAR NOT NULL , digest_text VARCHAR NOT NULL , count_star INTEGER NOT NULL , first_seen INTEGER NOT NULL , last_seen INTEGER NOT NULL , sum_time INTEGER NOT NULL , min_time INTEGER NOT NULL , max_time INTEGER NOT NULL , PRIMARY KEY(schemaname, username, digest))" +#define STATS_SQLITE_TABLE_MYSQL_GLOBAL "CREATE TABLE stats_mysql_global (Variable_Name VARCHAR NOT NULL PRIMARY KEY , Variable_Value VARCHAR NOT NULL)" + #ifdef DEBUG #define ADMIN_SQLITE_TABLE_DEBUG_LEVELS "CREATE TABLE debug_levels (module VARCHAR NOT NULL PRIMARY KEY , verbosity INT NOT NULL DEFAULT 0)" #endif /* DEBUG */ @@ -934,6 +936,7 @@ void ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign bool stats_mysql_connection_pool=false; bool stats_mysql_query_digest=false; bool stats_mysql_query_digest_reset=false; + bool stats_mysql_global=false; bool dump_global_variables=false; if (strcasestr(query_no_space,"processlist")) @@ -946,6 +949,8 @@ void ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign { stats_mysql_query_digest=true; refresh=true; } if (strstr(query_no_space,"stats_mysql_query_digest_reset")) { stats_mysql_query_digest_reset=true; refresh=true; } + if (strstr(query_no_space,"stats_mysql_global")) + { stats_mysql_global=true; refresh=true; } if (strstr(query_no_space,"stats_mysql_connection_pool")) { stats_mysql_connection_pool=true; refresh=true; } if (admin) { @@ -964,6 +969,8 @@ void ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign stats___mysql_query_digests_reset(); if (stats_mysql_connection_pool) stats___mysql_connection_pool(); + if (stats_mysql_global) + stats___mysql_global(); if (admin) { if (dump_global_variables) { flush_admin_variables___runtime_to_database(admindb, false, false, false); @@ -1155,6 +1162,14 @@ void admin_session_handler(MySQL_Session *sess, ProxySQL_Admin *pa, PtrSize_t *p goto __run_query; } + if (query_no_space_length==strlen("SHOW MYSQL STATUS") && !strncasecmp("SHOW MYSQL STATUS",query_no_space, query_no_space_length)) { + l_free(query_length,query); + query=l_strdup("SELECT Variable_Name AS Variable_name, Variable_Value AS Value FROM stats_mysql_global ORDER BY variable_name"); + query_length=strlen(query)+1; + GloAdmin->stats___mysql_global(); + goto __run_query; + } + strA=(char *)"SHOW CREATE TABLE "; strB=(char *)"SELECT name AS 'table' , REPLACE(REPLACE(sql,' , ', X'2C0A'),'CREATE TABLE %s (','CREATE TABLE %s ('||X'0A') AS 'Create Table' FROM %s.sqlite_master WHERE type='table' AND name='%s'"; strAl=strlen(strA); @@ -1615,6 +1630,7 @@ bool ProxySQL_Admin::init() { insert_into_tables_defs(tables_defs_stats,"stats_mysql_connection_pool", STATS_SQLITE_TABLE_MYSQL_CONNECTION_POOL); insert_into_tables_defs(tables_defs_stats,"stats_mysql_query_digest", STATS_SQLITE_TABLE_MYSQL_QUERY_DIGEST); insert_into_tables_defs(tables_defs_stats,"stats_mysql_query_digest_reset", STATS_SQLITE_TABLE_MYSQL_QUERY_DIGEST_RESET); + insert_into_tables_defs(tables_defs_stats,"stats_mysql_global", STATS_SQLITE_TABLE_MYSQL_GLOBAL); check_and_build_standard_tables(admindb, tables_defs_admin); @@ -2152,6 +2168,28 @@ bool ProxySQL_Admin::set_variable(char *name, char *value) { // this is the pub +void ProxySQL_Admin::stats___mysql_global() { + if (!GloMTH) return; + SQLite3_result * resultset=GloMTH->SQL3_GlobalStatus(); + if (resultset==NULL) return; + statsdb->execute("BEGIN"); + statsdb->execute("DELETE FROM stats_mysql_global"); + char *a=(char *)"INSERT INTO stats_mysql_global VALUES (\"%s\",\"%s\")"; + for (std::vector::iterator it = resultset->rows.begin() ; it != resultset->rows.end(); ++it) { + SQLite3_row *r=*it; + int arg_len=0; + for (int i=0; i<2; i++) { + arg_len+=strlen(r->fields[i]); + } + char *query=(char *)malloc(strlen(a)+arg_len+32); + sprintf(query,a,r->fields[0],r->fields[1]); + statsdb->execute(query); + free(query); + } + statsdb->execute("COMMIT"); + delete resultset; +} + void ProxySQL_Admin::stats___mysql_processlist() { if (!GloMTH) return; SQLite3_result * resultset=GloMTH->SQL3_Processlist(); From 72d87fc3fc8973f503b356c156b96c0fe46f3841 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Wed, 19 Aug 2015 07:24:57 +0000 Subject: [PATCH 09/16] Removed semi-colon (#333) --- 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 8b124a88e..49c4f5959 100644 --- a/lib/ProxySQL_Admin.cpp +++ b/lib/ProxySQL_Admin.cpp @@ -1213,7 +1213,7 @@ void admin_session_handler(MySQL_Session *sess, ProxySQL_Admin *pa, PtrSize_t *p if (query_no_space_length==strlen("SHOW PROCESSLIST") && !strncasecmp("SHOW PROCESSLIST",query_no_space, query_no_space_length)) { l_free(query_length,query); - query=l_strdup("SELECT SessionID, user, db, hostgroup, command, time_ms, SUBSTR(info,0,100) info FROM stats_mysql_processlist;"); + query=l_strdup("SELECT SessionID, user, db, hostgroup, command, time_ms, SUBSTR(info,0,100) info FROM stats_mysql_processlist"); query_length=strlen(query)+1; goto __run_query; } From cdffa376ca7a5ddf102b8934d02db9fb2d0587ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Wed, 19 Aug 2015 07:54:25 +0000 Subject: [PATCH 10/16] Added ConnOK and ConnERR in stats_mysql_connection_pool , per issue #338 --- include/MySQL_HostGroups_Manager.h | 2 ++ lib/MySQL_HostGroups_Manager.cpp | 10 +++++++++- lib/ProxySQL_Admin.cpp | 8 ++++---- lib/mysql_connection.cpp | 3 +++ 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/include/MySQL_HostGroups_Manager.h b/include/MySQL_HostGroups_Manager.h index 3dea64619..7bb25395a 100644 --- a/include/MySQL_HostGroups_Manager.h +++ b/include/MySQL_HostGroups_Manager.h @@ -45,6 +45,8 @@ class MySrvC { // MySQL Server Container enum MySerStatus status; unsigned int compression; unsigned int max_connections; + unsigned int connect_OK; + unsigned int connect_ERR; //uint8_t charset; MySrvConnList *ConnectionsUsed; MySrvConnList *ConnectionsFree; diff --git a/lib/MySQL_HostGroups_Manager.cpp b/lib/MySQL_HostGroups_Manager.cpp index 2ac69d2aa..a579f423f 100644 --- a/lib/MySQL_HostGroups_Manager.cpp +++ b/lib/MySQL_HostGroups_Manager.cpp @@ -109,6 +109,8 @@ MySrvC::MySrvC(char *add, uint16_t p, unsigned int _weight, enum MySerStatus _st status=_status; compression=_compression; max_connections=_max_connections; + connect_OK=0; + connect_ERR=0; //charset=_charset; myhgc=NULL; ConnectionsUsed=new MySrvConnList(this); @@ -602,7 +604,7 @@ __exit_get_multiple_idle_connections: } SQLite3_result * MySQL_HostGroups_Manager::SQL3_Connection_Pool() { - const int colnum=6; + const int colnum=8; proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 4, "Dumping Connection Pool\n"); SQLite3_result *result=new SQLite3_result(colnum); result->add_column_definition(SQLITE_TEXT,"hostgroup"); @@ -611,6 +613,8 @@ SQLite3_result * MySQL_HostGroups_Manager::SQL3_Connection_Pool() { result->add_column_definition(SQLITE_TEXT,"status"); result->add_column_definition(SQLITE_TEXT,"ConnUsed"); result->add_column_definition(SQLITE_TEXT,"ConnFree"); + result->add_column_definition(SQLITE_TEXT,"ConnOK"); + result->add_column_definition(SQLITE_TEXT,"ConnERR"); wrlock(); int i,j, k; @@ -655,6 +659,10 @@ SQLite3_result * MySQL_HostGroups_Manager::SQL3_Connection_Pool() { pta[4]=strdup(buf); sprintf(buf,"%u", mysrvc->ConnectionsFree->conns->len); pta[5]=strdup(buf); + sprintf(buf,"%u", mysrvc->connect_OK); + pta[6]=strdup(buf); + sprintf(buf,"%u", mysrvc->connect_ERR); + pta[7]=strdup(buf); result->add_row(pta); for (k=0; kexecute("BEGIN"); statsdb->execute("DELETE FROM stats_mysql_connection_pool"); - char *a=(char *)"INSERT INTO stats_mysql_connection_pool VALUES (\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\")"; + char *a=(char *)"INSERT INTO stats_mysql_connection_pool VALUES (\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\")"; for (std::vector::iterator it = resultset->rows.begin() ; it != resultset->rows.end(); ++it) { SQLite3_row *r=*it; int arg_len=0; - for (int i=0; i<6; i++) { + for (int i=0; i<8; i++) { arg_len+=strlen(r->fields[i]); } char *query=(char *)malloc(strlen(a)+arg_len+32); - sprintf(query,a,r->fields[0],r->fields[1],r->fields[2],r->fields[3],r->fields[4],r->fields[5]); + sprintf(query,a,r->fields[0],r->fields[1],r->fields[2],r->fields[3],r->fields[4],r->fields[5],r->fields[6],r->fields[7]); statsdb->execute(query); free(query); } diff --git a/lib/mysql_connection.cpp b/lib/mysql_connection.cpp index e4c109a57..698949aca 100644 --- a/lib/mysql_connection.cpp +++ b/lib/mysql_connection.cpp @@ -386,11 +386,14 @@ handler_again: } break; case ASYNC_CONNECT_SUCCESSFUL: + __sync_fetch_and_add(&parent->connect_OK,1); break; case ASYNC_CONNECT_FAILED: + __sync_fetch_and_add(&parent->connect_ERR,1); break; case ASYNC_CONNECT_TIMEOUT: 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); + __sync_fetch_and_add(&parent->connect_ERR,1); break; case ASYNC_CHANGE_USER_START: change_user_start(); From 6d496d46ee7eca8f7b6dbe3a733363d9e80f85ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Wed, 19 Aug 2015 11:26:02 +0000 Subject: [PATCH 11/16] Implementation of Automatic shun failing backends (issue #339) --- include/MySQL_HostGroups_Manager.h | 5 ++++ include/MySQL_Thread.h | 2 ++ include/proxysql_structs.h | 4 +++ lib/MySQL_HostGroups_Manager.cpp | 47 +++++++++++++++++++++++++++++- lib/MySQL_Thread.cpp | 34 +++++++++++++++++++++ lib/ProxySQL_Admin.cpp | 8 ++--- lib/mysql_connection.cpp | 5 ++-- 7 files changed, 98 insertions(+), 7 deletions(-) diff --git a/include/MySQL_HostGroups_Manager.h b/include/MySQL_HostGroups_Manager.h index 7bb25395a..4f38e724d 100644 --- a/include/MySQL_HostGroups_Manager.h +++ b/include/MySQL_HostGroups_Manager.h @@ -47,11 +47,16 @@ class MySrvC { // MySQL Server Container unsigned int max_connections; unsigned int connect_OK; unsigned int connect_ERR; + time_t time_last_detected_error; + unsigned int connect_ERR_at_time_last_detected_error; + unsigned long long queries_sent; + bool shunned_automatic; //uint8_t charset; MySrvConnList *ConnectionsUsed; MySrvConnList *ConnectionsFree; MySrvC(char *, uint16_t, unsigned int, enum MySerStatus, unsigned int, unsigned int _max_connections); ~MySrvC(); + void connect_error(); }; class MySrvList { // MySQL Server List diff --git a/include/MySQL_Thread.h b/include/MySQL_Thread.h index 4f261a461..93dc0217f 100644 --- a/include/MySQL_Thread.h +++ b/include/MySQL_Thread.h @@ -254,6 +254,8 @@ class MySQL_Threads_Handler bool monitor_timer_cached; int ping_interval_server; int ping_timeout_server; + int shun_on_failures; + int shun_recovery_time; int connect_retries_on_failure; int connect_retries_delay; int connect_timeout_server; diff --git a/include/proxysql_structs.h b/include/proxysql_structs.h index 77fc200b4..f660874d0 100644 --- a/include/proxysql_structs.h +++ b/include/proxysql_structs.h @@ -676,6 +676,8 @@ __thread int mysql_thread___long_query_time; __thread int mysql_thread___free_connections_pct; __thread int mysql_thread___ping_interval_server; __thread int mysql_thread___ping_timeout_server; +__thread int mysql_thread___shun_on_failures; +__thread int mysql_thread___shun_recovery_time; __thread int mysql_thread___connect_retries_on_failure; __thread int mysql_thread___connect_retries_delay; __thread int mysql_thread___connect_timeout_server; @@ -726,6 +728,8 @@ extern __thread int mysql_thread___long_query_time; extern __thread int mysql_thread___free_connections_pct; extern __thread int mysql_thread___ping_interval_server; extern __thread int mysql_thread___ping_timeout_server; +extern __thread int mysql_thread___shun_on_failures; +extern __thread int mysql_thread___shun_recovery_time; extern __thread int mysql_thread___connect_retries_on_failure; extern __thread int mysql_thread___connect_retries_delay; extern __thread int mysql_thread___connect_timeout_server; diff --git a/lib/MySQL_HostGroups_Manager.cpp b/lib/MySQL_HostGroups_Manager.cpp index a579f423f..70960f4a7 100644 --- a/lib/MySQL_HostGroups_Manager.cpp +++ b/lib/MySQL_HostGroups_Manager.cpp @@ -111,12 +111,34 @@ MySrvC::MySrvC(char *add, uint16_t p, unsigned int _weight, enum MySerStatus _st max_connections=_max_connections; connect_OK=0; connect_ERR=0; + queries_sent=0; + time_last_detected_error=0; + connect_ERR_at_time_last_detected_error=0; + shunned_automatic=false; //charset=_charset; myhgc=NULL; ConnectionsUsed=new MySrvConnList(this); ConnectionsFree=new MySrvConnList(this); } +void MySrvC::connect_error() { + // NOTE: this function operates without any mutex + // although, it is not extremely important if any counter is lost + // as a single connection failure won't make a significant difference + __sync_fetch_and_add(&connect_ERR,1); + time_t t=time(NULL); + if (t!=time_last_detected_error) { + time_last_detected_error=t; + connect_ERR_at_time_last_detected_error=1; + } else { + 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) { + status=MYSQL_SERVER_STATUS_SHUNNED; + shunned_automatic=true; + } + } +} + MySrvC::~MySrvC() { if (address) free(address); delete ConnectionsUsed; @@ -298,6 +320,9 @@ bool MySQL_HostGroups_Manager::commit() { if (atoi(r->fields[4])!=atoi(r->fields[9])) { proxy_debug(PROXY_DEBUG_MYSQL_CONNPOOL, 5, "Changing status for server %s:%d (%s:%d) from %d (%d) to %d\n" , mysrvc->address, mysrvc->port, r->fields[1], atoi(r->fields[2]), r->fields[4] , mysrvc->status , atoi(r->fields[9])); mysrvc->status=(MySerStatus)atoi(r->fields[9]); + if (mysrvc->status==MYSQL_SERVER_STATUS_SHUNNED) { + mysrvc->shunned_automatic=false; + } } if (atoi(r->fields[5])!=atoi(r->fields[10])) { proxy_debug(PROXY_DEBUG_MYSQL_CONNPOOL, 5, "Changing compression for server %s:%d (%s:%d) from %d (%d) to %d\n" , mysrvc->address, mysrvc->port, r->fields[1], atoi(r->fields[2]), r->fields[4] , mysrvc->compression , atoi(r->fields[10])); @@ -453,6 +478,23 @@ MySrvC *MyHGC::get_random_MySrvC() { if (mysrvc->ConnectionsUsed->conns->len < mysrvc->max_connections) { // consider this server only if didn't reach max_connections sum+=mysrvc->weight; } + } else { + if (mysrvc->status==MYSQL_SERVER_STATUS_SHUNNED) { + // try to recover shunned servers + if (mysrvc->shunned_automatic && mysql_thread___shun_recovery_time) { + time_t t; + t=time(NULL); + // we do all these changes without locking . We assume the server is not used from long + // even if the server is still in used and any of the follow command fails it is not critical + // because this is only an attempt to recover a server that is probably dead anyway + if ((t - mysrvc->time_last_detected_error) > mysql_thread___shun_recovery_time) { + mysrvc->status=MYSQL_SERVER_STATUS_ONLINE; + mysrvc->shunned_automatic=false; + mysrvc->connect_ERR_at_time_last_detected_error=0; + mysrvc->time_last_detected_error=0; + } + } + } } } if (sum==0) { @@ -604,7 +646,7 @@ __exit_get_multiple_idle_connections: } SQLite3_result * MySQL_HostGroups_Manager::SQL3_Connection_Pool() { - const int colnum=8; + const int colnum=9; proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 4, "Dumping Connection Pool\n"); SQLite3_result *result=new SQLite3_result(colnum); result->add_column_definition(SQLITE_TEXT,"hostgroup"); @@ -615,6 +657,7 @@ SQLite3_result * MySQL_HostGroups_Manager::SQL3_Connection_Pool() { result->add_column_definition(SQLITE_TEXT,"ConnFree"); result->add_column_definition(SQLITE_TEXT,"ConnOK"); result->add_column_definition(SQLITE_TEXT,"ConnERR"); + result->add_column_definition(SQLITE_TEXT,"Queries"); wrlock(); int i,j, k; @@ -663,6 +706,8 @@ SQLite3_result * MySQL_HostGroups_Manager::SQL3_Connection_Pool() { pta[6]=strdup(buf); sprintf(buf,"%u", mysrvc->connect_ERR); pta[7]=strdup(buf); + sprintf(buf,"%llu", mysrvc->queries_sent); + pta[8]=strdup(buf); result->add_row(pta); for (k=0; kcsname); } + if (!strcasecmp(name,"shun_on_failures")) { + sprintf(intbuf,"%d",variables.shun_on_failures); + return strdup(intbuf); + } + if (!strcasecmp(name,"shun_recovery_time")) { + sprintf(intbuf,"%d",variables.shun_recovery_time); + return strdup(intbuf); + } if (!strcasecmp(name,"connect_retries_on_failure")) { sprintf(intbuf,"%d",variables.connect_retries_on_failure); return strdup(intbuf); @@ -738,6 +752,24 @@ bool MySQL_Threads_Handler::set_variable(char *name, char *value) { // this is t return false; } } + if (!strcasecmp(name,"shun_on_failures")) { + int intv=atoi(value); + if (intv >= 0 && intv <= 10000000) { + variables.shun_on_failures=intv; + return true; + } else { + return false; + } + } + if (!strcasecmp(name,"shun_recovery_time")) { + int intv=atoi(value); + if (intv >= 0 && intv <= 3600*24*365) { + variables.shun_recovery_time=intv; + return true; + } else { + return false; + } + } if (!strcasecmp(name,"connect_retries_on_failure")) { int intv=atoi(value); if (intv >= 0 && intv <= 1000) { @@ -1543,6 +1575,8 @@ void MySQL_Thread::refresh_variables() { mysql_thread___long_query_time=GloMTH->get_variable_int((char *)"long_query_time"); mysql_thread___ping_interval_server=GloMTH->get_variable_int((char *)"ping_interval_server"); mysql_thread___ping_timeout_server=GloMTH->get_variable_int((char *)"ping_timeout_server"); + mysql_thread___shun_on_failures=GloMTH->get_variable_int((char *)"shun_on_failures"); + mysql_thread___shun_recovery_time=GloMTH->get_variable_int((char *)"shun_recovery_time"); mysql_thread___connect_retries_on_failure=GloMTH->get_variable_int((char *)"connect_retries_on_failure"); mysql_thread___connect_timeout_server=GloMTH->get_variable_int((char *)"connect_timeout_server"); mysql_thread___connect_timeout_server_max=GloMTH->get_variable_int((char *)"connect_timeout_server_max"); diff --git a/lib/ProxySQL_Admin.cpp b/lib/ProxySQL_Admin.cpp index 8113fa88e..4e9d32834 100644 --- a/lib/ProxySQL_Admin.cpp +++ b/lib/ProxySQL_Admin.cpp @@ -62,7 +62,7 @@ pthread_mutex_t admin_mutex = PTHREAD_MUTEX_INITIALIZER; #define STATS_SQLITE_TABLE_MYSQL_QUERY_RULES "CREATE TABLE stats_mysql_query_rules (rule_id INTEGER PRIMARY KEY , hits INT NOT NULL)" #define STATS_SQLITE_TABLE_MYSQL_COMMANDS_COUNTERS "CREATE TABLE stats_mysql_commands_counters (Command VARCHAR NOT NULL PRIMARY KEY , Total_Time_us INT NOT NULL , Total_cnt INT NOT NULL , cnt_100us INT NOT NULL , cnt_500us INT NOT NULL , cnt_1ms INT NOT NULL , cnt_5ms INT NOT NULL , cnt_10ms INT NOT NULL , cnt_50ms INT NOT NULL , cnt_100ms INT NOT NULL , cnt_500ms INT NOT NULL , cnt_1s INT NOT NULL , cnt_5s INT NOT NULL , cnt_10s INT NOT NULL , cnt_INFs)" #define STATS_SQLITE_TABLE_MYSQL_PROCESSLIST "CREATE TABLE stats_mysql_processlist (ThreadID INT NOT NULL , SessionID INTEGER PRIMARY KEY , user VARCHAR , db VARCHAR , cli_host VARCHAR , cli_port VARCHAR , hostgroup VARCHAR , l_srv_host VARCHAR , l_srv_port VARCHAR , srv_host VARCHAR , srv_port VARCHAR , command VARCHAR , time_ms INT NOT NULL , info VARCHAR)" -#define STATS_SQLITE_TABLE_MYSQL_CONNECTION_POOL "CREATE TABLE stats_mysql_connection_pool (hostgroup VARCHAR , srv_host VARCHAR , srv_port VARCHAR , status VARCHAR , ConnUsed INT , ConnFree INT, ConnOK INT, ConnERR INT)" +#define STATS_SQLITE_TABLE_MYSQL_CONNECTION_POOL "CREATE TABLE stats_mysql_connection_pool (hostgroup VARCHAR , srv_host VARCHAR , srv_port VARCHAR , status VARCHAR , ConnUsed INT , ConnFree INT , ConnOK INT , ConnERR INT , Queries INT)" #define STATS_SQLITE_TABLE_MYSQL_QUERY_DIGEST "CREATE TABLE stats_mysql_query_digest (schemaname VARCHAR NOT NULL , username VARCHAR NOT NULL , digest VARCHAR NOT NULL , digest_text VARCHAR NOT NULL , count_star INTEGER NOT NULL , first_seen INTEGER NOT NULL , last_seen INTEGER NOT NULL , sum_time INTEGER NOT NULL , min_time INTEGER NOT NULL , max_time INTEGER NOT NULL , PRIMARY KEY(schemaname, username, digest))" @@ -2219,15 +2219,15 @@ void ProxySQL_Admin::stats___mysql_connection_pool() { if (resultset==NULL) return; statsdb->execute("BEGIN"); statsdb->execute("DELETE FROM stats_mysql_connection_pool"); - char *a=(char *)"INSERT INTO stats_mysql_connection_pool VALUES (\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\")"; + char *a=(char *)"INSERT INTO stats_mysql_connection_pool VALUES (\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\")"; for (std::vector::iterator it = resultset->rows.begin() ; it != resultset->rows.end(); ++it) { SQLite3_row *r=*it; int arg_len=0; - for (int i=0; i<8; i++) { + for (int i=0; i<9; i++) { arg_len+=strlen(r->fields[i]); } char *query=(char *)malloc(strlen(a)+arg_len+32); - sprintf(query,a,r->fields[0],r->fields[1],r->fields[2],r->fields[3],r->fields[4],r->fields[5],r->fields[6],r->fields[7]); + sprintf(query,a,r->fields[0],r->fields[1],r->fields[2],r->fields[3],r->fields[4],r->fields[5],r->fields[6],r->fields[7],r->fields[8]); statsdb->execute(query); free(query); } diff --git a/lib/mysql_connection.cpp b/lib/mysql_connection.cpp index 698949aca..9def84171 100644 --- a/lib/mysql_connection.cpp +++ b/lib/mysql_connection.cpp @@ -389,11 +389,11 @@ handler_again: __sync_fetch_and_add(&parent->connect_OK,1); break; case ASYNC_CONNECT_FAILED: - __sync_fetch_and_add(&parent->connect_ERR,1); + parent->connect_error(); break; case ASYNC_CONNECT_TIMEOUT: 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); - __sync_fetch_and_add(&parent->connect_ERR,1); + parent->connect_error(); break; case ASYNC_CHANGE_USER_START: change_user_start(); @@ -454,6 +454,7 @@ handler_again: break; case ASYNC_QUERY_START: real_query_start(); + __sync_fetch_and_add(&parent->queries_sent,1); if (async_exit_status) { next_event(ASYNC_QUERY_CONT); } else { From 8c78dec1c2e89fa13d605b8d544b975158a5e738 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Wed, 19 Aug 2015 11:30:16 +0000 Subject: [PATCH 12/16] Removed reference to issue #211 and minor cleanup --- include/MySQL_Data_Stream.h | 12 ++++++------ lib/MySQL_Session.cpp | 24 ------------------------ 2 files changed, 6 insertions(+), 30 deletions(-) diff --git a/include/MySQL_Data_Stream.h b/include/MySQL_Data_Stream.h index 704a83bbc..b9d4d318f 100644 --- a/include/MySQL_Data_Stream.h +++ b/include/MySQL_Data_Stream.h @@ -168,12 +168,12 @@ class MySQL_Data_Stream } void free_mysql_real_query(); - void destroy_MySQL_Connection() { - MySQL_Connection *mc=myconn; - detach_connection(); - unplug_backend(); - delete mc; - } +// void destroy_MySQL_Connection() { +// MySQL_Connection *mc=myconn; +// detach_connection(); +// unplug_backend(); +// delete mc; +// } }; #endif /* __CLASS_MYSQL_DATA_STREAM_H */ diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 26feeb827..e9566566d 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -1418,30 +1418,6 @@ __exit_DSS__STATE_NOT_INITIALIZED: writeout(); - // FIXME: see bug #211 - if ( - mybe - && - mybe->server_myds - && - mybe->server_myds->DSS==STATE_QUERY_SENT_DS - && - mybe->server_myds->PSarrayOUT->len==0 - && - mybe->server_myds->PSarrayOUTpending->len==0 - && - mybe->server_myds->net_failure==false - && - mybe->server_myds->available_data_out()==false - ) { - if (connections_handler) { - //fprintf(stderr,"time=%llu\n",monotonic_time()); - //mybe->server_myds->timeout=thread->curtime+100; - //mybe->server_myds->DSS=STATE_PING_SENT_NET; - } else { - mybe->server_myds->setDSS_STATE_QUERY_SENT_NET(); - } - } if (mybe && mybe->server_myds) { if (mybe->server_myds->net_failure) { proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Sess:%p , MYDS:%p , myds_type=%d, DSS=%d , myconn:%p\n" , this, mybe->server_myds , mybe->server_myds->myds_type , mybe->server_myds->DSS, mybe->server_myds->myconn); From 618dc8bb4d90d90e2bbb836ff576242ce08ebaf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Wed, 19 Aug 2015 11:50:57 +0000 Subject: [PATCH 13/16] Removing code that is now incompatible with current backend implementation and could lead to inconsistent state of backend --- lib/MySQL_Session.cpp | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index e9566566d..ffa234977 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -1418,36 +1418,6 @@ __exit_DSS__STATE_NOT_INITIALIZED: writeout(); - if (mybe && mybe->server_myds) { - if (mybe->server_myds->net_failure) { - proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Sess:%p , MYDS:%p , myds_type=%d, DSS=%d , myconn:%p\n" , this, mybe->server_myds , mybe->server_myds->myds_type , mybe->server_myds->DSS, mybe->server_myds->myconn); - if (( mybe->server_myds->DSS==STATE_READY || mybe->server_myds->DSS==STATE_QUERY_SENT_DS ) && mybe->server_myds->myds_type==MYDS_BACKEND) { - //mybe->server_myds->myconn=NULL; - mybe->server_myds->detach_connection(); - mybe->server_myds->DSS=STATE_NOT_INITIALIZED; - mybe->server_myds->move_from_OUT_to_OUTpending(); - if (mybe->server_myds->myconn) { - MyHGM->destroy_MyConn_from_pool(mybe->server_myds->myconn); - //mybe->server_myds->myconn=NULL; - mybe->server_myds->detach_connection(); - } - if (mybe->server_myds->fd) { - mybe->server_myds->shut_hard(); -// shutdown(mybe->server_myds->fd,SHUT_RDWR); -// close(mybe->server_myds->fd); - mybe->server_myds->fd=0; - thread->mypolls.remove_index_fast(mybe->server_myds->poll_fds_idx); - //server_fd=0; - } - mybe->server_myds->clean_net_failure(); - mybe->server_myds->active=1; - goto __get_a_backend; - } else { - set_unhealthy(); - } - } - } - //writeout(); /* From 315e2f2f66a53622cfeb611865d2145f793fd873 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Wed, 19 Aug 2015 11:55:56 +0000 Subject: [PATCH 14/16] Bugfix: as precaution, MySQL_HostGroups_Manager::push_MyConn_to_pool() checks that the connection is idle (ASYNC_IDLE) before pushing it back in the connection pool. If not, the connection is deleted. --- lib/MySQL_HostGroups_Manager.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/MySQL_HostGroups_Manager.cpp b/lib/MySQL_HostGroups_Manager.cpp index 70960f4a7..adb1a130a 100644 --- a/lib/MySQL_HostGroups_Manager.cpp +++ b/lib/MySQL_HostGroups_Manager.cpp @@ -455,7 +455,12 @@ void MySQL_HostGroups_Manager::push_MyConn_to_pool(MySQL_Connection *c) { proxy_debug(PROXY_DEBUG_MYSQL_CONNPOOL, 7, "Returning MySQL_Connection %p, server %s:%d with status %d\n", c, mysrvc->address, mysrvc->port, mysrvc->status); mysrvc->ConnectionsUsed->remove(c); if (mysrvc->status==MYSQL_SERVER_STATUS_ONLINE) { - mysrvc->ConnectionsFree->add(c); + if (c->async_state_machine==ASYNC_IDLE) { + mysrvc->ConnectionsFree->add(c); + } else { + proxy_debug(PROXY_DEBUG_MYSQL_CONNPOOL, 7, "Destroying MySQL_Connection %p, server %s:%d with status %d\n", c, mysrvc->address, mysrvc->port, mysrvc->status); + delete c; + } } else { proxy_debug(PROXY_DEBUG_MYSQL_CONNPOOL, 7, "Destroying MySQL_Connection %p, server %s:%d with status %d\n", c, mysrvc->address, mysrvc->port, mysrvc->status); delete c; From 4763faa91501124be93f199df8e9b4a277957ae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Wed, 19 Aug 2015 12:00:43 +0000 Subject: [PATCH 15/16] Code cleanup --- lib/MySQL_Session.cpp | 129 +----------------------------------------- 1 file changed, 1 insertion(+), 128 deletions(-) diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index ffa234977..e4a195a38 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -1266,80 +1266,10 @@ __exit_DSS__STATE_NOT_INITIALIZED: case PROCESSING_QUERY: break; case PINGING_SERVER: -/* - if (myds->revents) { - myconn->handler(myds->revents); - if (myconn->async_state_machine==ASYNC_PING_SUCCESSFUL) { - myds->DSS=STATE_READY; - /// multi-plexing attempt - if ((myds->myconn->reusable==true) && ((myds->myprot.prot_status & SERVER_STATUS_IN_TRANS)==0)) { - myds->myconn->last_time_used=thread->curtime; - myds->myconn->async_state_machine=ASYNC_IDLE; - MyHGM->push_MyConn_to_pool(myds->myconn); - //MyHGM->destroy_MyConn_from_pool(mybe->server_myds->myconn); - //mybe->server_myds->myconn=NULL; - myds->detach_connection(); - myds->unplug_backend(); - } - // multi-plexing attempt - status=NONE; - } - } -*/ break; case CHANGING_SCHEMA: -/* - if (myds->revents) { - myconn->handler(myds->revents); - if (myconn->async_state_machine==ASYNC_INITDB_SUCCESSFUL) { - myds->DSS=STATE_READY; - status=WAITING_CLIENT_DATA; - unsigned int k; - PtrSize_t pkt2; - for (k=0; kserver_myds->PSarrayOUTpending->len;) { - myds->PSarrayOUTpending->remove_index(0,&pkt2); - myds->PSarrayOUT->add(pkt2.ptr, pkt2.size); - myds->DSS=STATE_QUERY_SENT_DS; - } - } - if (myconn->async_state_machine==ASYNC_INITDB_FAILED) { - set_unhealthy(); - myds->myconn->reusable=false; - return -1; - } - } -*/ break; case CHANGING_CHARSET: -/* - if (myds->revents) { - myconn->handler(myds->revents); - if (myconn->async_state_machine==ASYNC_SET_NAMES_SUCCESSFUL) { -#ifdef EXPMARIA - myds->DSS=STATE_MARIADB_QUERY; - status=PROCESSING_QUERY; - myds->myconn->async_state_machine=ASYNC_QUERY_START; - myds->myconn->set_query(myds->mysql_real_query.ptr,myds->mysql_real_query.size); - myds->myconn->handler(0); -#else - myds->DSS=STATE_READY; - status=WAITING_CLIENT_DATA; -#endif // EXPMARIA - unsigned int k; - PtrSize_t pkt2; - for (k=0; kserver_myds->PSarrayOUTpending->len;) { - myds->PSarrayOUTpending->remove_index(0,&pkt2); - myds->PSarrayOUT->add(pkt2.ptr, pkt2.size); - myds->DSS=STATE_QUERY_SENT_DS; - } - } - if (myconn->async_state_machine==ASYNC_SET_NAMES_FAILED) { - set_unhealthy(); - myds->myconn->reusable=false; - return -1; - } - } -*/ break; default: assert(0); @@ -1353,55 +1283,11 @@ __exit_DSS__STATE_NOT_INITIALIZED: /* ATTEMPT TO COMMENT THIS BLOCK + leaving ONLY FAST_FORWARD for now for (j=0; jserver_myds->PSarrayIN->len;) { mybe->server_myds->PSarrayIN->remove_index(0,&pkt); switch (status) { - case WAITING_SERVER_DATA: - switch (mybe->server_myds->DSS) { -// case STATE_PING_SENT_NET: -// handler___status_WAITING_SERVER_DATA___STATE_PING_SENT(&pkt); -// break; - - case STATE_QUERY_SENT_NET: - handler___status_WAITING_SERVER_DATA___STATE_QUERY_SENT(&pkt); - break; - - case STATE_ROW: - handler___status_WAITING_SERVER_DATA___STATE_ROW(&pkt); - break; - - case STATE_EOF1: - handler___status_WAITING_SERVER_DATA___STATE_EOF1(&pkt); - break; - - case STATE_READING_COM_STMT_PREPARE_RESPONSE: - handler___status_WAITING_SERVER_DATA___STATE_READING_COM_STMT_PREPARE_RESPONSE(&pkt); - break; - - default: - assert(0); - } - break; - -// case CHANGING_SCHEMA: -// if (handler___status_CHANGING_SCHEMA(&pkt)==false) { -// return -1; -// } -// break; - - case CHANGING_USER_SERVER: - if (handler___status_CHANGING_USER_SERVER(&pkt)==false) { - return -1; - } - break; - -// case CHANGING_CHARSET: -// if (handler___status_CHANGING_CHARSET(&pkt)==false) { -// return -1; -// } -// break; - case FAST_FORWARD: client_myds->PSarrayOUT->add(pkt.ptr, pkt.size); break; @@ -1418,19 +1304,6 @@ __exit_DSS__STATE_NOT_INITIALIZED: writeout(); - //writeout(); - -/* - if ( // FIXME: this implementation is horrible - (server_myds ? server_myds->PSarrayIN->len==0 : 1 ) && - (server_myds ? server_myds->PSarrayOUT->len==0 : 1 ) && - (client_myds ? client_myds->PSarrayIN->len==0 : 1 ) && - (client_myds ? client_myds->PSarrayOUT->len==0 : 1 ) - ) - { - to_process=0; - } -*/ if (wrong_pass==true) { client_myds->array2buffer_full(); client_myds->write_to_net(); From 908e043eb9a74498a36d6c53ec112e55b69ffd75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Wed, 19 Aug 2015 12:25:35 +0000 Subject: [PATCH 16/16] Code cleanup : commented and not deleted for now. Removed: - handler___status_WAITING_SERVER_DATA___STATE_QUERY_SENT() - handler___status_WAITING_SERVER_DATA___STATE_ROW() - handler___status_WAITING_SERVER_DATA___STATE_EOF1() --- include/MySQL_Session.h | 6 +++--- lib/MySQL_Session.cpp | 17 ++++++++++------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/include/MySQL_Session.h b/include/MySQL_Session.h index 56d5b3830..9146ebb19 100644 --- a/include/MySQL_Session.h +++ b/include/MySQL_Session.h @@ -42,10 +42,10 @@ class MySQL_Session // bool handler___status_CHANGING_SCHEMA(PtrSize_t *); bool handler___status_CHANGING_USER_SERVER(PtrSize_t *); // bool handler___status_CHANGING_CHARSET(PtrSize_t *); - void handler___status_WAITING_SERVER_DATA___STATE_QUERY_SENT(PtrSize_t *); +// void handler___status_WAITING_SERVER_DATA___STATE_QUERY_SENT(PtrSize_t *); // void handler___status_WAITING_SERVER_DATA___STATE_PING_SENT(PtrSize_t *); - void handler___status_WAITING_SERVER_DATA___STATE_ROW(PtrSize_t *); - void handler___status_WAITING_SERVER_DATA___STATE_EOF1(PtrSize_t *); +// void handler___status_WAITING_SERVER_DATA___STATE_ROW(PtrSize_t *); +// void handler___status_WAITING_SERVER_DATA___STATE_EOF1(PtrSize_t *); //void handler___status_CONNECTING_SERVER___STATE_NOT_CONNECTED(PtrSize_t *); //void handler___status_CONNECTING_SERVER___STATE_CLIENT_HANDSHAKE(PtrSize_t *, bool *); void handler___status_CONNECTING_CLIENT___STATE_SERVER_HANDSHAKE(PtrSize_t *, bool *); diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index e4a195a38..41622a3d2 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -1342,6 +1342,7 @@ bool MySQL_Session::handler___status_CHANGING_USER_SERVER(PtrSize_t *pkt) { return false; } +/* void MySQL_Session::handler___status_WAITING_SERVER_DATA___STATE_QUERY_SENT(PtrSize_t *pkt) { proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Statuses: WAITING_SERVER_DATA - STATE_QUERY_SENT\n"); unsigned char c; @@ -1349,7 +1350,7 @@ void MySQL_Session::handler___status_WAITING_SERVER_DATA___STATE_QUERY_SENT(PtrS if (mybe->server_myds->myconn->processing_prepared_statement_prepare==false && mybe->server_myds->myconn->processing_prepared_statement_execute==false) { if (c==0 || c==0xff) { mybe->server_myds->DSS=STATE_READY; - /* multi-plexing attempt */ + // multi-plexing attempt if (c==0) { mybe->server_myds->myprot.process_pkt_OK((unsigned char *)pkt->ptr,pkt->size); if ((mybe->server_myds->myconn->reusable==true) && ((mybe->server_myds->myprot.prot_status & SERVER_STATUS_IN_TRANS)==0)) { @@ -1361,7 +1362,7 @@ void MySQL_Session::handler___status_WAITING_SERVER_DATA___STATE_QUERY_SENT(PtrS // mybe->server_myds->unplug_backend(); } } - /* multi-plexing attempt */ + // multi-plexing attempt status=WAITING_CLIENT_DATA; client_myds->DSS=STATE_SLEEP; client_myds->PSarrayOUT->add(pkt->ptr, pkt->size); @@ -1435,6 +1436,7 @@ void MySQL_Session::handler___status_WAITING_SERVER_DATA___STATE_QUERY_SENT(PtrS } } } +*/ void MySQL_Session::handler___status_WAITING_SERVER_DATA___STATE_READING_COM_STMT_PREPARE_RESPONSE(PtrSize_t *pkt) { unsigned char c; @@ -1463,6 +1465,7 @@ void MySQL_Session::handler___status_WAITING_SERVER_DATA___STATE_READING_COM_STM client_myds->PSarrayOUT->add(pkt->ptr, pkt->size); } +/* void MySQL_Session::handler___status_WAITING_SERVER_DATA___STATE_ROW(PtrSize_t *pkt) { unsigned char c; c=*((unsigned char *)pkt->ptr+sizeof(mysql_hdr)); @@ -1476,8 +1479,8 @@ void MySQL_Session::handler___status_WAITING_SERVER_DATA___STATE_ROW(PtrSize_t * client_myds->PSarrayOUT->add(pkt->ptr, pkt->size); } } - - +*/ +/* void MySQL_Session::handler___status_WAITING_SERVER_DATA___STATE_EOF1(PtrSize_t *pkt) { unsigned char c; c=*((unsigned char *)pkt->ptr+sizeof(mysql_hdr)); @@ -1495,7 +1498,7 @@ void MySQL_Session::handler___status_WAITING_SERVER_DATA___STATE_EOF1(PtrSize_t client_myds->DSS=STATE_SLEEP; - /* multi-plexing attempt */ + // multi-plexing attempt if (c==0xfe) { mybe->server_myds->myprot.process_pkt_EOF((unsigned char *)pkt->ptr,pkt->size); //fprintf(stderr,"hid=%d status=%d\n", mybe->hostgroup_id, server_myds->myprot.prot_status); @@ -1508,7 +1511,7 @@ void MySQL_Session::handler___status_WAITING_SERVER_DATA___STATE_EOF1(PtrSize_t // mybe->server_myds->unplug_backend(); } } - /* multi-plexing attempt */ + // multi-plexing attempt if (qpo) { if (qpo->cache_ttl>0) { // Fixed bug #145 @@ -1565,7 +1568,7 @@ void MySQL_Session::handler___status_WAITING_SERVER_DATA___STATE_EOF1(PtrSize_t } } } - +*/ void MySQL_Session::handler___status_CHANGING_USER_CLIENT___STATE_CLIENT_HANDSHAKE(PtrSize_t *pkt, bool *wrong_pass) { // FIXME: no support for SSL yet