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:
Markus Mäkelä 2019-03-05 12:24:15 +02:00
parent b97976c4ee
commit 5b43940559
No known key found for this signature in database
GPG Key ID: 72D48FCE664F7B19
5 changed files with 16 additions and 2 deletions

View File

@ -56,6 +56,7 @@ typedef enum
GWBUF_TYPE_RESULT = (1 << 3),
GWBUF_TYPE_REPLY_OK = (1 << 4),
GWBUF_TYPE_REPLAYED = (1 << 5),
GWBUF_TYPE_TRACK_STATE = (1 << 6),
} gwbuf_type_t;
#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)
// 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
{

View File

@ -338,6 +338,7 @@ typedef struct
GWBUF* stored_query; /*< Temporarily stored queries */
bool collect_result; /*< Collect the next result set as one buffer */
bool changing_user;
bool track_state; /*< Track session state */
uint32_t num_eof_packets; /*< Encountered eof packet number, used for check
* packet type */
bool large_query; /*< Whether to ignore the command byte of the next

View File

@ -447,6 +447,8 @@ static inline void prepare_for_write(DCB* dcb, GWBUF* buffer)
{
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
* format so we need to detect and skip them. */
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);
}

View File

@ -63,6 +63,7 @@ MySQLProtocol* mysql_protocol_init(DCB* dcb, int fd)
p->changing_user = false;
p->num_eof_packets = 0;
p->large_query = false;
p->track_state = false;
/*< Assign fd with protocol */
p->fd = fd;
p->owner_dcb = dcb;

View File

@ -280,6 +280,11 @@ bool RWSplitSession::route_single_stmt(GWBUF* querybuf)
}
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);
if (!succp && should_migrate_trx(target))