MXS-1203: Fix current command tracking with statement routing
When statement based routing was used, it was possible that the current statement being executed wasn't properly updated. Readwritesplit requires it to track whether a command will create a response.
This commit is contained in:
@ -1399,6 +1399,10 @@ static int route_by_statement(MXS_SESSION* session, uint64_t capabilities, GWBUF
|
|||||||
if (packetbuf != NULL)
|
if (packetbuf != NULL)
|
||||||
{
|
{
|
||||||
CHK_GWBUF(packetbuf);
|
CHK_GWBUF(packetbuf);
|
||||||
|
|
||||||
|
MySQLProtocol* proto = session->client_dcb->protocol;
|
||||||
|
proto->current_command = (mysql_server_cmd_t)GWBUF_DATA(packetbuf)[4];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This means that buffer includes exactly one MySQL
|
* This means that buffer includes exactly one MySQL
|
||||||
* statement.
|
* statement.
|
||||||
|
@ -1230,6 +1230,13 @@ bool handle_master_is_target(ROUTER_INSTANCE *inst, ROUTER_CLIENT_SES *rses,
|
|||||||
return succp;
|
return succp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool query_creates_reply(mysql_server_cmd_t cmd)
|
||||||
|
{
|
||||||
|
return cmd != MYSQL_COM_QUIT &&
|
||||||
|
cmd != MYSQL_COM_STMT_SEND_LONG_DATA &&
|
||||||
|
cmd != MYSQL_COM_STMT_CLOSE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Handle got a target
|
* @brief Handle got a target
|
||||||
*
|
*
|
||||||
@ -1279,22 +1286,26 @@ handle_got_target(ROUTER_INSTANCE *inst, ROUTER_CLIENT_SES *rses,
|
|||||||
MXS_ERROR("Failed to store current statement, it won't be retried if it fails.");
|
MXS_ERROR("Failed to store current statement, it won't be retried if it fails.");
|
||||||
}
|
}
|
||||||
|
|
||||||
backend_ref_t *bref;
|
|
||||||
|
|
||||||
atomic_add_uint64(&inst->stats.n_queries, 1);
|
atomic_add_uint64(&inst->stats.n_queries, 1);
|
||||||
/**
|
|
||||||
* Add one query response waiter to backend reference
|
|
||||||
*/
|
|
||||||
bref = get_bref_from_dcb(rses, target_dcb);
|
|
||||||
bref_set_state(bref, BREF_QUERY_ACTIVE);
|
|
||||||
bref_set_state(bref, BREF_WAITING_RESULT);
|
|
||||||
|
|
||||||
ss_dassert(bref->reply_state == REPLY_STATE_DONE);
|
mysql_server_cmd_t cmd = mxs_mysql_current_command(rses->client_dcb->session);
|
||||||
LOG_RS(bref, REPLY_STATE_START);
|
|
||||||
bref->reply_state = REPLY_STATE_START;
|
if (query_creates_reply(cmd))
|
||||||
rses->expected_responses++;
|
{
|
||||||
|
/** The server will reply to this command */
|
||||||
|
ss_dassert(bref->reply_state == REPLY_STATE_DONE);
|
||||||
|
|
||||||
|
bref = get_bref_from_dcb(rses, target_dcb);
|
||||||
|
bref_set_state(bref, BREF_QUERY_ACTIVE);
|
||||||
|
bref_set_state(bref, BREF_WAITING_RESULT);
|
||||||
|
|
||||||
|
LOG_RS(bref, REPLY_STATE_START);
|
||||||
|
bref->reply_state = REPLY_STATE_START;
|
||||||
|
rses->expected_responses++;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If a READ ONLYtransaction is ending set forced_node to NULL
|
* If a READ ONLY transaction is ending set forced_node to NULL
|
||||||
*/
|
*/
|
||||||
if (rses->forced_node &&
|
if (rses->forced_node &&
|
||||||
session_trx_is_read_only(rses->client_dcb->session) &&
|
session_trx_is_read_only(rses->client_dcb->session) &&
|
||||||
|
Reference in New Issue
Block a user