Track session state only when required
The protocol should not track the session state as the parsing is quite expensive with the current code. This change is a workaround that enables the parsing only when required. A proper way to handle this would be to do all the response processing in one place thus avoiding the duplication of work.
This commit is contained in:
@ -56,6 +56,7 @@ typedef enum
|
|||||||
GWBUF_TYPE_RESULT = (1 << 3),
|
GWBUF_TYPE_RESULT = (1 << 3),
|
||||||
GWBUF_TYPE_REPLY_OK = (1 << 4),
|
GWBUF_TYPE_REPLY_OK = (1 << 4),
|
||||||
GWBUF_TYPE_REPLAYED = (1 << 5),
|
GWBUF_TYPE_REPLAYED = (1 << 5),
|
||||||
|
GWBUF_TYPE_TRACK_STATE = (1 << 6),
|
||||||
} gwbuf_type_t;
|
} gwbuf_type_t;
|
||||||
|
|
||||||
#define GWBUF_IS_TYPE_UNDEFINED(b) ((b)->gwbuf_type == 0)
|
#define GWBUF_IS_TYPE_UNDEFINED(b) ((b)->gwbuf_type == 0)
|
||||||
@ -65,7 +66,10 @@ typedef enum
|
|||||||
#define GWBUF_IS_REPLY_OK(b) ((b)->gwbuf_type & GWBUF_TYPE_REPLY_OK)
|
#define GWBUF_IS_REPLY_OK(b) ((b)->gwbuf_type & GWBUF_TYPE_REPLY_OK)
|
||||||
|
|
||||||
// True if the query is not initiated by the client but an internal replaying mechanism
|
// True if the query is not initiated by the client but an internal replaying mechanism
|
||||||
#define GWBUF_IS_REPLAYED(b) ((b)->gwbuf_type & GWBUF_TYPE_REPLAYED)
|
#define GWBUF_IS_REPLAYED(b) ((b)->gwbuf_type & GWBUF_TYPE_REPLAYED)
|
||||||
|
|
||||||
|
// Track session state change response
|
||||||
|
#define GWBUF_SHOULD_TRACK_STATE(b) ((b)->gwbuf_type & GWBUF_TYPE_TRACK_STATE)
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
@ -338,6 +338,7 @@ typedef struct
|
|||||||
GWBUF* stored_query; /*< Temporarily stored queries */
|
GWBUF* stored_query; /*< Temporarily stored queries */
|
||||||
bool collect_result; /*< Collect the next result set as one buffer */
|
bool collect_result; /*< Collect the next result set as one buffer */
|
||||||
bool changing_user;
|
bool changing_user;
|
||||||
|
bool track_state; /*< Track session state */
|
||||||
uint32_t num_eof_packets; /*< Encountered eof packet number, used for check
|
uint32_t num_eof_packets; /*< Encountered eof packet number, used for check
|
||||||
* packet type */
|
* packet type */
|
||||||
bool large_query; /*< Whether to ignore the command byte of the next
|
bool large_query; /*< Whether to ignore the command byte of the next
|
||||||
|
@ -447,6 +447,8 @@ static inline void prepare_for_write(DCB* dcb, GWBUF* buffer)
|
|||||||
{
|
{
|
||||||
proto->collect_result = true;
|
proto->collect_result = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proto->track_state = GWBUF_SHOULD_TRACK_STATE(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -836,7 +838,8 @@ static int gw_read_and_write(DCB* dcb)
|
|||||||
* The OK packets sent in response to COM_STMT_PREPARE are of a different
|
* The OK packets sent in response to COM_STMT_PREPARE are of a different
|
||||||
* format so we need to detect and skip them. */
|
* format so we need to detect and skip them. */
|
||||||
if (rcap_type_required(capabilities, RCAP_TYPE_SESSION_STATE_TRACKING)
|
if (rcap_type_required(capabilities, RCAP_TYPE_SESSION_STATE_TRACKING)
|
||||||
&& !expecting_ps_response(proto))
|
&& !expecting_ps_response(proto)
|
||||||
|
&& proto->track_state)
|
||||||
{
|
{
|
||||||
mxs_mysql_get_session_track_info(tmp, proto);
|
mxs_mysql_get_session_track_info(tmp, proto);
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,7 @@ MySQLProtocol* mysql_protocol_init(DCB* dcb, int fd)
|
|||||||
p->changing_user = false;
|
p->changing_user = false;
|
||||||
p->num_eof_packets = 0;
|
p->num_eof_packets = 0;
|
||||||
p->large_query = false;
|
p->large_query = false;
|
||||||
|
p->track_state = false;
|
||||||
/*< Assign fd with protocol */
|
/*< Assign fd with protocol */
|
||||||
p->fd = fd;
|
p->fd = fd;
|
||||||
p->owner_dcb = dcb;
|
p->owner_dcb = dcb;
|
||||||
|
@ -280,6 +280,11 @@ bool RWSplitSession::route_single_stmt(GWBUF* querybuf)
|
|||||||
}
|
}
|
||||||
else if (TARGET_IS_MASTER(route_target))
|
else if (TARGET_IS_MASTER(route_target))
|
||||||
{
|
{
|
||||||
|
if (m_config.causal_reads)
|
||||||
|
{
|
||||||
|
gwbuf_set_type(querybuf, GWBUF_TYPE_TRACK_STATE);
|
||||||
|
}
|
||||||
|
|
||||||
succp = handle_master_is_target(&target);
|
succp = handle_master_is_target(&target);
|
||||||
|
|
||||||
if (!succp && should_migrate_trx(target))
|
if (!succp && should_migrate_trx(target))
|
||||||
|
Reference in New Issue
Block a user