From 3b15ce609cf50d459afb140cff0302dde7ba3c70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Fri, 9 Mar 2018 18:11:49 +0100 Subject: [PATCH] Try to get from connection pool and connections cache, a connection with the same schemaname --- include/MySQL_HostGroups_Manager.h | 4 +-- include/MySQL_Thread.h | 2 +- lib/MySQL_HostGroups_Manager.cpp | 46 +++++++++++++++++++++++++++--- lib/MySQL_Session.cpp | 4 +-- lib/MySQL_Thread.cpp | 26 +++++++++++++++-- 5 files changed, 71 insertions(+), 11 deletions(-) diff --git a/include/MySQL_HostGroups_Manager.h b/include/MySQL_HostGroups_Manager.h index 6532c4b24..3ff002ecd 100644 --- a/include/MySQL_HostGroups_Manager.h +++ b/include/MySQL_HostGroups_Manager.h @@ -68,7 +68,7 @@ class MySrvConnList { conns->remove_index_fast((unsigned int)i); } MySQL_Connection *remove(int); - MySQL_Connection * get_random_MyConn(bool ff); + MySQL_Connection * get_random_MyConn(MySQL_Session *sess, bool ff); unsigned int conns_length(); void drop_all_connections(); MySQL_Connection *index(unsigned int); @@ -232,7 +232,7 @@ class MySQL_HostGroups_Manager { void MyConn_add_to_pool(MySQL_Connection *); - MySQL_Connection * get_MyConn_from_pool(unsigned int, bool ff=false); + MySQL_Connection * get_MyConn_from_pool(unsigned int hid, MySQL_Session *sess, bool ff=false); void drop_all_idle_connections(); int get_multiple_idle_connections(int, unsigned long long, MySQL_Connection **, int); diff --git a/include/MySQL_Thread.h b/include/MySQL_Thread.h index 845ab95cf..999a46472 100644 --- a/include/MySQL_Thread.h +++ b/include/MySQL_Thread.h @@ -258,7 +258,7 @@ class MySQL_Thread void unregister_session_connection_handler(int idx, bool _new=false); void listener_handle_new_connection(MySQL_Data_Stream *myds, unsigned int n); void Get_Memory_Stats(); - MySQL_Connection * get_MyConn_local(unsigned int); + MySQL_Connection * get_MyConn_local(unsigned int _hid, MySQL_Session *sess); void push_MyConn_local(MySQL_Connection *); void return_local_connections(); }; diff --git a/lib/MySQL_HostGroups_Manager.cpp b/lib/MySQL_HostGroups_Manager.cpp index ded634218..8da5dcaf2 100644 --- a/lib/MySQL_HostGroups_Manager.cpp +++ b/lib/MySQL_HostGroups_Manager.cpp @@ -1423,7 +1423,7 @@ unsigned int MySrvList::cnt() { MySrvC * MySrvList::idx(unsigned int i) { return (MySrvC *)servers->index(i); } -MySQL_Connection * MySrvConnList::get_random_MyConn(bool ff) { +MySQL_Connection * MySrvConnList::get_random_MyConn(MySQL_Session *sess, bool ff) { MySQL_Connection * conn=NULL; unsigned int i; unsigned int l=conns_length(); @@ -1433,7 +1433,45 @@ MySQL_Connection * MySrvConnList::get_random_MyConn(bool ff) { } else { i=fastrand()%l; } - conn=(MySQL_Connection *)conns->remove_index_fast(i); + if (sess && sess->client_myds && sess->client_myds->myconn && sess->client_myds->myconn->userinfo) { + // try to match schemaname + char *schema = sess->client_myds->myconn->userinfo->schemaname; + bool conn_found = false; + unsigned int k; + for (k = i; conn_found == false && k < l; k++) { + conn = (MySQL_Connection *)conns->index(k); + if (strcmp(conn->userinfo->schemaname,schema)==0) { + conn_found = true; + i = k; + } + } + if (conn_found == false ) { + for (k = 0; conn_found == false && k < i; k++) { + conn = (MySQL_Connection *)conns->index(k); + if (strcmp(conn->userinfo->schemaname,schema)==0) { + conn_found = true; + i = k; + } + } + } + if (conn_found == true) { + conn=(MySQL_Connection *)conns->remove_index_fast(i); + } else { + // we may consider creating a new connection + unsigned int conns_free = mysrvc->ConnectionsFree->conns_length(); + unsigned int conns_used = mysrvc->ConnectionsUsed->conns_length(); + if ((conns_used > conns_free) && (mysrvc->max_connections > (conns_free/2 + conns_used/2)) ) { + conn = new MySQL_Connection(); + conn->parent=mysrvc; + __sync_fetch_and_add(&MyHGM->status.server_connections_created, 1); + proxy_debug(PROXY_DEBUG_MYSQL_CONNPOOL, 7, "Returning MySQL Connection %p, server %s:%d\n", conn, conn->parent->address, conn->parent->port); + } else { + conn=(MySQL_Connection *)conns->remove_index_fast(i); + } + } + } else { + conn=(MySQL_Connection *)conns->remove_index_fast(i); + } proxy_debug(PROXY_DEBUG_MYSQL_CONNPOOL, 7, "Returning MySQL Connection %p, server %s:%d\n", conn, conn->parent->address, conn->parent->port); return conn; } else { @@ -1459,14 +1497,14 @@ MySQL_Connection * MySrvConnList::get_random_MyConn(bool ff) { return NULL; // never reach here } -MySQL_Connection * MySQL_HostGroups_Manager::get_MyConn_from_pool(unsigned int _hid, bool ff) { +MySQL_Connection * MySQL_HostGroups_Manager::get_MyConn_from_pool(unsigned int _hid, MySQL_Session *sess, bool ff) { MySQL_Connection * conn=NULL; wrlock(); status.myconnpoll_get++; MyHGC *myhgc=MyHGC_lookup(_hid); MySrvC *mysrvc=myhgc->get_random_MySrvC(); if (mysrvc) { // a MySrvC exists. If not, we return NULL = no targets - conn=mysrvc->ConnectionsFree->get_random_MyConn(ff); + conn=mysrvc->ConnectionsFree->get_random_MyConn(sess, ff); if (conn) { mysrvc->ConnectionsUsed->add(conn); status.myconnpoll_get_ok++; diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index d82a2f69b..47b3dbf47 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -3951,10 +3951,10 @@ void MySQL_Session::handler___client_DSS_QUERY_SENT___server_DSS_NOT_INITIALIZED } #else if (session_fast_forward == false) { - mc=thread->get_MyConn_local(mybe->hostgroup_id); // experimental , #644 + mc=thread->get_MyConn_local(mybe->hostgroup_id, this); // experimental , #644 } if (mc==NULL) { - mc=MyHGM->get_MyConn_from_pool(mybe->hostgroup_id, session_fast_forward); + mc=MyHGM->get_MyConn_from_pool(mybe->hostgroup_id, this, session_fast_forward); } else { thread->status_variables.ConnPool_get_conn_immediate++; } diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp index cf5ef4285..ab6a282be 100644 --- a/lib/MySQL_Thread.cpp +++ b/lib/MySQL_Thread.cpp @@ -4565,13 +4565,35 @@ void MySQL_Thread::Get_Memory_Stats() { } -MySQL_Connection * MySQL_Thread::get_MyConn_local(unsigned int _hid) { +MySQL_Connection * MySQL_Thread::get_MyConn_local(unsigned int _hid, MySQL_Session *sess) { unsigned int i; + unsigned int bc = 0; // best candidate + bool pcf = false; // possible candidate found + unsigned int npc = 0; // number of possible candidates MySQL_Connection *c=NULL; for (i=0; ilen; i++) { c=(MySQL_Connection *)cached_connections->index(i); if (c->parent->myhgc->hid==_hid) { - c=(MySQL_Connection *)cached_connections->remove_index_fast(i); + if (pcf == false) { + bc = i; + pcf = true; + } + npc++; + if (sess && sess->client_myds && sess->client_myds->myconn && sess->client_myds->myconn->userinfo) { + char *schema = sess->client_myds->myconn->userinfo->schemaname; + if (strcmp(c->userinfo->schemaname,schema)==0) { + c=(MySQL_Connection *)cached_connections->remove_index_fast(i); + return c; + } + } else { + c=(MySQL_Connection *)cached_connections->remove_index_fast(i); + return c; + } + } + } + if (pcf) { // there was a possible connection, but we skipped trying to find a better one + if (npc > 5) { // more candidates were evaluated + c=(MySQL_Connection *)cached_connections->remove_index_fast(bc); return c; } }