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
No known key found for this signature in database
GPG Key ID: 72D48FCE664F7B19
4 changed files with 27 additions and 13 deletions

View File

@ -19,7 +19,7 @@ bool query(TestConnections& test)
sleep(5);
Row row = get_row(test.maxscales->conn_rwsplit[0], "SELECT @a");
test.maxscales->disconnect();
return row[0] == "1";
return !row.empty() && row[0] == "1";
}
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)
{
ss_dassert(!in_use());
bool rval = false;
if ((m_dcb = dcb_connect(m_backend->server, session, m_backend->server->protocol)))

View File

@ -343,25 +343,36 @@ bool RWSplit::select_connect_backend_servers(MXS_SESSION *session,
int slaves_connected = counts.second;
int max_nslaves = max_slave_count();
ss_dassert(slaves_connected < max_nslaves || max_nslaves == 0);
ss_dassert(slaves_connected <= max_nslaves || max_nslaves == 0);
/** Connect to all possible slaves */
for (SRWBackend backend(get_slave_candidate(backends, master, cmpfun));
backend && slaves_connected < max_nslaves;
backend = get_slave_candidate(backends, master, cmpfun))
if (slaves_connected < max_nslaves)
{
if (backend->can_connect() && backend->connect(session, sescmd_list))
/** Connect to all possible slaves */
for (SRWBackend backend(get_slave_candidate(backends, master, cmpfun));
backend && slaves_connected < max_nslaves;
backend = get_slave_candidate(backends, master, cmpfun))
{
MXS_INFO("Selected Slave: %s", backend->name());
if (sescmd_list && sescmd_list->size() && expected_responses)
if (backend->can_connect() && backend->connect(session, sescmd_list))
{
(*expected_responses)++;
}
MXS_INFO("Selected Slave: %s", backend->name());
slaves_connected++;
if (sescmd_list && sescmd_list->size() && expected_responses)
{
(*expected_responses)++;
}
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;
}

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