From 2bb322db6f8dcdecc697842bba444d82bf6e12bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Thu, 22 Mar 2018 17:31:52 +0100 Subject: [PATCH] Several fixed in Prepared statements * is STMT_PREPARE failed when there is a previous status (maybe STMT_EXECUTE) disconnect the client immediately. Maybe this is related to #1366 , but I can't reproduce it yet * purge prepared statements is also their server reference counter is 0 * initialize connections queue for purging connections --- lib/MySQL_HostGroups_Manager.cpp | 1 + lib/MySQL_PreparedStatement.cpp | 8 +++++--- lib/MySQL_Session.cpp | 7 +++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/MySQL_HostGroups_Manager.cpp b/lib/MySQL_HostGroups_Manager.cpp index 730f38540..14ab2bf33 100644 --- a/lib/MySQL_HostGroups_Manager.cpp +++ b/lib/MySQL_HostGroups_Manager.cpp @@ -831,6 +831,7 @@ MySQL_HostGroups_Manager::MySQL_HostGroups_Manager() { mydb->execute(MYHGM_MYSQL_SERVERS_INCOMING); mydb->execute(MYHGM_MYSQL_REPLICATION_HOSTGROUPS); mydb->execute(MYHGM_MYSQL_GROUP_REPLICATION_HOSTGROUPS); + queue = wqueue(); MyHostGroups=new PtrArray(); incoming_replication_hostgroups=NULL; incoming_group_replication_hostgroups=NULL; diff --git a/lib/MySQL_PreparedStatement.cpp b/lib/MySQL_PreparedStatement.cpp index 22bbb5ef5..2d0249841 100644 --- a/lib/MySQL_PreparedStatement.cpp +++ b/lib/MySQL_PreparedStatement.cpp @@ -532,16 +532,18 @@ void MySQL_STMT_Manager_v14::ref_count_client(uint64_t _stmt_id ,int _v, bool lo continue; // nothing left to clean up } MySQL_STMT_Global_info *a = it->second; - if (__sync_add_and_fetch(&a->ref_count_client, 0) == 0) { + if ((__sync_add_and_fetch(&a->ref_count_client, 0) == 0) && + (a->ref_count_server == 0) ) // this to avoid that IDs are incorrectly reused + { uint64_t hash = a->hash; auto s2 = map_stmt_hash_to_info.find(hash); if (s2 != map_stmt_hash_to_info.end()) { map_stmt_hash_to_info.erase(s2); } __sync_sub_and_fetch(&num_stmt_with_ref_client_count_zero,1); - if (a->ref_count_server == 0) { + //if (a->ref_count_server == 0) { //__sync_sub_and_fetch(&num_stmt_with_ref_server_count_zero,1); - } + //} // m.erase(it); // delete a; i++; diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 9a83c3bcc..8be87a774 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -2906,6 +2906,13 @@ handler_again: sprintf(sqlstate,"%s",mysql_sqlstate(myconn->mysql)); client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,client_myds->pkt_sid+1,mysql_errno(myconn->mysql),sqlstate,(char *)mysql_stmt_error(myconn->query.stmt)); client_myds->pkt_sid++; + if (previous_status.size()) { + // an STMT_PREPARE failed + // we have a previous status, probably STMT_EXECUTE, + // but returning to that status is not safe after STMT_PREPARE failed + // for this reason we exit immediately + wrong_pass=true; + } } break; case PROCESSING_STMT_EXECUTE: