diff --git a/include/MySQL_HostGroups_Manager.h b/include/MySQL_HostGroups_Manager.h index e0aacec8e..9402e8160 100644 --- a/include/MySQL_HostGroups_Manager.h +++ b/include/MySQL_HostGroups_Manager.h @@ -133,6 +133,7 @@ class MySQL_HostGroups_Manager { MySQL_Connection * get_MyConn_from_pool(unsigned int); + void drop_all_idle_connections(); int get_multiple_idle_connections(int, unsigned long long, MySQL_Connection **, int); SQLite3_result * SQL3_Connection_Pool(); diff --git a/lib/MySQL_HostGroups_Manager.cpp b/lib/MySQL_HostGroups_Manager.cpp index 35464f282..f18c6464f 100644 --- a/lib/MySQL_HostGroups_Manager.cpp +++ b/lib/MySQL_HostGroups_Manager.cpp @@ -737,6 +737,33 @@ __exit_replication_lag_action: wrunlock(); } +void MySQL_HostGroups_Manager::drop_all_idle_connections() { + // NOTE: the caller should hold wrlock + int i, j; + for (i=0; i<(int)MyHostGroups->len; i++) { + MyHGC *myhgc=(MyHGC *)MyHostGroups->index(i); + for (j=0; j<(int)myhgc->mysrvs->cnt(); j++) { + MySrvC *mysrvc=(MySrvC *)myhgc->mysrvs->servers->index(j); + if (mysrvc->status!=MYSQL_SERVER_STATUS_ONLINE) { + proxy_debug(PROXY_DEBUG_MYSQL_CONNPOOL, 5, "Server %s:%d is not online\n", mysrvc->address, mysrvc->port); + mysrvc->ConnectionsFree->drop_all_connections(); + } + + // Drop idle connections if beyond max_connection + while (mysrvc->ConnectionsFree->conns->len && mysrvc->ConnectionsUsed->conns->len+mysrvc->ConnectionsFree->conns->len > mysrvc->max_connections) { + MySQL_Connection *conn=(MySQL_Connection *)mysrvc->ConnectionsFree->conns->remove_index_fast(0); + delete conn; + } + + PtrArray *pa=mysrvc->ConnectionsFree->conns; + while (pa->len > mysql_thread___free_connections_pct*mysrvc->max_connections/100) { + MySQL_Connection *mc=(MySQL_Connection *)pa->remove_index_fast(0); + delete mc; + } + } + } +} + /* * Prepares at most num_conn idle connections in the given hostgroup for * pinging. When -1 is passed as a hostgroup, all hostgroups are examined. @@ -753,6 +780,7 @@ __exit_replication_lag_action: */ int MySQL_HostGroups_Manager::get_multiple_idle_connections(int _hid, unsigned long long _max_last_time_used, MySQL_Connection **conn_list, int num_conn) { wrlock(); + drop_all_idle_connections(); int num_conn_current=0; int i,j, k; for (i=0; i<(int)MyHostGroups->len; i++) { @@ -760,31 +788,11 @@ int MySQL_HostGroups_Manager::get_multiple_idle_connections(int _hid, unsigned l if (_hid >= 0 && _hid!=(int)myhgc->hid) continue; for (j=0; j<(int)myhgc->mysrvs->cnt(); j++) { MySrvC *mysrvc=(MySrvC *)myhgc->mysrvs->servers->index(j); - if (mysrvc->status!=MYSQL_SERVER_STATUS_ONLINE) { - proxy_debug(PROXY_DEBUG_MYSQL_CONNPOOL, 5, "Server %s:%d is not online\n", mysrvc->address, mysrvc->port); - mysrvc->ConnectionsFree->drop_all_connections(); - } - - // Drop idle connections if beyond max_connection - while (mysrvc->ConnectionsFree->conns->len && mysrvc->ConnectionsUsed->conns->len+mysrvc->ConnectionsFree->conns->len > mysrvc->max_connections) { - MySQL_Connection *conn=(MySQL_Connection *)mysrvc->ConnectionsFree->conns->remove_index_fast(0); - delete conn; - } - - PtrArray *pa=mysrvc->ConnectionsFree->conns; for (k=0; k<(int)pa->len; k++) { MySQL_Connection *mc=(MySQL_Connection *)pa->index(k); // If the connection is idle ... if (mc->last_time_used < _max_last_time_used) { - // Then we will remove it if there are too many idle connections sitting around. - 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; - } // If the connection is idle but wasn't dropped, we'll // move it to the returned results (conn_list) in order to diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 12b614cf1..0e69b54fe 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -658,7 +658,7 @@ handler_again: mybe->server_myds->max_connect_time=0; } if ( - (mybe->server_myds->myconn && mybe->server_myds->myconn!=ASYNC_IDLE && mybe->server_myds->wait_until && thread->curtime >= mybe->server_myds->wait_until) + (mybe->server_myds->myconn && mybe->server_myds->myconn->async_state_machine!=ASYNC_IDLE && mybe->server_myds->wait_until && thread->curtime >= mybe->server_myds->wait_until) // query timed out || (killed==true) // session was killed by admin