Fix slave reconnection logic

Allowing calls to select_connect_backend_servers even when all slaves are
connected solves the debug assertion in select_connect_backend_servers
that happens when the execution of a queued query causes a new connection
to be created.
This commit is contained in:
Markus Mäkelä
2018-06-13 12:44:09 +03:00
parent 3ed6411741
commit 2005164222
4 changed files with 27 additions and 13 deletions

View File

@ -19,7 +19,7 @@ bool query(TestConnections& test)
sleep(5); sleep(5);
Row row = get_row(test.maxscales->conn_rwsplit[0], "SELECT @a"); Row row = get_row(test.maxscales->conn_rwsplit[0], "SELECT @a");
test.maxscales->disconnect(); test.maxscales->disconnect();
return row[0] == "1"; return !row.empty() && row[0] == "1";
} }
void block(TestConnections& test, std::vector<int> nodes) void block(TestConnections& test, std::vector<int> nodes)

View File

@ -179,6 +179,7 @@ void Backend::set_state(backend_state state)
bool Backend::connect(MXS_SESSION* session, SessionCommandList* sescmd) bool Backend::connect(MXS_SESSION* session, SessionCommandList* sescmd)
{ {
ss_dassert(!in_use());
bool rval = false; bool rval = false;
if ((m_dcb = dcb_connect(m_backend->server, session, m_backend->server->protocol))) if ((m_dcb = dcb_connect(m_backend->server, session, m_backend->server->protocol)))

View File

@ -343,8 +343,10 @@ bool RWSplit::select_connect_backend_servers(MXS_SESSION *session,
int slaves_connected = counts.second; int slaves_connected = counts.second;
int max_nslaves = max_slave_count(); int max_nslaves = max_slave_count();
ss_dassert(slaves_connected < max_nslaves || max_nslaves == 0); ss_dassert(slaves_connected <= max_nslaves || max_nslaves == 0);
if (slaves_connected < max_nslaves)
{
/** Connect to all possible slaves */ /** Connect to all possible slaves */
for (SRWBackend backend(get_slave_candidate(backends, master, cmpfun)); for (SRWBackend backend(get_slave_candidate(backends, master, cmpfun));
backend && slaves_connected < max_nslaves; backend && slaves_connected < max_nslaves;
@ -362,6 +364,15 @@ bool RWSplit::select_connect_backend_servers(MXS_SESSION *session,
slaves_connected++; slaves_connected++;
} }
} }
}
else
{
/**
* We are already connected to all possible slaves. Currently this can
* only happen if this function is called by handle_error_new_connection
* and the routing of queued queries created new connections.
*/
}
return true; return true;
} }

View File

@ -681,6 +681,7 @@ void RWSplitSession::handleError(GWBUF *errmsgbuf, DCB *problem_dcb,
if (m_current_master && m_current_master->in_use() && m_current_master == backend) if (m_current_master && m_current_master->in_use() && m_current_master == backend)
{ {
MXS_INFO("Master '%s' failed", backend->name());
/** The connection to the master has failed */ /** The connection to the master has failed */
if (!backend->is_waiting_result()) if (!backend->is_waiting_result())
@ -739,6 +740,7 @@ void RWSplitSession::handleError(GWBUF *errmsgbuf, DCB *problem_dcb,
} }
else else
{ {
MXS_INFO("Slave '%s' failed", backend->name());
if (m_target_node && m_target_node == backend && if (m_target_node && m_target_node == backend &&
session_trx_is_read_only(problem_dcb->session)) session_trx_is_read_only(problem_dcb->session))
{ {