diff --git a/include/MySQL_Thread.h b/include/MySQL_Thread.h index 0699393ab..9a5ece971 100644 --- a/include/MySQL_Thread.h +++ b/include/MySQL_Thread.h @@ -404,6 +404,7 @@ class MySQL_Threads_Handler int connect_retries_delay; int connection_delay_multiplex_ms; int connection_max_age_ms; + int connect_timeout_client; int connect_timeout_server; int connect_timeout_server_max; int free_connections_pct; diff --git a/include/proxysql_structs.h b/include/proxysql_structs.h index da3a6ab39..c1ec54ae8 100644 --- a/include/proxysql_structs.h +++ b/include/proxysql_structs.h @@ -721,6 +721,7 @@ __thread int mysql_thread___connect_retries_on_failure; __thread int mysql_thread___connect_retries_delay; __thread int mysql_thread___connection_delay_multiplex_ms; __thread int mysql_thread___connection_max_age_ms; +__thread int mysql_thread___connect_timeout_client; __thread int mysql_thread___connect_timeout_server; __thread int mysql_thread___connect_timeout_server_max; __thread int mysql_thread___query_processor_iterations; @@ -867,6 +868,7 @@ extern __thread int mysql_thread___connect_retries_on_failure; extern __thread int mysql_thread___connect_retries_delay; extern __thread int mysql_thread___connection_delay_multiplex_ms; extern __thread int mysql_thread___connection_max_age_ms; +extern __thread int mysql_thread___connect_timeout_client; extern __thread int mysql_thread___connect_timeout_server; extern __thread int mysql_thread___connect_timeout_server_max; extern __thread int mysql_thread___query_processor_iterations; diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index b277f8095..a538cbc0a 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -6147,13 +6147,17 @@ int MySQL_Session::FindOneActiveTransaction() { } 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; + unsigned long long ret = 0; + if (client_myds==0) return 0; + if (status!=WAITING_CLIENT_DATA && status!=CONNECTING_CLIENT) 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); + if (thread->curtime > last_time) { + ret = thread->curtime - last_time; + } + return ret; } diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp index c3eddea2f..c40bff533 100644 --- a/lib/MySQL_Thread.cpp +++ b/lib/MySQL_Thread.cpp @@ -406,6 +406,7 @@ static char * mysql_thread_variables_names[]= { (char *)"connect_retries_delay", (char *)"connection_delay_multiplex_ms", (char *)"connection_max_age_ms", + (char *)"connect_timeout_client", (char *)"connect_timeout_server", (char *)"connect_timeout_server_max", (char *)"eventslog_filename", @@ -989,6 +990,7 @@ MySQL_Threads_Handler::MySQL_Threads_Handler() { variables.connect_retries_on_failure=10; variables.connection_delay_multiplex_ms=0; variables.connection_max_age_ms=0; + variables.connect_timeout_client=10000; variables.connect_timeout_server=1000; variables.connect_timeout_server_max=10000; variables.free_connections_pct=10; @@ -1397,6 +1399,7 @@ int MySQL_Threads_Handler::get_variable_int(const char *name) { if (!strcmp(name,"commands_stats")) return (int)variables.commands_stats; if (!strcmp(name,"connect_retries_delay")) return (int)variables.connect_retries_delay; if (!strcmp(name,"connect_retries_on_failure")) return (int)variables.connect_retries_on_failure; + if (!strcmp(name,"connect_timeout_client")) return (int)variables.connect_timeout_client; if (!strcmp(name,"connect_timeout_server")) return (int)variables.connect_timeout_server; if (!strcmp(name,"connect_timeout_server_max")) return (int)variables.connect_timeout_server_max; if (!strcmp(name,"connection_delay_multiplex_ms")) return (int)variables.connection_delay_multiplex_ms; @@ -1778,6 +1781,10 @@ char * MySQL_Threads_Handler::get_variable(char *name) { // this is the public f sprintf(intbuf,"%d",variables.connection_max_age_ms); return strdup(intbuf); } + if (!strcasecmp(name,"connect_timeout_client")) { + sprintf(intbuf,"%d",variables.connect_timeout_client); + return strdup(intbuf); + } if (!strcasecmp(name,"connect_timeout_server")) { sprintf(intbuf,"%d",variables.connect_timeout_server); return strdup(intbuf); @@ -2777,6 +2784,15 @@ bool MySQL_Threads_Handler::set_variable(char *name, const char *value) { // thi return false; } } + if (!strcasecmp(name,"connect_timeout_client")) { + int intv=atoi(value); + if (intv >= 500 && intv <= 3600*1000) { + variables.connect_timeout_client=intv; + return true; + } else { + return false; + } + } if (!strcasecmp(name,"connect_timeout_server")) { int intv=atoi(value); if (intv >= 10 && intv <= 120*1000) { @@ -4631,6 +4647,13 @@ void MySQL_Thread::process_all_sessions() { continue; } } + if (sess->status == CONNECTING_CLIENT) { + unsigned long long sess_time = sess->IdleTime(); + if (sess_time/1000 > (unsigned long long)mysql_thread___connect_timeout_client) { + proxy_warning("Closing not established client connection %s:%d after %llums\n",sess->client_myds->addr.addr,sess->client_myds->addr.port, sess_time/1000); + sess->healthy = 0; + } + } if (maintenance_loop) { unsigned int numTrx=0; unsigned long long sess_time = sess->IdleTime(); @@ -4777,6 +4800,7 @@ void MySQL_Thread::refresh_variables() { mysql_thread___client_multi_statements=(bool)GloMTH->get_variable_int((char *)"client_multi_statements"); mysql_thread___connection_delay_multiplex_ms=GloMTH->get_variable_int((char *)"connection_delay_multiplex_ms"); mysql_thread___connection_max_age_ms=GloMTH->get_variable_int((char *)"connection_max_age_ms"); + mysql_thread___connect_timeout_client=GloMTH->get_variable_int((char *)"connect_timeout_client"); 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"); mysql_thread___free_connections_pct=GloMTH->get_variable_int((char *)"free_connections_pct");