MXS-1506: Use session_delay_routing with retry_failed_reads

Using the same functionality with the failed read retrying mechanism
removes the need to have multiple versions of the target deduction logic.
This commit is contained in:
Markus Mäkelä
2018-04-04 16:49:56 +03:00
parent 34008082e5
commit d6f98784f7
3 changed files with 25 additions and 73 deletions

View File

@ -205,8 +205,6 @@ bool RWSplitSession::route_single_stmt(GWBUF *querybuf, const RouteInfo& info)
}
}
MXS_SESSION* session = m_client->session;
if (succp && target)
{
// We have a valid target, reset retry duration
@ -240,12 +238,11 @@ bool RWSplitSession::route_single_stmt(GWBUF *querybuf, const RouteInfo& info)
}
}
}
else if (m_config.query_retry_interval > 0 &&
m_retry_duration < m_config.query_retry_timeout &&
!session_trx_is_active(session))
else if (can_retry_query())
{
// Try to route the query again later
uint64_t interval = m_config.query_retry_interval;
MXS_SESSION* session = m_client->session;
session_delay_routing(session, router_as_downstream(session),
gwbuf_clone(querybuf), interval);
m_retry_duration += interval;

View File

@ -211,56 +211,6 @@ bool RWSplitSession::route_stored_query()
return rval;
}
bool RWSplitSession::reroute_stored_statement(const SRWBackend& old, GWBUF *stored)
{
bool success = false;
if (!session_trx_is_active(m_client->session))
{
/**
* Only try to retry the read if autocommit is enabled and we are
* outside of a transaction
*/
for (auto it = m_backends.begin(); it != m_backends.end(); it++)
{
SRWBackend& backend = *it;
if (backend->in_use() && backend != old &&
!backend->is_master() && backend->is_slave())
{
/** Found a valid candidate; a non-master slave that's in use */
if (backend->write(stored))
{
MXS_INFO("Retrying failed read at '%s'.", backend->name());
ss_dassert(backend->get_reply_state() == REPLY_STATE_DONE);
backend->set_reply_state(REPLY_STATE_START);
m_expected_responses++;
success = true;
break;
}
}
}
if (!success && m_current_master && m_current_master->in_use())
{
/**
* Either we failed to write to the slave or no valid slave was found.
* Try to retry the read on the master.
*/
if (m_current_master->write(stored))
{
MXS_INFO("Retrying failed read at '%s'.", m_current_master->name());
ss_dassert(m_current_master->get_reply_state() == REPLY_STATE_DONE);
m_current_master->set_reply_state(REPLY_STATE_START);
m_expected_responses++;
success = true;
}
}
}
return success;
}
/**
* @bref discard the result of wait gtid statment, the result will be an error
* packet or an error packet.
@ -664,32 +614,31 @@ bool RWSplitSession::handle_error_new_connection(DCB *backend_dcb, GWBUF *errmsg
*/
GWBUF *stored = NULL;
const SERVER *target = NULL;
if (!session_take_stmt(backend_dcb->session, &stored, &target) ||
target != backend->backend()->server ||
!reroute_stored_statement(backend, stored))
if (session_take_stmt(backend_dcb->session, &stored, &target) &&
m_config.retry_failed_reads)
{
ss_dassert(target == backend->server());
MXS_INFO("Re-routing failed read after server '%s' failed", backend->name());
MXS_SESSION* session = m_client->session;
// Try to route the failed read as often as possible
session_delay_routing(session, router_as_downstream(session), stored, 1);
}
else
{
/**
* We failed to route the stored statement or no statement was
* stored for this server. Either way we can safely free the buffer
* and decrement the expected response count.
*/
gwbuf_free(stored);
if (!backend->has_session_commands())
{
/**
* The backend was executing a command that requires a reply.
* Send an error to the client to let it know the query has
* failed.
*/
DCB *client_dcb = ses->client_dcb;
client_dcb->func.write(client_dcb, gwbuf_clone(errmsg));
/** The backend was not executing a session command so the client
* is expecting a response. Send an error so they know to proceed. */
m_client->func.write(m_client, gwbuf_clone(errmsg));
}
if (m_expected_responses == 0)
{
/** The response from this server was the last one, try to
* route all queued queries */
// This was the last response, try to route pending queries
route_stored = true;
}
}

View File

@ -138,7 +138,6 @@ private:
bool route_session_write(GWBUF *querybuf, uint8_t command, uint32_t type);
bool route_single_stmt(GWBUF *querybuf, const RouteInfo& info);
bool route_stored_query();
bool reroute_stored_statement(const mxs::SRWBackend& old, GWBUF *stored);
mxs::SRWBackend get_hinted_backend(char *name);
mxs::SRWBackend get_slave_backend(int max_rlag);
@ -185,6 +184,13 @@ private:
bool lock_to_master();
bool is_locked_to_master() const;
bool supports_hint(HINT_TYPE hint_type) const;
inline bool can_retry_query() const
{
return m_config.query_retry_interval > 0 &&
m_retry_duration < m_config.query_retry_timeout &&
!session_trx_is_active(m_client->session);
}
};
/**