MXS-1653: Fix hang on preparation of BEGIN

When a BEGIN statement is prepared using the binary protocol, it returns a
single OK packet. Due to a bug in the code that deals with multi-statement
results and EOF packets, the response was never sent to the client.

Also added back the error messages of failed session commands to the INFO
level. This way it's still possible to see why a session command fails but
the log isn't flooded by them in normal usage.
This commit is contained in:
Markus Mäkelä 2018-02-08 14:52:06 +02:00
parent 91f4372478
commit fa37198da1
No known key found for this signature in database
GPG Key ID: 72D48FCE664F7B19
2 changed files with 31 additions and 2 deletions

View File

@ -637,9 +637,11 @@ int modutil_count_signal_packets(GWBUF *reply, int n_found, bool* more_out, modu
bool skip_next = state ? state->state : false;
bool more = false;
bool only_ok = true;
uint64_t num_packets = 0;
while (offset < len)
{
num_packets++;
uint8_t header[MYSQL_HEADER_LEN + 5]; // Maximum size of an EOF packet
gwbuf_copy_data(reply, offset, MYSQL_HEADER_LEN + 1, header);
@ -720,7 +722,9 @@ int modutil_count_signal_packets(GWBUF *reply, int n_found, bool* more_out, modu
*more_out = more;
if (only_ok && !more)
// Treat complete multi-statement result sets that consist of only OK packets as a single result set
// TODO: Review this, it doesn't look very convincing.
if (only_ok && !more && num_packets > 1)
{
total = 2;
}

View File

@ -26,6 +26,26 @@
* Functions for session command handling
*/
static std::string extract_error(GWBUF* buffer)
{
std::string rval;
if (MYSQL_IS_ERROR_PACKET(((uint8_t *)GWBUF_DATA(buffer))))
{
size_t replylen = MYSQL_GET_PAYLOAD_LEN(GWBUF_DATA(buffer));
char replybuf[replylen];
gwbuf_copy_data(buffer, 0, gwbuf_length(buffer), (uint8_t*)replybuf);
std::string err;
std::string msg;
err.append(replybuf + 8, 5);
msg.append(replybuf + 13, replylen - 4 - 5);
rval = err + ": " + msg;
}
return rval;
}
/**
* Discards the slave connection if its response differs from the master's response
*
@ -88,7 +108,12 @@ void process_sescmd_response(RWSplitSession* rses, SRWBackend& backend,
* be compared to it */
rses->sescmd_responses[id] = cmd;
if (command == MXS_COM_STMT_PREPARE)
if (cmd == MYSQL_REPLY_ERR)
{
MXS_INFO("Session command no. %lu failed: %s",
id, extract_error(*ppPacket).c_str());
}
else if (command == MXS_COM_STMT_PREPARE)
{
/** Map the returned response to the internal ID */
MXS_INFO("PS ID %u maps to internal ID %lu", resp.id, id);