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:
parent
8251389813
commit
9e9cd0c596
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user