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.
This commit is contained in:
Johan Wikman 2019-06-06 12:16:18 +03:00
parent aa9b6cb8c5
commit e1b611aa06

View File

@ -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--;