diff --git a/include/MySQL_Thread.h b/include/MySQL_Thread.h index 356e4f7eb..9b4d06880 100644 --- a/include/MySQL_Thread.h +++ b/include/MySQL_Thread.h @@ -253,6 +253,7 @@ class MySQL_Threads_Handler int connect_retries_delay; int connect_timeout_server; int connect_timeout_server_max; + int free_connections_pct; bool sessions_sort; char *connect_timeout_server_error; char *default_schema; diff --git a/include/proxysql_structs.h b/include/proxysql_structs.h index 60e62d6e5..55751a20d 100644 --- a/include/proxysql_structs.h +++ b/include/proxysql_structs.h @@ -670,6 +670,7 @@ __thread int mysql_thread___max_transaction_time; __thread int mysql_thread___max_connections; __thread int mysql_thread___default_query_delay; __thread int mysql_thread___default_query_timeout; +__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___connect_retries_on_failure; @@ -716,6 +717,7 @@ extern __thread int mysql_thread___max_transaction_time; extern __thread int mysql_thread___max_connections; extern __thread int mysql_thread___default_query_delay; extern __thread int mysql_thread___default_query_timeout; +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___connect_retries_on_failure; diff --git a/lib/MySQL_HostGroups_Manager.cpp b/lib/MySQL_HostGroups_Manager.cpp index d9c3c197b..d7f6da78a 100644 --- a/lib/MySQL_HostGroups_Manager.cpp +++ b/lib/MySQL_HostGroups_Manager.cpp @@ -552,6 +552,13 @@ int MySQL_HostGroups_Manager::get_multiple_idle_connections(int _hid, unsigned l for (k=0; k<(int)pa->len; k++) { MySQL_Connection *mc=(MySQL_Connection *)pa->index(k); if (mc->last_time_used < _max_last_time_used) { + if (pa->len > mysql_thread___free_connections_pct*mysrvc->max_connections/100) { + // the idle connection are more than mysql_thread___free_connections_pct of max_connections + // we will drop this connection instead of pinging it + mc=(MySQL_Connection *)pa->remove_index_fast(k); + delete mc; + continue; + } mc=(MySQL_Connection *)pa->remove_index_fast(k); mysrvc->ConnectionsUsed->add(mc); k--; diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp index 5b362c047..7e3636efe 100644 --- a/lib/MySQL_Thread.cpp +++ b/lib/MySQL_Thread.cpp @@ -115,6 +115,7 @@ static char * mysql_thread_variables_names[]= { (char *)"connect_timeout_server_max", (char *)"connect_timeout_server_error", (char *)"default_charset", + (char *)"free_connections_pct", (char *)"have_compress", (char *)"interfaces", (char *)"monitor_history", @@ -170,6 +171,7 @@ MySQL_Threads_Handler::MySQL_Threads_Handler() { variables.connect_retries_on_failure=5; variables.connect_timeout_server=1000; variables.connect_timeout_server_max=10000; + variables.free_connections_pct=10; variables.connect_retries_delay=1; variables.monitor_history=600000; variables.monitor_connect_interval=120000; @@ -327,6 +329,7 @@ int MySQL_Threads_Handler::get_variable_int(char *name) { 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; + if (!strcasecmp(name,"free_connections_pct")) return (int)variables.free_connections_pct; if (!strcasecmp(name,"ping_interval_server")) return (int)variables.ping_interval_server; if (!strcasecmp(name,"ping_timeout_server")) return (int)variables.ping_timeout_server; if (!strcasecmp(name,"have_compress")) return (int)variables.have_compress; @@ -407,6 +410,10 @@ char * MySQL_Threads_Handler::get_variable(char *name) { // this is the public f sprintf(intbuf,"%d",variables.connect_timeout_server_max); return strdup(intbuf); } + if (!strcasecmp(name,"free_connections_pct")) { + sprintf(intbuf,"%d",variables.free_connections_pct); + return strdup(intbuf); + } if (!strcasecmp(name,"connect_retries_delay")) { sprintf(intbuf,"%d",variables.connect_retries_delay); return strdup(intbuf); @@ -610,6 +617,15 @@ bool MySQL_Threads_Handler::set_variable(char *name, char *value) { // this is t return false; } } + if (!strcasecmp(name,"free_connections_pct")) { + int intv=atoi(value); + if (intv >= 0 && intv <= 100) { + variables.free_connections_pct=intv; + return true; + } else { + return false; + } + } if (!strcasecmp(name,"max_connections")) { int intv=atoi(value); if (intv >= 1 && intv <= 1000*1000) { @@ -1399,6 +1415,7 @@ void MySQL_Thread::refresh_variables() { 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"); + mysql_thread___free_connections_pct=GloMTH->get_variable_int((char *)"free_connections_pct"); mysql_thread___connect_retries_delay=GloMTH->get_variable_int((char *)"connect_retries_delay"); if (mysql_thread___connect_timeout_server_error) free(mysql_thread___connect_timeout_server_error); mysql_thread___connect_timeout_server_error=GloMTH->get_variable_string((char *)"connect_timeout_server_error");