refactor, check every packet before parser ok packet, move config to service, fix code style, ...

This commit is contained in:
Dapeng Huang
2018-01-15 20:25:44 +08:00
parent e1aeac8b07
commit d234b13027
17 changed files with 76 additions and 69 deletions

View File

@ -755,6 +755,9 @@ gw_read_and_write(DCB *dcb)
bool result_collected = false;
MySQLProtocol *proto = (MySQLProtocol *)dcb->protocol;
/** Get sesion track info from ok packet and save it to gwbuf properties */
mxs_mysql_get_session_track_info(read_buffer, proto->server_capabilities);
if (rcap_type_required(capabilities, RCAP_TYPE_PACKET_OUTPUT) ||
rcap_type_required(capabilities, RCAP_TYPE_CONTIGUOUS_OUTPUT) ||
proto->ignore_replies != 0)
@ -977,8 +980,6 @@ gw_read_and_write(DCB *dcb)
gwbuf_set_type(stmt, GWBUF_TYPE_RESULT);
}
mxs_mysql_get_session_track_info(stmt, proto->server_capabilities);
session->service->router->clientReply(session->service->router_instance,
session->router_session,
stmt, dcb);

View File

@ -412,7 +412,8 @@ int MySQLSendHandshake(DCB* dcb)
int gw_MySQLWrite_client(DCB *dcb, GWBUF *queue)
{
MySQLProtocol *protocol = DCB_PROTOCOL(dcb, MySQLProtocol);
if (GWBUF_IS_REPLY_OK(queue) && protocol->session_track_trx_state)
SERVICE *service = DCB_SERVICE(dcb, SERVICE);
if (GWBUF_IS_REPLY_OK(queue) && service->session_track_trx_state)
{
parse_and_set_trx_state(dcb->session, queue);
}
@ -1271,8 +1272,6 @@ int gw_MySQLListener(DCB *listen_dcb, char *config_bind)
int gw_MySQLAccept(DCB *listener)
{
DCB *client_dcb;
MySQLProtocol *cli_proto;
SERV_LISTENER *listener_proto;
CHK_DCB(listener);
@ -1285,9 +1284,6 @@ int gw_MySQLAccept(DCB *listener)
while ((client_dcb = dcb_accept(listener)) != NULL)
{
gw_process_one_new_client(client_dcb);
cli_proto = DCB_PROTOCOL(client_dcb, MySQLProtocol);
listener_proto = (SERV_LISTENER *)listener->listener;
cli_proto->session_track_trx_state = listener_proto->session_track_trx_state;
} /**< while client_dcb != NULL */
}
@ -1519,8 +1515,8 @@ static int route_by_statement(MXS_SESSION* session, uint64_t capabilities, GWBUF
}
}
MySQLProtocol *protocol = DCB_PROTOCOL(session->client_dcb, MySQLProtocol);
if (rcap_type_required(capabilities, RCAP_TYPE_TRANSACTION_TRACKING) && !protocol->session_track_trx_state)
SERVICE *service = DCB_SERVICE(session->client_dcb, SERVICE);
if (rcap_type_required(capabilities, RCAP_TYPE_TRANSACTION_TRACKING) && service->session_track_trx_state)
{
if (session_trx_is_ending(session))
{
@ -1900,9 +1896,23 @@ static bool parse_kill_query(char *query, uint64_t *thread_id_out, kill_type_t *
}
}
/*
* Mapping two session tracker's info to mxs_session_trx_state_t
* SESSION_TRACK_STATE_CHANGE:
* When session variable autocommit is changed, it will give a latest value {0|1}
* SESSION_TRACK_TRANSACTION_TYPE:
* TX_EMPTY => SESSION_TRX_INACTIVE
* TX_WRITE_TRX => SESSION_TRX_READ_WRITE
* TX_READ_TRX => SESSION_TRX_READ_ONLY
* TX_EXPLICIT | TX_IMPLICIT => SESSION_TRX_ACTIVE
* refs:
* 1. https://dev.mysql.com/worklog/task/?id=6885
* 2. https://dev.mysql.com/worklog/task/?id=6631
*/
static void parse_and_set_trx_state(MXS_SESSION *ses, GWBUF *data)
{
char *autocommit = gwbuf_get_property(data, (char *)"autocommit");
if (autocommit)
{
if (strncasecmp(autocommit, "0", 1) == 0)
@ -1924,17 +1934,17 @@ static void parse_and_set_trx_state(MXS_SESSION *ses, GWBUF *data)
{
session_set_trx_state(ses, SESSION_TRX_INACTIVE);
}
else if(s & TX_READ_TRX)
else if (s & TX_READ_TRX)
{
session_set_trx_state(ses, SESSION_TRX_READ_ONLY);
}
else if(s & TX_WRITE_TRX)
else if (s & TX_WRITE_TRX)
{
session_set_trx_state(ses, SESSION_TRX_READ_WRITE);
}
else if((s & TX_EXPLICIT) | (s & TX_IMPLICIT))
else if ((s & TX_EXPLICIT) || (s & TX_IMPLICIT))
{
session_set_trx_state(ses, SESSION_TRX_ACTIVE);
}
}
}
}

View File

@ -1778,33 +1778,28 @@ void mxs_mysql_execute_kill_user(MXS_SESSION* issuer, const char* user, kill_typ
void mxs_mysql_get_session_track_info(GWBUF *buff, uint32_t server_capabilities)
{
char *trx_info, *var_name, *var_value;
if (GWBUF_LENGTH(buff) < 9 || !mxs_mysql_is_ok_packet(buff))
size_t len = GWBUF_LENGTH(buff);
uint8_t local_buf[len];
uint8_t *ptr = local_buf;
if (len < MYSQL_OK_PACKET_MIN_LEN || !mxs_mysql_is_ok_packet(buff))
{
return;
}
if (!GWBUF_IS_CONTIGUOUS(buff))
{
buff = gwbuf_make_contiguous(buff);
}
gwbuf_copy_data(buff, 0, len, local_buf);
buff->gwbuf_type |= GWBUF_TYPE_REPLY_OK;
uint8_t* ptr = GWBUF_DATA(buff);
ptr += (MYSQL_COM_OFFSET + 1); // Header and Command type
mxs_leint_consume(&ptr); // Affected rows
mxs_leint_consume(&ptr); // Last insert-id
ptr += (MYSQL_HEADER_LEN + 1); // Header and Command type
mxs_leint_consume(&ptr); // Affected rows
mxs_leint_consume(&ptr); // Last insert-id
uint16_t server_status = gw_mysql_get_byte2(ptr);
ptr += 2; // status
ptr += 2; // number of warnings
if (server_capabilities & GW_MYSQL_CAPABILITIES_SESSION_TRACK)
{
if (ptr < buff->end) {
if (ptr < buff->end)
{
ptr += mxs_leint_consume(&ptr); // info
if (server_status & SERVER_SESSION_STATE_CHANGED)
{
@ -1832,7 +1827,7 @@ void mxs_mysql_get_session_track_info(GWBUF *buff, uint32_t server_capabilities)
case SESSION_TRACK_TRANSACTION_TYPE:
mxs_leint_consume(&ptr); // length
trx_info = mxs_lestr_consume_dup(&ptr);
MXS_INFO("get trx_info:%s", trx_info);
MXS_DEBUG("get trx_info:%s", trx_info);
gwbuf_add_property(buff, (char *)"trx_state", trx_info);
MXS_FREE(trx_info);
break;
@ -1847,10 +1842,16 @@ void mxs_mysql_get_session_track_info(GWBUF *buff, uint32_t server_capabilities)
}
}
mysql_tx_state_t parse_trx_state(char *str)
/***
* As described in https://dev.mysql.com/worklog/task/?id=6631
* When session transation state changed
* SESSION_TRACK_TRANSACTION_TYPE (or SESSION_TRACK_TRANSACTION_STATE in MySQL) will
* return an 8 bytes string to indicate the transaction state details
* */
mysql_tx_state_t parse_trx_state(const char *str)
{
int s = TX_EMPTY;
assert(str);
ss_dassert(str);
do
{
switch (*str)
@ -1889,4 +1890,4 @@ mysql_tx_state_t parse_trx_state(char *str)
} while(*(str++) != 0);
return (mysql_tx_state_t)s;
}
}