MXS-1503: Remove redundant code
Moved session command execution into the Backend class itself as the session commands are defined as a related part of it. This allows all connections to execute session commands if some are available. Removed explicit SERVER_REF usage in the readwritesplit connection creation code and replaced it with SRWBackend. This allows the removal of the get_root_master_backend function which duplicated the functionality in get_root_master.
This commit is contained in:
@ -143,10 +143,11 @@ public:
|
||||
* @brief Create a new connection
|
||||
*
|
||||
* @param session The session to which the connection is linked
|
||||
* @param sescmd Pointer to a list of session commands to execute
|
||||
*
|
||||
* @return True if connection was successfully created
|
||||
*/
|
||||
bool connect(MXS_SESSION* session);
|
||||
bool connect(MXS_SESSION* session, SessionCommandList* sescmd = NULL);
|
||||
|
||||
/**
|
||||
* @brief Close the backend
|
||||
|
||||
@ -176,7 +176,7 @@ void Backend::set_state(backend_state state)
|
||||
m_state |= state;
|
||||
}
|
||||
|
||||
bool Backend::connect(MXS_SESSION* session)
|
||||
bool Backend::connect(MXS_SESSION* session, SessionCommandList* sescmd)
|
||||
{
|
||||
bool rval = false;
|
||||
|
||||
@ -186,6 +186,16 @@ bool Backend::connect(MXS_SESSION* session)
|
||||
m_state = IN_USE;
|
||||
atomic_add(&m_backend->connections, 1);
|
||||
rval = true;
|
||||
|
||||
if (sescmd && sescmd->size())
|
||||
{
|
||||
append_session_command(*sescmd);
|
||||
|
||||
if (!execute_session_command())
|
||||
{
|
||||
rval = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -441,8 +441,7 @@ static bool handle_error_new_connection(RWSplit *inst,
|
||||
}
|
||||
else
|
||||
{
|
||||
succp = select_connect_backend_servers(myrses->rses_nbackends, max_nslaves,
|
||||
ses, inst->config(), myrses->backends,
|
||||
succp = select_connect_backend_servers(inst, ses, myrses->backends,
|
||||
myrses->current_master, &myrses->sescmd_list,
|
||||
&myrses->expected_responses,
|
||||
connection_type::SLAVE);
|
||||
@ -770,8 +769,7 @@ RWSplitSession* RWSplitSession::create(RWSplit* router, MXS_SESSION* session)
|
||||
|
||||
SRWBackend master;
|
||||
|
||||
if (select_connect_backend_servers(router->service()->n_dbref, router->max_slave_count(),
|
||||
session, router->config(), backends, master,
|
||||
if (select_connect_backend_servers(router, session, backends, master,
|
||||
NULL, NULL, connection_type::ALL))
|
||||
{
|
||||
if ((rses = new RWSplitSession(router, session, backends, master)))
|
||||
|
||||
@ -93,15 +93,13 @@ enum connection_type
|
||||
SLAVE
|
||||
};
|
||||
|
||||
bool select_connect_backend_servers(int router_nservers,
|
||||
int max_nslaves,
|
||||
MXS_SESSION *session,
|
||||
const Config& config,
|
||||
bool select_connect_backend_servers(RWSplit *inst, MXS_SESSION *session,
|
||||
SRWBackendList& backends,
|
||||
SRWBackend& current_master,
|
||||
mxs::SessionCommandList* sescmd,
|
||||
int* expected_responses,
|
||||
connection_type type);
|
||||
SRWBackend get_root_master(const SRWBackendList& backends);
|
||||
/*
|
||||
* The following are implemented in rwsplit_tmp_table_multi.c
|
||||
*/
|
||||
|
||||
@ -35,8 +35,6 @@
|
||||
|
||||
extern int (*criteria_cmpfun[LAST_CRITERIA])(const SRWBackend&, const SRWBackend&);
|
||||
|
||||
static SRWBackend get_root_master_backend(RWSplitSession *rses);
|
||||
|
||||
/**
|
||||
* Find out which of the two backend servers has smaller value for select
|
||||
* criteria property.
|
||||
@ -345,9 +343,6 @@ SRWBackend get_target_backend(RWSplitSession *rses, backend_type_t btype,
|
||||
return rses->target_node;
|
||||
}
|
||||
|
||||
/** get root master from available servers */
|
||||
SRWBackend master = get_root_master_backend(rses);
|
||||
|
||||
if (name) /*< Choose backend by name from a hint */
|
||||
{
|
||||
ss_dassert(btype != BE_MASTER); /*< Master dominates and no name should be passed with it */
|
||||
@ -462,26 +457,19 @@ SRWBackend get_target_backend(RWSplitSession *rses, backend_type_t btype,
|
||||
*/
|
||||
else if (btype == BE_MASTER)
|
||||
{
|
||||
if (master)
|
||||
{
|
||||
/** It is possible for the server status to change at any point in time
|
||||
* so copying it locally will make possible error messages
|
||||
* easier to understand */
|
||||
SERVER server;
|
||||
server.status = master->server()->status;
|
||||
/** get root master from available servers */
|
||||
SRWBackend master = get_root_master(rses->backends);
|
||||
|
||||
if (master->in_use())
|
||||
if (master && master->in_use())
|
||||
{
|
||||
if (SERVER_IS_MASTER(&server))
|
||||
if (master->is_master())
|
||||
{
|
||||
rval = master;
|
||||
}
|
||||
else
|
||||
{
|
||||
MXS_ERROR("Server '%s' should be master but is %s instead "
|
||||
"and can't be chosen as the master.",
|
||||
master->name(),
|
||||
STRSRVSTATUS(&server));
|
||||
MXS_ERROR("Server '%s' does not have the master state and "
|
||||
"can't be chosen as the master.", master->name());
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -490,7 +478,6 @@ SRWBackend get_target_backend(RWSplitSession *rses, backend_type_t btype,
|
||||
master->name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
@ -943,52 +930,3 @@ bool handle_got_target(RWSplit *inst, RWSplitSession *rses,
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the root master server from MySQL replication tree
|
||||
*
|
||||
* Finds the server with the lowest replication depth level which has the master
|
||||
* status. Servers are checked even if they are in 'maintenance'.
|
||||
*
|
||||
* @param rses Router client session
|
||||
*
|
||||
* @return The backend that points to the master server or an empty reference
|
||||
* if the master cannot be found
|
||||
*/
|
||||
static SRWBackend get_root_master_backend(RWSplitSession *rses)
|
||||
{
|
||||
SRWBackend candidate;
|
||||
SERVER master = {};
|
||||
|
||||
for (SRWBackendList::iterator it = rses->backends.begin();
|
||||
it != rses->backends.end(); it++)
|
||||
{
|
||||
SRWBackend& backend = *it;
|
||||
if (backend->in_use())
|
||||
{
|
||||
if (backend == rses->current_master)
|
||||
{
|
||||
/** Store master state for better error reporting */
|
||||
master.status = backend->server()->status;
|
||||
}
|
||||
|
||||
if (backend->is_master())
|
||||
{
|
||||
if (!candidate ||
|
||||
(backend->server()->depth < candidate->server()->depth))
|
||||
{
|
||||
candidate = backend;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!candidate && rses->rses_config.master_failure_mode == RW_FAIL_INSTANTLY &&
|
||||
rses->current_master && rses->current_master->in_use())
|
||||
{
|
||||
MXS_ERROR("Could not find master among the backend servers. "
|
||||
"Previous master's state : %s", STRSRVSTATUS(&master));
|
||||
}
|
||||
|
||||
return candidate;
|
||||
}
|
||||
|
||||
@ -36,10 +36,10 @@
|
||||
*
|
||||
* @return True if this server is a valid slave candidate
|
||||
*/
|
||||
static bool valid_for_slave(const SRWBackend& backend, const SERVER_REF *master)
|
||||
static bool valid_for_slave(const SRWBackend& backend, const SRWBackend& master)
|
||||
{
|
||||
return (backend->is_slave() || backend->is_relay()) &&
|
||||
(master == NULL || (backend->server() != master->server));
|
||||
(!master || backend != master);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -54,7 +54,7 @@ static bool valid_for_slave(const SRWBackend& backend, const SERVER_REF *master)
|
||||
*
|
||||
* @return The best slave backend reference or NULL if no candidates could be found
|
||||
*/
|
||||
static SRWBackend get_slave_candidate(const SRWBackendList& backends, const SERVER_REF *master,
|
||||
static SRWBackend get_slave_candidate(const SRWBackendList& backends, const SRWBackend& master,
|
||||
int (*cmpfun)(const SRWBackend&, const SRWBackend&))
|
||||
{
|
||||
SRWBackend candidate;
|
||||
@ -239,44 +239,25 @@ static void log_server_connections(select_criteria_t criteria, const SRWBackendL
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief Find the master server that is at the root of the replication tree
|
||||
*
|
||||
* @param rses Router client session
|
||||
*
|
||||
* @return The root master reference or NULL if no master is found
|
||||
*/
|
||||
static SERVER_REF* get_root_master(const SRWBackendList& backends)
|
||||
{
|
||||
SERVER_REF *master_host = NULL;
|
||||
|
||||
for (SRWBackendList::const_iterator it = backends.begin();
|
||||
it != backends.end(); it++)
|
||||
SRWBackend get_root_master(const SRWBackendList& backends)
|
||||
{
|
||||
SERVER_REF* b = (*it)->backend();
|
||||
SRWBackend master;
|
||||
|
||||
if (SERVER_IS_MASTER(b->server))
|
||||
for (auto it = backends.begin(); it != backends.end(); it++)
|
||||
{
|
||||
if (master_host == NULL ||
|
||||
(b->server->depth < master_host->server->depth))
|
||||
auto b = *it;
|
||||
|
||||
if (b->is_master() && (!master || b->server()->depth < master->server()->depth))
|
||||
{
|
||||
master_host = b;
|
||||
}
|
||||
master = b;
|
||||
}
|
||||
}
|
||||
|
||||
return master_host;
|
||||
return master;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the total number of slaves and number of connected slaves
|
||||
*
|
||||
* @param backends List of backend servers
|
||||
* @param master The master server or NULL for no master
|
||||
*
|
||||
* @return the total number of slaves and the connected slave count
|
||||
*/
|
||||
std::pair<int, int> get_slave_counts(SRWBackendList& backends, SERVER_REF* master)
|
||||
std::pair<int, int> get_slave_counts(SRWBackendList& backends, SRWBackend& master)
|
||||
{
|
||||
int slaves_found = 0;
|
||||
int slaves_connected = 0;
|
||||
@ -301,55 +282,35 @@ std::pair<int, int> get_slave_counts(SRWBackendList& backends, SERVER_REF* maste
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Search suitable backend servers from those of router instance
|
||||
* Select and connect to backend servers
|
||||
*
|
||||
* It is assumed that there is only one master among servers of a router instance.
|
||||
* As a result, the first master found is chosen. There will possibly be more
|
||||
* backend references than connected backends because only those in correct state
|
||||
* are connected to.
|
||||
*
|
||||
* @param router_nservers Number of backend servers
|
||||
* @param max_nslaves Upper limit for the number of slaves
|
||||
* @param select_criteria Slave selection criteria
|
||||
* @param inst Router instance
|
||||
* @param session Client session
|
||||
* @param router Router instance
|
||||
* @param rses Router client session
|
||||
* @param backends List of backend servers
|
||||
* @param current_master The current master server
|
||||
* @param sescmd_list List of session commands to execute
|
||||
* @param expected_responses Pointer where number of expected responses are written
|
||||
* @param type Connection type, ALL for all types, SLAVE for slaves only
|
||||
*
|
||||
* @return True if at least one master and one slave was found
|
||||
* @return True if session can continue
|
||||
*/
|
||||
bool select_connect_backend_servers(int router_nservers,
|
||||
int max_nslaves,
|
||||
MXS_SESSION *session,
|
||||
const Config& config,
|
||||
bool select_connect_backend_servers(RWSplit *inst, MXS_SESSION *session,
|
||||
SRWBackendList& backends,
|
||||
SRWBackend& current_master,
|
||||
mxs::SessionCommandList* sescmd_list,
|
||||
int* expected_responses,
|
||||
connection_type type)
|
||||
{
|
||||
SERVER_REF *master = get_root_master(backends);
|
||||
SRWBackend master = get_root_master(backends);
|
||||
|
||||
if (!master && config.master_failure_mode == RW_FAIL_INSTANTLY)
|
||||
if (!master && inst->config().master_failure_mode == RW_FAIL_INSTANTLY)
|
||||
{
|
||||
MXS_ERROR("Couldn't find suitable Master from %d candidates.", router_nservers);
|
||||
MXS_ERROR("Couldn't find suitable Master from %lu candidates.", backends.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* New session:
|
||||
*
|
||||
* Connect to both master and slaves
|
||||
*
|
||||
* Existing session:
|
||||
*
|
||||
* Master is already connected or we don't have a master. The function was
|
||||
* called because new slaves must be selected to replace failed ones.
|
||||
*/
|
||||
bool master_connected = type == SLAVE || current_master;
|
||||
|
||||
/** Check slave selection criteria and set compare function */
|
||||
select_criteria_t select_criteria = config.slave_selection_criteria;
|
||||
select_criteria_t select_criteria = inst->config().slave_selection_criteria;
|
||||
int (*cmpfun)(const SRWBackend&, const SRWBackend&) = criteria_cmpfun[select_criteria];
|
||||
ss_dassert(cmpfun);
|
||||
|
||||
@ -358,14 +319,14 @@ bool select_connect_backend_servers(int router_nservers,
|
||||
log_server_connections(select_criteria, backends);
|
||||
}
|
||||
|
||||
if (!master_connected)
|
||||
if (type == ALL)
|
||||
{
|
||||
/** Find a master server */
|
||||
for (SRWBackendList::const_iterator it = backends.begin(); it != backends.end(); it++)
|
||||
{
|
||||
const SRWBackend& backend = *it;
|
||||
|
||||
if (backend->can_connect() && master && backend->server() == master->server)
|
||||
if (backend->can_connect() && master && backend == master)
|
||||
{
|
||||
if (backend->connect(session))
|
||||
{
|
||||
@ -379,6 +340,7 @@ bool select_connect_backend_servers(int router_nservers,
|
||||
auto counts = get_slave_counts(backends, master);
|
||||
int slaves_found = counts.first;
|
||||
int slaves_connected = counts.second;
|
||||
int max_nslaves = inst->max_slave_count();
|
||||
|
||||
ss_dassert(slaves_connected < max_nslaves || max_nslaves == 0);
|
||||
|
||||
@ -387,27 +349,19 @@ bool select_connect_backend_servers(int router_nservers,
|
||||
backend && slaves_connected < max_nslaves;
|
||||
backend = get_slave_candidate(backends, master, cmpfun))
|
||||
{
|
||||
if (backend->can_connect() && backend->connect(session))
|
||||
if (backend->can_connect() && backend->connect(session, sescmd_list))
|
||||
{
|
||||
if (sescmd_list && sescmd_list->size())
|
||||
{
|
||||
backend->append_session_command(*sescmd_list);
|
||||
|
||||
if (backend->execute_session_command())
|
||||
{
|
||||
if (expected_responses)
|
||||
{
|
||||
(*expected_responses)++;
|
||||
}
|
||||
}
|
||||
|
||||
slaves_connected++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
slaves_connected++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (MXS_LOG_PRIORITY_IS_ENABLED(LOG_INFO))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user