From 90a4922ed8712dada76f604f85ea3cab31f5fe1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Tue, 16 Mar 2021 17:56:46 +0100 Subject: [PATCH] Fixing an inifinite loop in case of multi-statements and closed backend connection If a backend connection was terminated in the middle of the execution of multiple statements in a multi-statements command, the worker thread was entering an infinite loop. Furthermore, this commit disables query retry in case of multi-statements if the first one completed successfully This fixes #3339 --- lib/MySQL_Session.cpp | 11 +++++++++-- lib/mysql_connection.cpp | 13 +++++++++---- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 935315d22..49570a2e3 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -4066,8 +4066,15 @@ handler_again: if (myds->myconn->MyRS && myds->myconn->MyRS->transfer_started) { // transfer to frontend has started, we cannot retry } else { - retry_conn=true; - proxy_warning("Retrying query.\n"); + if (myds->myconn->mysql->server_status & SERVER_MORE_RESULTS_EXIST) { + // transfer to frontend has started, because this is, at least, + // the second resultset coming from the server + // we cannot retry + proxy_warning("Disabling query retry because SERVER_MORE_RESULTS_EXIST is set\n"); + } else { + retry_conn=true; + proxy_warning("Retrying query.\n"); + } } } } diff --git a/lib/mysql_connection.cpp b/lib/mysql_connection.cpp index 11f0201d3..0da1b7cad 100644 --- a/lib/mysql_connection.cpp +++ b/lib/mysql_connection.cpp @@ -1404,15 +1404,20 @@ handler_again: } else { compute_unknown_transaction_status(); } + if (_myerrno < 2000) { + // we can continue only if the error is coming from the backend. + // (or if zero) + // if the error comes from the client library, something terribly + // wrong happened and we cannot continue + if (mysql->server_status & SERVER_MORE_RESULTS_EXIST) { + async_state_machine=ASYNC_NEXT_RESULT_START; + } + } } if (mysql_result) { mysql_free_result(mysql_result); mysql_result=NULL; } - //if (mysql_next_result(mysql)==0) { - if (mysql->server_status & SERVER_MORE_RESULTS_EXIST) { - async_state_machine=ASYNC_NEXT_RESULT_START; - } break; case ASYNC_SET_AUTOCOMMIT_START: set_autocommit_start();