Pick servers that can be connected to as candidates

Only servers that qualify to be connected should be considered as
candidate servers. This triggered a debug assertion when a slave server
failed to execute a session command but it was chosen as a candidate
server later on.
This commit is contained in:
Markus Mäkelä
2018-04-10 16:04:52 +03:00
parent b34e0000b4
commit dc3c848df8
2 changed files with 32 additions and 39 deletions

View File

@ -99,28 +99,11 @@ bool RWSplitSession::prepare_target(SRWBackend& target, route_target_t route_tar
bool rval = true; bool rval = true;
// Check if we need to connect to the server in order to use it // Check if we need to connect to the server in order to use it
if (!target->in_use() && target->can_connect()) if (!target->in_use())
{ {
if (TARGET_IS_SLAVE(route_target) || ss_dassert(target->can_connect() && can_recover_servers());
(m_config.master_reconnection && TARGET_IS_MASTER(route_target))) ss_dassert(!TARGET_IS_MASTER(route_target) || m_config.master_reconnection);
{ rval = target->connect(m_client->session, &m_sescmd_list);
if ((!m_config.disable_sescmd_history || m_recv_sescmd == 0))
{
rval = target->connect(m_client->session, &m_sescmd_list);
}
else
{
MXS_ERROR("Cannot reconnect to server '%s', session command"
" history is disabled (session has executed"
" %lu session commands).", target->name(), m_recv_sescmd);
}
}
else if (TARGET_IS_MASTER(route_target))
{
MXS_ERROR("The connection to the master was lost and the connection "
"could be recreated but 'master_reconnection' is not enabled.");
rval = false;
}
} }
return rval; return rval;
@ -454,7 +437,8 @@ SRWBackend RWSplitSession::get_hinted_backend(char *name)
auto& backend = *it; auto& backend = *it;
/** The server must be a valid slave, relay server, or master */ /** The server must be a valid slave, relay server, or master */
if (backend->in_use() && strcasecmp(name, backend->name()) == 0 && if ((backend->in_use() || (can_recover_servers() && backend->can_connect())) &&
strcasecmp(name, backend->name()) == 0 &&
(backend->is_slave() || backend->is_relay() || backend->is_master())) (backend->is_slave() || backend->is_relay() || backend->is_master()))
{ {
rval = backend; rval = backend;
@ -477,26 +461,29 @@ SRWBackend RWSplitSession::get_slave_backend(int max_rlag)
if ((backend->is_master() || backend->is_slave()) && // Either a master or a slave if ((backend->is_master() || backend->is_slave()) && // Either a master or a slave
rpl_lag_is_ok(backend, max_rlag)) // Not lagging too much rpl_lag_is_ok(backend, max_rlag)) // Not lagging too much
{ {
if (!rval) if (backend->in_use() || (can_recover_servers() && backend->can_connect()))
{ {
// No previous candidate, accept any valid server (includes master) if (!rval)
if ((backend->is_master() && backend == m_current_master) ||
backend->is_slave())
{ {
rval = backend; // No previous candidate, accept any valid server (includes master)
if ((backend->is_master() && backend == m_current_master) ||
backend->is_slave())
{
rval = backend;
}
} }
} else if (backend->in_use() || counts.second < m_router->max_slave_count())
else if (backend->in_use() || counts.second < m_router->max_slave_count())
{
if (!m_config.master_accept_reads && rval->is_master())
{ {
// Pick slaves over masters with master_accept_reads=false if (!m_config.master_accept_reads && rval->is_master())
rval = backend; {
} // Pick slaves over masters with master_accept_reads=false
else rval = backend;
{ }
// Compare the two servers and pick the best one else
rval = compare_backends(rval, backend, m_config.slave_selection_criteria); {
// Compare the two servers and pick the best one
rval = compare_backends(rval, backend, m_config.slave_selection_criteria);
}
} }
} }
} }
@ -513,7 +500,7 @@ SRWBackend RWSplitSession::get_master_backend()
if (master) if (master)
{ {
if (master->in_use() || master->can_connect()) if (master->in_use() || (m_config.master_reconnection && master->can_connect()))
{ {
if (master->is_master()) if (master->is_master())
{ {
@ -925,6 +912,7 @@ GWBUF* RWSplitSession::add_prefix_wait_gtid(SERVER *server, GWBUF *origin)
*/ */
bool RWSplitSession::handle_got_target(GWBUF* querybuf, SRWBackend& target, bool store) bool RWSplitSession::handle_got_target(GWBUF* querybuf, SRWBackend& target, bool store)
{ {
ss_dassert(target->in_use());
/** /**
* If the transaction is READ ONLY set forced_node to this backend. * If the transaction is READ ONLY set forced_node to this backend.
* This SLAVE backend will be used until the COMMIT is seen. * This SLAVE backend will be used until the COMMIT is seen.

View File

@ -202,6 +202,11 @@ private:
m_retry_duration < m_config.delayed_retry_timeout && m_retry_duration < m_config.delayed_retry_timeout &&
!session_trx_is_active(m_client->session); !session_trx_is_active(m_client->session);
} }
inline bool can_recover_servers() const
{
return !m_config.disable_sescmd_history || m_recv_sescmd == 0;
}
}; };
/** /**