MXS-2313: Pick best available master
Readwritesplit now picks the best available master if no open master connection is available. This is required if the server rank is to be taken into account when master selection is done.
This commit is contained in:
@ -391,7 +391,8 @@ static inline const char* failure_mode_to_str(enum failure_mode type)
|
|||||||
void closed_session_reply(GWBUF* querybuf);
|
void closed_session_reply(GWBUF* querybuf);
|
||||||
bool send_readonly_error(DCB* dcb);
|
bool send_readonly_error(DCB* dcb);
|
||||||
|
|
||||||
mxs::RWBackend* get_root_master(const mxs::PRWBackends& backends);
|
mxs::RWBackend* get_root_master(const mxs::PRWBackends& backends, mxs::RWBackend* current_master,
|
||||||
|
const BackendSelectFunction& func);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get total slave count and connected slave count
|
* Get total slave count and connected slave count
|
||||||
|
@ -696,7 +696,7 @@ RWBackend* RWSplitSession::get_master_backend()
|
|||||||
{
|
{
|
||||||
RWBackend* rval = nullptr;
|
RWBackend* rval = nullptr;
|
||||||
/** get root master from available servers */
|
/** get root master from available servers */
|
||||||
RWBackend* master = get_root_master(m_raw_backends);
|
RWBackend* master = get_root_master(m_raw_backends, m_current_master, m_config.backend_select_fct);
|
||||||
|
|
||||||
if (master)
|
if (master)
|
||||||
{
|
{
|
||||||
|
@ -335,18 +335,29 @@ static void log_server_connections(select_criteria_t criteria, const PRWBackends
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RWBackend* get_root_master(const PRWBackends& backends)
|
namespace
|
||||||
{
|
{
|
||||||
RWBackend* master = nullptr;
|
// Buffer used for selecting the best master
|
||||||
for (auto candidate : backends)
|
thread_local PRWBackends sort_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
RWBackend* get_root_master(const PRWBackends& backends, RWBackend* current_master,
|
||||||
|
const BackendSelectFunction& func)
|
||||||
|
{
|
||||||
|
if (current_master && current_master->in_use() && current_master->is_master())
|
||||||
{
|
{
|
||||||
if (candidate->is_master())
|
return current_master;
|
||||||
{
|
|
||||||
master = candidate;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::copy_if(backends.begin(), backends.end(), std::back_inserter(sort_buffer),
|
||||||
|
[](RWBackend* backend) {
|
||||||
|
return backend->can_connect() && backend->is_master();
|
||||||
|
});
|
||||||
|
|
||||||
|
auto it = func(sort_buffer);
|
||||||
|
auto master = it != sort_buffer.end() ? *it : nullptr;
|
||||||
|
sort_buffer.clear();
|
||||||
|
|
||||||
return master;
|
return master;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -394,8 +405,8 @@ bool RWSplit::select_connect_backend_servers(MXS_SESSION* session,
|
|||||||
int* expected_responses,
|
int* expected_responses,
|
||||||
connection_type type)
|
connection_type type)
|
||||||
{
|
{
|
||||||
RWBackend* master = get_root_master(backends);
|
|
||||||
const Config& cnf {config()};
|
const Config& cnf {config()};
|
||||||
|
RWBackend* master = get_root_master(backends, *current_master, cnf.backend_select_fct);
|
||||||
|
|
||||||
if ((!master || !master->can_connect()) && cnf.master_failure_mode == RW_FAIL_INSTANTLY)
|
if ((!master || !master->can_connect()) && cnf.master_failure_mode == RW_FAIL_INSTANTLY)
|
||||||
{
|
{
|
||||||
@ -419,23 +430,10 @@ bool RWSplit::select_connect_backend_servers(MXS_SESSION* session,
|
|||||||
log_server_connections(select_criteria, backends);
|
log_server_connections(select_criteria, backends);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == ALL)
|
if (type == ALL && master && master->connect(session))
|
||||||
{
|
{
|
||||||
/** Find a master server */
|
MXS_INFO("Selected Master: %s", master->name());
|
||||||
for (PRWBackends::const_iterator it = backends.begin(); it != backends.end(); it++)
|
*current_master = master;
|
||||||
{
|
|
||||||
RWBackend* backend = *it;
|
|
||||||
|
|
||||||
if (backend->can_connect() && master && backend == master)
|
|
||||||
{
|
|
||||||
if (backend->connect(session))
|
|
||||||
{
|
|
||||||
MXS_INFO("Selected Master: %s", backend->name());
|
|
||||||
*current_master = backend;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto counts = get_slave_counts(backends, master);
|
auto counts = get_slave_counts(backends, master);
|
||||||
|
Reference in New Issue
Block a user