Merge pull request #2274 from val214/tx_isolation

set tx_isolation implementation
pull/2277/head
René Cannaò 7 years ago committed by GitHub
commit 781aafb70f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -116,6 +116,7 @@ class MySQL_Session
bool handler_again___verify_backend_time_zone();
bool handler_again___verify_backend_isolation_level();
bool handler_again___verify_backend_transaction_read();
bool handler_again___verify_backend_tx_isolation();
bool handler_again___verify_backend_character_set_results();
bool handler_again___verify_backend_session_track_gtids();
bool handler_again___verify_backend_sql_auto_is_null();
@ -132,6 +133,7 @@ class MySQL_Session
bool handler_again___status_SETTING_TIME_ZONE(int *);
bool handler_again___status_SETTING_ISOLATION_LEVEL(int *);
bool handler_again___status_SETTING_TRANSACTION_READ(int *);
bool handler_again___status_SETTING_TX_ISOLATION(int *);
bool handler_again___status_SETTING_CHARACTER_SET_RESULTS(int *);
bool handler_again___status_SETTING_SESSION_TRACK_GTIDS(int *);
bool handler_again___status_SETTING_SQL_AUTO_IS_NULL(int *);

@ -21,6 +21,7 @@
#define MYSQL_DEFAULT_TIME_ZONE "SYSTEM"
#define MYSQL_DEFAULT_ISOLATION_LEVEL "READ COMMITTED"
#define MYSQL_DEFAULT_TRANSACTION_READ "WRITE"
#define MYSQL_DEFAULT_TX_ISOLATION "READ COMMITTED"
#define MYSQL_DEFAULT_CHARACTER_SET_RESULTS "NULL"
#define MYSQL_DEFAULT_SESSION_TRACK_GTIDS "OFF"
#define MYSQL_DEFAULT_SQL_AUTO_IS_NULL "OFF"
@ -456,6 +457,7 @@ class MySQL_Threads_Handler
char *default_time_zone;
char *default_isolation_level;
char *default_transaction_read;
char *default_tx_isolation;
char *default_character_set_results;
char *default_session_track_gtids;
char *default_sql_auto_is_null;

@ -47,6 +47,7 @@ class MySQL_Connection {
uint32_t character_set_results_int;
uint32_t isolation_level_int;
uint32_t transaction_read_int;
uint32_t tx_isolation_int;
uint32_t session_track_gtids_int;
uint32_t sql_auto_is_null_int;
uint32_t sql_select_limit_int;
@ -63,6 +64,7 @@ class MySQL_Connection {
char * character_set_results;
char * isolation_level;
char * transaction_read;
char * tx_isolation;
char * session_track_gtids;
char * sql_auto_is_null;
char * sql_select_limit;
@ -71,6 +73,7 @@ class MySQL_Connection {
char * net_write_timeout;
char * max_join_size;
bool isolation_level_sent;
bool tx_isolation_sent;
bool transaction_read_sent;
bool character_set_results_sent;
bool session_track_gtids_sent;

@ -154,6 +154,7 @@ enum session_status {
SETTING_TIME_ZONE,
SETTING_ISOLATION_LEVEL,
SETTING_TRANSACTION_READ,
SETTING_TX_ISOLATION,
SETTING_CHARACTER_SET_RESULTS,
SETTING_SESSION_TRACK_GTIDS,
SETTING_SQL_AUTO_IS_NULL,
@ -624,6 +625,7 @@ __thread char *mysql_thread___default_sql_mode;
__thread char *mysql_thread___default_time_zone;
__thread char *mysql_thread___default_isolation_level;
__thread char *mysql_thread___default_transaction_read;
__thread char *mysql_thread___default_tx_isolation;
__thread char *mysql_thread___default_character_set_results;
__thread char *mysql_thread___default_session_track_gtids;
__thread char *mysql_thread___default_sql_auto_is_null;
@ -771,6 +773,7 @@ extern __thread char *mysql_thread___default_sql_mode;
extern __thread char *mysql_thread___default_time_zone;
extern __thread char *mysql_thread___default_isolation_level;
extern __thread char *mysql_thread___default_transaction_read;
extern __thread char *mysql_thread___default_tx_isolation;
extern __thread char *mysql_thread___default_character_set_results;
extern __thread char *mysql_thread___default_session_track_gtids;
extern __thread char *mysql_thread___default_sql_auto_is_null;

@ -928,6 +928,7 @@ void MySQL_Session::generate_proxysql_internal_session_json(json &j) {
j["conn"]["time_zone"] = ( client_myds->myconn->options.time_zone ? client_myds->myconn->options.time_zone : "") ;
j["conn"]["isolation_level"] = ( client_myds->myconn->options.isolation_level ? client_myds->myconn->options.isolation_level : "") ;
j["conn"]["transaction_read"] = ( client_myds->myconn->options.transaction_read ? client_myds->myconn->options.transaction_read : "") ;
j["conn"]["tx_isolation"] = ( client_myds->myconn->options.tx_isolation ? client_myds->myconn->options.tx_isolation : "") ;
j["conn"]["character_set_results"] = ( client_myds->myconn->options.character_set_results ? client_myds->myconn->options.character_set_results : "") ;
j["conn"]["session_track_gtids"] = ( client_myds->myconn->options.session_track_gtids ? client_myds->myconn->options.session_track_gtids : "") ;
j["conn"]["sql_auto_is_null"] = ( client_myds->myconn->options.sql_auto_is_null ? client_myds->myconn->options.sql_auto_is_null : "") ;
@ -981,6 +982,7 @@ void MySQL_Session::generate_proxysql_internal_session_json(json &j) {
j["backends"][i]["conn"]["sql_mode_sent"] = _myds->myconn->options.sql_mode_sent;
j["backends"][i]["conn"]["time_zone"] = ( _myconn->options.time_zone ? _myconn->options.time_zone : "") ;
j["backends"][i]["conn"]["isolation_level"] = ( _myconn->options.isolation_level ? _myconn->options.isolation_level : "") ;
j["backends"][i]["conn"]["tx_isolation"] = ( _myconn->options.tx_isolation ? _myconn->options.tx_isolation : "") ;
j["backends"][i]["conn"]["transaction_read"] = ( _myconn->options.transaction_read ? _myconn->options.transaction_read : "") ;
j["backends"][i]["conn"]["character_set_results"] = ( _myconn->options.character_set_results ? _myconn->options.character_set_results : "") ;
j["backends"][i]["conn"]["session_track_gtids"] = ( _myconn->options.session_track_gtids ? _myconn->options.session_track_gtids : "") ;
@ -1719,6 +1721,20 @@ bool MySQL_Session::handler_again___verify_backend_transaction_read() {
return ret;
}
bool MySQL_Session::handler_again___verify_backend_tx_isolation() {
bool ret = false;
proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Session %p , client: %s , backend: %s\n", this, client_myds->myconn->options.tx_isolation, mybe->server_myds->myconn->options.tx_isolation);
ret = handler_again___verify_backend__generic_variable(
&mybe->server_myds->myconn->options.tx_isolation_int,
&mybe->server_myds->myconn->options.tx_isolation,
mysql_thread___default_tx_isolation,
&client_myds->myconn->options.tx_isolation_int,
client_myds->myconn->options.tx_isolation,
SETTING_TX_ISOLATION
);
return ret;
}
bool MySQL_Session::handler_again___verify_backend_character_set_results() {
bool ret = false;
proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Session %p , client: %s , backend: %s\n", this, client_myds->myconn->options.character_set_results, mybe->server_myds->myconn->options.character_set_results);
@ -2405,7 +2421,18 @@ bool MySQL_Session::handler_again___status_SETTING_GENERIC_VARIABLE(int *_rc, ch
q=(char *)"SET %s %s";
}
query=(char *)malloc(strlen(q)+strlen(var_name)+strlen(var_value));
sprintf(query,q,var_name, var_value);
if (strncasecmp("tx_isolation", var_name, 12) == 0) {
char *sv = mybe->server_myds->myconn->mysql->server_version;
if (strncmp(sv,(char *)"8",1)==0) {
sprintf(query,q,"transaction_isolation", var_value);
}
else {
sprintf(query,q,"tx_isolation", var_value);
}
}
else {
sprintf(query,q,var_name, var_value);
}
query_length=strlen(query);
}
int rc=myconn->async_send_simple_command(myds->revents,query,query_length);
@ -2504,6 +2531,13 @@ bool MySQL_Session::handler_again___status_SETTING_TRANSACTION_READ(int *_rc) {
return ret;
}
bool MySQL_Session::handler_again___status_SETTING_TX_ISOLATION(int *_rc) {
bool ret=false;
assert(mybe->server_myds->myconn);
ret = handler_again___status_SETTING_GENERIC_VARIABLE(_rc, (char *)"TX_ISOLATION", mybe->server_myds->myconn->options.tx_isolation, false, false);
return ret;
}
bool MySQL_Session::handler_again___status_SETTING_CHARACTER_SET_RESULTS(int *_rc) {
bool ret=false;
assert(mybe->server_myds->myconn);
@ -3799,6 +3833,9 @@ handler_again:
if (handler_again___verify_backend_transaction_read()) {
goto handler_again;
}
if (handler_again___verify_backend_tx_isolation()) {
goto handler_again;
}
if (handler_again___verify_backend_character_set_results()) {
goto handler_again;
}
@ -4381,6 +4418,19 @@ handler_again:
}
break;
case SETTING_TX_ISOLATION:
{
int rc=0;
if (handler_again___status_SETTING_TX_ISOLATION(&rc))
goto handler_again; // we changed status
if (rc==-1) { // we have an error we can't handle
handler_ret = -1;
return handler_ret;
}
}
break;
case SETTING_CHARACTER_SET_RESULTS:
{
int rc=0;
@ -5733,6 +5783,20 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
client_myds->myconn->set_charset(c->nr);
exit_after_SetParse = true;
}
} else if (var == "tx_isolation") {
std::string value1 = *values;
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Processing SET tx_isolation value %s\n", value1.c_str());
uint32_t tx_isolation_int=SpookyHash::Hash32(value1.c_str(),value1.length(),10);
if (client_myds->myconn->options.tx_isolation_int != tx_isolation_int) {
//fprintf(stderr,"sql_mode_int='%u'\n", sql_mode_int);
client_myds->myconn->options.tx_isolation_int = tx_isolation_int;
if (client_myds->myconn->options.tx_isolation) {
free(client_myds->myconn->options.tx_isolation);
}
proxy_debug(PROXY_DEBUG_MYSQL_COM, 8, "Changing connection TX ISOLATION to %s\n", value1.c_str());
client_myds->myconn->options.tx_isolation=strdup(value1.c_str());
}
exit_after_SetParse = true;
} else {
std::string value1 = *values;
std::size_t found_at = value1.find("@");

@ -336,6 +336,7 @@ static char * mysql_thread_variables_names[]= {
(char *)"default_time_zone",
(char *)"default_isolation_level",
(char *)"default_transaction_read",
(char *)"default_tx_isolation",
(char *)"default_character_set_results",
(char *)"default_session_track_gtids",
(char *)"default_sql_auto_is_null",
@ -447,6 +448,7 @@ MySQL_Threads_Handler::MySQL_Threads_Handler() {
variables.default_time_zone=strdup((char *)MYSQL_DEFAULT_TIME_ZONE);
variables.default_isolation_level=strdup((char *)MYSQL_DEFAULT_ISOLATION_LEVEL);
variables.default_transaction_read=strdup((char *)MYSQL_DEFAULT_TRANSACTION_READ);
variables.default_tx_isolation=strdup((char *)MYSQL_DEFAULT_TX_ISOLATION);
variables.default_character_set_results=strdup((char *)MYSQL_DEFAULT_CHARACTER_SET_RESULTS);
variables.default_session_track_gtids=strdup((char *)MYSQL_DEFAULT_SESSION_TRACK_GTIDS);
variables.default_sql_auto_is_null=strdup((char *)MYSQL_DEFAULT_SQL_AUTO_IS_NULL);
@ -663,6 +665,12 @@ char * MySQL_Threads_Handler::get_variable_string(char *name) {
}
return strdup(variables.default_isolation_level);
}
if (!strcmp(name,"default_tx_isolation")) {
if (variables.default_tx_isolation==NULL) {
variables.default_tx_isolation=strdup((char *)MYSQL_DEFAULT_TX_ISOLATION);
}
return strdup(variables.default_tx_isolation);
}
if (!strcmp(name,"default_transaction_read")) {
if (variables.default_transaction_read==NULL) {
variables.default_transaction_read=strdup((char *)MYSQL_DEFAULT_TRANSACTION_READ);
@ -963,6 +971,12 @@ char * MySQL_Threads_Handler::get_variable(char *name) { // this is the public f
}
return strdup(variables.default_isolation_level);
}
if (!strcasecmp(name,"default_tx_isolation")) {
if (variables.default_tx_isolation==NULL) {
variables.default_tx_isolation=strdup((char *)MYSQL_DEFAULT_TX_ISOLATION);
}
return strdup(variables.default_tx_isolation);
}
if (!strcasecmp(name,"default_transaction_read")) {
if (variables.default_transaction_read==NULL) {
variables.default_transaction_read=strdup((char *)MYSQL_DEFAULT_TRANSACTION_READ);
@ -2309,6 +2323,19 @@ bool MySQL_Threads_Handler::set_variable(char *name, char *value) { // this is t
return true;
}
if (!strcasecmp(name,"default_tx_isolation")) {
if (variables.default_tx_isolation) free(variables.default_tx_isolation);
variables.default_tx_isolation=NULL;
if (vallen) {
if (strcmp(value,"(null)"))
variables.default_tx_isolation=strdup(value);
}
if (variables.default_tx_isolation==NULL) {
variables.default_tx_isolation=strdup((char *)MYSQL_DEFAULT_TX_ISOLATION); // default
}
return true;
}
if (!strcasecmp(name,"default_transaction_read")) {
if (variables.default_transaction_read) free(variables.default_transaction_read);
variables.default_transaction_read=NULL;
@ -3037,6 +3064,7 @@ MySQL_Threads_Handler::~MySQL_Threads_Handler() {
if (variables.default_sql_mode) free(variables.default_sql_mode);
if (variables.default_time_zone) free(variables.default_time_zone);
if (variables.default_isolation_level) free(variables.default_isolation_level);
if (variables.default_tx_isolation) free(variables.default_tx_isolation);
if (variables.default_transaction_read) free(variables.default_transaction_read);
if (variables.default_character_set_results) free(variables.default_character_set_results);
if (variables.default_session_track_gtids) free(variables.default_session_track_gtids);
@ -3167,6 +3195,7 @@ MySQL_Thread::~MySQL_Thread() {
if (mysql_thread___default_sql_mode) { free(mysql_thread___default_sql_mode); mysql_thread___default_sql_mode=NULL; }
if (mysql_thread___default_time_zone) { free(mysql_thread___default_time_zone); mysql_thread___default_time_zone=NULL; }
if (mysql_thread___default_isolation_level) { free(mysql_thread___default_isolation_level); mysql_thread___default_isolation_level=NULL; }
if (mysql_thread___default_tx_isolation) { free(mysql_thread___default_tx_isolation); mysql_thread___default_tx_isolation=NULL; }
if (mysql_thread___default_transaction_read) { free(mysql_thread___default_transaction_read); mysql_thread___default_transaction_read=NULL; }
if (mysql_thread___default_character_set_results) { free(mysql_thread___default_character_set_results); mysql_thread___default_character_set_results=NULL; }
if (mysql_thread___default_session_track_gtids) { free(mysql_thread___default_session_track_gtids); mysql_thread___default_session_track_gtids=NULL; }
@ -3246,6 +3275,13 @@ MySQL_Session * MySQL_Thread::create_new_session_and_client_data_stream(int _fd)
}
sess->client_myds->myconn->options.isolation_level=strdup(mysql_thread___default_isolation_level);
uint32_t tx_isolation_int=SpookyHash::Hash32(mysql_thread___default_tx_isolation,strlen(mysql_thread___default_tx_isolation),10);
sess->client_myds->myconn->options.tx_isolation_int = tx_isolation_int;
if (sess->client_myds->myconn->options.tx_isolation) {
free(sess->client_myds->myconn->options.tx_isolation);
}
sess->client_myds->myconn->options.tx_isolation=strdup(mysql_thread___default_tx_isolation);
uint32_t transaction_read_int=SpookyHash::Hash32(mysql_thread___default_transaction_read,strlen(mysql_thread___default_transaction_read),10);
sess->client_myds->myconn->options.transaction_read_int = transaction_read_int;
if (sess->client_myds->myconn->options.transaction_read) {
@ -3347,7 +3383,7 @@ bool MySQL_Thread::init() {
match_regexes=(Session_Regex **)malloc(sizeof(Session_Regex *)*3);
match_regexes[0]=new Session_Regex((char *)"^SET (|SESSION |@@|@@session.)SQL_LOG_BIN( *)(:|)=( *)");
match_regexes[1]=new Session_Regex((char *)"^SET (|SESSION |@@|@@session.)(SQL_MODE|TIME_ZONE|CHARACTER_SET_RESULTS|SESSION_TRACK_GTIDS|SQL_AUTO_IS_NULL|SQL_SELECT_LIMIT|SQL_SAFE_UPDATES|COLLATION_CONNECTION|NET_WRITE_TIMEOUT|MAX_JOIN_SIZE( *)(:|)=( *))");
match_regexes[1]=new Session_Regex((char *)"^SET (|SESSION |@@|@@session.)(SQL_MODE|TIME_ZONE|CHARACTER_SET_RESULTS|SESSION_TRACK_GTIDS|SQL_AUTO_IS_NULL|SQL_SELECT_LIMIT|SQL_SAFE_UPDATES|COLLATION_CONNECTION|NET_WRITE_TIMEOUT|TX_ISOLATION|MAX_JOIN_SIZE( *)(:|)=( *))");
match_regexes[2]=new Session_Regex((char *)"^SET(?: +)(|SESSION +)TRANSACTION(?: +)(?:(?:(ISOLATION(?: +)LEVEL)(?: +)(REPEATABLE(?: +)READ|READ(?: +)COMMITTED|READ(?: +)UNCOMMITTED|SERIALIZABLE))|(?:(READ)(?: +)(WRITE|ONLY)))");
@ -4383,6 +4419,8 @@ void MySQL_Thread::refresh_variables() {
mysql_thread___default_time_zone=GloMTH->get_variable_string((char *)"default_time_zone");
if (mysql_thread___default_isolation_level) free(mysql_thread___default_isolation_level);
mysql_thread___default_isolation_level=GloMTH->get_variable_string((char *)"default_isolation_level");
if (mysql_thread___default_tx_isolation) free(mysql_thread___default_tx_isolation);
mysql_thread___default_tx_isolation=GloMTH->get_variable_string((char *)"default_tx_isolation");
if (mysql_thread___default_transaction_read) free(mysql_thread___default_transaction_read);
mysql_thread___default_transaction_read=GloMTH->get_variable_string((char *)"default_transaction_read");
if (mysql_thread___default_character_set_results) free(mysql_thread___default_character_set_results);

@ -208,6 +208,7 @@ MySQL_Connection::MySQL_Connection() {
options.init_connect_sent=false;
options.character_set_results = NULL;
options.isolation_level = NULL;
options.tx_isolation = NULL;
options.transaction_read = NULL;
options.session_track_gtids = NULL;
options.sql_auto_is_null = NULL;
@ -217,6 +218,7 @@ MySQL_Connection::MySQL_Connection() {
options.net_write_timeout = NULL;
options.max_join_size = NULL;
options.isolation_level_sent = false;
options.tx_isolation_sent = false;
options.transaction_read_sent = false;
options.character_set_results_sent = false;
options.session_track_gtids_sent = false;
@ -236,6 +238,7 @@ MySQL_Connection::MySQL_Connection() {
options.time_zone=NULL; // #819
options.time_zone_int=0; // #819
options.isolation_level_int=0;
options.tx_isolation_int=0;
options.transaction_read_int=0;
options.character_set_results_int=0;
options.session_track_gtids_int=0;
@ -325,6 +328,10 @@ MySQL_Connection::~MySQL_Connection() {
free(options.isolation_level);
options.isolation_level=NULL;
}
if (options.tx_isolation) {
free(options.tx_isolation);
options.tx_isolation=NULL;
}
if (options.transaction_read) {
free(options.transaction_read);
options.transaction_read=NULL;
@ -2095,6 +2102,12 @@ void MySQL_Connection::reset() {
options.isolation_level = NULL;
options.isolation_level_sent = false;
}
options.tx_isolation_int = 0;
if (options.tx_isolation) {
free (options.tx_isolation);
options.tx_isolation = NULL;
options.tx_isolation_sent = false;
}
options.transaction_read_int = 0;
if (options.transaction_read) {
free (options.transaction_read);

Loading…
Cancel
Save