From 2df5ff2691a80873f44e779658c9a5d41c6c7e13 Mon Sep 17 00:00:00 2001 From: Teemu Ollakka Date: Wed, 11 Mar 2015 13:04:00 +0200 Subject: [PATCH] refs codership/mysql-wsrep#90 - fixed race in OSU Make sure that thd uses the same method to begin and end OSU operation. --- sql/handler.cc | 4 ++-- sql/sql_class.cc | 3 ++- sql/sql_class.h | 1 + sql/wsrep_mysqld.cc | 27 +++++++++++++++++++++------ sql/wsrep_mysqld.h | 7 ++++++- sql/wsrep_thd.cc | 2 +- 6 files changed, 33 insertions(+), 11 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index 6a69af0b900..8bafb178e8b 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -6233,8 +6233,8 @@ int ha_wsrep_abort_transaction(THD *bf_thd, THD *victim_thd, my_bool signal) { DBUG_ENTER("ha_wsrep_abort_transaction"); if (!WSREP(bf_thd) && - !(wsrep_OSU_method_options == WSREP_OSU_RSU && - bf_thd->wsrep_exec_mode == TOTAL_ORDER)) { + !(bf_thd->wsrep_OSU_method == WSREP_OSU_RSU && + bf_thd->wsrep_exec_mode == TOTAL_ORDER)) { DBUG_RETURN(0); } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 8106eb95cb0..7f2b49a9f2b 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1203,6 +1203,7 @@ THD::THD() wsrep_consistency_check = NO_CONSISTENCY_CHECK; wsrep_status_vars = 0; wsrep_mysql_replicated = 0; + wsrep_OSU_method = WSREP_OSU_NONE; wsrep_TOI_pre_query = NULL; wsrep_TOI_pre_query_len = 0; #endif @@ -1609,7 +1610,7 @@ void THD::init(void) wsrep_PA_safe= true; wsrep_consistency_check = NO_CONSISTENCY_CHECK; wsrep_mysql_replicated = 0; - + wsrep_OSU_method = WSREP_OSU_NONE; wsrep_TOI_pre_query = NULL; wsrep_TOI_pre_query_len = 0; diff --git a/sql/sql_class.h b/sql/sql_class.h index 9b42f31c1f8..356fb3cd126 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2792,6 +2792,7 @@ public: wsrep_consistency_check; wsrep_stats_var* wsrep_status_vars; int wsrep_mysql_replicated; + ulong wsrep_OSU_method; const char* wsrep_TOI_pre_query; /* a query to apply before the actual TOI query */ size_t wsrep_TOI_pre_query_len; diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 7cfde65ebf1..f1a91f40e1e 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -1392,6 +1392,12 @@ int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_, thd->query(), thd->thread_id); } + /* + Save current global value into thd to persist the used method + even if global wsrep_OSU_method_options changes during isolation + */ + thd->wsrep_OSU_method= wsrep_OSU_method_options; + /* It makes sense to set auto_increment_* to defaults in TOI operations. Must be done before wsrep_TOI_begin() since Query_log_event encapsulating @@ -1407,19 +1413,23 @@ int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_, if (thd->variables.wsrep_on && thd->wsrep_exec_mode==LOCAL_STATE) { - switch (wsrep_OSU_method_options) { + switch (thd->wsrep_OSU_method) { case WSREP_OSU_TOI: ret = wsrep_TOI_begin(thd, db_, table_, table_list); break; case WSREP_OSU_RSU: ret = wsrep_RSU_begin(thd, db_, table_); break; + default: + WSREP_ERROR("Unsupported OSU method: %lu", thd->wsrep_OSU_method); + ret= -1; + break; } switch (ret) { case 0: thd->wsrep_exec_mode= TOTAL_ORDER; break; - case 1: - /* TOI replication skipped, treat as success */ - ret = 0; + case 1: + /* TOI replication skipped, treat as success */ + ret = 0; break; case -1: - /* TOI replication failed, treat as error */ + /* TOI replication failed, treat as error */ break; } } @@ -1430,13 +1440,18 @@ void wsrep_to_isolation_end(THD *thd) { if (thd->wsrep_exec_mode == TOTAL_ORDER) { - switch(wsrep_OSU_method_options) + switch(thd->wsrep_OSU_method) { case WSREP_OSU_TOI: wsrep_TOI_end(thd); break; case WSREP_OSU_RSU: wsrep_RSU_end(thd); break; + default: + WSREP_WARN("Unsupported wsrep OSU method at isolation end: %lu", + thd->wsrep_OSU_method); + break; } wsrep_cleanup_transaction(thd); } + thd->wsrep_OSU_method= WSREP_OSU_NONE; } #define WSREP_MDL_LOG(severity, msg, req, gra) \ diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index 24df127135e..279aea0bef7 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -109,7 +109,12 @@ extern my_bool wsrep_slave_FK_checks; extern my_bool wsrep_slave_UK_checks; extern bool wsrep_new_cluster; // bootstrap the cluster ? -enum enum_wsrep_OSU_method { WSREP_OSU_TOI, WSREP_OSU_RSU }; +enum enum_wsrep_OSU_method { + WSREP_OSU_TOI, + WSREP_OSU_RSU, + WSREP_OSU_NONE, +}; + enum enum_wsrep_sync_wait { WSREP_SYNC_WAIT_NONE = 0x0, // show, select, begin diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc index 81999d11296..1e27310a201 100644 --- a/sql/wsrep_thd.cc +++ b/sql/wsrep_thd.cc @@ -575,7 +575,7 @@ int wsrep_abort_thd(void *bf_thd_ptr, void *victim_thd_ptr, my_bool signal) DBUG_ENTER("wsrep_abort_thd"); if ( (WSREP(bf_thd) || - ( (WSREP_ON || wsrep_OSU_method_options == WSREP_OSU_RSU) && + ( (WSREP_ON || bf_thd->wsrep_OSU_method == WSREP_OSU_RSU) && bf_thd->wsrep_exec_mode == TOTAL_ORDER) ) && victim_thd) {