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:
Markus Mäkelä 2019-03-08 08:57:51 +02:00
parent 8251389813
commit 9e9cd0c596
No known key found for this signature in database
GPG Key ID: 72D48FCE664F7B19
3 changed files with 26 additions and 27 deletions

View File

@ -391,7 +391,8 @@ static inline const char* failure_mode_to_str(enum failure_mode type)
void closed_session_reply(GWBUF* querybuf);
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

View File

@ -696,7 +696,7 @@ RWBackend* RWSplitSession::get_master_backend()
{
RWBackend* rval = nullptr;
/** 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)
{

View File

@ -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;
for (auto candidate : backends)
// Buffer used for selecting the best master
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())
{
master = candidate;
break;
}
return current_master;
}
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;
}
@ -394,8 +405,8 @@ bool RWSplit::select_connect_backend_servers(MXS_SESSION* session,
int* expected_responses,
connection_type type)
{
RWBackend* master = get_root_master(backends);
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)
{
@ -419,23 +430,10 @@ bool RWSplit::select_connect_backend_servers(MXS_SESSION* session,
log_server_connections(select_criteria, backends);
}
if (type == ALL)
if (type == ALL && master && master->connect(session))
{
/** Find a master server */
for (PRWBackends::const_iterator it = backends.begin(); it != backends.end(); it++)
{
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;
}
}
MXS_INFO("Selected Master: %s", master->name());
*current_master = master;
}
auto counts = get_slave_counts(backends, master);