From c5ff130b33f157260cae926d04417464351747fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Sun, 8 Oct 2017 23:15:18 +0300 Subject: [PATCH] Process backend packets only once When the router requires statement based output, the gathering of complete packets can be skipped as the process of splitting the complete packets into individual packets implies that only complete packets are handled. Also added a quicker check for stored protocol commands than a call to protocol_get_srv_command. --- .../MySQL/MySQLBackend/mysql_backend.c | 98 ++++++++++--------- 1 file changed, 53 insertions(+), 45 deletions(-) diff --git a/server/modules/protocol/MySQL/MySQLBackend/mysql_backend.c b/server/modules/protocol/MySQL/MySQLBackend/mysql_backend.c index 83fd4bcd7..d4f332fe3 100644 --- a/server/modules/protocol/MySQL/MySQLBackend/mysql_backend.c +++ b/server/modules/protocol/MySQL/MySQLBackend/mysql_backend.c @@ -745,7 +745,8 @@ gw_read_and_write(DCB *dcb) bool result_collected = false; MySQLProtocol *proto = (MySQLProtocol *)dcb->protocol; - if (rcap_type_required(capabilities, RCAP_TYPE_STMT_OUTPUT) || (proto->ignore_replies != 0)) + if (rcap_type_required(capabilities, RCAP_TYPE_CONTIGUOUS_OUTPUT) || + proto->collect_result || proto->ignore_replies != 0) { GWBUF *tmp = modutil_get_complete_packets(&read_buffer); /* Put any residue into the read queue */ @@ -760,53 +761,48 @@ gw_read_and_write(DCB *dcb) read_buffer = tmp; - if (rcap_type_required(capabilities, RCAP_TYPE_CONTIGUOUS_OUTPUT) || - proto->collect_result || - proto->ignore_replies != 0) + if ((tmp = gwbuf_make_contiguous(read_buffer))) { - if ((tmp = gwbuf_make_contiguous(read_buffer))) - { - read_buffer = tmp; - } - else - { - /** Failed to make the buffer contiguous */ - gwbuf_free(read_buffer); - poll_fake_hangup_event(dcb); - return 0; - } + read_buffer = tmp; + } + else + { + /** Failed to make the buffer contiguous */ + gwbuf_free(read_buffer); + poll_fake_hangup_event(dcb); + return 0; + } - if (collecting_resultset(proto, capabilities)) + if (collecting_resultset(proto, capabilities)) + { + if (expecting_resultset(proto)) { - if (expecting_resultset(proto)) + if (mxs_mysql_is_result_set(read_buffer)) { - if (mxs_mysql_is_result_set(read_buffer)) - { - bool more = false; - if (modutil_count_signal_packets(read_buffer, 0, &more, NULL) != 2) - { - dcb_readq_prepend(dcb, read_buffer); - return 0; - } - } - - // Collected the complete result - proto->collect_result = false; - result_collected = true; - } - else if (expecting_ps_response(proto) && - mxs_mysql_is_prep_stmt_ok(read_buffer)) - { - if (!complete_ps_response(read_buffer)) + bool more = false; + if (modutil_count_signal_packets(read_buffer, 0, &more, NULL) != 2) { dcb_readq_prepend(dcb, read_buffer); return 0; } - - // Collected the complete result - proto->collect_result = false; - result_collected = true; } + + // Collected the complete result + proto->collect_result = false; + result_collected = true; + } + else if (expecting_ps_response(proto) && + mxs_mysql_is_prep_stmt_ok(read_buffer)) + { + if (!complete_ps_response(read_buffer)) + { + dcb_readq_prepend(dcb, read_buffer); + return 0; + } + + // Collected the complete result + proto->collect_result = false; + result_collected = true; } } } @@ -909,7 +905,8 @@ gw_read_and_write(DCB *dcb) * If protocol has session command set, concatenate whole * response into one buffer. */ - if (protocol_get_srv_command((MySQLProtocol *)dcb->protocol, true) != MXS_COM_UNDEFINED) + if (proto->protocol_command.scom_cmd != MXS_COM_UNDEFINED && + protocol_get_srv_command(proto, true) != MXS_COM_UNDEFINED) { if (result_collected) { @@ -943,12 +940,23 @@ gw_read_and_write(DCB *dcb) !rcap_type_required(capabilities, RCAP_TYPE_RESULTSET_OUTPUT) && !result_collected) { - stmt = modutil_get_next_MySQL_packet(&read_buffer); - - if (!GWBUF_IS_CONTIGUOUS(stmt)) + if ((stmt = modutil_get_next_MySQL_packet(&read_buffer))) { - // Make sure the buffer is contiguous - stmt = gwbuf_make_contiguous(stmt); + if (!GWBUF_IS_CONTIGUOUS(stmt)) + { + // Make sure the buffer is contiguous + stmt = gwbuf_make_contiguous(stmt); + } + } + else + { + // All complete packets are processed, store partial packets for later use + if (read_buffer) + { + dcb_readq_prepend(dcb, read_buffer); + } + + return return_code; } } else