From 866a15dafaea909a5c8d61d6480a00443da0c478 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Tue, 29 Aug 2017 11:15:06 +0300 Subject: [PATCH] Skip COM_CHANGE_USER for COM_QUIT As COM_QUIT would terminate the connection, there's no need to initiate the session reset process. Also make sure all buffers are empty before putting the DCB into the pool. Added extra debug assertions for parts of the code that are related to the COM_CHANGE_USER processing. --- server/core/dcb.c | 10 +++++++++ .../MySQL/MySQLBackend/mysql_backend.c | 21 +++++++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index 81182ab3b..83737a300 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -1698,6 +1698,16 @@ dcb_maybe_add_persistent(DCB *dcb) MXS_FREE(loopcallback); } + /** Free all buffered data */ + gwbuf_free(dcb->dcb_fakequeue); + gwbuf_free(dcb->dcb_readqueue); + gwbuf_free(dcb->delayq); + gwbuf_free(dcb->writeq); + dcb->dcb_fakequeue = NULL; + dcb->dcb_readqueue = NULL; + dcb->delayq = NULL; + dcb->writeq = NULL; + dcb->nextpersistent = dcb->server->persistent[dcb->thread.id]; dcb->server->persistent[dcb->thread.id] = dcb; atomic_add(&dcb->server->stats.n_persistent, 1); diff --git a/server/modules/protocol/MySQL/MySQLBackend/mysql_backend.c b/server/modules/protocol/MySQL/MySQLBackend/mysql_backend.c index cba370813..b0a68cd03 100644 --- a/server/modules/protocol/MySQL/MySQLBackend/mysql_backend.c +++ b/server/modules/protocol/MySQL/MySQLBackend/mysql_backend.c @@ -752,6 +752,7 @@ gw_read_and_write(DCB *dcb) else { MXS_ERROR("Unknown response to COM_CHANGE_USER: 0x%02hhx", result); + ss_dassert(false); } gwbuf_free(query); poll_fake_hangup_event(dcb); @@ -899,8 +900,13 @@ static int gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue) if (dcb->was_persistent && dcb->state == DCB_STATE_POLLING && backend_protocol->protocol_auth_state == MXS_AUTH_STATE_COMPLETE) { + ss_dassert(!dcb->dcb_fakequeue); + ss_dassert(!dcb->dcb_readqueue); + ss_dassert(!dcb->delayq); + ss_dassert(!dcb->writeq); ss_dassert(dcb->persistentstart == 0); - ss_dassert(!MYSQL_IS_COM_QUIT(GWBUF_DATA(queue))); + dcb->was_persistent = false; + /** * This is a DCB that was just taken out of the persistent connection pool. * We need to sent a COM_CHANGE_USER query to the backend to reset the @@ -912,7 +918,16 @@ static int gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue) * response is received. */ gwbuf_free(backend_protocol->stored_query); } - dcb->was_persistent = false; + + if (MYSQL_IS_COM_QUIT(GWBUF_DATA(queue))) + { + /** The connection is being closed before the first write to this + * backend was done. The COM_QUIT is ignored and the DCB is put + * into the pool once iẗ́'s closed. */ + gwbuf_free(queue); + return 1; + } + backend_protocol->ignore_reply = true; backend_protocol->stored_query = queue; @@ -1314,6 +1329,8 @@ static void backend_set_delayqueue(DCB *dcb, GWBUF *queue) static int backend_write_delayqueue(DCB *dcb, GWBUF *buffer) { ss_dassert(buffer); + ss_dassert(dcb->persistentstart == 0); + ss_dassert(!dcb->was_persistent); if (MYSQL_IS_CHANGE_USER(((uint8_t *)GWBUF_DATA(buffer)))) {