diff --git a/include/maxscale/buffer.h b/include/maxscale/buffer.h index 3dafdb0b9..63dc2ce10 100644 --- a/include/maxscale/buffer.h +++ b/include/maxscale/buffer.h @@ -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 { diff --git a/include/maxscale/protocol/mysql.h b/include/maxscale/protocol/mysql.h index 9c8ff0783..cc506a949 100644 --- a/include/maxscale/protocol/mysql.h +++ b/include/maxscale/protocol/mysql.h @@ -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 diff --git a/server/modules/protocol/MySQL/mariadbbackend/mysql_backend.cc b/server/modules/protocol/MySQL/mariadbbackend/mysql_backend.cc index 30fc9eeab..2236f7da8 100644 --- a/server/modules/protocol/MySQL/mariadbbackend/mysql_backend.cc +++ b/server/modules/protocol/MySQL/mariadbbackend/mysql_backend.cc @@ -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); } diff --git a/server/modules/protocol/MySQL/mysql_common.cc b/server/modules/protocol/MySQL/mysql_common.cc index cdb8fd1e1..c575304f4 100644 --- a/server/modules/protocol/MySQL/mysql_common.cc +++ b/server/modules/protocol/MySQL/mysql_common.cc @@ -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; diff --git a/server/modules/routing/readwritesplit/rwsplit_route_stmt.cc b/server/modules/routing/readwritesplit/rwsplit_route_stmt.cc index 4f24c7e70..05e94e66f 100644 --- a/server/modules/routing/readwritesplit/rwsplit_route_stmt.cc +++ b/server/modules/routing/readwritesplit/rwsplit_route_stmt.cc @@ -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))