MXS-1047: Fix batch insert execution

Doing batch inserts though readwritesplit would stall due to the fact that
pending session commands were stored instead of executed immediately.

Session command responses that weren't complete also discarded the partial
event instead of storing it for later use.
This commit is contained in:
Markus Makela
2016-12-08 14:23:48 +02:00
parent 0e50ecb525
commit 570e12942b
2 changed files with 11 additions and 20 deletions

View File

@ -848,6 +848,8 @@ gw_read_and_write(DCB *dcb)
*/ */
if (!sescmd_response_complete(dcb)) if (!sescmd_response_complete(dcb))
{ {
stmt = gwbuf_append(stmt, read_buffer);
dcb->dcb_readqueue = gwbuf_append(stmt, dcb->dcb_readqueue);
return 0; return 0;
} }

View File

@ -383,11 +383,11 @@ bool route_session_write(ROUTER_CLIENT_SES *router_cli_ses,
bref_set_state(get_bref_from_dcb(router_cli_ses, backend_ref[i].bref_dcb), bref_set_state(get_bref_from_dcb(router_cli_ses, backend_ref[i].bref_dcb),
BREF_WAITING_RESULT); BREF_WAITING_RESULT);
/** /**
* Start execution if cursor is not already executing. * Start execution if cursor is not already executing or this is the
* Otherwise, cursor will execute pending commands * master server. Otherwise, cursor will execute pending commands
* when it completes with previous commands. * when it completes the previous command.
*/ */
if (sescmd_cursor_is_active(scur)) if (sescmd_cursor_is_active(scur) && &backend_ref[i] != router_cli_ses->rses_master_ref)
{ {
nsucc += 1; nsucc += 1;
MXS_INFO("Backend %s:%d already executing sescmd.", MXS_INFO("Backend %s:%d already executing sescmd.",
@ -1242,24 +1242,13 @@ handle_got_target(ROUTER_INSTANCE *inst, ROUTER_CLIENT_SES *rses,
(SERVER_IS_MASTER(bref->ref->server) ? "master" (SERVER_IS_MASTER(bref->ref->server) ? "master"
: "slave"), bref->ref->server->name, bref->ref->server->port); : "slave"), bref->ref->server->name, bref->ref->server->port);
/** /**
* Store current stmt if execution of previous session command * Store current statement if execution of previous session command is still
* haven't completed yet. * active. Since the master server's response is always used, we can safely
* * write session commands to the master even if it is already executing.
* !!! Note that according to MySQL protocol
* there can only be one such non-sescmd stmt at the time.
* It is possible that bref->bref_pending_cmd includes a pending
* command if rwsplit is parent or child for another router,
* which runs all the same commands.
*
* If the assertion below traps, pending queries are treated
* somehow wrong, or client is sending more queries before
* previous is received.
*/ */
if (sescmd_cursor_is_active(scur)) if (sescmd_cursor_is_active(scur) && bref != rses->rses_master_ref)
{ {
ss_dassert(bref->bref_pending_cmd == NULL); bref->bref_pending_cmd = gwbuf_append(bref->bref_pending_cmd, gwbuf_clone(querybuf));
bref->bref_pending_cmd = gwbuf_clone(querybuf);
return true; return true;
} }