From de48e781333a700f2704ed61e60e5eefa8f0edf3 Mon Sep 17 00:00:00 2001 From: winkyao <82091309@qq.com> Date: Tue, 29 Sep 2015 10:39:48 +0800 Subject: [PATCH] 1. fix bug: when user use 'set autocommit = 0' and after that, user never send any 'commit' statement, the is_in_transaction variable will be true always, which will make all continue sql send to the master, 2. send set statement and show statement to master --- bootstrap.sh | 1 + plugins/proxy/proxy-plugin.c | 39 ++++++++++++++++++++---------------- src/network-mysqld.h | 10 ++++----- 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/bootstrap.sh b/bootstrap.sh index 8938c7a..e25f0aa 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -1,4 +1,5 @@ #!/bin/sh base=$(cd "$(dirname "$0")"; pwd) cd $base +export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH PKG_CONFIG_PATH=/usr/local/lib/pkgconfig ./configure --with-mysql=/usr --prefix=/usr/local/mysql-proxy CFLAGS="-DHAVE_LUA_H -O2" LDFLAGS="-lm -ldl -lcrypto -ljemalloc" LUA_CFLAGS="-I/usr/local/include/" LUA_LIBS="-L/usr/local/lib -llua" diff --git a/plugins/proxy/proxy-plugin.c b/plugins/proxy/proxy-plugin.c index 7b1009d..6671d49 100644 --- a/plugins/proxy/proxy-plugin.c +++ b/plugins/proxy/proxy-plugin.c @@ -1233,6 +1233,7 @@ void modify_charset(GPtrArray* tokens, network_mysqld_con* con) { void check_flags(GPtrArray* tokens, network_mysqld_con* con) { con->is_in_select_calc_found_rows = FALSE; + *is_set_autocommit = FALSE; sql_token** ts = (sql_token**)(tokens->pdata); guint len = tokens->len; @@ -1243,15 +1244,15 @@ void check_flags(GPtrArray* tokens, network_mysqld_con* con) { if (!g_hash_table_lookup(con->locks, key)) g_hash_table_add(con->locks, g_strdup(key)); } - if (len > 4) { //SET AUTOCOMMIT = {0 | 1} - if (ts[1]->token_id == TK_SQL_SET && ts[3]->token_id == TK_EQ) { - if (strcasecmp(ts[2]->text->str, "AUTOCOMMIT") == 0) { - char* str = ts[4]->text->str; - if (strcmp(str, "0") == 0) con->is_not_autocommit = TRUE; - else if (strcmp(str, "1") == 0) con->is_not_autocommit = FALSE; - } - } - } + /* if (len > 4) { //SET AUTOCOMMIT = {0 | 1} */ + /* if (ts[1]->token_id == TK_SQL_SET && ts[3]->token_id == TK_EQ) { */ + /* if (strcasecmp(ts[2]->text->str, "AUTOCOMMIT") == 0) { */ + /* /1* char* str = ts[4]->text->str; *1/ */ + /* /1* if (strcmp(str, "0") == 0) con->is_not_autocommit = TRUE; *1/ */ + /* /1* else if (strcmp(str, "1") == 0) con->is_not_autocommit = FALSE; *1/ */ + /* } */ + /* } */ + /* } */ } guint i; @@ -1302,7 +1303,8 @@ gboolean sql_is_write(GPtrArray *tokens) { token_id = ts[i]->token_id; } - return (token_id != TK_SQL_SELECT && token_id != TK_SQL_SET && token_id != TK_SQL_USE && token_id != TK_SQL_SHOW && token_id != TK_SQL_DESC && token_id != TK_SQL_EXPLAIN); + // "set autocommit = 0; or show variables" need send to master + return (token_id != TK_SQL_SELECT /*&& token_id != TK_SQL_SET */ && token_id != TK_SQL_USE /*&& token_id != TK_SQL_SHOW*/ && token_id != TK_SQL_DESC && token_id != TK_SQL_EXPLAIN); } return TRUE; @@ -1445,7 +1447,7 @@ NETWORK_MYSQLD_PLUGIN_PROTO(proxy_read_query) { if (con->is_in_select_calc_found_rows && is_write) { network_connection_pool_lua_add_connection(con); } - + check_flags(tokens, con); if (con->server == NULL) { @@ -1453,7 +1455,7 @@ NETWORK_MYSQLD_PLUGIN_PROTO(proxy_read_query) { if (!con->is_in_transaction && !con->is_not_autocommit && g_hash_table_size(con->locks) == 0) { if (type == COM_QUERY) { - if (is_write) { + if (is_write || is_set_autocommit) { backend_ndx = idle_rw(con); } else { backend_ndx = rw_split(tokens, con); @@ -1819,6 +1821,9 @@ NETWORK_MYSQLD_PLUGIN_PROTO(proxy_read_query_result) { inj->qstat.server_status = com_query->server_status; inj->qstat.warning_count = com_query->warning_count; inj->qstat.query_status = com_query->query_status; + + con->is_in_transaction = com_query->server_status & SERVER_STATUS_IN_TRANS; + con->is_not_autocommit = !(com_query->server_status & SERVER_STATUS_AUTOCOMMIT); } inj->ts_read_query_result_last = chassis_get_rel_microseconds(); /* g_get_current_time(&(inj->ts_read_query_result_last)); */ @@ -1906,11 +1911,11 @@ NETWORK_MYSQLD_PLUGIN_PROTO(proxy_read_query_result) { switch (ret) { case PROXY_SEND_RESULT: - if (!con->is_in_transaction || (inj->qstat.server_status & SERVER_STATUS_IN_TRANS)) { - con->is_in_transaction = (inj->qstat.server_status & SERVER_STATUS_IN_TRANS); - } else { - if (strcasestr(str, "COMMIT") == str || strcasestr(str, "ROLLBACK") == str) con->is_in_transaction = FALSE; - } + /* if (!con->is_in_transaction || (inj->qstat.server_status & SERVER_STATUS_IN_TRANS)) { */ + /* con->is_in_transaction = (inj->qstat.server_status & SERVER_STATUS_IN_TRANS); */ + /* } else { */ + /* if (strcasestr(str, "COMMIT") == str || strcasestr(str, "ROLLBACK") == str) con->is_in_transaction = FALSE; */ + /* } */ if (g_hash_table_size(con->locks) > 0 && strcasestr(str, "SELECT RELEASE_LOCK") == str) { gchar* b = strchr(str+strlen("SELECT RELEASE_LOCK"), '(') + 1; diff --git a/src/network-mysqld.h b/src/network-mysqld.h index eee88ad..552fc80 100644 --- a/src/network-mysqld.h +++ b/src/network-mysqld.h @@ -60,12 +60,12 @@ typedef struct network_mysqld_con network_mysqld_con; /* forward declaration */ -#undef NETWORK_MYSQLD_WANT_CON_TRACK_TIME -#ifdef NETWORK_MYSQLD_WANT_CON_TRACK_TIME -#define NETWORK_MYSQLD_CON_TRACK_TIME(con, name) chassis_timestamps_add(con->timestamps, name, __FILE__, __LINE__) -#else +/* #undef NETWORK_MYSQLD_WANT_CON_TRACK_TIME */ +/* #ifdef NETWORK_MYSQLD_WANT_CON_TRACK_TIME */ +/* #define NETWORK_MYSQLD_CON_TRACK_TIME(con, name) chassis_timestamps_add(con->timestamps, name, __FILE__, __LINE__) */ +/* #else */ #define NETWORK_MYSQLD_CON_TRACK_TIME(con, name) -#endif +/* #endif */ /** * A macro that produces a plugin callback function pointer declaration.