MXS-359: Close failed backend if in read-only transaction
If the connection to the backend where a read-only transaction is being performed fails, the Backend object should be closed for it. This fixes a debug assertion in readwritesplit.cc:check_and_log_backend_state which asserts that the failed connection must not be in use after the error handling is done. Also reordered the failing assertion and the accompanying error message so that the error is logged first.
This commit is contained in:
@ -617,9 +617,9 @@ void check_and_log_backend_state(const SRWBackend& backend, DCB* problem_dcb)
|
|||||||
/** This is a valid DCB for a backend ref */
|
/** This is a valid DCB for a backend ref */
|
||||||
if (backend->in_use() && backend->dcb() == problem_dcb)
|
if (backend->in_use() && backend->dcb() == problem_dcb)
|
||||||
{
|
{
|
||||||
ss_dassert(false);
|
|
||||||
MXS_ERROR("Backend '%s' is still in use and points to the problem DCB.",
|
MXS_ERROR("Backend '%s' is still in use and points to the problem DCB.",
|
||||||
backend->name());
|
backend->name());
|
||||||
|
ss_dassert(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1370,17 +1370,17 @@ static void handleError(MXS_ROUTER *instance,
|
|||||||
case ERRACT_NEW_CONNECTION:
|
case ERRACT_NEW_CONNECTION:
|
||||||
{
|
{
|
||||||
if (rses->current_master && rses->current_master->in_use() &&
|
if (rses->current_master && rses->current_master->in_use() &&
|
||||||
rses->current_master->dcb() == problem_dcb)
|
rses->current_master == backend)
|
||||||
{
|
{
|
||||||
/** The connection to the master has failed */
|
/** The connection to the master has failed */
|
||||||
SERVER *srv = rses->current_master->server();
|
SERVER *srv = rses->current_master->server();
|
||||||
bool can_continue = false;
|
bool can_continue = false;
|
||||||
|
|
||||||
if (rses->rses_config.master_failure_mode != RW_FAIL_INSTANTLY &&
|
if (!backend->is_waiting_result())
|
||||||
(!backend || !backend->is_waiting_result()))
|
|
||||||
{
|
{
|
||||||
/** The failure of a master is not considered a critical
|
/** The failure of a master is not considered a critical
|
||||||
* failure as partial functionality still remains. Reads
|
* failure as partial functionality still remains. If
|
||||||
|
* master_failure_mode is not set to fail_instantly, reads
|
||||||
* are allowed as long as slave servers are available
|
* are allowed as long as slave servers are available
|
||||||
* and writes will cause an error to be returned.
|
* and writes will cause an error to be returned.
|
||||||
*
|
*
|
||||||
@ -1392,34 +1392,28 @@ static void handleError(MXS_ROUTER *instance,
|
|||||||
}
|
}
|
||||||
else if (!SERVER_IS_MASTER(srv) && !srv->master_err_is_logged)
|
else if (!SERVER_IS_MASTER(srv) && !srv->master_err_is_logged)
|
||||||
{
|
{
|
||||||
MXS_ERROR("Server %s:%d lost the master status. Readwritesplit "
|
ss_dassert(backend);
|
||||||
"service can't locate the master. Client sessions "
|
MXS_ERROR("Server %s (%s) lost the master status while waiting"
|
||||||
"will be closed.", srv->name, srv->port);
|
" for a result. Client sessions will be closed.",
|
||||||
srv->master_err_is_logged = true;
|
backend->name(), backend->uri());
|
||||||
|
backend->server()->master_err_is_logged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
*succp = can_continue;
|
*succp = can_continue;
|
||||||
|
|
||||||
if (backend)
|
|
||||||
{
|
|
||||||
backend->close(mxs::Backend::CLOSE_FATAL);
|
backend->close(mxs::Backend::CLOSE_FATAL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MXS_ERROR("Server %s:%d lost the master status but could not locate the "
|
if (rses->target_node && rses->target_node == backend &&
|
||||||
"corresponding backend ref.", srv->name, srv->port);
|
session_trx_is_read_only(problem_dcb->session))
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (backend)
|
|
||||||
{
|
{
|
||||||
if (rses->target_node &&
|
/**
|
||||||
(rses->target_node->dcb() == problem_dcb &&
|
* We were locked to a single node but the node died. Currently
|
||||||
session_trx_is_read_only(problem_dcb->session)))
|
* this only happens with read-only transactions so the only
|
||||||
{
|
* thing we can do is to close the connection.
|
||||||
/** The problem DCB is the current target of a READ ONLY transaction.
|
*/
|
||||||
* Reset the target and close the session. */
|
|
||||||
rses->target_node.reset();
|
|
||||||
*succp = false;
|
*succp = false;
|
||||||
|
backend->close(mxs::Backend::CLOSE_FATAL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user