From e1b611aa06af420c32ecc0b3659100bc328079cf Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Thu, 6 Jun 2019 12:16:18 +0300 Subject: [PATCH] MXS-2512 Use existing information As an error returned by the server is now stored inside RWBackend, irrespective of whether it is returned solely or e.g. last after a result set, there is no need to examine the GWBUF in rws, but we can use the information that exists. --- .../routing/readwritesplit/rwsplitsession.cc | 66 ++----------------- 1 file changed, 5 insertions(+), 61 deletions(-) diff --git a/server/modules/routing/readwritesplit/rwsplitsession.cc b/server/modules/routing/readwritesplit/rwsplitsession.cc index 4c6a46ea5..50a12f18e 100644 --- a/server/modules/routing/readwritesplit/rwsplitsession.cc +++ b/server/modules/routing/readwritesplit/rwsplitsession.cc @@ -575,66 +575,6 @@ void RWSplitSession::close_stale_connections() } } -namespace -{ - -inline bool is_transaction_rollback(uint8_t* pData) -{ - bool rv = false; - - // The 'sql_state' of all transaction rollbacks is "40XXX". In an error - // packet, the 'sql_state' is found in the payload at offset 4, after the one - // byte 'header', the two byte 'error_code', and the 1 byte 'sql_state_marker'. - uint8_t* p = pData + MYSQL_HEADER_LEN + 1 + 2 + 1; - - if (*p++ == '4' && *p == '0') - { - rv = true; - - if (mxb_log_is_priority_enabled(LOG_INFO)) - { - // p now points at the second byte of the 5 byte long 'sql_state'. - p += 4; // Now at the start of the human readable error message - - uint8_t* end = pData + MYSQL_HEADER_LEN + MYSQL_GET_PAYLOAD_LEN(pData); - int len = end - p; - char message[len + 1]; - memcpy(message, p, len); - message[len] = 0; - - MXS_NOTICE("A retryable Clustrix error: %s", message); - } - } - - return rv; -} - -bool is_transaction_rollback(GWBUF* writebuf) -{ - bool rv = false; - - if (MYSQL_IS_ERROR_PACKET(GWBUF_DATA(writebuf))) - { - if (GWBUF_IS_CONTIGUOUS(writebuf)) - { - rv = is_transaction_rollback(GWBUF_DATA(writebuf)); - } - else - { - uint8_t* pData = GWBUF_DATA(writebuf); - int len = MYSQL_HEADER_LEN + MYSQL_GET_PAYLOAD_LEN(pData); - uint8_t data[len]; - - gwbuf_copy_data(writebuf, 0, len, data); - - rv = is_transaction_rollback(data); - } - } - - return rv; -} -} - void RWSplitSession::clientReply(GWBUF* writebuf, DCB* backend_dcb) { DCB* client_dcb = backend_dcb->session->client_dcb; @@ -673,8 +613,12 @@ void RWSplitSession::clientReply(GWBUF* writebuf, DCB* backend_dcb) backend->process_reply(writebuf); - if (m_config.transaction_replay && is_transaction_rollback(writebuf)) + const RWBackend::Error& error = backend->error(); + + if (error && m_config.transaction_replay && error.is_rollback()) { + MXS_INFO("A retryable error: %s", error.message().c_str()); + // writebuf was an error that can be handled by replaying the transaction. m_expected_responses--;