From ced8227d8eb2e19ef950d38ba92cb2b1a208f2d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Wed, 12 Dec 2018 02:11:39 +1100 Subject: [PATCH 1/6] Removed several deadlocks related to Threads stats --- lib/MySQL_Thread.cpp | 63 ++------------------------------------------ 1 file changed, 2 insertions(+), 61 deletions(-) diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp index 32452aad7..eee77bfa3 100644 --- a/lib/MySQL_Thread.cpp +++ b/lib/MySQL_Thread.cpp @@ -4225,33 +4225,7 @@ void MySQL_Threads_Handler::Get_Memory_Stats() { #endif // IDLE_THREADS } pthread_mutex_lock(&thr->thread_mutex); -/* - } - for (i=0;iGet_Memory_Stats(); -/* - } - for (i=0;ithread_mutex); } } @@ -4260,7 +4234,7 @@ SQLite3_result * MySQL_Threads_Handler::SQL3_Processlist() { const int colnum=14; char port[NI_MAXSERV]; proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 4, "Dumping MySQL Processlist\n"); - SQLite3_result *result=new SQLite3_result(colnum); + SQLite3_result *result=new SQLite3_result(colnum); result->add_column_definition(SQLITE_TEXT,"ThreadID"); result->add_column_definition(SQLITE_TEXT,"SessionID"); result->add_column_definition(SQLITE_TEXT,"user"); @@ -4298,21 +4272,6 @@ SQLite3_result * MySQL_Threads_Handler::SQL3_Processlist() { } #endif // IDLE_THREADS } -/* - } -#ifdef IDLE_THREADS - for (i=0;i < ( (mysql_thread___session_idle_show_processlist && GloVars.global.idle_threads ) ? num_threads*2 : num_threads); i++) { -#else - for (i=0;i < num_threads; i++) { -#endif // IDLE_THREADS - if (imysql_sessions->len; j++) { MySQL_Session *sess=(MySQL_Session *)thr->mysql_sessions->pdata[j]; @@ -4526,25 +4485,7 @@ SQLite3_result * MySQL_Threads_Handler::SQL3_Processlist() { free(pta); } } -/* - } -#ifdef IDLE_THREADS - for (i=0;i < ( (mysql_thread___session_idle_show_processlist && GloVars.global.idle_threads ) ? num_threads*2 : num_threads); i++) { -#else - for (i=0;i < num_threads; i++) { -#endif // IDLE_THREADS -*/ - if (ithread_mutex); -#ifdef IDLE_THREADS - } else { - if (mysql_thread___session_idle_show_processlist) { - thr=(MySQL_Thread *)mysql_threads_idles[i-num_threads].worker; - pthread_mutex_unlock(&thr->thread_mutex); - } -#endif // IDLE_THREADS - } + pthread_mutex_unlock(&thr->thread_mutex); } return result; } From 3c49b2bf615da0d5b7e7805c3f4128c06bb461d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Tue, 13 Nov 2018 17:34:03 +0200 Subject: [PATCH 2/6] Revert autcommit to 1 if it is the first SELECT If: * client wants autocommit=0 * enforce_autocommit_on_reads=false * there is no transaction * this seems to be the first query, and a SELECT not FOR UPDATE Action: * switch back to autcommit=1 --- lib/MySQL_Session.cpp | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 30acc0edf..98cd8152d 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -1343,6 +1343,24 @@ bool MySQL_Session::handler_again___verify_backend_autocommit() { } NEXT_IMMEDIATE_NEW(CHANGING_AUTOCOMMIT); } + } else { + if (autocommit == false) { // also IsAutoCommit==false + if (mysql_thread___enforce_autocommit_on_reads == false) { + if (mybe->server_myds->myconn->IsActiveTransaction() == false) { + if (CurrentQuery.is_select_NOT_for_update()==true) { + // client wants autocommit=0 + // enforce_autocommit_on_reads=false + // there is no transaction + // this seems to be the first query, and a SELECT not FOR UPDATE + // we will switch back to autcommit=1 + if (status == PROCESSING_QUERY) { + previous_status.push(PROCESSING_QUERY); + NEXT_IMMEDIATE_NEW(CHANGING_AUTOCOMMIT); + } + } + } + } + } } return false; } @@ -2019,7 +2037,22 @@ bool MySQL_Session::handler_again___status_CHANGING_AUTOCOMMIT(int *_rc) { if (myds->mypolls==NULL) { thread->mypolls.add(POLLIN|POLLOUT, mybe->server_myds->fd, mybe->server_myds, thread->curtime); } - int rc=myconn->async_set_autocommit(myds->revents, autocommit); + bool ac = autocommit; + if (autocommit == false) { // also IsAutoCommit==false + if (mysql_thread___enforce_autocommit_on_reads == false) { + if (mybe->server_myds->myconn->IsActiveTransaction() == false) { + if (CurrentQuery.is_select_NOT_for_update()==true) { + // client wants autocommit=0 + // enforce_autocommit_on_reads=false + // there is no transaction + // this seems to be the first query, and a SELECT not FOR UPDATE + // we will switch back to autcommit=1 + ac = true; + } + } + } + } + int rc=myconn->async_set_autocommit(myds->revents, ac); if (rc==0) { st=previous_status.top(); previous_status.pop(); From 8396041fd2df8894c5ebb6aa7c13322f4be8fe3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Tue, 13 Nov 2018 19:29:40 +0200 Subject: [PATCH 3/6] Minor tuning on previous commit --- lib/MySQL_Session.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 98cd8152d..b91c5bd0a 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -2040,14 +2040,16 @@ bool MySQL_Session::handler_again___status_CHANGING_AUTOCOMMIT(int *_rc) { bool ac = autocommit; if (autocommit == false) { // also IsAutoCommit==false if (mysql_thread___enforce_autocommit_on_reads == false) { - if (mybe->server_myds->myconn->IsActiveTransaction() == false) { - if (CurrentQuery.is_select_NOT_for_update()==true) { - // client wants autocommit=0 - // enforce_autocommit_on_reads=false - // there is no transaction - // this seems to be the first query, and a SELECT not FOR UPDATE - // we will switch back to autcommit=1 - ac = true; + if (mybe->server_myds->myconn->IsAutoCommit() == false) { + if (mybe->server_myds->myconn->IsActiveTransaction() == false) { + if (CurrentQuery.is_select_NOT_for_update()==true) { + // client wants autocommit=0 + // enforce_autocommit_on_reads=false + // there is no transaction + // this seems to be the first query, and a SELECT not FOR UPDATE + // we will switch back to autcommit=1 + ac = true; + } } } } From 0e452c7bbd6a86ebc52dfc10da2b9c9a790b593b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Tue, 13 Nov 2018 22:55:22 +0200 Subject: [PATCH 4/6] Fix edge case --- lib/MySQL_Session.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index b91c5bd0a..7e4623523 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -2050,6 +2050,10 @@ bool MySQL_Session::handler_again___status_CHANGING_AUTOCOMMIT(int *_rc) { // we will switch back to autcommit=1 ac = true; } + } else { + st=previous_status.top(); + previous_status.pop(); + NEXT_IMMEDIATE_NEW(st); } } } From 4fc81d945ad9ce0c5693fd1eba94da82dfde149c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Wed, 14 Nov 2018 12:32:49 +0200 Subject: [PATCH 5/6] Free dataset after INIT_CONNECT --- lib/MySQL_Session.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 7e4623523..ab8158035 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -1422,6 +1422,7 @@ bool MySQL_Session::handler_again___status_SETTING_INIT_CONNECT(int *_rc) { int rc=myconn->async_send_simple_command(myds->revents,myconn->options.init_connect,strlen(myconn->options.init_connect)); if (rc==0) { myds->revents|=POLLOUT; // we also set again POLLOUT to send a query immediately! + myds->free_mysql_real_query(); st=previous_status.top(); previous_status.pop(); NEXT_IMMEDIATE_NEW(st); From ad625ba745f365e42829944bb576d7320a86d314 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Thu, 15 Nov 2018 12:33:21 +0200 Subject: [PATCH 6/6] Remove asserts from MyDS_real_query::init() --- include/MySQL_Data_Stream.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/MySQL_Data_Stream.h b/include/MySQL_Data_Stream.h index 2fa068c0c..f0ed5a5a1 100644 --- a/include/MySQL_Data_Stream.h +++ b/include/MySQL_Data_Stream.h @@ -26,10 +26,12 @@ class MyDS_real_query { char *QueryPtr; // pointer to beginning of the query unsigned int QuerySize; // size of the query void init(PtrSize_t *_pkt) { +/* assert(QueryPtr==NULL); assert(QuerySize==0); assert(pkt.ptr==NULL); assert(pkt.size==0); +*/ pkt.ptr=_pkt->ptr; pkt.size=_pkt->size; QueryPtr=(char *)pkt.ptr+5;