From 7f0745e552ed7e9dea227bc4acfcfdf4a8acafbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Wed, 28 Mar 2018 16:26:46 +0300 Subject: [PATCH] MXS-1503: Queue command if executing a session command When a non-connected target is chosed as the target server and the session command history is not empty, the query needs to be placed into the query queue and routed only after the session commands have been executed. --- .../routing/readwritesplit/readwritesplit.cc | 23 +++++--------- .../readwritesplit/rwsplit_route_stmt.cc | 31 ++++++++++++------- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/server/modules/routing/readwritesplit/readwritesplit.cc b/server/modules/routing/readwritesplit/readwritesplit.cc index 9c8e88ca5..c3553dc86 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.cc +++ b/server/modules/routing/readwritesplit/readwritesplit.cc @@ -1272,11 +1272,15 @@ static void clientReply(MXS_ROUTER *instance, process_sescmd_response(rses, backend, &writebuf); } - bool queue_routed = false; - - if (rses->expected_responses == 0 && rses->query_queue) + if (backend->session_command_count()) + { + if (backend->execute_session_command()) + { + rses->expected_responses++; + } + } + else if (rses->expected_responses == 0 && rses->query_queue) { - queue_routed = true; route_stored_query(rses); } @@ -1286,17 +1290,6 @@ static void clientReply(MXS_ROUTER *instance, /** Write reply to client DCB */ MXS_SESSION_ROUTE_REPLY(backend_dcb->session, writebuf); } - /** Check pending session commands */ - else if (!queue_routed && backend->session_command_count()) - { - MXS_DEBUG("Backend %s processed reply and starts to execute active cursor.", - backend->uri()); - - if (backend->execute_session_command()) - { - rses->expected_responses++; - } - } } diff --git a/server/modules/routing/readwritesplit/rwsplit_route_stmt.cc b/server/modules/routing/readwritesplit/rwsplit_route_stmt.cc index 1ab2cbcf3..e10f79cab 100644 --- a/server/modules/routing/readwritesplit/rwsplit_route_stmt.cc +++ b/server/modules/routing/readwritesplit/rwsplit_route_stmt.cc @@ -211,18 +211,27 @@ bool route_single_stmt(RWSplit *inst, RWSplitSession *rses, GWBUF *querybuf, con if (succp && target && prepare_target(rses, target, route_target)) { - // Target server was found and is in the correct state - ss_dassert(!store_stmt || TARGET_IS_SLAVE(route_target)); - succp = handle_got_target(inst, rses, querybuf, target, store_stmt); - - if (succp && command == MXS_COM_STMT_EXECUTE && not_locked_to_master) + if (target->session_command_count()) { - /** Track the targets of the COM_STMT_EXECUTE statements. This - * information is used to route all COM_STMT_FETCH commands - * to the same server where the COM_STMT_EXECUTE was done. */ - ss_dassert(stmt_id > 0); - rses->exec_map[stmt_id] = target; - MXS_INFO("COM_STMT_EXECUTE on %s", target->uri()); + // We need to wait until the session commands are executed + rses->expected_responses++; + rses->query_queue = gwbuf_append(rses->query_queue, gwbuf_clone(querybuf)); + } + else + { + // Target server was found and is in the correct state + ss_dassert(!store_stmt || TARGET_IS_SLAVE(route_target)); + succp = handle_got_target(inst, rses, querybuf, target, store_stmt); + + if (succp && command == MXS_COM_STMT_EXECUTE && not_locked_to_master) + { + /** Track the targets of the COM_STMT_EXECUTE statements. This + * information is used to route all COM_STMT_FETCH commands + * to the same server where the COM_STMT_EXECUTE was done. */ + ss_dassert(stmt_id > 0); + rses->exec_map[stmt_id] = target; + MXS_INFO("COM_STMT_EXECUTE on %s", target->uri()); + } } } else