MXS-1506: Retry interrupted writes

If a query is interrupted that was sent to the master, it is now
retried. This allows all autocommit queries to be transparently retried if
the server in question fails.
This commit is contained in:
Markus Mäkelä
2018-04-06 12:20:08 +03:00
parent ed0f20708f
commit 196543ef39
3 changed files with 17 additions and 6 deletions

View File

@ -128,6 +128,14 @@ bool RWSplitSession::prepare_target(SRWBackend& target, route_target_t route_tar
return rval;
}
void RWSplitSession::retry_query(GWBUF* querybuf)
{
// Try to route the query again later
MXS_SESSION* session = m_client->session;
session_delay_routing(session, router_as_downstream(session), querybuf, 1);
++m_retry_duration;
}
/**
* Routing function. Find out query type, backend type, and target DCB(s).
* Then route query to found target(s).
@ -241,10 +249,7 @@ bool RWSplitSession::route_single_stmt(GWBUF *querybuf, const RouteInfo& info)
}
else if (can_retry_query())
{
// Try to route the query again later
MXS_SESSION* session = m_client->session;
session_delay_routing(session, router_as_downstream(session), gwbuf_clone(querybuf), 1);
++m_retry_duration;
retry_query(gwbuf_clone(querybuf));
succp = true;
MXS_INFO("Delaying routing: %s", extract_sql(querybuf).c_str());

View File

@ -509,7 +509,12 @@ void RWSplitSession::handleError(GWBUF *errmsgbuf, DCB *problem_dcb,
// We were expecting a response but we aren't going to get one
m_expected_responses--;
if (m_config.master_failure_mode == RW_ERROR_ON_WRITE)
if (can_retry_query())
{
can_continue = true;
retry_query(release_query());
}
else if (m_config.master_failure_mode == RW_ERROR_ON_WRITE)
{
/** In error_on_write mode, the session can continue even
* if the master is lost. Send a read-only error to
@ -518,7 +523,7 @@ void RWSplitSession::handleError(GWBUF *errmsgbuf, DCB *problem_dcb,
send_readonly_error(m_client);
}
if (!SERVER_IS_MASTER(srv) && !srv->master_err_is_logged)
if (!can_continue && !SERVER_IS_MASTER(srv) && !srv->master_err_is_logged)
{
ss_dassert(backend);
MXS_ERROR("Server %s (%s) lost the master status while waiting"

View File

@ -153,6 +153,7 @@ private:
bool handle_got_target(GWBUF* querybuf, mxs::SRWBackend& target, bool store);
void handle_connection_keepalive(mxs::SRWBackend& target);
bool prepare_target(mxs::SRWBackend& target, route_target_t route_target);
void retry_query(GWBUF* querybuf);
bool should_replace_master(mxs::SRWBackend& target);
void replace_master(mxs::SRWBackend& target);