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:
@ -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());
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
|
Reference in New Issue
Block a user