Only add MASTER_GTID_WAIT if it fits into one packet

The MASTER_GTID_WAIT "prefix" should only be added if it fits into one
packet. This is not a complete solution as it prevents queries larger than
16MB from benefiting from the consistent reads.
This commit is contained in:
Markus Mäkelä
2018-04-04 14:35:28 +03:00
parent 5a846063c1
commit 87de1dc468

View File

@ -845,7 +845,7 @@ GWBUF* RWSplitSession::add_prefix_wait_gtid(SERVER *server, GWBUF *origin)
* on master; * on master;
**/ **/
GWBUF *rval; GWBUF* rval = origin;
const char* wait_func = (server->server_type == SERVER_TYPE_MARIADB) ? const char* wait_func = (server->server_type == SERVER_TYPE_MARIADB) ?
MARIADB_WAIT_GTID_FUNC : MYSQL_WAIT_GTID_FUNC; MARIADB_WAIT_GTID_FUNC : MYSQL_WAIT_GTID_FUNC;
const char *gtid_wait_timeout = router->config().causal_read_timeout.c_str(); const char *gtid_wait_timeout = router->config().causal_read_timeout.c_str();
@ -854,22 +854,27 @@ GWBUF* RWSplitSession::add_prefix_wait_gtid(SERVER *server, GWBUF *origin)
/* Create a new buffer to store prefix sql */ /* Create a new buffer to store prefix sql */
size_t prefix_len = strlen(gtid_wait_stmt) + strlen(gtid_position) + size_t prefix_len = strlen(gtid_wait_stmt) + strlen(gtid_position) +
strlen(gtid_wait_timeout) + strlen(wait_func); strlen(gtid_wait_timeout) + strlen(wait_func);
char prefix_sql[prefix_len];
snprintf(prefix_sql, prefix_len, gtid_wait_stmt, wait_func, gtid_position, gtid_wait_timeout);
GWBUF *prefix_buff = modutil_create_query(prefix_sql);
/* Trim origin to sql, Append origin buffer to the prefix buffer */ // Only do the replacement if it fits into one packet
uint8_t header[MYSQL_HEADER_LEN]; if (gwbuf_length(origin) + prefix_len < GW_MYSQL_MAX_PACKET_LEN + MYSQL_HEADER_LEN)
gwbuf_copy_data(origin, 0, MYSQL_HEADER_LEN, header); {
/* Command length = 1 */ char prefix_sql[prefix_len];
size_t origin_sql_len = MYSQL_GET_PAYLOAD_LEN(header) - 1; snprintf(prefix_sql, prefix_len, gtid_wait_stmt, wait_func, gtid_position, gtid_wait_timeout);
/* Trim mysql header and command */ GWBUF *prefix_buff = modutil_create_query(prefix_sql);
origin = gwbuf_consume(origin, MYSQL_HEADER_LEN + 1);
rval = gwbuf_append(prefix_buff, origin);
/* Modify totol length: Prefix sql len + origin sql len + command len */ /* Trim origin to sql, Append origin buffer to the prefix buffer */
size_t new_payload_len = strlen(prefix_sql) + origin_sql_len + 1; uint8_t header[MYSQL_HEADER_LEN];
gw_mysql_set_byte3(GWBUF_DATA(rval), new_payload_len); gwbuf_copy_data(origin, 0, MYSQL_HEADER_LEN, header);
/* Command length = 1 */
size_t origin_sql_len = MYSQL_GET_PAYLOAD_LEN(header) - 1;
/* Trim mysql header and command */
origin = gwbuf_consume(origin, MYSQL_HEADER_LEN + 1);
rval = gwbuf_append(prefix_buff, origin);
/* Modify totol length: Prefix sql len + origin sql len + command len */
size_t new_payload_len = strlen(prefix_sql) + origin_sql_len + 1;
gw_mysql_set_byte3(GWBUF_DATA(rval), new_payload_len);
}
return rval; return rval;
} }