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.
This commit is contained in:
Markus Mäkelä 2017-10-08 23:15:18 +03:00 committed by Johan Wikman
parent 5c9b953d69
commit 489520a5c0

View File

@ -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