diff --git a/include/MySQL_Session.h b/include/MySQL_Session.h index 5c4764958..38bc1bcd1 100644 --- a/include/MySQL_Session.h +++ b/include/MySQL_Session.h @@ -186,6 +186,7 @@ class MySQL_Session // bool bool autocommit; bool autocommit_handled; + bool sending_set_autocommit; bool killed; bool locked_on_hostgroup_and_all_variables_set; //bool admin; diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 711842496..65cd42fca 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -441,6 +441,7 @@ MySQL_Session::MySQL_Session() { healthy=1; autocommit=true; autocommit_handled=false; + sending_set_autocommit=false; autocommit_on_hostgroup=-1; killed=false; session_type=PROXYSQL_SESSION_MYSQL; @@ -506,6 +507,7 @@ void MySQL_Session::init() { void MySQL_Session::reset() { autocommit=true; autocommit_handled=false; + sending_set_autocommit=false; autocommit_on_hostgroup=-1; current_hostgroup=-1; default_hostgroup=-1; @@ -782,6 +784,7 @@ bool MySQL_Session::handler_CommitRollback(PtrSize_t *pkt) { bool MySQL_Session::handler_SetAutocommit(PtrSize_t *pkt) { autocommit_handled=false; + sending_set_autocommit=false; size_t sal=strlen("set autocommit"); char * _ptr = (char *)pkt->ptr; #ifdef DEBUG @@ -879,6 +882,7 @@ bool MySQL_Session::handler_SetAutocommit(PtrSize_t *pkt) { client_myds->myconn->set_autocommit(autocommit); autocommit_on_hostgroup=FindOneActiveTransaction(); free(_new_pkt.ptr); + sending_set_autocommit=true; return false; } else { // as there is no active transaction, we do no need to forward it @@ -1755,6 +1759,20 @@ bool MySQL_Session::handler_again___verify_backend_autocommit() { if (mysql_thread___forward_autocommit == true) { return false; } + if (sending_set_autocommit) { + // if sending_set_autocommit==true, the next query proxysql is going + // to run defines autocommit, for example: + // * SET autocommit=1 , or + // * SET sql_mode='', autocommit=1 + // for this reason, matching autocommit beforehand is not required + // and we return + // + // Nonetheless, we need to set autocommit in backend's MySQL_Connection + MySQL_Connection *mc = mybe->server_myds->myconn; + mc->set_autocommit(autocommit); + mc->options.last_set_autocommit = ( mc->options.autocommit ? 1 : 0 ); + return false; + } proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Session %p , client: %d , backend: %d\n", this, client_myds->myconn->options.autocommit, mybe->server_myds->myconn->options.autocommit); if (autocommit != mybe->server_myds->myconn->IsAutoCommit()) { // see case #485 @@ -5124,6 +5142,7 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C client_myds->myconn->set_autocommit(autocommit); autocommit_on_hostgroup=FindOneActiveTransaction(); exit_after_SetParse = false; + sending_set_autocommit=true; } else { // as there is no active transaction, we do no need to forward it // just change internal state