MXS-1503: Refactor slave selection

Refactored and cleaned up the slave selection in preparation of
reconnection code unification.
This commit is contained in:
Markus Mäkelä
2018-03-28 12:22:11 +03:00
parent 876187b340
commit 9c7578272c

View File

@ -343,6 +343,16 @@ bool route_session_write(RWSplitSession *rses, GWBUF *querybuf,
return nsucc; return nsucc;
} }
/**
* Check if replication lag is below acceptable levels
*/
static inline bool rpl_lag_is_ok(SRWBackend& backend, int max_rlag)
{
return max_rlag == MAX_RLAG_UNDEFINED ||
(backend->server()->rlag != MAX_RLAG_NOT_AVAILABLE &&
backend->server()->rlag <= max_rlag);
}
/** /**
* Provide the router with a reference to a suitable backend * Provide the router with a reference to a suitable backend
* *
@ -396,84 +406,38 @@ SRWBackend get_target_backend(RWSplitSession *rses, backend_type_t btype,
if (btype == BE_SLAVE) if (btype == BE_SLAVE)
{ {
for (SRWBackendList::iterator it = rses->backends.begin(); for (auto it = rses->backends.begin(); it != rses->backends.end(); it++)
it != rses->backends.end(); it++)
{ {
SRWBackend& backend = *it; auto& backend = *it;
/** if (backend->in_use() && // Backend is in use
* Unused backend or backend which is not master nor (backend->is_master() || backend->is_slave()) && // Either a master or a slave
* slave can't be used rpl_lag_is_ok(backend, max_rlag)) // Not lagging too much
*/
if (!backend->in_use() ||
(!backend->is_master() && !backend->is_slave()))
{ {
continue; if (!rval)
}
/**
* If there are no candidates yet accept both master or
* slave.
*/
else if (!rval)
{
/**
* Ensure that master has not changed during
* session and abort if it has.
*/
if (backend->is_master() && backend == rses->current_master)
{ {
/** found master */ // No previous candidate, accept any valid server (includes master)
rval = backend; if ((backend->is_master() && backend == rses->current_master) ||
} backend->is_slave())
/** {
* Ensure that max replication lag is not set rval = backend;
* or that candidate's lag doesn't exceed the }
* maximum allowed replication lag.
*/
else if (max_rlag == MAX_RLAG_UNDEFINED ||
(backend->server()->rlag != MAX_RLAG_NOT_AVAILABLE &&
backend->server()->rlag <= max_rlag))
{
/** found slave */
rval = backend;
}
}
/**
* If candidate is master, any slave which doesn't break
* replication lag limits replaces it.
*/
else if (rval->is_master() && backend->is_slave() &&
(max_rlag == MAX_RLAG_UNDEFINED ||
(backend->server()->rlag != MAX_RLAG_NOT_AVAILABLE &&
backend->server()->rlag <= max_rlag)) &&
!rses->rses_config.master_accept_reads)
{
/** found slave */
rval = backend;
}
/**
* When candidate exists, compare it against the current
* backend and update assign it to new candidate if
* necessary.
*/
else if (backend->is_slave() ||
(rses->rses_config.master_accept_reads &&
backend->is_master()))
{
if (max_rlag == MAX_RLAG_UNDEFINED ||
(backend->server()->rlag != MAX_RLAG_NOT_AVAILABLE &&
backend->server()->rlag <= max_rlag))
{
rval = compare_backends(rval, backend, rses->rses_config.slave_selection_criteria);
} }
else else
{ {
MXS_INFO("Server %s is too much behind the master " if (!rses->rses_config.master_accept_reads && rval->is_master())
"(%d seconds) and can't be chosen", {
backend->uri(), backend->server()->rlag); // Pick slaves over masters with master_accept_reads=false
rval = backend;
}
else
{
// Compare the two servers and pick the best one
rval = compare_backends(rval, backend, rses->rses_config.slave_selection_criteria);
}
} }
} }
} /*< for */ }
} }
/** /**
* If target was originally master only then the execution jumps * If target was originally master only then the execution jumps