From 1f166482b258f333f5982310413ccd463ebe0046 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Sat, 16 Jun 2018 17:24:44 +0300 Subject: [PATCH] Fix slave reconnection regression The state of the backend needs to be checked before any pending session commands are executed on it. Added debug assertions to catch invalid use of the status functions of closed backends. --- include/maxscale/backend.hh | 1 + .../modules/routing/readwritesplit/rwsplit_route_stmt.cc | 4 ++-- server/modules/routing/readwritesplit/rwsplitsession.cc | 8 ++++++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/include/maxscale/backend.hh b/include/maxscale/backend.hh index 7bb035268..cb4bb650f 100644 --- a/include/maxscale/backend.hh +++ b/include/maxscale/backend.hh @@ -100,6 +100,7 @@ public: */ inline bool has_session_commands() const { + ss_dassert(in_use()); return !m_session_commands.empty(); } diff --git a/server/modules/routing/readwritesplit/rwsplit_route_stmt.cc b/server/modules/routing/readwritesplit/rwsplit_route_stmt.cc index d5d741ee5..91eaf40bc 100644 --- a/server/modules/routing/readwritesplit/rwsplit_route_stmt.cc +++ b/server/modules/routing/readwritesplit/rwsplit_route_stmt.cc @@ -64,8 +64,8 @@ static SRWBackend compare_backends(SRWBackend a, SRWBackend b, select_criteria_t } // Prefer servers that are not busy executing session commands - bool a_busy = a->has_session_commands(); - bool b_busy = b->has_session_commands(); + bool a_busy = a->in_use() && a->has_session_commands(); + bool b_busy = b->in_use() && b->has_session_commands(); if (a_busy && !b_busy) { diff --git a/server/modules/routing/readwritesplit/rwsplitsession.cc b/server/modules/routing/readwritesplit/rwsplitsession.cc index 7057f736a..4a2d55658 100644 --- a/server/modules/routing/readwritesplit/rwsplitsession.cc +++ b/server/modules/routing/readwritesplit/rwsplitsession.cc @@ -547,12 +547,14 @@ void RWSplitSession::clientReply(GWBUF *writebuf, DCB *backend_dcb) if (backend->has_session_commands()) { - /** Reply to an executed session command */ + /** Process the reply to an executed session command. This function can + * close the backend if it's a slave. */ process_sescmd_response(backend, &writebuf); } - if (backend->has_session_commands()) + if (backend->in_use() && backend->has_session_commands()) { + // Backend is still in use and has more session commands to execute if (backend->execute_session_command() && backend->is_waiting_result()) { m_expected_responses++; @@ -560,12 +562,14 @@ void RWSplitSession::clientReply(GWBUF *writebuf, DCB *backend_dcb) } else if (m_expected_responses == 0 && m_query_queue) { + // All replies received, route any stored queries route_stored_query(); } if (writebuf) { ss_dassert(client_dcb); + ss_info_dassert(backend->in_use(), "Backend should be in use when routing reply"); /** Write reply to client DCB */ MXS_SESSION_ROUTE_REPLY(backend_dcb->session, writebuf); }