diff --git a/include/thr_lock.h b/include/thr_lock.h index f05db666da9..2561709285f 100644 --- a/include/thr_lock.h +++ b/include/thr_lock.h @@ -20,16 +20,6 @@ #ifdef __cplusplus extern "C" { #endif -#ifdef WITH_WSREP -#include - typedef my_bool (* wsrep_thd_is_brute_force_fun)(void *, my_bool); - typedef int (* wsrep_abort_thd_fun)(void *, void *, my_bool); - typedef int (* wsrep_on_fun)(void *); - void wsrep_thr_lock_init( - wsrep_thd_is_brute_force_fun bf_fun, wsrep_abort_thd_fun abort_fun, - my_bool debug, my_bool convert_LOCK_to_trx, wsrep_on_fun on_fun); -#endif - #include #include @@ -104,10 +94,7 @@ typedef struct st_thr_lock_info { pthread_t thread; my_thread_id thread_id; -#ifdef WITH_WSREP void *mysql_thd; // THD pointer - my_bool in_lock_tables; // true, if inside locking session -#endif } THR_LOCK_INFO; @@ -177,6 +164,17 @@ my_bool thr_reschedule_write_lock(THR_LOCK_DATA *data, ulong lock_wait_timeout); void thr_set_lock_wait_callback(void (*before_wait)(void), void (*after_wait)(void)); + +#ifdef WITH_WSREP +#include + typedef my_bool (* wsrep_thd_is_brute_force_fun)(void *, my_bool); + typedef int (* wsrep_abort_thd_fun)(void *, void *, my_bool); + typedef int (* wsrep_on_fun)(void *); + void wsrep_thr_lock_init( + wsrep_thd_is_brute_force_fun bf_fun, wsrep_abort_thd_fun abort_fun, + my_bool debug, my_bool convert_LOCK_to_trx, wsrep_on_fun on_fun); +#endif + #ifdef __cplusplus } #endif diff --git a/include/wsrep.h b/include/wsrep.h new file mode 100644 index 00000000000..c261d9c4b5f --- /dev/null +++ b/include/wsrep.h @@ -0,0 +1,58 @@ +/* Copyright 2014 Codership Oy & SkySQL Ab + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef WSREP_INCLUDED +#define WSERP_INCLUDED + +#ifdef WITH_WSREP +#define IF_WSREP(A,B) A +#define DBUG_ASSERT_IF_WSREP(A) DBUG_ASSERT(A) + +#if !defined(EMBEDDED_LIBRARY) +#define WSREP_FORMAT(my_format) \ + ((wsrep_forced_binlog_format != BINLOG_FORMAT_UNSPEC) ? \ + wsrep_forced_binlog_format : my_format) +#else +#define WSREP_FORMAT(my_format) my_format +#endif /* && !EMBEDDED_LIBRARY */ + +#define WSREP_MYSQL_DB (char *)"mysql" +#define WSREP_TO_ISOLATION_BEGIN(db_, table_, table_list_) \ + if (WSREP_ON && WSREP(thd) && wsrep_to_isolation_begin(thd, db_, table_, table_list_)) \ + goto error; + +#define WSREP_TO_ISOLATION_END \ + if (WSREP_ON && (WSREP(thd) || (thd && thd->wsrep_exec_mode==TOTAL_ORDER))) \ + wsrep_to_isolation_end(thd); + +#define WSREP_DEBUG(...) \ + if (wsrep_debug) WSREP_LOG(sql_print_information, ##__VA_ARGS__) +#define WSREP_INFO(...) WSREP_LOG(sql_print_information, ##__VA_ARGS__) +#define WSREP_WARN(...) WSREP_LOG(sql_print_warning, ##__VA_ARGS__) +#define WSREP_ERROR(...) WSREP_LOG(sql_print_error, ##__VA_ARGS__) + +#else +#define IF_WSREP(A,B) B +#define DBUG_ASSERT_IF_WSREP(A) +#define WSREP_DEBUG(...) +#define WSREP_INFO(...) +#define WSREP_WARN(...) +#define WSREP_ERROR(...) +#define WSREP_FORMAT(my_format) my_format +#define WSREP_TO_ISOLATION_BEGIN(db_, table_, table_list_) +#define WSREP_TO_ISOLATION_END +#endif + +#endif /* WSERP_INCLUDED */ diff --git a/mysys/my_default.c b/mysys/my_default.c index 4721382acc2..1a29fd87a34 100644 --- a/mysys/my_default.c +++ b/mysys/my_default.c @@ -813,7 +813,7 @@ static int search_default_file_with_ext(Process_option_func opt_handler, #ifdef WITH_WSREP /* make sure we do this only once - for top-level file */ if ('\0' == wsrep_defaults_file[0]) - strncpy(wsrep_defaults_file, name, sizeof(wsrep_defaults_file) - 1); + strmake(wsrep_defaults_file, name, sizeof(wsrep_defaults_file) - 1); #endif /* WITH_WSREP */ while (mysql_file_fgets(buff, sizeof(buff) - 1, fp)) diff --git a/mysys/my_static.c b/mysys/my_static.c index 84d2dc64fc6..4c977837e05 100644 --- a/mysys/my_static.c +++ b/mysys/my_static.c @@ -68,6 +68,10 @@ uint my_large_page_size= 0; int volatile my_have_got_alarm=0; /* declare variable to reset */ ulong my_time_to_wait_for_lock=2; /* In seconds */ +#ifdef WITH_WSREP +my_bool mysys_wsrep= 0; +#endif + /* from errors.c */ #ifdef SHARED_LIBRARY const char *globerrs[GLOBERRS]; /* my_error_messages is here */ diff --git a/mysys/mysys_priv.h b/mysys/mysys_priv.h index 9c6855bb92f..80c6a981db2 100644 --- a/mysys/mysys_priv.h +++ b/mysys/mysys_priv.h @@ -62,6 +62,8 @@ extern mysql_mutex_t THR_LOCK_malloc, THR_LOCK_open, THR_LOCK_keycache; extern mysql_mutex_t THR_LOCK_lock, THR_LOCK_net; extern mysql_mutex_t THR_LOCK_charset; +extern my_bool mysys_wsrep; + #include #ifdef HAVE_PSI_INTERFACE diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index 80a43974324..acc7d718546 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -683,10 +683,10 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data, * This needs an condition to check for bf locks first. * TODO: we still have a debug fprintf, this should be removed */ -static inline my_bool +static my_bool wsrep_break_lock( THR_LOCK_DATA *data, struct st_lock_list *lock_queue1, - struct st_lock_list *lock_queue2, struct st_lock_list *wait_queue) + struct st_lock_list *wait_queue) { if (wsrep_on(data->owner->mysql_thd) && wsrep_thd_is_brute_force && @@ -698,7 +698,7 @@ wsrep_break_lock( we know that this conflicting lock must be read lock and furthermore, lock holder is read-only. It is safe to wait for him. */ -#ifdef TODO +#ifdef TODO_WHEN_LOCK_TABLES_IS_A_TRANSACTION if (wsrep_convert_LOCK_to_trx && (THD*)(data->owner->mysql_thd)->in_lock_tables) { @@ -727,22 +727,6 @@ wsrep_break_lock( return FALSE; } } - for (holder=(lock_queue2) ? lock_queue2->data : NULL; - holder; - holder=holder->next) - { - if (!wsrep_thd_is_brute_force(holder->owner->mysql_thd, TRUE)) - { - wsrep_abort_thd(data->owner->mysql_thd, - holder->owner->mysql_thd, FALSE); - } - else - { - if (wsrep_debug) - fprintf(stderr,"WSREP wsrep_break_lock skipping BF lock conflict\n"); - return FALSE; - } - } /* Add our lock to the head of the wait queue */ if (*(wait_queue->last)==wait_queue->data) @@ -846,14 +830,6 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner, ulong lock_wait_timeout) } if (lock->write.data->type == TL_WRITE_ONLY) { -#ifdef WITH_WSREP - if (wsrep_break_lock(data, &lock->write, NULL, &lock->read_wait)) - { - wsrep_lock_inserted= TRUE; - goto wsrep_read_wait; - } -#endif - /* We are not allowed to get a READ lock in this case */ data->type=TL_UNLOCK; result= THR_LOCK_ABORTED; /* Can't wait for this one */ @@ -882,7 +858,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner, ulong lock_wait_timeout) In the latter case we should yield the lock to the writer. */ #ifdef WITH_WSREP - if (wsrep_break_lock(data, &lock->write, NULL, &lock->read_wait)) + if (mysys_wsrep && wsrep_break_lock(data, &lock->write, &lock->read_wait)) { wsrep_lock_inserted= TRUE; } @@ -897,25 +873,12 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner, ulong lock_wait_timeout) { if (lock->write.data && lock->write.data->type == TL_WRITE_ONLY) { -#ifdef WITH_WSREP - if (wsrep_break_lock(data, &lock->write, NULL, &lock->write_wait)) - { - wsrep_lock_inserted=TRUE; - goto wsrep_write_wait; - } -#endif data->type=TL_UNLOCK; result= THR_LOCK_ABORTED; /* Can't wait for this one */ goto end; } if (lock->write.data || lock->read.data) { -#ifdef WITH_WSREP - if (wsrep_break_lock(data, &lock->write, NULL, &lock->write_wait)) - { - goto end; - } -#endif /* Add delayed write lock to write_wait queue, and return at once */ (*lock->write_wait.last)=data; data->prev=lock->write_wait.last; @@ -940,13 +903,6 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner, ulong lock_wait_timeout) /* Allow lock owner to bypass TL_WRITE_ONLY. */ if (!thr_lock_owner_equal(data->owner, lock->write.data->owner)) { -#ifdef WITH_WSREP - if (wsrep_break_lock(data, &lock->write, NULL, &lock->write_wait)) - { - wsrep_lock_inserted=TRUE; - goto wsrep_write_wait; - } -#endif /* We are not allowed to get a lock in this case */ data->type=TL_UNLOCK; result= THR_LOCK_ABORTED; /* Can't wait for this one */ @@ -1051,7 +1007,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner, ulong lock_wait_timeout) lock->read.data->owner->thread_id, data->type)); } #ifdef WITH_WSREP - if (wsrep_break_lock(data, &lock->write, NULL, &lock->write_wait)) + if (mysys_wsrep && wsrep_break_lock(data, &lock->write, &lock->write_wait)) { wsrep_lock_inserted= TRUE; } @@ -1063,7 +1019,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner, ulong lock_wait_timeout) } /* Can't get lock yet; Wait for it */ #ifdef WITH_WSREP - if (wsrep_on(data->owner->mysql_thd) && wsrep_lock_inserted) + if (mysys_wsrep && wsrep_lock_inserted && wsrep_on(data->owner->mysql_thd)) DBUG_RETURN(wait_for_lock(wait_queue, data, 1, lock_wait_timeout)); #endif result= wait_for_lock(wait_queue, data, 0, lock_wait_timeout); diff --git a/scripts/wsrep_sst_common b/scripts/wsrep_sst_common index 333d9dfab9a..88f5d80f53a 100755 --- a/scripts/wsrep_sst_common +++ b/scripts/wsrep_sst_common @@ -94,7 +94,7 @@ done readonly WSREP_SST_OPT_BYPASS readonly WSREP_SST_OPT_BINLOG -# For Bug:1200727 +# State Snapshot Transfer authentication password was displayed in the ps output. Bug fixed #1200727. if my_print_defaults -c $WSREP_SST_OPT_CONF sst | grep -q "wsrep_sst_auth";then if [ -z "$WSREP_SST_OPT_AUTH" -o "$WSREP_SST_OPT_AUTH" = "(null)" ];then WSREP_SST_OPT_AUTH=$(my_print_defaults -c $WSREP_SST_OPT_CONF sst | grep -- "--wsrep_sst_auth" | cut -d= -f2) @@ -114,7 +114,7 @@ wsrep_log() # echo everything to stderr so that it gets into common error log # deliberately made to look different from the rest of the log local readonly tst="$(date +%Y%m%d\ %H:%M:%S.%N | cut -b -21)" - echo "WSREP_SST: $* ($tst)" >&2 + echo "$tst WSREP_SST: " >&2 } wsrep_log_error() diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh index 333d9dfab9a..88f5d80f53a 100644 --- a/scripts/wsrep_sst_common.sh +++ b/scripts/wsrep_sst_common.sh @@ -94,7 +94,7 @@ done readonly WSREP_SST_OPT_BYPASS readonly WSREP_SST_OPT_BINLOG -# For Bug:1200727 +# State Snapshot Transfer authentication password was displayed in the ps output. Bug fixed #1200727. if my_print_defaults -c $WSREP_SST_OPT_CONF sst | grep -q "wsrep_sst_auth";then if [ -z "$WSREP_SST_OPT_AUTH" -o "$WSREP_SST_OPT_AUTH" = "(null)" ];then WSREP_SST_OPT_AUTH=$(my_print_defaults -c $WSREP_SST_OPT_CONF sst | grep -- "--wsrep_sst_auth" | cut -d= -f2) @@ -114,7 +114,7 @@ wsrep_log() # echo everything to stderr so that it gets into common error log # deliberately made to look different from the rest of the log local readonly tst="$(date +%Y%m%d\ %H:%M:%S.%N | cut -b -21)" - echo "WSREP_SST: $* ($tst)" >&2 + echo "$tst WSREP_SST: " >&2 } wsrep_log_error() diff --git a/scripts/wsrep_sst_mysqldump b/scripts/wsrep_sst_mysqldump index 3fce316f379..d4093dbcaef 100755 --- a/scripts/wsrep_sst_mysqldump +++ b/scripts/wsrep_sst_mysqldump @@ -24,11 +24,10 @@ WSREP_SST_OPT_CONF="" . $(dirname $0)/wsrep_sst_common EINVAL=22 +PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin local_ip() { - PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin - [ "$1" = "127.0.0.1" ] && return 0 [ "$1" = "localhost" ] && return 0 [ "$1" = "$(hostname -s)" ] && return 0 @@ -58,10 +57,10 @@ then fi # Check client version -if ! mysql --version | grep 'Distrib 10.0' >/dev/null +if ! mysql --version | grep 'Distrib 10' >/dev/null then mysql --version >&2 - wsrep_log_error "this operation requires MySQL client version 10.0.x" + wsrep_log_error "this operation requires MySQL client version 10 or newer" exit $EINVAL fi diff --git a/scripts/wsrep_sst_mysqldump.sh b/scripts/wsrep_sst_mysqldump.sh index 3fce316f379..d4093dbcaef 100644 --- a/scripts/wsrep_sst_mysqldump.sh +++ b/scripts/wsrep_sst_mysqldump.sh @@ -24,11 +24,10 @@ WSREP_SST_OPT_CONF="" . $(dirname $0)/wsrep_sst_common EINVAL=22 +PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin local_ip() { - PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin - [ "$1" = "127.0.0.1" ] && return 0 [ "$1" = "localhost" ] && return 0 [ "$1" = "$(hostname -s)" ] && return 0 @@ -58,10 +57,10 @@ then fi # Check client version -if ! mysql --version | grep 'Distrib 10.0' >/dev/null +if ! mysql --version | grep 'Distrib 10' >/dev/null then mysql --version >&2 - wsrep_log_error "this operation requires MySQL client version 10.0.x" + wsrep_log_error "this operation requires MySQL client version 10 or newer" exit $EINVAL fi diff --git a/sql/events.cc b/sql/events.cc index a14f1a6c384..5a5a8893f5e 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -1190,7 +1190,8 @@ end: #ifdef WITH_WSREP int wsrep_create_event_query(THD *thd, uchar** buf, size_t* buf_len) { - String log_query; + char buffer[1024]; + String log_query(buffer, sizeof(buffer), &my_charset_bin); if (create_query_string(thd, &log_query)) { diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 3ddd668fd12..23af3825756 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -386,14 +386,17 @@ const char *ha_partition::table_type() const // we can do this since we only support a single engine type return m_file[0]->table_type(); } + + #if defined(WITH_WSREP) && !defined(EMBEDDED_LIBRARY) int ha_partition::wsrep_db_type() const { // we can do this since we only support a single engine type - return ha_legacy_type(m_file[0]->ht); + return partition_ht()->db_type; } #endif /* WITH_WSREP && !EMBEDDED_LIBRARY */ + /* Destructor method diff --git a/sql/handler.cc b/sql/handler.cc index 2b91428460b..2bc6858df48 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -50,9 +50,9 @@ #include "../storage/maria/ha_maria.h" #endif -#ifdef WITH_WSREP #include "wsrep_mysqld.h" -#endif +#include "wsrep.h" + /* While we have legacy_db_type, we have this array to check for dups and to find handlerton from legacy_db_type. @@ -1169,26 +1169,24 @@ int ha_prepare(THD *thd) if ((err= ht->prepare(ht, thd, all))) { #ifdef WITH_WSREP - if (WSREP(thd) && ht->db_type== DB_TYPE_WSREP) + if (ht == wsrep_hton) { - error= 1; - /* avoid sending error, if we need to replay */ + error= 1; + /* avoid sending error, if we need to replay */ if (thd->wsrep_conflict_state!= MUST_REPLAY) { my_error(ER_LOCK_DEADLOCK, MYF(0), err); } } else +#endif { /* not wsrep hton, bail to native mysql behavior */ -#endif - my_error(ER_ERROR_DURING_COMMIT, MYF(0), err); - ha_rollback_trans(thd, all); - error=1; - break; -#ifdef WITH_WSREP + my_error(ER_ERROR_DURING_COMMIT, MYF(0), err); + ha_rollback_trans(thd, all); + error=1; + break; } -#endif } } else @@ -1386,13 +1384,9 @@ int ha_commit_trans(THD *thd, bool all) mdl_request.init(MDL_key::COMMIT, "", "", MDL_INTENTION_EXCLUSIVE, MDL_EXPLICIT); -#ifdef WITH_WSREP - if (!WSREP(thd) && + if (IF_WSREP(!WSREP(thd),1) && thd->mdl_context.acquire_lock(&mdl_request, -#else - if (thd->mdl_context.acquire_lock(&mdl_request, -#endif /* WITH_WSREP */ - thd->variables.lock_wait_timeout)) + thd->variables.lock_wait_timeout)) { ha_rollback_trans(thd, all); thd->wakeup_subsequent_commits(1); @@ -1439,15 +1433,13 @@ int ha_commit_trans(THD *thd, bool all) err= ht->prepare(ht, thd, all); status_var_increment(thd->status_var.ha_prepare_count); if (err) -#ifdef WITH_WSREP { - if (WSREP(thd) && ht->db_type== DB_TYPE_WSREP) +#ifdef WITH_WSREP + if (ht == wsrep_hton) { - error= 1; - switch (err) - { + switch (err) { case WSREP_TRX_SIZE_EXCEEDED: - /* give user size exeeded erro from wsrep_api.h */ + /* give user size exeeded error from wsrep_api.h */ my_error(ER_ERROR_DURING_COMMIT, MYF(0), WSREP_SIZE_EXCEEDED); break; case WSREP_TRX_CERT_FAIL: @@ -1458,15 +1450,11 @@ int ha_commit_trans(THD *thd, bool all) my_error(ER_LOCK_DEADLOCK, MYF(0), err); } } + goto err; } - else - /* not wsrep hton, bail to native mysql behavior */ #endif /* WITH_WSREP */ my_error(ER_ERROR_DURING_COMMIT, MYF(0), err); -#ifdef WITH_WSREP } -#endif /* WITH_WSREP */ - if (err) goto err; @@ -1477,12 +1465,13 @@ int ha_commit_trans(THD *thd, bool all) DBUG_EXECUTE_IF("crash_commit_after_prepare", DBUG_SUICIDE();); #ifdef WITH_WSREP - if (!error && wsrep_is_wsrep_xid(&thd->transaction.xid_state.xid)) + if (!error && WSREP_ON && wsrep_is_wsrep_xid(&thd->transaction.xid_state.xid)) { // xid was rewritten by wsrep xid= wsrep_xid_seqno(&thd->transaction.xid_state.xid); } #endif // WITH_WSREP + if (!is_real_trans) { error= commit_one_phase_2(thd, all, trans, is_real_trans); @@ -1859,13 +1848,10 @@ static my_bool xarecover_handlerton(THD *unused, plugin_ref plugin, got, hton_name(hton)->str); for (int i=0; i < got; i ++) { -#ifdef WITH_WSREP - my_xid x=(wsrep_is_wsrep_xid(&info->list[i]) ? - wsrep_xid_seqno(&info->list[i]) : - info->list[i].get_my_xid()); -#else - my_xid x=info->list[i].get_my_xid(); -#endif /* WITH_WSREP */ + my_xid x= IF_WSREP(WSREP_ON && wsrep_is_wsrep_xid(&info->list[i]) ? + wsrep_xid_seqno(&info->list[i]) : + info->list[i].get_my_xid(), + info->list[i].get_my_xid()); if (!x) // not "mine" - that is generated by external TM { #ifndef DBUG_OFF @@ -3150,15 +3136,12 @@ int handler::update_auto_increment() variables->auto_increment_increment); auto_inc_intervals_count++; /* Row-based replication does not need to store intervals in binlog */ -#ifdef WITH_WSREP - if (((WSREP(thd) && wsrep_emulate_bin_log) || mysql_bin_log.is_open()) && - !thd->is_current_stmt_binlog_format_row()) -#else - if (mysql_bin_log.is_open() && !thd->is_current_stmt_binlog_format_row()) -#endif /* WITH_WSREP */ - thd->auto_inc_intervals_in_cur_stmt_for_binlog.append(auto_inc_interval_for_cur_row.minimum(), - auto_inc_interval_for_cur_row.values(), - variables->auto_increment_increment); + if (IF_WSREP((WSREP(thd) && (wsrep_emulate_bin_log || mysql_bin_log.is_open())), mysql_bin_log.is_open()) + && !thd->is_current_stmt_binlog_format_row()) + thd->auto_inc_intervals_in_cur_stmt_for_binlog. + append(auto_inc_interval_for_cur_row.minimum(), + auto_inc_interval_for_cur_row.values(), + variables->auto_increment_increment); } /* @@ -5776,13 +5759,9 @@ static bool check_table_binlog_row_based(THD *thd, TABLE *table) return (thd->is_current_stmt_binlog_format_row() && table->s->cached_row_logging_check && (thd->variables.option_bits & OPTION_BIN_LOG) && -#ifdef WITH_WSREP /* applier and replayer should not binlog */ - ((WSREP_EMULATE_BINLOG(thd) && (thd->wsrep_exec_mode != REPL_RECV)) || + (IF_WSREP((WSREP_EMULATE_BINLOG(thd) && (thd->wsrep_exec_mode != REPL_RECV)),0) || mysql_bin_log.is_open())); -#else - mysql_bin_log.is_open()); -#endif } @@ -5884,14 +5863,9 @@ static int binlog_log_row(TABLE* table, #ifdef WITH_WSREP /* only InnoDB tables will be replicated through binlog emulation */ - if (WSREP_EMULATE_BINLOG(thd) && - table->file->ht->db_type != DB_TYPE_INNODB && - !(table->file->ht->db_type == DB_TYPE_PARTITION_DB && - (((ha_partition*)(table->file))->wsrep_db_type() == DB_TYPE_INNODB))) - // !strcmp(table->file->table_type(), "InnoDB")) - { + if (WSREP_ON && WSREP_EMULATE_BINLOG(thd) && + table->file->partition_ht()->db_type != DB_TYPE_INNODB) return 0; - } #endif /* WITH_WSREP */ if (check_table_binlog_row_based(thd, table)) { @@ -6240,46 +6214,58 @@ void handler::set_lock_type(enum thr_lock_type lock) int ha_wsrep_abort_transaction(THD *bf_thd, THD *victim_thd, my_bool signal) { DBUG_ENTER("ha_wsrep_abort_transaction"); - if (!WSREP(bf_thd) && + if (!WSREP(bf_thd) && !(wsrep_OSU_method_options == WSREP_OSU_RSU && bf_thd->wsrep_exec_mode == TOTAL_ORDER)) { DBUG_RETURN(0); } - handlerton *hton= installed_htons[DB_TYPE_INNODB]; - if (hton && hton->wsrep_abort_transaction) - { - hton->wsrep_abort_transaction(hton, bf_thd, victim_thd, signal); - } - else - { - WSREP_WARN("cannot abort InnoDB transaction"); - } + THD_TRANS *trans= &victim_thd->transaction.all; + Ha_trx_info *ha_info= trans->ha_list, *ha_info_next; + for (; ha_info; ha_info= ha_info_next) + { + handlerton *hton= ha_info->ht(); + if (!hton->wsrep_abort_transaction) + { + WSREP_WARN("cannot abort WRESP transaction"); + } + else + hton->wsrep_abort_transaction(hton, bf_thd, victim_thd, signal); + ha_info_next= ha_info->next(); + ha_info->reset(); /* keep it conveniently zero-filled */ + } DBUG_RETURN(0); } void ha_wsrep_fake_trx_id(THD *thd) { DBUG_ENTER("ha_wsrep_fake_trx_id"); - if (!WSREP(thd)) + if (!WSREP(thd)) { DBUG_VOID_RETURN; } - handlerton *hton= installed_htons[DB_TYPE_INNODB]; - if (hton && hton->wsrep_fake_trx_id) - { - hton->wsrep_fake_trx_id(hton, thd); - } - else - { - WSREP_WARN("cannot get fake InnoDB transaction ID"); - } + THD_TRANS *trans= &thd->transaction.all; + Ha_trx_info *ha_info= trans->ha_list, *ha_info_next; + for (; ha_info; ha_info= ha_info_next) + { + handlerton *hton= ha_info->ht(); + if (!hton->wsrep_fake_trx_id) + { + WSREP_WARN("cannot get fake InnoDB transaction ID"); + } + else + hton->wsrep_fake_trx_id(hton, thd); + ha_info_next= ha_info->next(); + ha_info->reset(); /* keep it conveniently zero-filled */ + } DBUG_VOID_RETURN; } #endif /* WITH_WSREP */ + + #ifdef TRANS_LOG_MGM_EXAMPLE_CODE /* Example of transaction log management functions based on assumption that logs diff --git a/sql/handler.h b/sql/handler.h index 15382b5979b..9622cef3a11 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -439,7 +439,6 @@ enum legacy_db_type DB_TYPE_BINLOG=21, DB_TYPE_PBXT=23, DB_TYPE_PERFORMANCE_SCHEMA=28, - DB_TYPE_WSREP=41, DB_TYPE_ARIA=42, DB_TYPE_TOKUDB=43, DB_TYPE_FIRST_DYNAMIC=44, diff --git a/sql/item_func.cc b/sql/item_func.cc index ccb7ec56021..13803cff2d6 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2769,7 +2769,19 @@ void Item_func_rand::seed_random(Item *arg) TODO: do not do reinit 'rand' for every execute of PS/SP if args[0] is a constant. */ - uint32 tmp= (uint32) arg->val_int(); + uint32 tmp; +#ifdef WITH_WSREP + if (WSREP(current_thd)) + { + if (current_thd->wsrep_exec_mode==REPL_RECV) + tmp= current_thd->wsrep_rand; + else + tmp= current_thd->wsrep_rand= (uint32) arg->val_int(); + } + else +#endif /* WITH_WSREP */ + tmp= (uint32) arg->val_int(); + my_rnd_init(rand, (uint32) (tmp*0x10001L+55555555L), (uint32) (tmp*0x10000001L)); } diff --git a/sql/lock.cc b/sql/lock.cc index 7d2cddc9b78..a74a12c41c3 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -83,10 +83,7 @@ #include "sql_acl.h" // SUPER_ACL #include #include - -#ifdef WITH_WSREP #include "wsrep_mysqld.h" -#endif /* WITH_WSREP */ /** @defgroup Locking Locking @@ -318,9 +315,6 @@ bool mysql_lock_tables(THD *thd, MYSQL_LOCK *sql_lock, uint flags) /* Copy the lock data array. thr_multi_lock() reorders its contents. */ memmove(sql_lock->locks + sql_lock->lock_count, sql_lock->locks, sql_lock->lock_count * sizeof(*sql_lock->locks)); -#ifdef WITH_WSREP - thd->lock_info.in_lock_tables= thd->in_lock_tables; -#endif /* Lock on the copied half of the lock data array. */ rc= thr_lock_errno_to_mysql[(int) thr_multi_lock(sql_lock->locks + @@ -332,26 +326,21 @@ bool mysql_lock_tables(THD *thd, MYSQL_LOCK *sql_lock, uint flags) end: THD_STAGE_INFO(thd, stage_after_table_lock); -#ifdef WITH_WSREP - thd_proc_info(thd, "mysql_lock_tables(): unlocking tables II"); -#else /* WITH_WSREP */ - thd_proc_info(thd, 0); -#endif /* WITH_WSREP */ if (thd->killed) { thd->send_kill_message(); if (!rc) + { mysql_unlock_tables(thd, sql_lock, 0); + THD_STAGE_INFO(thd, stage_after_table_lock); + } rc= 1; } else if (rc > 1) my_error(rc, MYF(0)); thd->set_time_after_lock(); -#ifdef WITH_WSREP - thd_proc_info(thd, "exit mysqld_lock_tables()"); -#endif /* WITH_WSREP */ DBUG_RETURN(rc); } @@ -396,6 +385,8 @@ static int lock_external(THD *thd, TABLE **tables, uint count) void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock, bool free_lock) { DBUG_ENTER("mysql_unlock_tables"); + THD_STAGE_INFO(thd, stage_unlocking_tables); + if (sql_lock->table_count) unlock_external(thd, sql_lock->table, sql_lock->table_count); if (sql_lock->lock_count) @@ -1069,8 +1060,11 @@ void Global_read_lock::unlock_global_read_lock(THD *thd) thd->mdl_context.release_lock(m_mdl_blocks_commits_lock); m_mdl_blocks_commits_lock= NULL; #ifdef WITH_WSREP - wsrep_locked_seqno= WSREP_SEQNO_UNDEFINED; - wsrep->resume(wsrep); + if (WSREP_ON) + { + wsrep_locked_seqno= WSREP_SEQNO_UNDEFINED; + wsrep->resume(wsrep); + } #endif /* WITH_WSREP */ } thd->mdl_context.release_lock(m_mdl_global_shared_lock); @@ -1105,8 +1099,11 @@ bool Global_read_lock::make_global_read_lock_block_commit(THD *thd) make_global_read_lock_block_commit(), do nothing. */ + if (m_state != GRL_ACQUIRED) + DBUG_RETURN(0); + #ifdef WITH_WSREP - if (m_mdl_blocks_commits_lock) + if (WSREP_ON && m_mdl_blocks_commits_lock) { WSREP_DEBUG("GRL was in block commit mode when entering " "make_global_read_lock_block_commit"); @@ -1114,13 +1111,9 @@ bool Global_read_lock::make_global_read_lock_block_commit(THD *thd) m_mdl_blocks_commits_lock= NULL; wsrep_locked_seqno= WSREP_SEQNO_UNDEFINED; wsrep->resume(wsrep); - m_state= GRL_ACQUIRED; } #endif /* WITH_WSREP */ - if (m_state != GRL_ACQUIRED) - DBUG_RETURN(0); - mdl_request.init(MDL_key::COMMIT, "", "", MDL_SHARED, MDL_EXPLICIT); if (thd->mdl_context.acquire_lock(&mdl_request, @@ -1131,19 +1124,22 @@ bool Global_read_lock::make_global_read_lock_block_commit(THD *thd) m_state= GRL_ACQUIRED_AND_BLOCKS_COMMIT; #ifdef WITH_WSREP - long long ret = wsrep->pause(wsrep); - if (ret >= 0) + if (WSREP_ON) { - wsrep_locked_seqno= ret; - } - else if (ret != -ENOSYS) /* -ENOSYS - no provider */ - { - WSREP_ERROR("Failed to pause provider: %lld (%s)", -ret, strerror(-ret)); + long long ret = wsrep->pause(wsrep); + if (ret >= 0) + { + wsrep_locked_seqno= ret; + } + else if (ret != -ENOSYS) /* -ENOSYS - no provider */ + { + WSREP_ERROR("Failed to pause provider: %lld (%s)", -ret, strerror(-ret)); - /* m_mdl_blocks_commits_lock is always NULL here */ - wsrep_locked_seqno= WSREP_SEQNO_UNDEFINED; - my_error(ER_LOCK_DEADLOCK, MYF(0)); - DBUG_RETURN(TRUE); + DBUG_ASSERT(m_mdl_blocks_commits_lock == NULL); + wsrep_locked_seqno= WSREP_SEQNO_UNDEFINED; + my_error(ER_LOCK_DEADLOCK, MYF(0)); + DBUG_RETURN(TRUE); + } } #endif /* WITH_WSREP */ DBUG_RETURN(FALSE); diff --git a/sql/log.cc b/sql/log.cc index 35bb0ffa0c9..1901efbb6bc 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -52,12 +52,11 @@ #include "sql_plugin.h" #include "rpl_handler.h" -#ifdef WITH_WSREP #include "wsrep_mysqld.h" -#endif /* WITH_WSREP */ #include "debug_sync.h" #include "sql_show.h" #include "my_pthread.h" +#include "wsrep_mysqld.h" /* max size of the log message */ #define MAX_LOG_BUFFER_SIZE 1024 @@ -66,6 +65,7 @@ #define FLAGSTR(V,F) ((V)&(F)?#F" ":"") +handlerton *binlog_hton; LOGGER logger; MYSQL_BIN_LOG mysql_bin_log(&sync_binlog_period); @@ -514,11 +514,6 @@ private: binlog_cache_mngr(const binlog_cache_mngr& info); }; -handlerton *binlog_hton; -#ifdef WITH_WSREP -extern handlerton *wsrep_hton; -#endif - bool LOGGER::is_log_table_enabled(uint log_table_type) { switch (log_table_type) { @@ -532,129 +527,6 @@ bool LOGGER::is_log_table_enabled(uint log_table_type) } } -#ifdef WITH_WSREP -IO_CACHE * get_trans_log(THD * thd) -{ - binlog_cache_mngr *cache_mngr = (binlog_cache_mngr*) - thd_get_ha_data(thd, binlog_hton); - if (cache_mngr) - { - return cache_mngr->get_binlog_cache_log(true); - } - else - { - WSREP_DEBUG("binlog cache not initialized, conn :%ld", thd->thread_id); - return NULL; - } -} - - -bool wsrep_trans_cache_is_empty(THD *thd) -{ - binlog_cache_mngr *const cache_mngr= - (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton); - return (!cache_mngr || cache_mngr->trx_cache.empty()); -} - -void thd_binlog_flush_pending_rows_event(THD *thd, bool stmt_end) -{ - thd->binlog_flush_pending_rows_event(stmt_end); -} -void thd_binlog_trx_reset(THD * thd) -{ - /* - todo: fix autocommit select to not call the caller - */ - if (thd_get_ha_data(thd, binlog_hton) != NULL) - { - binlog_cache_mngr *const cache_mngr= - (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton); - if (cache_mngr) cache_mngr->reset(false, true); - } - thd->clear_binlog_table_maps(); -} - -void thd_binlog_rollback_stmt(THD * thd) -{ - WSREP_DEBUG("thd_binlog_rollback_stmt :%ld", thd->thread_id); - binlog_cache_mngr *const cache_mngr= - (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton); - if (cache_mngr) cache_mngr->trx_cache.set_prev_position(MY_OFF_T_UNDEF); -} - -#ifdef REMOVED -/* - Write the contents of a cache to memory buffer. - - This function quite the same as MYSQL_BIN_LOG::write_cache(), - with the exception that here we write in buffer instead of log file. - */ - -int wsrep_write_cache(IO_CACHE *cache, uchar **buf, int *buf_len) -{ - - if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0)) - return ER_ERROR_ON_WRITE; - uint length= my_b_bytes_in_cache(cache); - long long total_length = 0; - uchar *buf_ptr = NULL; - - do - { - /* bail out if buffer grows too large - This is a temporary fix to avoid flooding replication - TODO: remove this check for 0.7.4 release - */ - if (total_length > wsrep_max_ws_size) - { - WSREP_WARN("transaction size limit (%lld) exceeded: %lld", - wsrep_max_ws_size, total_length); - if (reinit_io_cache(cache, WRITE_CACHE, 0, 0, 0)) - { - WSREP_WARN("failed to initialize io-cache"); - } - if (buf_ptr) my_free(*buf); - *buf_len = 0; - return ER_ERROR_ON_WRITE; - } - if (total_length > 0) - { - *buf_len += length; - *buf = (uchar *)my_realloc(*buf, total_length+length, - MYF(MY_ALLOW_ZERO_PTR)); - if (!*buf) - { - WSREP_ERROR("io cache write problem: %d %d", *buf_len, length); - return ER_ERROR_ON_WRITE; - } - buf_ptr = *buf+total_length; - } - else - { - if (buf_ptr != NULL) - { - WSREP_ERROR("io cache alloc error: %d %d", *buf_len, length); - my_free(*buf); - } - if (length > 0) - { - *buf = (uchar *) my_malloc(length, MYF(0)); - buf_ptr = *buf; - *buf_len = length; - } - } - total_length += length; - - memcpy(buf_ptr, cache->read_pos, length); - cache->read_pos=cache->read_end; - } while ((cache->file >= 0) && (length= my_b_fill(cache))); - - return 0; -} -#endif /* REMOVED */ -#endif - - /** Check if a given table is opened log table @@ -1705,11 +1577,8 @@ binlog_trans_log_savepos(THD *thd, my_off_t *pos) DBUG_ENTER("binlog_trans_log_savepos"); DBUG_ASSERT(pos != NULL); binlog_cache_mngr *const cache_mngr= thd->binlog_setup_trx_data(); -#ifdef WITH_WSREP - DBUG_ASSERT((WSREP(thd) && wsrep_emulate_bin_log) || mysql_bin_log.is_open()); -#else - DBUG_ASSERT(mysql_bin_log.is_open()); -#endif + DBUG_ASSERT_IF_WSREP(((WSREP(thd) && wsrep_emulate_bin_log)) || mysql_bin_log.is_open()); + DBUG_ASSERT(IF_WSREP(1, mysql_bin_log.is_open())); *pos= cache_mngr->trx_cache.get_byte_position(); DBUG_PRINT("return", ("*pos: %lu", (ulong) *pos)); DBUG_VOID_RETURN; @@ -1757,16 +1626,8 @@ binlog_trans_log_truncate(THD *thd, my_off_t pos) int binlog_init(void *p) { binlog_hton= (handlerton *)p; -#ifdef WITH_WSREP - if (WSREP_ON) - binlog_hton->state= SHOW_OPTION_YES; - else - { -#endif /* WITH_WSREP */ - binlog_hton->state=opt_bin_log ? SHOW_OPTION_YES : SHOW_OPTION_NO; -#ifdef WITH_WSREP - } -#endif /* WITH_WSREP */ + binlog_hton->state=IF_WSREP(WSREP_ON || opt_bin_log, opt_bin_log) ? + SHOW_OPTION_YES : SHOW_OPTION_NO; binlog_hton->db_type=DB_TYPE_BINLOG; binlog_hton->savepoint_offset= sizeof(my_off_t); binlog_hton->close_connection= binlog_close_connection; @@ -1889,7 +1750,9 @@ binlog_commit_flush_stmt_cache(THD *thd, bool all, #ifdef WITH_WSREP if (thd->wsrep_mysql_replicated > 0) { - WSREP_DEBUG("avoiding binlog_commit_flush_trx_cache: %d", thd->wsrep_mysql_replicated); + DBUG_ASSERT(WSREP_ON); + WSREP_DEBUG("avoiding binlog_commit_flush_trx_cache: %d", + thd->wsrep_mysql_replicated); return 0; } #endif @@ -2077,7 +1940,11 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all) binlog_cache_mngr *const cache_mngr= (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton); #ifdef WITH_WSREP - if (!cache_mngr) DBUG_RETURN(0); + if (!cache_mngr) + { + DBUG_ASSERT(WSREP(thd)); + DBUG_RETURN(0); + } #endif /* WITH_WSREP */ DBUG_PRINT("debug", @@ -2136,7 +2003,12 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all) binlog_cache_mngr *const cache_mngr= (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton); #ifdef WITH_WSREP - if (!cache_mngr) DBUG_RETURN(0); + if (!cache_mngr) + { + DBUG_ASSERT(WSREP(thd)); + DBUG_RETURN(0); + } + #endif /* WITH_WSREP */ DBUG_PRINT("debug", ("all: %s, all.modified_non_trans_table: %s, stmt.modified_non_trans_table: %s", @@ -2166,12 +2038,8 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all) cache_mngr->reset(false, true); DBUG_RETURN(error); } -#ifdef WITH_WSREP - if (!wsrep_emulate_bin_log && + if (IF_WSREP(!wsrep_emulate_bin_log,1) && mysql_bin_log.check_write_error(thd)) -#else - if (mysql_bin_log.check_write_error(thd)) -#endif { /* "all == true" means that a "rollback statement" triggered the error and @@ -2309,13 +2177,15 @@ bool MYSQL_BIN_LOG::check_write_error(THD *thd) static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv) { - DBUG_ENTER("binlog_savepoint_set"); int error= 1; + DBUG_ENTER("binlog_savepoint_set"); + +#ifdef WITH_WSREP + if (wsrep_emulate_bin_log) + DBUG_RETURN(0); +#endif /* WITH_WSREP */ char buf[1024]; -#ifdef WITH_WSREP - if (wsrep_emulate_bin_log) DBUG_RETURN(0); -#endif /* WITH_WSREP */ String log_query(buf, sizeof(buf), &my_charset_bin); if (log_query.copy(STRING_WITH_LEN("SAVEPOINT "), &my_charset_bin) || append_identifier(thd, &log_query, @@ -2352,14 +2222,9 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv) non-transactional table. Otherwise, truncate the binlog cache starting from the SAVEPOINT command. */ -#ifdef WITH_WSREP - if (!wsrep_emulate_bin_log && + if (IF_WSREP(!wsrep_emulate_bin_log, 1) && unlikely(trans_has_updated_non_trans_table(thd) || (thd->variables.option_bits & OPTION_KEEP_LOG))) -#else - if (unlikely(trans_has_updated_non_trans_table(thd) || - (thd->variables.option_bits & OPTION_KEEP_LOG))) -#endif { char buf[1024]; String log_query(buf, sizeof(buf), &my_charset_bin); @@ -2373,10 +2238,8 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv) DBUG_RETURN(mysql_bin_log.write(&qinfo)); } -#ifdef WITH_WSREP - if (!wsrep_emulate_bin_log) -#endif - binlog_trans_log_truncate(thd, *(my_off_t*)sv); + if (IF_WSREP(!wsrep_emulate_bin_log, 1)) + binlog_trans_log_truncate(thd, *(my_off_t*)sv); DBUG_RETURN(0); } @@ -5505,12 +5368,8 @@ int THD::binlog_write_table_map(TABLE *table, bool is_transactional, is_transactional= 1; /* Pre-conditions */ -#ifdef WITH_WSREP - DBUG_ASSERT(is_current_stmt_binlog_format_row() && - (WSREP_EMULATE_BINLOG(this) || mysql_bin_log.is_open())); -#else - DBUG_ASSERT(is_current_stmt_binlog_format_row() && mysql_bin_log.is_open()); -#endif + DBUG_ASSERT(is_current_stmt_binlog_format_row()); + DBUG_ASSERT(IF_WSREP(WSREP_EMULATE_BINLOG(this), 0) || mysql_bin_log.is_open()); DBUG_ASSERT(table->s->table_map_id != ULONG_MAX); Table_map_log_event @@ -5643,11 +5502,7 @@ MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd, bool is_transactional) { DBUG_ENTER("MYSQL_BIN_LOG::flush_and_set_pending_rows_event(event)"); -#ifdef WITH_WSREP - DBUG_ASSERT(WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()); -#else - DBUG_ASSERT(mysql_bin_log.is_open()); -#endif + DBUG_ASSERT(IF_WSREP(WSREP_EMULATE_BINLOG(thd),0) || mysql_bin_log.is_open()); DBUG_PRINT("enter", ("event: 0x%lx", (long) event)); int error= 0; @@ -5973,13 +5828,9 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info, my_bool *with_annotate) mostly called if is_open() *was* true a few instructions before, but it could have changed since. */ -#ifdef WITH_WSREP /* applier and replayer can skip writing binlog events */ - if ((WSREP_EMULATE_BINLOG(thd) && (thd->wsrep_exec_mode != REPL_RECV)) || - is_open()) -#else - if (likely(is_open())) -#endif + if (IF_WSREP((WSREP_EMULATE_BINLOG(thd) && (thd->wsrep_exec_mode != REPL_RECV)), 0) || + likely(is_open())) { my_off_t UNINIT_VAR(my_org_b_tell); #ifdef HAVE_REPLICATION @@ -6317,14 +6168,16 @@ int MYSQL_BIN_LOG::rotate(bool force_rotate, bool* check_purge) { int error= 0; DBUG_ENTER("MYSQL_BIN_LOG::rotate"); + #ifdef WITH_WSREP - if (WSREP_ON && wsrep_to_isolation) - { - *check_purge= false; - WSREP_DEBUG("avoiding binlog rotate due to TO isolation: %d", - wsrep_to_isolation); - DBUG_RETURN(0); - } + if (wsrep_to_isolation) + { + DBUG_ASSERT(WSREP_ON); + *check_purge= false; + WSREP_DEBUG("avoiding binlog rotate due to TO isolation: %d", + wsrep_to_isolation); + DBUG_RETURN(0); + } #endif //todo: fix the macro def and restore safe_mutex_assert_owner(&LOCK_log); @@ -6873,8 +6726,10 @@ MYSQL_BIN_LOG::write_transaction_to_binlog(THD *thd, DBUG_ENTER("MYSQL_BIN_LOG::write_transaction_to_binlog"); #ifdef WITH_WSREP - if (wsrep_emulate_bin_log) DBUG_RETURN(0); + if (wsrep_emulate_bin_log) + DBUG_RETURN(0); #endif /* WITH_WSREP */ + entry.thd= thd; entry.cache_mngr= cache_mngr; entry.error= 0; @@ -9020,14 +8875,10 @@ TC_LOG_BINLOG::log_and_order(THD *thd, my_xid xid, bool all, binlog_cache_mngr *cache_mngr= thd->binlog_setup_trx_data(); if (!cache_mngr) -#ifdef WITH_WSREP { WSREP_DEBUG("Skipping empty log_xid: %s", thd->query()); DBUG_RETURN(0); } -#else - DBUG_RETURN(0); -#endif /* WITH_WSREP */ cache_mngr->using_xa= TRUE; cache_mngr->xa_xid= xid; @@ -9857,3 +9708,50 @@ maria_declare_plugin(binlog) MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ } maria_declare_plugin_end; + +#ifdef WITH_WSREP +IO_CACHE * get_trans_log(THD * thd) +{ + binlog_cache_mngr *cache_mngr = (binlog_cache_mngr*) + thd_get_ha_data(thd, binlog_hton); + if (cache_mngr) + return cache_mngr->get_binlog_cache_log(true); + + WSREP_DEBUG("binlog cache not initialized, conn :%ld", thd->thread_id); + return NULL; +} + + +bool wsrep_trans_cache_is_empty(THD *thd) +{ + binlog_cache_mngr *const cache_mngr= + (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton); + return (!cache_mngr || cache_mngr->trx_cache.empty()); +} + + +void thd_binlog_trx_reset(THD * thd) +{ + /* + todo: fix autocommit select to not call the caller + */ + if (thd_get_ha_data(thd, binlog_hton) != NULL) + { + binlog_cache_mngr *const cache_mngr= + (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton); + if (cache_mngr) + cache_mngr->reset(false, true); + } + thd->clear_binlog_table_maps(); +} + + +void thd_binlog_rollback_stmt(THD * thd) +{ + WSREP_DEBUG("thd_binlog_rollback_stmt :%ld", thd->thread_id); + binlog_cache_mngr *const cache_mngr= + (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton); + if (cache_mngr) + cache_mngr->trx_cache.set_prev_position(MY_OFF_T_UNDEF); +} +#endif /* WITH_WSREP */ diff --git a/sql/log.h b/sql/log.h index 411b06bbced..3e9a11b8b94 100644 --- a/sql/log.h +++ b/sql/log.h @@ -19,6 +19,8 @@ #include "unireg.h" // REQUIRED: for other includes #include "handler.h" /* my_xid */ +#include "wsrep.h" +#include "wsrep_mysqld.h" class Relay_log_info; @@ -106,10 +108,11 @@ public: int log_and_order(THD *thd, my_xid xid, bool all, bool need_prepare_ordered, bool need_commit_ordered) { -#ifndef WITH_WSREP - DBUG_ASSERT(0 /* Internal error - TC_LOG_DUMMY::log_and_order() called - */); -#endif + /* + If we are not using WSREP this is an Internal error + - TC_LOG_DUMMY::log_and_order() called + */ + DBUG_ASSERT(IF_WSREP(1,0)); return 1; } int unlog(ulong cookie, my_xid xid) { return 0; } @@ -984,22 +987,6 @@ enum enum_binlog_format { BINLOG_FORMAT_UNSPEC=3 ///< thd_binlog_format() returns it when binlog is closed }; -#ifdef WITH_WSREP -IO_CACHE * get_trans_log(THD * thd); -bool wsrep_trans_cache_is_empty(THD *thd); -void thd_binlog_flush_pending_rows_event(THD *thd, bool stmt_end); -void thd_binlog_trx_reset(THD * thd); -void thd_binlog_rollback_stmt(THD * thd); -#endif /* WITH_WSREP */ - -#if defined(WITH_WSREP) && !defined(EMBEDDED_LIBRARY) -#define WSREP_FORMAT(my_format) \ - ((wsrep_forced_binlog_format != BINLOG_FORMAT_UNSPEC) ? \ - wsrep_forced_binlog_format : my_format) -#else -#define WSREP_FORMAT(my_format) my_format -#endif /* WITH_WSREP && !EMBEDDED_LIBRARY */ - int query_error_code(THD *thd, bool not_killed); uint purge_log_get_error_code(int res); diff --git a/sql/log_event.cc b/sql/log_event.cc index e288f4284b7..8e5f7a1f23e 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -44,10 +44,7 @@ #include #include #include "compat56.h" - -#if WITH_WSREP #include "wsrep_mysqld.h" -#endif #endif /* MYSQL_CLIENT */ #include @@ -3094,14 +3091,16 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, master_data_written(0) { time_t end_time; + #ifdef WITH_WSREP /* If Query_log_event will contain non trans keyword (not BEGIN, COMMIT, SAVEPOINT or ROLLBACK) we disable PA for this transaction. */ - if (!is_trans_keyword()) + if (WSREP_ON && !is_trans_keyword()) thd->wsrep_PA_safe= false; #endif /* WITH_WSREP */ + memset(&user, 0, sizeof(user)); memset(&host, 0, sizeof(host)); @@ -4055,11 +4054,7 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi, uint64 sub_id= 0; rpl_gtid gtid; Relay_log_info const *rli= rgi->rli; -#ifdef WITH_WSREP - Rpl_filter *rpl_filter= (rli->mi) ? rli->mi->rpl_filter: NULL; -#else Rpl_filter *rpl_filter= rli->mi->rpl_filter; -#endif /* WITH_WSREP */ bool current_stmt_is_commit; DBUG_ENTER("Query_log_event::do_apply_event"); @@ -4534,8 +4529,9 @@ Query_log_event::do_shall_skip(rpl_group_info *rgi) } } #ifdef WITH_WSREP - else if (wsrep_mysql_replication_bundle && WSREP_ON && thd->wsrep_mysql_replicated > 0 && - (!strncasecmp(query , "BEGIN", 5) || !strncasecmp(query , "COMMIT", 6))) + else if (WSREP_ON && wsrep_mysql_replication_bundle && opt_slave_domain_parallel_threads == 0 && + thd->wsrep_mysql_replicated > 0 && + (is_begin() || is_commit())) { if (++thd->wsrep_mysql_replicated < (int)wsrep_mysql_replication_bundle) { @@ -7378,7 +7374,8 @@ Xid_log_event::do_shall_skip(rpl_group_info *rgi) DBUG_RETURN(Log_event::EVENT_SKIP_COUNT); } #ifdef WITH_WSREP - else if (wsrep_mysql_replication_bundle && WSREP_ON) + else if (wsrep_mysql_replication_bundle && WSREP_ON && + opt_slave_domain_parallel_threads == 0) { if (++thd->wsrep_mysql_replicated < (int)wsrep_mysql_replication_bundle) { @@ -8413,14 +8410,6 @@ err: end_io_cache(&file); if (fd >= 0) mysql_file_close(fd, MYF(0)); -#ifdef WITH_WSREP - if (WSREP(thd)) - thd_proc_info(thd, "exit Create_file_log_event::do_apply_event()"); - else - thd_proc_info(thd, 0); -#else /* WITH_WSREP */ - thd_proc_info(thd, 0); -#endif /* WITH_WSREP */ return error != 0; } #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */ @@ -8592,14 +8581,6 @@ int Append_block_log_event::do_apply_event(rpl_group_info *rgi) err: if (fd >= 0) mysql_file_close(fd, MYF(0)); -#ifdef WITH_WSREP - if (WSREP(thd)) - thd_proc_info(thd, "exit Append_block_log_event::do_apply_event()"); - else - thd_proc_info(thd, 0); -#else /* WITH_WSREP */ - thd_proc_info(thd, 0); -#endif /* WITH_WSREP */ DBUG_RETURN(error); } #endif @@ -9694,7 +9675,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi) thd->wsrep_exec_mode, thd->wsrep_conflict_state, (long long)wsrep_thd_trx_seqno(thd)); - } + } #endif if (thd->is_slave_error || thd->is_fatal_error) { @@ -10842,13 +10823,8 @@ check_table_map(rpl_group_info *rgi, RPL_TABLE_LIST *table_list) DBUG_ENTER("check_table_map"); enum_tbl_map_status res= OK_TO_PROCESS; Relay_log_info *rli= rgi->rli; - -#ifdef WITH_WSREP - if ((rgi->thd->slave_thread /* filtering is for slave only */ || - (WSREP(rgi->thd) && rgi->thd->wsrep_applier)) && -#else - if (rgi->thd->slave_thread /* filtering is for slave only */ && -#endif /* WITH_WSREP */ + if ((rgi->thd->slave_thread /* filtering is for slave only */ || + IF_WSREP((WSREP(rgi->thd) && rgi->thd->wsrep_applier), 0)) && (!rli->mi->rpl_filter->db_ok(table_list->db) || (rli->mi->rpl_filter->is_on() && !rli->mi->rpl_filter->tables_ok("", table_list)))) res= FILTERED_OUT; @@ -11596,23 +11572,20 @@ int Write_rows_log_event::do_exec_row(rpl_group_info *rgi) { DBUG_ASSERT(m_table != NULL); -#ifdef WITH_WSREP -#ifdef WSREP_PROC_INFO - char info[64]; - info[sizeof(info) - 1] = '\0'; - snprintf(info, sizeof(info) - 1, "Write_rows_log_event::write_row(%lld)", - (long long) wsrep_thd_trx_seqno(thd)); - const char* tmp = (WSREP(thd)) ? thd_proc_info(thd, info) : NULL; -#else - const char* tmp = (WSREP(thd)) ? - thd_proc_info(thd,"Write_rows_log_event::write_row()") : NULL; -#endif /* WSREP_PROC_INFO */ -#endif /* WITH_WSREP */ - int error= write_row(rgi, slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT); + const char *tmp= thd->get_proc_info(); + const char *message= "Write_rows_log_event::write_row()"; + +#ifdef WSREP_PROC_INFO + my_snprintf(thd->wsrep_info, sizeof(thd->wsrep_info) - 1, + "Write_rows_log_event::write_row(%lld)", + (long long) wsrep_thd_trx_seqno(thd)); + message= thd->wsrep_info; +#endif /* WSREP_PROC_INFO */ + + thd_proc_info(thd, message); + int error= write_row(rgi, slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT); + thd_proc_info(thd, tmp); -#ifdef WITH_WSREP - if (WSREP(thd)) thd_proc_info(thd, tmp); -#endif /* WITH_WSREP */ if (error && !thd->is_error()) { DBUG_ASSERT(0); @@ -12289,37 +12262,34 @@ Delete_rows_log_event::do_after_row_operations(const Slave_reporting_capability int Delete_rows_log_event::do_exec_row(rpl_group_info *rgi) { int error; + const char *tmp= thd->get_proc_info(); + const char *message= "Delete_rows_log_event::find_row()"; const bool invoke_triggers= slave_run_triggers_for_rbr && !master_had_triggers && m_table->triggers; DBUG_ASSERT(m_table != NULL); -#ifdef WITH_WSREP #ifdef WSREP_PROC_INFO - char info[64]; - info[sizeof(info) - 1] = '\0'; - snprintf(info, sizeof(info) - 1, "Delete_rows_log_event::find_row(%lld)", - (long long) wsrep_thd_trx_seqno(thd)); - const char* tmp = (WSREP(thd)) ? thd_proc_info(thd, info) : NULL; -#else - const char* tmp = (WSREP(thd)) ? - thd_proc_info(thd,"Delete_rows_log_event::find_row()") : NULL; + my_snprintf(thd->wsrep_info, sizeof(thd->wsrep_info) - 1, + "Delete_rows_log_event::find_row(%lld)", + (long long) wsrep_thd_trx_seqno(thd)); + message= thd->wsrep_info; #endif /* WSREP_PROC_INFO */ -#endif /* WITH_WSREP */ + + thd_proc_info(thd, message); if (!(error= find_row(rgi))) { /* Delete the record found, located in record[0] */ -#ifdef WITH_WSREP + message= "Delete_rows_log_event::ha_delete_row()"; #ifdef WSREP_PROC_INFO - snprintf(info, sizeof(info) - 1, + snprintf(thd->wsrep_info, sizeof(thd->wsrep_info) - 1, "Delete_rows_log_event::ha_delete_row(%lld)", (long long) wsrep_thd_trx_seqno(thd)); - if (WSREP(thd)) thd_proc_info(thd, info); -#else - if (WSREP(thd)) thd_proc_info(thd,"Delete_rows_log_event::ha_delete_row()"); -#endif /* WSREP_PROC_INFO */ -#endif /* WITH_WSREP */ + message= thd->wsrep_info; +#endif + thd_proc_info(thd, message); + if (invoke_triggers && process_triggers(TRG_EVENT_DELETE, TRG_ACTION_BEFORE, FALSE)) error= HA_ERR_GENERIC; // in case if error is not set yet @@ -12330,9 +12300,7 @@ int Delete_rows_log_event::do_exec_row(rpl_group_info *rgi) error= HA_ERR_GENERIC; // in case if error is not set yet m_table->file->ha_index_or_rnd_end(); } -#ifdef WITH_WSREP - if (WSREP(thd)) thd_proc_info(thd, tmp); -#endif /* WITH_WSREP */ + thd_proc_info(thd, tmp); return error; } @@ -12460,20 +12428,18 @@ Update_rows_log_event::do_exec_row(rpl_group_info *rgi) { const bool invoke_triggers= slave_run_triggers_for_rbr && !master_had_triggers && m_table->triggers; + const char *tmp= thd->get_proc_info(); + const char *message= "Update_rows_log_event::find_row()"; DBUG_ASSERT(m_table != NULL); -#ifdef WITH_WSREP #ifdef WSREP_PROC_INFO - char info[64]; - info[sizeof(info) - 1] = '\0'; - snprintf(info, sizeof(info) - 1, "Update_rows_log_event::find_row(%lld)", - (long long) wsrep_thd_trx_seqno(thd)); - const char* tmp = (WSREP(thd)) ? thd_proc_info(thd, info) : NULL; -#else - const char* tmp = (WSREP(thd)) ? - thd_proc_info(thd,"Update_rows_log_event::find_row()") : NULL; + my_snprintf(thd->wsrep_info, sizeof(thd->wsrep_info) - 1, + "Update_rows_log_event::find_row(%lld)", + (long long) wsrep_thd_trx_seqno(thd)); + message= thd->wsrep_info; #endif /* WSREP_PROC_INFO */ -#endif /* WITH_WSREP */ + + thd_proc_info(thd, message); int error= find_row(rgi); if (error) { @@ -12483,6 +12449,7 @@ Update_rows_log_event::do_exec_row(rpl_group_info *rgi) */ m_curr_row= m_curr_row_end; unpack_current_row(rgi); + thd_proc_info(thd, tmp); return error; } @@ -12500,18 +12467,16 @@ Update_rows_log_event::do_exec_row(rpl_group_info *rgi) store_record(m_table,record[1]); m_curr_row= m_curr_row_end; -#ifdef WITH_WSREP + message= "Update_rows_log_event::unpack_current_row()"; #ifdef WSREP_PROC_INFO - snprintf(info, sizeof(info) - 1, - "Update_rows_log_event::unpack_current_row(%lld)", - (long long) wsrep_thd_trx_seqno(thd)); - if (WSREP(thd)) thd_proc_info(thd, info); -#else - if (WSREP(thd)) - thd_proc_info(thd,"Update_rows_log_event::unpack_current_row()"); + my_snprintf(thd->wsrep_info, sizeof(thd->wsrep_info) - 1, + "Update_rows_log_event::unpack_current_row(%lld)", + (long long) wsrep_thd_trx_seqno(thd)); + message= thd->wsrep_info; #endif /* WSREP_PROC_INFO */ -#endif /* WITH_WSREP */ + /* this also updates m_curr_row_end */ + thd_proc_info(thd, message); if ((error= unpack_current_row(rgi))) goto err; @@ -12529,17 +12494,15 @@ Update_rows_log_event::do_exec_row(rpl_group_info *rgi) DBUG_DUMP("new values", m_table->record[0], m_table->s->reclength); #endif -#ifdef WITH_WSREP + message= "Update_rows_log_event::ha_update_row()"; #ifdef WSREP_PROC_INFO - snprintf(info, sizeof(info) - 1, - "Update_rows_log_event::ha_update_row(%lld)", - (long long) wsrep_thd_trx_seqno(thd)); - if (WSREP(thd)) thd_proc_info(thd, info); -#else - if (WSREP(thd)) thd_proc_info(thd,"Update_rows_log_event::ha_update_row()"); + my_snprintf(thd->wsrep_info, sizeof(thd->wsrep_info) - 1, + "Update_rows_log_event::ha_update_row(%lld)", + (long long) wsrep_thd_trx_seqno(thd)); + message= thd->wsrep_info; #endif /* WSREP_PROC_INFO */ -#endif /* WITH_WSREP */ + thd_proc_info(thd, message); if (invoke_triggers && process_triggers(TRG_EVENT_UPDATE, TRG_ACTION_BEFORE, TRUE)) { @@ -12555,9 +12518,8 @@ Update_rows_log_event::do_exec_row(rpl_group_info *rgi) process_triggers(TRG_EVENT_UPDATE, TRG_ACTION_AFTER, TRUE)) error= HA_ERR_GENERIC; // in case if error is not set yet -#ifdef WITH_WSREP - if (WSREP(thd)) thd_proc_info(thd, tmp); -#endif /* WITH_WSREP */ + thd_proc_info(thd, tmp); + err: m_table->file->ha_index_or_rnd_end(); return error; @@ -12647,7 +12609,9 @@ void Incident_log_event::pack_info(THD *thd, Protocol *protocol) m_incident, description(), m_message.str); protocol->store(buf, bytes, &my_charset_bin); } -#endif +#endif /* MYSQL_CLIENT */ + + #if WITH_WSREP && !defined(MYSQL_CLIENT) Format_description_log_event *wsrep_format_desc; // TODO: free them at the end /* @@ -12661,13 +12625,12 @@ Log_event* wsrep_read_log_event( char **arg_buf, size_t *arg_buf_len, const Format_description_log_event *description_event) { - DBUG_ENTER("wsrep_read_log_event"); char *head= (*arg_buf); - uint data_len = uint4korr(head + EVENT_LEN_OFFSET); char *buf= (*arg_buf); const char *error= 0; Log_event *res= 0; + DBUG_ENTER("wsrep_read_log_event"); if (data_len > WSREP_MAX_ALLOWED_PACKET) { diff --git a/sql/log_event.h b/sql/log_event.h index 2091d968558..6d0281bd790 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -1340,7 +1340,12 @@ public: */ int apply_event(rpl_group_info *rgi) { - return do_apply_event(rgi); + int res; + THD_STAGE_INFO(thd, stage_apply_event); + res= do_apply_event(rgi); + THD_STAGE_INFO(thd, stage_after_apply_event); + res= 0; + return res; } diff --git a/sql/mdl.cc b/sql/mdl.cc index 2172e34cd2a..e5e906ae5d0 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -22,19 +22,9 @@ #include #include #include - -#ifdef WITH_WSREP #include "wsrep_mysqld.h" #include "wsrep_thd.h" -extern "C" my_thread_id wsrep_thd_thread_id(THD *thd); -extern "C" char *wsrep_thd_query(THD *thd); -void sql_print_information(const char *format, ...) - ATTRIBUTE_FORMAT(printf, 1, 2); -extern bool -wsrep_grant_mdl_exception(MDL_context *requestor_ctx, - MDL_ticket *ticket); -#endif /* WITH_WSREP */ #ifdef HAVE_PSI_INTERFACE static PSI_mutex_key key_MDL_map_mutex; static PSI_mutex_key key_MDL_wait_LOCK_wait_status; @@ -1511,22 +1501,23 @@ void MDL_lock::Ticket_list::add_ticket(MDL_ticket *ticket) DBUG_ASSERT(ticket->get_lock()); #ifdef WITH_WSREP if ((this == &(ticket->get_lock()->m_waiting)) && - wsrep_thd_is_BF((void *)(ticket->get_ctx()->wsrep_get_thd()), false)) + wsrep_thd_is_BF((void *)(ticket->get_ctx()->get_thd()), false)) { Ticket_iterator itw(ticket->get_lock()->m_waiting); Ticket_iterator itg(ticket->get_lock()->m_granted); + DBUG_ASSERT(WSREP_ON); MDL_ticket *waiting, *granted; MDL_ticket *prev=NULL; bool added= false; while ((waiting= itw++) && !added) { - if (!wsrep_thd_is_BF((void *)(waiting->get_ctx()->wsrep_get_thd()), true)) + if (!wsrep_thd_is_BF((void *)(waiting->get_ctx()->get_thd()), true)) { WSREP_DEBUG("MDL add_ticket inserted before: %lu %s", - wsrep_thd_thread_id(waiting->get_ctx()->wsrep_get_thd()), - wsrep_thd_query(waiting->get_ctx()->wsrep_get_thd())); + wsrep_thd_thread_id(waiting->get_ctx()->get_thd()), + wsrep_thd_query(waiting->get_ctx()->get_thd())); m_list.insert_after(prev, ticket); added= true; } @@ -1547,16 +1538,14 @@ void MDL_lock::Ticket_list::add_ticket(MDL_ticket *ticket) } } else +#endif /* WITH_WSREP */ { -#endif /* WITH_WSREP */ - /* - Add ticket to the *back* of the queue to ensure fairness - among requests with the same priority. - */ - m_list.push_back(ticket); -#ifdef WITH_WSREP + /* + Add ticket to the *back* of the queue to ensure fairness + among requests with the same priority. + */ + m_list.push_back(ticket); } -#endif /* WITH_WSREP */ m_bitmap|= MDL_BIT(ticket->get_type()); } @@ -1897,9 +1886,7 @@ MDL_lock::can_grant_lock(enum_mdl_type type_arg, bool can_grant= FALSE; bitmap_t waiting_incompat_map= incompatible_waiting_types_bitmap()[type_arg]; bitmap_t granted_incompat_map= incompatible_granted_types_bitmap()[type_arg]; -#ifdef WITH_WSREP bool wsrep_can_grant= TRUE; -#endif /* WITH_WSREP */ /* New lock request can be satisfied iff: @@ -1922,55 +1909,49 @@ MDL_lock::can_grant_lock(enum_mdl_type type_arg, { if (ticket->get_ctx() != requestor_ctx && ticket->is_incompatible_when_granted(type_arg)) -#ifdef WITH_WSREP { - if (wsrep_thd_is_BF((void *)(requestor_ctx->wsrep_get_thd()),false) && + if (IF_WSREP(!WSREP_ON, 0)) + break; +#ifdef WITH_WSREP + if (wsrep_thd_is_BF((void *)(requestor_ctx->get_thd()),false) && key.mdl_namespace() == MDL_key::GLOBAL) { WSREP_DEBUG("global lock granted for BF: %lu %s", - wsrep_thd_thread_id(requestor_ctx->wsrep_get_thd()), - wsrep_thd_query(requestor_ctx->wsrep_get_thd())); + wsrep_thd_thread_id(requestor_ctx->get_thd()), + wsrep_thd_query(requestor_ctx->get_thd())); can_grant = true; } else if (!wsrep_grant_mdl_exception(requestor_ctx, ticket)) { wsrep_can_grant= FALSE; - if (wsrep_log_conflicts) - { - MDL_lock * lock = ticket->get_lock(); - WSREP_INFO( - "MDL conflict db=%s table=%s ticket=%d solved by %s", - lock->key.db_name(), lock->key.name(), ticket->get_type(), "abort" - ); + if (wsrep_log_conflicts) + { + MDL_lock * lock = ticket->get_lock(); + WSREP_INFO( + "MDL conflict db=%s table=%s ticket=%d solved by %s", + lock->key.db_name(), lock->key.name(), ticket->get_type(), + "abort" ); } } else - { can_grant= TRUE; - } + /* Continue loop */ } -#else - break; #endif /* WITH_WSREP */ } -#ifdef WITH_WSREP - if ((ticket == NULL) && wsrep_can_grant) -#else - if (ticket == NULL) /* Incompatible locks are our own. */ -#endif /* WITH_WSREP */ - + if ((ticket == NULL) && IF_WSREP(wsrep_can_grant, 1)) can_grant= TRUE; } } #ifdef WITH_WSREP else { - if (wsrep_thd_is_BF((void *)(requestor_ctx->wsrep_get_thd()), false) && + if (wsrep_thd_is_BF((void *)(requestor_ctx->get_thd()), false) && key.mdl_namespace() == MDL_key::GLOBAL) { WSREP_DEBUG("global lock granted for BF (waiting queue): %lu %s", - wsrep_thd_thread_id(requestor_ctx->wsrep_get_thd()), - wsrep_thd_query(requestor_ctx->wsrep_get_thd())); + wsrep_thd_thread_id(requestor_ctx->get_thd()), + wsrep_thd_query(requestor_ctx->get_thd())); can_grant = true; } } @@ -3019,12 +3000,7 @@ void MDL_context::release_locks_stored_before(enum_mdl_duration duration, DBUG_VOID_RETURN; } -#ifdef WITH_WSREP -void MDL_context::release_explicit_locks() -{ - release_locks_stored_before(MDL_EXPLICIT, NULL); -} -#endif + /** Release all explicit locks in the context which correspond to the same name/object as this lock request. @@ -3332,7 +3308,16 @@ void MDL_context::set_transaction_duration_for_all_locks() ticket->m_duration= MDL_TRANSACTION; #endif } + + #ifdef WITH_WSREP + +void MDL_context::release_explicit_locks() +{ + release_locks_stored_before(MDL_EXPLICIT, NULL); +} + + void MDL_ticket::wsrep_report(bool debug) { if (debug) diff --git a/sql/mdl.h b/sql/mdl.h index 639a8966b33..231f95d7419 100644 --- a/sql/mdl.h +++ b/sql/mdl.h @@ -776,13 +776,10 @@ public: m_tickets[MDL_TRANSACTION].is_empty() && m_tickets[MDL_EXPLICIT].is_empty()); } - -#ifdef WITH_WSREP inline bool has_transactional_locks() const { return !m_tickets[MDL_TRANSACTION].is_empty(); } -#endif /* WITH_WSREP */ MDL_savepoint mdl_savepoint() { @@ -923,7 +920,6 @@ private: */ MDL_wait_for_subgraph *m_waiting_for; private: - THD *get_thd() const { return m_owner->get_thd(); } MDL_ticket *find_ticket(MDL_request *mdl_req, enum_mdl_duration *duration); void release_locks_stored_before(enum_mdl_duration duration, MDL_ticket *sentinel); @@ -932,9 +928,7 @@ private: MDL_ticket **out_ticket); public: -#ifdef WITH_WSREP - THD *wsrep_get_thd() const { return get_thd(); } -#endif + THD *get_thd() const { return m_owner->get_thd(); } void find_deadlock(); ulong get_thread_id() const { return thd_get_thread_id(get_thd()); } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index b2cbeebae49..1288f2c2fc7 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -71,13 +71,11 @@ #include "scheduler.h" #include #include "debug_sync.h" -#ifdef WITH_WSREP #include "wsrep_mysqld.h" #include "wsrep_var.h" #include "wsrep_thd.h" #include "wsrep_sst.h" -ulong wsrep_running_threads = 0; // # of currently running wsrep threads -#endif + #include "sql_callback.h" #include "threadpool.h" @@ -359,7 +357,8 @@ static bool volatile select_thread_in_use, signal_thread_in_use; static volatile bool ready_to_exit; static my_bool opt_debugging= 0, opt_external_locking= 0, opt_console= 0; static my_bool opt_short_log_format= 0; -static uint kill_cached_threads, wake_thread; +uint kill_cached_threads; +static uint wake_thread; ulong max_used_connections; static volatile ulong cached_thread_count= 0; static char *mysqld_user, *mysqld_chroot; @@ -367,25 +366,19 @@ static char *default_character_set_name; static char *character_set_filesystem_name; static char *lc_messages; static char *lc_time_names_name; -#ifndef WITH_WSREP -static char *my_bind_addr_str; -#else char *my_bind_addr_str; -#endif /* WITH_WSREP */ static char *default_collation_name; char *default_storage_engine, *default_tmp_storage_engine; static char compiled_default_collation_name[]= MYSQL_DEFAULT_COLLATION_NAME; static I_List thread_cache; static bool binlog_format_used= false; LEX_STRING opt_init_connect, opt_init_slave; -static mysql_cond_t COND_thread_cache, COND_flush_thread_cache; +mysql_cond_t COND_thread_cache; +static mysql_cond_t COND_flush_thread_cache; static DYNAMIC_ARRAY all_options; /* Global variables */ -#ifdef WITH_WSREP -ulong my_bind_addr; -#endif /* WITH_WSREP */ bool opt_bin_log, opt_bin_log_used=0, opt_ignore_builtin_innodb= 0; my_bool opt_log, opt_slow_log, debug_assert_if_crashed_table= 0, opt_help= 0; static my_bool opt_abort; @@ -479,10 +472,6 @@ ulong opt_binlog_rows_event_max_size; my_bool opt_master_verify_checksum= 0; my_bool opt_slave_sql_verify_checksum= 1; const char *binlog_format_names[]= {"MIXED", "STATEMENT", "ROW", NullS}; -#ifdef WITH_WSREP -const char *wsrep_binlog_format_names[]= - {"MIXED", "STATEMENT", "ROW", "NONE", NullS}; -#endif /*WITH_WSREP */ #ifdef HAVE_INITGROUPS volatile sig_atomic_t calling_initgroups= 0; /**< Used in SIGSEGV handler. */ #endif @@ -748,6 +737,7 @@ mysql_cond_t COND_server_started; int mysqld_server_started=0, mysqld_server_initialized= 0; File_parser_dummy_hook file_parser_dummy_hook; + #ifdef WITH_WSREP mysql_mutex_t LOCK_wsrep_ready; mysql_cond_t COND_wsrep_ready; @@ -763,7 +753,10 @@ mysql_cond_t COND_wsrep_replaying; mysql_mutex_t LOCK_wsrep_slave_threads; mysql_mutex_t LOCK_wsrep_desync; int wsrep_replaying= 0; -static void wsrep_close_threads(THD* thd); +ulong wsrep_running_threads = 0; // # of currently running wsrep threads +ulong my_bind_addr; +const char *wsrep_binlog_format_names[]= + {"MIXED", "STATEMENT", "ROW", "NONE", NullS}; #endif /* WITH_WSREP */ /* replication parameters, if master_host is not NULL, we are a slave */ @@ -1465,7 +1458,7 @@ bool mysqld_embedded=0; bool mysqld_embedded=1; #endif -static my_bool plugins_are_initialized= FALSE; +my_bool plugins_are_initialized= FALSE; #ifndef DBUG_OFF static const char* default_dbug_option; @@ -1772,7 +1765,8 @@ static void close_connections(void) #endif #ifdef WITH_WSREP /* - * TODO: this code block may turn out redundant. wsrep->disconnect() + * WSREP_TODO: + * this code block may turn out redundant. wsrep->disconnect() * should terminate slave threads gracefully, and we don't need * to signal them here. * The code here makes sure mysqld will not hang during shutdown @@ -1950,15 +1944,19 @@ static void __cdecl kill_server(int sig_ptr) } } #endif + #ifdef WITH_WSREP - if (WSREP_ON) wsrep_stop_replication(NULL); + if (WSREP_ON) + wsrep_stop_replication(NULL); #endif close_connections(); + #ifdef WITH_WSREP - if (wsrep_inited == 1) + if (WSREP_ON && wsrep_inited == 1) wsrep_deinit(true); #endif + if (sig != MYSQL_KILL_SIGNAL && sig != 0) unireg_abort(1); /* purecov: inspected */ @@ -2053,14 +2051,18 @@ extern "C" void unireg_abort(int exit_code) usage(); if (exit_code) sql_print_error("Aborting\n"); + #ifdef WITH_WSREP + /* Check if wsrep class is used. If yes, then cleanup wsrep */ if (wsrep) { - /* This is an abort situation, we cannot expect to gracefully close all - * wsrep threads here, we can only diconnect from service */ + /* + This is an abort situation, we cannot expect to gracefully close all + wsrep threads here, we can only diconnect from service + */ wsrep_close_client_connections(FALSE); shutdown_in_progress= 1; - THD* thd(0); + THD *thd(0); wsrep->disconnect(wsrep); WSREP_INFO("Service disconnected."); wsrep_close_threads(thd); /* this won't close all threads */ @@ -2072,6 +2074,7 @@ extern "C" void unireg_abort(int exit_code) wsrep_deinit(true); } #endif // WITH_WSREP + clean_up(!opt_abort && (exit_code || !opt_bootstrap)); /* purecov: inspected */ DBUG_PRINT("quit",("done with cleanup in unireg_abort")); mysqld_exit(exit_code); @@ -2621,6 +2624,7 @@ static MYSQL_SOCKET activate_tcp_port(uint port) unireg_abort(1); } #if defined(WITH_WSREP) && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) + if (WSREP_ON) (void) fcntl(mysql_socket_getfd(ip_sock), F_SETFD, FD_CLOEXEC); #endif /* WITH_WSREP */ @@ -2751,7 +2755,8 @@ static void network_init(void) sql_print_warning("listen() on Unix socket failed with error %d", socket_errno); #if defined(WITH_WSREP) && defined(HAVE_FCNTL) - (void) fcntl(mysql_socket_getfd(unix_sock), F_SETFD, FD_CLOEXEC); + if (WSREP_ON) + (void) fcntl(mysql_socket_getfd(unix_sock), F_SETFD, FD_CLOEXEC); #endif /* WITH_WSREP */ } #endif @@ -2833,15 +2838,16 @@ void dec_connection_count(THD *thd) applier as well as rollbacker threads. */ if (!thd->wsrep_applier) + return; #endif /* WITH_WSREP */ - { - DBUG_ASSERT(*thd->scheduler->connection_count > 0); - mysql_mutex_lock(&LOCK_connection_count); - (*thd->scheduler->connection_count)--; - mysql_mutex_unlock(&LOCK_connection_count); - } + + DBUG_ASSERT(*thd->scheduler->connection_count > 0); + mysql_mutex_lock(&LOCK_connection_count); + (*thd->scheduler->connection_count)--; + mysql_mutex_unlock(&LOCK_connection_count); } + /* Delete THD and decrement thread counters, including thread_running */ @@ -3014,11 +3020,7 @@ bool one_thread_per_connection_end(THD *thd, bool put_in_cache) /* Mark that current_thd is not valid anymore */ set_current_thd(0); -#ifdef WITH_WSREP - if (put_in_cache && cache_thread() && !wsrep_applier) -#else - if (put_in_cache && cache_thread()) -#endif /* WITH_WSREP */ + if (put_in_cache && cache_thread() && IF_WSREP(!wsrep_applier, 1)) DBUG_RETURN(0); // Thread is reused /* @@ -4139,6 +4141,7 @@ static int init_common_variables() } else opt_log_basename= glob_hostname; + #ifdef WITH_WSREP if (0 == wsrep_node_name || 0 == wsrep_node_name[0]) { @@ -4146,6 +4149,7 @@ static int init_common_variables() wsrep_node_name= my_strdup(glob_hostname, MYF(MY_WME)); } #endif /* WITH_WSREP */ + if (!*pidfile_name) { strmake(pidfile_name, opt_log_basename, sizeof(pidfile_name)-5); @@ -4205,11 +4209,16 @@ static int init_common_variables() compile_time_assert(sizeof(com_status_vars)/sizeof(com_status_vars[0]) - 1 == SQLCOM_END + 8); #endif + #ifdef WITH_WSREP - /* This is a protection against mutually incompatible option values. */ + /* + This is a protection against mutually incompatible option values. + Note WSREP_ON == global_system_variables.wsrep_on + */ if (WSREP_ON && wsrep_check_opts (remaining_argc, remaining_argv)) global_system_variables.wsrep_on= 0; #endif /* WITH_WSREP */ + if (get_options(&remaining_argc, &remaining_argv)) return 1; set_server_version(); @@ -4923,18 +4932,10 @@ static int init_server_components() /* need to configure logging before initializing storage engines */ if (!opt_bin_log_used) { -#ifdef WITH_WSREP - if (!WSREP_ON && opt_log_slave_updates) -#else - if (opt_log_slave_updates) -#endif + if (IF_WSREP(!WSREP_ON,1) && opt_log_slave_updates) sql_print_warning("You need to use --log-bin to make " "--log-slave-updates work."); -#ifdef WITH_WSREP - if (!WSREP_ON && binlog_format_used) -#else - if (binlog_format_used) -#endif + if (IF_WSREP(!WSREP_ON, 1) && binlog_format_used) sql_print_warning("You need to use --log-bin to make " "--binlog-format work."); } @@ -5018,7 +5019,7 @@ a file name for --log-bin-index option", opt_binlog_index_name); after SST has happened */ } - if (!wsrep_recovery) + if (WSREP_ON && !wsrep_recovery) { if (opt_bootstrap) // bootsrap option given - disable wsrep functionality { @@ -5192,23 +5193,34 @@ a file name for --log-bin-index option", opt_binlog_index_name); #endif #ifdef WITH_WSREP - if (!opt_bin_log) + if (WSREP_ON && !opt_bin_log) { wsrep_emulate_bin_log= 1; } #endif + + /* if total_ha_2pc <= 1 + tc_log = tc_log_dummy + else + if opt_bin_log == true + tc_log = mysql_bin_log + else + if WITH_WSREP + if WSREP_ON + tc_log = tc_log_dummy + else + tc_log = tc_log_mmap + else + tc_log=tc_log_mmap + */ tc_log= (total_ha_2pc > 1 ? (opt_bin_log ? (TC_LOG *) &mysql_bin_log : + IF_WSREP((WSREP_ON ? (TC_LOG *) &tc_log_dummy : + (TC_LOG *) &tc_log_mmap), (TC_LOG *) &tc_log_mmap)) : + (TC_LOG *) &tc_log_dummy); + #ifdef WITH_WSREP - (WSREP_ON ? - (TC_LOG *) &tc_log_dummy : - (TC_LOG *) &tc_log_mmap)) : -#else - (TC_LOG *) &tc_log_mmap) : -#endif - (TC_LOG *) &tc_log_dummy); -#ifdef WITH_WSREP - WSREP_DEBUG("Initial TC log open: %s", + WSREP_DEBUG("Initial TC log open: %s", (tc_log == &mysql_bin_log) ? "binlog" : (tc_log == &tc_log_mmap) ? "mmap" : (tc_log == &tc_log_dummy) ? "dummy" : "unknown" @@ -5296,468 +5308,6 @@ static void create_shutdown_thread() #endif /* EMBEDDED_LIBRARY */ -#ifdef WITH_WSREP -typedef void (*wsrep_thd_processor_fun)(THD *); - -pthread_handler_t start_wsrep_THD(void *arg) -{ - THD *thd; - rpl_sql_thread_info sql_info(NULL); - wsrep_thd_processor_fun processor= (wsrep_thd_processor_fun)arg; - - if (my_thread_init()) - { - WSREP_ERROR("Could not initialize thread"); - return(NULL); - } - - if (!(thd= new THD(true))) - { - return(NULL); - } - mysql_mutex_lock(&LOCK_thread_count); - thd->thread_id=thread_id++; - - thd->real_id=pthread_self(); // Keep purify happy - thread_count++; - thread_created++; - threads.append(thd); - - my_net_init(&thd->net,(st_vio*) 0, MYF(0)); - - DBUG_PRINT("wsrep",(("creating thread %lld"), (long long)thd->thread_id)); - thd->prior_thr_create_utime= thd->start_utime= microsecond_interval_timer(); - (void) mysql_mutex_unlock(&LOCK_thread_count); - - /* from bootstrap()... */ - thd->bootstrap=1; - thd->max_client_packet_length= thd->net.max_packet; - thd->security_ctx->master_access= ~(ulong)0; - thd->system_thread_info.rpl_sql_info= &sql_info; - - /* from handle_one_connection... */ - pthread_detach_this_thread(); - - mysql_thread_set_psi_id(thd->thread_id); - thd->thr_create_utime= microsecond_interval_timer(); - if (MYSQL_CALLBACK_ELSE(thread_scheduler, init_new_connection_thread, (), 0)) - { - close_connection(thd, ER_OUT_OF_RESOURCES); - statistic_increment(aborted_connects,&LOCK_status); - MYSQL_CALLBACK(thread_scheduler, end_thread, (thd, 0)); - - return(NULL); - } - -// - /* - handle_one_connection() is normally the only way a thread would - start and would always be on the very high end of the stack , - therefore, the thread stack always starts at the address of the - first local variable of handle_one_connection, which is thd. We - need to know the start of the stack so that we could check for - stack overruns. - */ - DBUG_PRINT("wsrep", ("handle_one_connection called by thread %lld\n", - (long long)thd->thread_id)); - /* now that we've called my_thread_init(), it is safe to call DBUG_* */ - - thd->thread_stack= (char*) &thd; - if (thd->store_globals()) - { - close_connection(thd, ER_OUT_OF_RESOURCES); - statistic_increment(aborted_connects,&LOCK_status); - MYSQL_CALLBACK(thread_scheduler, end_thread, (thd, 0)); - delete thd; - - return(NULL); - } - - thd->system_thread= SYSTEM_THREAD_SLAVE_SQL; - thd->security_ctx->skip_grants(); - - /* handle_one_connection() again... */ - //thd->version= refresh_version; - thd->proc_info= 0; - thd->set_command(COM_SLEEP); - thd->set_time(); - thd->init_for_queries(); - - mysql_mutex_lock(&LOCK_thread_count); - wsrep_running_threads++; - mysql_cond_broadcast(&COND_thread_count); - mysql_mutex_unlock(&LOCK_thread_count); - - processor(thd); - - close_connection(thd, 0); - - mysql_mutex_lock(&LOCK_thread_count); - wsrep_running_threads--; - WSREP_DEBUG("wsrep running threads now: %lu", wsrep_running_threads); - mysql_cond_broadcast(&COND_thread_count); - mysql_mutex_unlock(&LOCK_thread_count); - - // Note: We can't call THD destructor without crashing - // if plugins have not been initialized. However, in most of the - // cases this means that pre SE initialization SST failed and - // we are going to exit anyway. - if (plugins_are_initialized) - { - net_end(&thd->net); - MYSQL_CALLBACK(thread_scheduler, end_thread, (thd, 1)); - } - else - { - // TODO: lightweight cleanup to get rid of: - // 'Error in my_thread_global_end(): 2 threads didn't exit' - // at server shutdown - } - - my_thread_end(); - if (thread_handling > SCHEDULER_ONE_THREAD_PER_CONNECTION) - { - mysql_mutex_lock(&LOCK_thread_count); - delete thd; - thread_count--; - mysql_mutex_unlock(&LOCK_thread_count); - } - return(NULL); -} - -/**/ -static bool abort_replicated(THD *thd) -{ - bool ret_code= false; - if (thd->wsrep_query_state== QUERY_COMMITTING) - { - if (wsrep_debug) WSREP_INFO("aborting replicated trx: %lu", thd->real_id); - - (void)wsrep_abort_thd(thd, thd, TRUE); - ret_code= true; - } - return ret_code; -} -/**/ -static inline bool is_client_connection(THD *thd) -{ -#if REMOVE -// REMOVE THIS LATER (lp:777201). Below we had to add an explicit check for -// wsrep_applier since wsrep_exec_mode didn't seem to always work -if (thd->wsrep_applier && thd->wsrep_exec_mode != REPL_RECV) -WSREP_WARN("applier has wsrep_exec_mode = %d", thd->wsrep_exec_mode); - - if ( thd->slave_thread || /* declared as mysql slave */ - thd->system_thread || /* declared as system thread */ - !thd->vio_ok() || /* server internal thread */ - thd->wsrep_exec_mode==REPL_RECV || /* applier or replaying thread */ - thd->wsrep_applier || /* wsrep slave applier */ - !thd->variables.wsrep_on) /* client, but fenced outside wsrep */ - return false; - - return true; -#else - return (thd->wsrep_client_thread && thd->variables.wsrep_on); -#endif /* REMOVE */ -} - -static inline bool is_replaying_connection(THD *thd) -{ - bool ret; - - mysql_mutex_lock(&thd->LOCK_wsrep_thd); - ret= (thd->wsrep_conflict_state == REPLAYING) ? true : false; - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); - - return ret; -} - -static inline bool is_committing_connection(THD *thd) -{ - bool ret; - - mysql_mutex_lock(&thd->LOCK_wsrep_thd); - ret= (thd->wsrep_query_state == QUERY_COMMITTING) ? true : false; - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); - - return ret; -} - -static bool have_client_connections() -{ - THD *tmp; - - I_List_iterator it(threads); - while ((tmp=it++)) - { - DBUG_PRINT("quit",("Informing thread %ld that it's time to die", - tmp->thread_id)); - if (is_client_connection(tmp) && tmp->killed == KILL_CONNECTION) - { - (void)abort_replicated(tmp); - return true; - } - } - return false; -} - -/* - returns the number of wsrep appliers running. - However, the caller (thd parameter) is not taken in account - */ -static int have_wsrep_appliers(THD *thd) -{ - int ret= 0; - THD *tmp; - - I_List_iterator it(threads); - while ((tmp=it++)) - { - ret+= (tmp != thd && tmp->wsrep_applier); - } - return ret; -} - -static void wsrep_close_thread(THD *thd) -{ - thd->killed= KILL_CONNECTION; - MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (thd)); - if (thd->mysys_var) - { - thd->mysys_var->abort=1; - mysql_mutex_lock(&thd->mysys_var->mutex); - if (thd->mysys_var->current_cond) - { - mysql_mutex_lock(thd->mysys_var->current_mutex); - mysql_cond_broadcast(thd->mysys_var->current_cond); - mysql_mutex_unlock(thd->mysys_var->current_mutex); - } - mysql_mutex_unlock(&thd->mysys_var->mutex); - } -} - -static my_bool have_committing_connections() -{ - THD *tmp; - mysql_mutex_lock(&LOCK_thread_count); // For unlink from list - - I_List_iterator it(threads); - while ((tmp=it++)) - { - if (!is_client_connection(tmp)) - continue; - - if (is_committing_connection(tmp)) - { - mysql_mutex_unlock(&LOCK_thread_count); - return TRUE; - } - } - mysql_mutex_unlock(&LOCK_thread_count); - return FALSE; -} - -int wsrep_wait_committing_connections_close(int wait_time) -{ - int sleep_time= 100; - - while (have_committing_connections() && wait_time > 0) - { - WSREP_DEBUG("wait for committing transaction to close: %d", wait_time); - my_sleep(sleep_time); - wait_time -= sleep_time; - } - if (have_committing_connections()) - { - return 1; - } - return 0; -} - -void wsrep_close_client_connections(my_bool wait_to_end) -{ - /* - First signal all threads that it's time to die - */ - - THD *tmp; - mysql_mutex_lock(&LOCK_thread_count); // For unlink from list - - bool kill_cached_threads_saved= kill_cached_threads; - kill_cached_threads= true; // prevent future threads caching - mysql_cond_broadcast(&COND_thread_cache); // tell cached threads to die - - I_List_iterator it(threads); - while ((tmp=it++)) - { - DBUG_PRINT("quit",("Informing thread %ld that it's time to die", - tmp->thread_id)); - /* We skip slave threads & scheduler on this first loop through. */ - if (!is_client_connection(tmp)) - continue; - - if (is_replaying_connection(tmp)) - { - tmp->killed= KILL_CONNECTION; - continue; - } - - /* replicated transactions must be skipped */ - if (abort_replicated(tmp)) - continue; - - WSREP_DEBUG("closing connection %ld", tmp->thread_id); - wsrep_close_thread(tmp); - } - mysql_mutex_unlock(&LOCK_thread_count); - - if (thread_count) - sleep(2); // Give threads time to die - - mysql_mutex_lock(&LOCK_thread_count); - /* - Force remaining threads to die by closing the connection to the client - */ - - I_List_iterator it2(threads); - while ((tmp=it2++)) - { -#ifndef __bsdi__ // Bug in BSDI kernel - if (is_client_connection(tmp) && - !abort_replicated(tmp) && - !is_replaying_connection(tmp)) - { - WSREP_INFO("killing local connection: %ld",tmp->thread_id); - close_connection(tmp,0); - } -#endif - } - - DBUG_PRINT("quit",("Waiting for threads to die (count=%u)",thread_count)); - if (wsrep_debug) - WSREP_INFO("waiting for client connections to close: %u", thread_count); - - while (wait_to_end && have_client_connections()) - { - mysql_cond_wait(&COND_thread_count, &LOCK_thread_count); - DBUG_PRINT("quit",("One thread died (count=%u)", thread_count)); - } - - kill_cached_threads= kill_cached_threads_saved; - - mysql_mutex_unlock(&LOCK_thread_count); - - /* All client connection threads have now been aborted */ -} - -void wsrep_close_applier(THD *thd) -{ - WSREP_DEBUG("closing applier %ld", thd->thread_id); - wsrep_close_thread(thd); -} - -static void wsrep_close_threads(THD *thd) -{ - THD *tmp; - mysql_mutex_lock(&LOCK_thread_count); // For unlink from list - - I_List_iterator it(threads); - while ((tmp=it++)) - { - DBUG_PRINT("quit",("Informing thread %ld that it's time to die", - tmp->thread_id)); - /* We skip slave threads & scheduler on this first loop through. */ - if (tmp->wsrep_applier && tmp != thd) - { - WSREP_DEBUG("closing wsrep thread %ld", tmp->thread_id); - wsrep_close_thread (tmp); - } - } - - mysql_mutex_unlock(&LOCK_thread_count); -} - -void wsrep_close_applier_threads(int count) -{ - THD *tmp; - mysql_mutex_lock(&LOCK_thread_count); // For unlink from list - - I_List_iterator it(threads); - while ((tmp=it++) && count) - { - DBUG_PRINT("quit",("Informing thread %ld that it's time to die", - tmp->thread_id)); - /* We skip slave threads & scheduler on this first loop through. */ - if (tmp->wsrep_applier) - { - WSREP_DEBUG("closing wsrep applier thread %ld", tmp->thread_id); - tmp->wsrep_applier_closing= TRUE; - count--; - } - } - - mysql_mutex_unlock(&LOCK_thread_count); -} - -void wsrep_wait_appliers_close(THD *thd) -{ - /* Wait for wsrep appliers to gracefully exit */ - mysql_mutex_lock(&LOCK_thread_count); - while (have_wsrep_appliers(thd) > 1) - // 1 is for rollbacker thread which needs to be killed explicitly. - // This gotta be fixed in a more elegant manner if we gonna have arbitrary - // number of non-applier wsrep threads. - { - if (thread_handling > SCHEDULER_ONE_THREAD_PER_CONNECTION) - { - mysql_mutex_unlock(&LOCK_thread_count); - my_sleep(100); - mysql_mutex_lock(&LOCK_thread_count); - } - else - mysql_cond_wait(&COND_thread_count,&LOCK_thread_count); - DBUG_PRINT("quit",("One applier died (count=%u)",thread_count)); - } - mysql_mutex_unlock(&LOCK_thread_count); - /* Now kill remaining wsrep threads: rollbacker */ - wsrep_close_threads (thd); - /* and wait for them to die */ - mysql_mutex_lock(&LOCK_thread_count); - while (have_wsrep_appliers(thd) > 0) - { - if (thread_handling > SCHEDULER_ONE_THREAD_PER_CONNECTION) - { - mysql_mutex_unlock(&LOCK_thread_count); - my_sleep(100); - mysql_mutex_lock(&LOCK_thread_count); - } - else - mysql_cond_wait(&COND_thread_count,&LOCK_thread_count); - DBUG_PRINT("quit",("One thread died (count=%u)",thread_count)); - } - mysql_mutex_unlock(&LOCK_thread_count); - - /* All wsrep applier threads have now been aborted. However, if this thread - is also applier, we are still running... - */ -} - -void wsrep_kill_mysql(THD *thd) -{ - if (mysqld_server_started) - { - if (!shutdown_in_progress) - { - WSREP_INFO("starting shutdown"); - kill_mysql(); - } - } - else - { - unireg_abort(1); - } -} -#endif /* WITH_WSREP */ #if (defined(_WIN32) || defined(HAVE_SMEM)) && !defined(EMBEDDED_LIBRARY) static void handle_connections_methods() @@ -5935,7 +5485,8 @@ int mysqld_main(int argc, char **argv) } #endif #ifdef WITH_WSREP - wsrep_filter_new_cluster (&argc, argv); + if (WSREP_ON) + wsrep_filter_new_cluster (&argc, argv); #endif /* WITH_WSREP */ orig_argc= argc; @@ -6154,7 +5705,7 @@ int mysqld_main(int argc, char **argv) #endif #ifdef WITH_WSREP /* WSREP AFTER SE */ - if (wsrep_recovery) + if (WSREP_ON && wsrep_recovery) { select_thread_in_use= 0; wsrep_recover(); @@ -6219,28 +5770,31 @@ int mysqld_main(int argc, char **argv) unireg_abort(1); #ifdef WITH_WSREP /* WSREP AFTER SE */ - if (opt_bootstrap) + if (WSREP_ON) { - /*! bootstrap wsrep init was taken care of above */ - } - else - { - wsrep_SE_initialized(); - - if (wsrep_before_SE()) + if (opt_bootstrap) { - /*! in case of no SST wsrep waits in view handler callback */ - wsrep_SE_init_grab(); - wsrep_SE_init_done(); - /*! in case of SST wsrep waits for wsrep->sst_received */ - wsrep_sst_continue(); + /*! bootstrap wsrep init was taken care of above */ } else { - wsrep_init_startup (false); - } + wsrep_SE_initialized(); - wsrep_create_appliers(wsrep_slave_threads - 1); + if (wsrep_before_SE()) + { + /*! in case of no SST wsrep waits in view handler callback */ + wsrep_SE_init_grab(); + wsrep_SE_init_done(); + /*! in case of SST wsrep waits for wsrep->sst_received */ + wsrep_sst_continue(); + } + else + { + wsrep_init_startup (false); + } + + wsrep_create_appliers(wsrep_slave_threads - 1); + } } #endif /* WITH_WSREP */ if (opt_bootstrap) @@ -6311,9 +5865,7 @@ int mysqld_main(int argc, char **argv) #ifdef EXTRA_DEBUG2 sql_print_error("Before Lock_thread_count"); #endif -#ifdef WITH_WSREP WSREP_DEBUG("Before Lock_thread_count"); -#endif mysql_mutex_lock(&LOCK_thread_count); DBUG_PRINT("quit", ("Got thread_count mutex")); select_thread_in_use=0; // For close_connections @@ -10140,7 +9692,8 @@ void refresh_status(THD *thd) /* Reset some global variables */ reset_status_vars(); #ifdef WITH_WSREP - wsrep->stats_reset(wsrep); + if (WSREP_ON) + wsrep->stats_reset(wsrep); #endif /* WITH_WSREP */ /* Reset the counters of all key caches (default and named). */ @@ -10193,6 +9746,7 @@ static PSI_file_info all_server_files[]= }; #endif /* HAVE_PSI_INTERFACE */ +PSI_stage_info stage_after_apply_event= { 0, "after apply log event", 0}; PSI_stage_info stage_after_create= { 0, "After create", 0}; PSI_stage_info stage_after_opening_tables= { 0, "After opening tables", 0}; PSI_stage_info stage_after_table_lock= { 0, "After table lock", 0}; @@ -10200,6 +9754,7 @@ PSI_stage_info stage_allocating_local_table= { 0, "allocating local table", 0}; PSI_stage_info stage_alter_inplace_prepare= { 0, "preparing for alter table", 0}; PSI_stage_info stage_alter_inplace= { 0, "altering table", 0}; PSI_stage_info stage_alter_inplace_commit= { 0, "committing alter table to storage engine", 0}; +PSI_stage_info stage_apply_event= { 0, "apply log event", 0}; PSI_stage_info stage_changing_master= { 0, "Changing master", 0}; PSI_stage_info stage_checking_master_version= { 0, "Checking master version", 0}; PSI_stage_info stage_checking_permissions= { 0, "checking permissions", 0}; @@ -10273,6 +9828,7 @@ PSI_stage_info stage_sql_thd_waiting_until_delay= { 0, "Waiting until MASTER_DEL PSI_stage_info stage_storing_result_in_query_cache= { 0, "storing result in query cache", 0}; PSI_stage_info stage_storing_row_into_queue= { 0, "storing row into queue", 0}; PSI_stage_info stage_system_lock= { 0, "System lock", 0}; +PSI_stage_info stage_unlocking_tables= { 0, "Unlocking tables", 0}; PSI_stage_info stage_update= { 0, "update", 0}; PSI_stage_info stage_updating= { 0, "updating", 0}; PSI_stage_info stage_updating_main_table= { 0, "updating main table", 0}; @@ -10317,6 +9873,7 @@ PSI_stage_info stage_gtid_wait_other_connection= { 0, "Waiting for other master PSI_stage_info *all_server_stages[]= { + & stage_after_apply_event, & stage_after_create, & stage_after_opening_tables, & stage_after_table_lock, @@ -10324,6 +9881,7 @@ PSI_stage_info *all_server_stages[]= & stage_alter_inplace, & stage_alter_inplace_commit, & stage_alter_inplace_prepare, + & stage_apply_event, & stage_binlog_processing_checkpoint_notify, & stage_binlog_stopping_background_thread, & stage_binlog_waiting_background_tasks, @@ -10405,6 +9963,7 @@ PSI_stage_info *all_server_stages[]= & stage_storing_result_in_query_cache, & stage_storing_row_into_queue, & stage_system_lock, + & stage_unlocking_tables, & stage_update, & stage_updating, & stage_updating_main_table, diff --git a/sql/mysqld.h b/sql/mysqld.h index d00fa5c57a6..8a6794cc30c 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -25,6 +25,7 @@ #include "sql_list.h" /* I_List */ #include "sql_cmd.h" #include +#include "my_pthread.h" class THD; struct handlerton; @@ -333,6 +334,7 @@ void init_server_psi_keys(); MAINTAINER: Please keep this list in order, to limit merge collisions. Hint: grep PSI_stage_info | sort -u */ +extern PSI_stage_info stage_apply_event; extern PSI_stage_info stage_after_create; extern PSI_stage_info stage_after_opening_tables; extern PSI_stage_info stage_after_table_lock; @@ -340,6 +342,7 @@ extern PSI_stage_info stage_allocating_local_table; extern PSI_stage_info stage_alter_inplace_prepare; extern PSI_stage_info stage_alter_inplace; extern PSI_stage_info stage_alter_inplace_commit; +extern PSI_stage_info stage_after_apply_event; extern PSI_stage_info stage_changing_master; extern PSI_stage_info stage_checking_master_version; extern PSI_stage_info stage_checking_permissions; @@ -413,6 +416,7 @@ extern PSI_stage_info stage_statistics; extern PSI_stage_info stage_storing_result_in_query_cache; extern PSI_stage_info stage_storing_row_into_queue; extern PSI_stage_info stage_system_lock; +extern PSI_stage_info stage_unlocking_tables; extern PSI_stage_info stage_update; extern PSI_stage_info stage_updating; extern PSI_stage_info stage_updating_main_table; @@ -766,9 +770,4 @@ extern uint internal_tmp_table_max_key_segments; extern uint volatile global_disable_checkpoint; extern my_bool opt_help; -#ifdef WITH_WSREP -#include "my_pthread.h" -pthread_handler_t start_wsrep_THD(void*); -#endif /* WITH_WSREP */ - #endif /* MYSQLD_INCLUDED */ diff --git a/sql/protocol.cc b/sql/protocol.cc index af2accfd146..caa00dd80e3 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -488,14 +488,8 @@ static uchar *net_store_length_fast(uchar *packet, uint length) void Protocol::end_statement() { -#ifdef WITH_WSREP - /*sanity check, can be removed before 1.0 release */ - if (WSREP(thd) && thd->wsrep_conflict_state== REPLAYING) - { - WSREP_ERROR("attempting net_end_statement while replaying"); - return; - } -#endif + /* sanity check*/ + DBUG_ASSERT_IF_WSREP(!(WSREP_ON && WSREP(thd) && thd->wsrep_conflict_state == REPLAYING)); DBUG_ENTER("Protocol::end_statement"); DBUG_ASSERT(! thd->get_stmt_da()->is_sent()); bool error= FALSE; diff --git a/sql/rpl_record.cc b/sql/rpl_record.cc index b82dbb07a42..29a1b9728e5 100644 --- a/sql/rpl_record.cc +++ b/sql/rpl_record.cc @@ -305,13 +305,8 @@ unpack_row(rpl_group_info *rgi, normal unpack operation. */ uint16 const metadata= tabledef->field_metadata(i); -#ifndef DBUG_OFF uchar const *const old_pack_ptr= pack_ptr; -#else -#ifdef WITH_WSREP - uchar const *const old_pack_ptr= pack_ptr; -#endif /* WITH_WSREP */ -#endif /* !DBUF_OFF */ + pack_ptr= f->unpack(f->ptr, pack_ptr, row_end, metadata); DBUG_PRINT("debug", ("field: %s; metadata: 0x%x;" " pack_ptr: 0x%lx; pack_ptr': 0x%lx; bytes: %d", @@ -321,17 +316,21 @@ unpack_row(rpl_group_info *rgi, if (!pack_ptr) { #ifdef WITH_WSREP - /* - Debug message to troubleshoot bug: - https://mariadb.atlassian.net/browse/MDEV-4404 - */ - WSREP_WARN("ROW event unpack field: %s metadata: 0x%x;" - " pack_ptr: 0x%lx; conv_table %p conv_field %p table %s" - " row_end: 0x%lx", - f->field_name, metadata, - (ulong) old_pack_ptr, conv_table, conv_field, - (table_found) ? "found" : "not found", (ulong)row_end - ); + if (WSREP_ON) + { + /* + Debug message to troubleshoot bug: + https://mariadb.atlassian.net/browse/MDEV-4404 + Galera Node throws "Could not read field" error and drops out of cluster + */ + WSREP_WARN("ROW event unpack field: %s metadata: 0x%x;" + " pack_ptr: 0x%lx; conv_table %p conv_field %p table %s" + " row_end: 0x%lx", + f->field_name, metadata, + (ulong) old_pack_ptr, conv_table, conv_field, + (table_found) ? "found" : "not found", (ulong)row_end + ); + } #endif /* WITH_WSREP */ rgi->rli->report(ERROR_LEVEL, ER_SLAVE_CORRUPT_EVENT, diff --git a/sql/slave.cc b/sql/slave.cc index 54a32f320c0..746b1d48458 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -52,10 +52,8 @@ #include "log_event.h" // Rotate_log_event, // Create_file_log_event, // Format_description_log_event - -#ifdef WITH_WSREP #include "wsrep_mysqld.h" -#endif + #ifdef HAVE_REPLICATION #include "rpl_tblmap.h" @@ -4370,9 +4368,7 @@ pthread_handler_t handle_slave_sql(void *arg) my_off_t saved_skip= 0; Master_info *mi= ((Master_info*)arg); Relay_log_info* rli = &mi->rli; -#ifdef WITH_WSREP my_bool wsrep_node_dropped= FALSE; -#endif /* WITH_WSREP */ const char *errmsg; rpl_group_info *serial_rgi; rpl_sql_thread_info sql_info(mi->rpl_filter); @@ -4380,9 +4376,8 @@ pthread_handler_t handle_slave_sql(void *arg) // needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff my_thread_init(); DBUG_ENTER("handle_slave_sql"); -#ifdef WITH_WSREP + wsrep_restart_point: -#endif /* WITH_WSREP */ LINT_INIT(saved_master_log_pos); LINT_INIT(saved_log_pos); @@ -4515,7 +4510,8 @@ pthread_handler_t handle_slave_sql(void *arg) #ifdef WITH_WSREP thd->wsrep_exec_mode= LOCAL_STATE; /* synchronize with wsrep replication */ - if (WSREP_ON) wsrep_ready_wait(); + if (WSREP_ON) + wsrep_ready_wait(); #endif DBUG_PRINT("master_info",("log_file_name: %s position: %s", rli->group_master_log_name, @@ -4617,7 +4613,7 @@ log '%s' at position %s, relay log '%s' position: %s%s", RPL_LOG_NAME, rli->group_master_log_name, (ulong) rli->group_master_log_pos); saved_skip= 0; } - + if (exec_relay_log_event(thd, rli, serial_rgi)) { DBUG_PRINT("info", ("exec_relay_log_event() failed")); @@ -4626,8 +4622,7 @@ log '%s' at position %s, relay log '%s' position: %s%s", RPL_LOG_NAME, { slave_output_error_info(rli, thd); #ifdef WITH_WSREP - uint32 const last_errno= rli->last_error().number; - if (WSREP_ON && last_errno == ER_UNKNOWN_COM_ERROR) + if (WSREP_ON && rli->last_error().number == ER_UNKNOWN_COM_ERROR) { wsrep_node_dropped= TRUE; } @@ -4721,7 +4716,7 @@ err_during_init: /* if slave stopped due to node going non primary, we set global flag to trigger automatic restart of slave when node joins back to cluster */ - if (wsrep_node_dropped && wsrep_restart_slave) + if (WSREP_ON && wsrep_node_dropped && wsrep_restart_slave) { if (wsrep_ready) { diff --git a/sql/sp.cc b/sql/sp.cc index b5b543ead0e..261299464c5 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -32,7 +32,7 @@ #include -static bool +bool create_string(THD *thd, String *buf, stored_procedure_type sp_type, const char *db, ulong dblen, @@ -924,7 +924,7 @@ end: } -static void +void sp_returns_type(THD *thd, String &result, sp_head *sp) { TABLE table; @@ -2126,7 +2126,7 @@ int sp_cache_routine(THD *thd, enum stored_procedure_type type, sp_name *name, @return Returns TRUE on success, FALSE on (alloc) failure. */ -static bool +bool create_string(THD *thd, String *buf, stored_procedure_type type, const char *db, ulong dblen, @@ -2271,37 +2271,4 @@ sp_load_for_information_schema(THD *thd, TABLE *proc_table, String *db, thd->lex= old_lex; return sp; } -#ifdef WITH_WSREP -int wsrep_create_sp(THD *thd, uchar** buf, size_t* buf_len) -{ - String log_query; - sp_head *sp = thd->lex->sphead; - ulong saved_mode= thd->variables.sql_mode; - String retstr(64); - retstr.set_charset(system_charset_info); - log_query.set_charset(system_charset_info); - - if (sp->m_type == TYPE_ENUM_FUNCTION) - { - sp_returns_type(thd, retstr, sp); - } - - if (!create_string(thd, &log_query, - sp->m_type, - (sp->m_explicit_name ? sp->m_db.str : NULL), - (sp->m_explicit_name ? sp->m_db.length : 0), - sp->m_name.str, sp->m_name.length, - sp->m_params.str, sp->m_params.length, - retstr.c_ptr(), retstr.length(), - sp->m_body.str, sp->m_body.length, - sp->m_chistics, &(thd->lex->definer->user), - &(thd->lex->definer->host), - saved_mode)) - { - WSREP_WARN("SP create string failed: %s", thd->query()); - return 1; - } - return wsrep_to_buf_helper(thd, log_query.ptr(), log_query.length(), buf, buf_len); -} -#endif /* WITH_WSREP */ diff --git a/sql/sp.h b/sql/sp.h index 3353132346b..de32b5454f8 100644 --- a/sql/sp.h +++ b/sql/sp.h @@ -214,4 +214,19 @@ bool load_collation(MEM_ROOT *mem_root, CHARSET_INFO *dflt_cl, CHARSET_INFO **cl); +void sp_returns_type(THD *thd, + String &result, + sp_head *sp); + +bool create_string(THD *thd, String *buf, + stored_procedure_type type, + const char *db, ulong dblen, + const char *name, ulong namelen, + const char *params, ulong paramslen, + const char *returns, ulong returnslen, + const char *body, ulong bodylen, + st_sp_chistics *chistics, + const LEX_STRING *definer_user, + const LEX_STRING *definer_host, + ulonglong sql_mode); #endif /* _SP_H_ */ diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 2491c019e6a..b55b89265c4 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2560,12 +2560,8 @@ int check_alter_user(THD *thd, const char *host, const char *user) goto end; } -#ifdef WITH_WSREP - if ((!WSREP(thd) || !thd->wsrep_applier) && + if (IF_WSREP((!WSREP(thd) || !thd->wsrep_applier), 1) && !thd->slave_thread && !thd->security_ctx->priv_user[0]) -#else - if (!thd->slave_thread && !thd->security_ctx->priv_user[0]) -#endif /* WITH_WSREP */ { my_message(ER_PASSWORD_ANONYMOUS_USER, ER(ER_PASSWORD_ANONYMOUS_USER), MYF(0)); @@ -2576,10 +2572,9 @@ int check_alter_user(THD *thd, const char *host, const char *user) my_error(ER_PASSWORD_NO_MATCH, MYF(0)); goto end; } + if (!thd->slave_thread && -#ifdef WITH_WSREP - (!WSREP(thd) || !thd->wsrep_applier) && -#endif /* WITH_WSREP */ + IF_WSREP((!WSREP(thd) || !thd->wsrep_applier),1) && (strcmp(thd->security_ctx->priv_user, user) || my_strcasecmp(system_charset_info, host, thd->security_ctx->priv_host))) @@ -2648,9 +2643,8 @@ bool change_password(THD *thd, const char *host, const char *user, enum_binlog_format save_binlog_format; uint new_password_len= (uint) strlen(new_password); int result=0; -#ifdef WITH_WSREP const CSET_STRING query_save = thd->query_string; -#endif /* WITH_WSREP */ + DBUG_ENTER("change_password"); DBUG_PRINT("enter",("host: '%s' user: '%s' new_password: '%s'", host,user,new_password)); @@ -2658,10 +2652,11 @@ bool change_password(THD *thd, const char *host, const char *user, if (check_change_password(thd, host, user, new_password, new_password_len)) DBUG_RETURN(1); + #ifdef WITH_WSREP if (WSREP(thd) && !thd->wsrep_applier) { - query_length= sprintf(buff, "SET PASSWORD FOR '%-.120s'@'%-.120s'='%-.120s'", + query_length= sprintf(buff, "SET PASSWORD FOR '%-.120s'@'%-.120s'='%-.120s'", user ? user : "", host ? host : "", new_password); @@ -2736,11 +2731,10 @@ end: DBUG_RETURN(result); -#ifdef WITH_WSREP - error: - WSREP_ERROR("Replication of SET PASSWORD failed: %s", buff); +error: + WSREP_ERROR("Repliation of SET PASSWORD failed: %s", buff); DBUG_RETURN(result); -#endif /* WITH_WSREP */ + } int acl_check_set_default_role(THD *thd, const char *host, const char *user) @@ -2759,9 +2753,7 @@ int acl_set_default_role(THD *thd, const char *host, const char *user, bool clear_role= FALSE; char buff[512]; enum_binlog_format save_binlog_format; -#ifdef WITH_WSREP const CSET_STRING query_save = thd->query_string; -#endif /* WITH_WSREP */ DBUG_ENTER("acl_set_default_role"); DBUG_PRINT("enter",("host: '%s' user: '%s' rolename: '%s'", @@ -2867,6 +2859,7 @@ int acl_set_default_role(THD *thd, const char *host, const char *user, } end: close_mysql_tables(thd); + #ifdef WITH_WSREP if (WSREP(thd) && !thd->wsrep_applier) { @@ -2876,14 +2869,10 @@ end: thd->wsrep_exec_mode = LOCAL_STATE; } #endif /* WITH_WSREP */ + thd->restore_stmt_binlog_format(save_binlog_format); DBUG_RETURN(result); -#ifdef WITH_WSREP - error: - WSREP_ERROR("Replication of SET PASSWORD failed: %s", buff); - DBUG_RETURN(result); -#endif /* WITH_WSREP */ } diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index ee70914d331..a620ae98c6d 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -1143,9 +1143,8 @@ bool Sql_cmd_analyze_table::execute(THD *thd) FALSE, UINT_MAX, FALSE)) goto error; thd->enable_slow_log= opt_log_slow_admin_statements; -#ifdef WITH_WSREP WSREP_TO_ISOLATION_BEGIN(first_table->db, first_table->table_name, NULL); -#endif + res= mysql_admin_table(thd, first_table, &m_lex->check_opt, "analyze", lock_type, 1, 0, 0, 0, &handler::ha_analyze, 0); diff --git a/sql/sql_alter.cc b/sql/sql_alter.cc index 8b4f4ab9963..cfe360217c2 100644 --- a/sql/sql_alter.cc +++ b/sql/sql_alter.cc @@ -18,9 +18,8 @@ // mysql_exchange_partition #include "sql_base.h" // open_temporary_tables #include "sql_alter.h" -#ifdef WITH_WSREP #include "wsrep_mysqld.h" -#endif /* WITH_WSREP */ + Alter_info::Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root) :drop_list(rhs.drop_list, mem_root), alter_list(rhs.alter_list, mem_root), @@ -320,6 +319,7 @@ bool Sql_cmd_alter_table::execute(THD *thd) DBUG_RETURN(TRUE); } #endif /* WITH_WSREP */ + result= mysql_alter_table(thd, select_lex->db, lex->name.str, &create_info, first_table, @@ -328,8 +328,6 @@ bool Sql_cmd_alter_table::execute(THD *thd) select_lex->order_list.first, lex->ignore); -#ifdef WITH_WSREP -#endif /* WITH_WSREP */ DBUG_RETURN(result); } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 373adf2596e..68f325e20ab 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -61,11 +61,8 @@ #ifdef __WIN__ #include #endif - -#ifdef WITH_WSREP #include "wsrep_mysqld.h" #include "wsrep_thd.h" -#endif // WITH_WSREP bool No_such_table_error_handler::handle_condition(THD *, @@ -4588,8 +4585,10 @@ restart: } } } + #ifdef WITH_WSREP - if ((thd->lex->sql_command== SQLCOM_INSERT || + if (WSREP_ON && + (thd->lex->sql_command== SQLCOM_INSERT || thd->lex->sql_command== SQLCOM_INSERT_SELECT || thd->lex->sql_command== SQLCOM_REPLACE || thd->lex->sql_command== SQLCOM_REPLACE_SELECT || @@ -4608,15 +4607,7 @@ restart: err: THD_STAGE_INFO(thd, stage_after_opening_tables); - -#ifdef WITH_WSREP - if (WSREP(thd)) - thd_proc_info(thd, "exit open_tables()"); - else - thd_proc_info(thd, 0); -#else /* WITH_WSREP */ thd_proc_info(thd, 0); -#endif /* WITH_WSREP */ free_root(&new_frm_mem, MYF(0)); // Free pre-alloced block @@ -5072,15 +5063,7 @@ end: } THD_STAGE_INFO(thd, stage_after_opening_tables); -#ifdef WITH_WSREP - if (WSREP(thd)) - thd_proc_info(thd, "End opening table"); - else thd_proc_info(thd, 0); -#else /* WITH_WSREP */ - thd_proc_info(thd, 0); -#endif /* WITH_WSREP */ - DBUG_RETURN(table); } @@ -9034,19 +9017,17 @@ bool mysql_notify_thread_having_shared_lock(THD *thd, THD *in_use, (e.g. see partitioning code). */ if (!thd_table->needs_reopen()) -#ifdef WITH_WSREP { signalled|= mysql_lock_abort_for_thread(thd, thd_table); - if (thd && WSREP(thd) && wsrep_thd_is_BF((void *)thd, true)) +#ifdef WITH_WSREP + if (thd && WSREP(thd) && wsrep_thd_is_BF((void *)thd, true)) { WSREP_DEBUG("remove_table_from_cache: %llu", (unsigned long long) thd->real_id); wsrep_abort_thd((void *)thd, (void *)in_use, FALSE); } - } -#else - signalled|= mysql_lock_abort_for_thread(thd, thd_table); #endif + } } mysql_mutex_unlock(&in_use->LOCK_thd_data); } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index aef03199503..1f0c19538b2 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -64,10 +64,8 @@ #include "sql_parse.h" // is_update_query #include "sql_callback.h" #include "lock.h" -#ifdef WITH_WSREP #include "wsrep_mysqld.h" #include "wsrep_thd.h" -#endif #include "sql_connect.h" /* @@ -820,176 +818,6 @@ char *thd_get_error_context_description(THD *thd, char *buffer, return buffer; } -#ifdef WITH_WSREP -extern int wsrep_on(void *thd) -{ - return (int)(WSREP(((THD*)thd))); -} -extern "C" bool wsrep_thd_is_wsrep_on(THD *thd) -{ - return thd->variables.wsrep_on; -} - -extern "C" bool wsrep_consistency_check(void *thd) -{ - return ((THD*)thd)->wsrep_consistency_check == CONSISTENCY_CHECK_RUNNING; -} - -extern "C" void wsrep_thd_set_exec_mode(THD *thd, enum wsrep_exec_mode mode) -{ - thd->wsrep_exec_mode= mode; -} -extern "C" void wsrep_thd_set_query_state( - THD *thd, enum wsrep_query_state state) -{ - thd->wsrep_query_state= state; -} -extern "C" void wsrep_thd_set_conflict_state( - THD *thd, enum wsrep_conflict_state state) -{ - thd->wsrep_conflict_state= state; -} - - -extern "C" enum wsrep_exec_mode wsrep_thd_exec_mode(THD *thd) -{ - return thd->wsrep_exec_mode; -} - -extern "C" const char *wsrep_thd_exec_mode_str(THD *thd) -{ - return - (!thd) ? "void" : - (thd->wsrep_exec_mode == LOCAL_STATE) ? "local" : - (thd->wsrep_exec_mode == REPL_RECV) ? "applier" : - (thd->wsrep_exec_mode == TOTAL_ORDER) ? "total order" : - (thd->wsrep_exec_mode == LOCAL_COMMIT) ? "local commit" : "void"; -} - -extern "C" enum wsrep_query_state wsrep_thd_query_state(THD *thd) -{ - return thd->wsrep_query_state; -} - -extern "C" const char *wsrep_thd_query_state_str(THD *thd) -{ - return - (!thd) ? "void" : - (thd->wsrep_query_state == QUERY_IDLE) ? "idle" : - (thd->wsrep_query_state == QUERY_EXEC) ? "executing" : - (thd->wsrep_query_state == QUERY_COMMITTING) ? "committing" : - (thd->wsrep_query_state == QUERY_EXITING) ? "exiting" : - (thd->wsrep_query_state == QUERY_ROLLINGBACK) ? "rolling back" : "void"; -} - -extern "C" enum wsrep_conflict_state wsrep_thd_conflict_state(THD *thd) -{ - return thd->wsrep_conflict_state; -} -extern "C" const char *wsrep_thd_conflict_state_str(THD *thd) -{ - return - (!thd) ? "void" : - (thd->wsrep_conflict_state == NO_CONFLICT) ? "no conflict" : - (thd->wsrep_conflict_state == MUST_ABORT) ? "must abort" : - (thd->wsrep_conflict_state == ABORTING) ? "aborting" : - (thd->wsrep_conflict_state == MUST_REPLAY) ? "must replay" : - (thd->wsrep_conflict_state == REPLAYING) ? "replaying" : - (thd->wsrep_conflict_state == RETRY_AUTOCOMMIT) ? "retrying" : - (thd->wsrep_conflict_state == CERT_FAILURE) ? "cert failure" : "void"; -} - -extern "C" wsrep_ws_handle_t* wsrep_thd_ws_handle(THD *thd) -{ - return &thd->wsrep_ws_handle; -} - -extern "C" void wsrep_thd_LOCK(THD *thd) -{ - mysql_mutex_lock(&thd->LOCK_wsrep_thd); -} -extern "C" void wsrep_thd_UNLOCK(THD *thd) -{ - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); -} -extern "C" time_t wsrep_thd_query_start(THD *thd) -{ - return thd->query_start(); -} -extern "C" uint32 wsrep_thd_wsrep_rand(THD *thd) -{ - return thd->wsrep_rand; -} -extern "C" my_thread_id wsrep_thd_thread_id(THD *thd) -{ - return thd->thread_id; -} -extern "C" wsrep_seqno_t wsrep_thd_trx_seqno(THD *thd) -{ - return (thd) ? thd->wsrep_trx_meta.gtid.seqno : WSREP_SEQNO_UNDEFINED; -} -extern "C" query_id_t wsrep_thd_query_id(THD *thd) -{ - return thd->query_id; -} -extern "C" char *wsrep_thd_query(THD *thd) -{ - return (thd) ? thd->query() : NULL; -} -extern "C" query_id_t wsrep_thd_wsrep_last_query_id(THD *thd) -{ - return thd->wsrep_last_query_id; -} -extern "C" void wsrep_thd_set_wsrep_last_query_id(THD *thd, query_id_t id) -{ - thd->wsrep_last_query_id= id; -} -extern "C" void wsrep_thd_awake(THD *thd, my_bool signal) -{ - if (signal) - { - mysql_mutex_lock(&thd->LOCK_thd_data); - thd->awake(KILL_QUERY); - mysql_mutex_unlock(&thd->LOCK_thd_data); - } - else - { - mysql_mutex_lock(&LOCK_wsrep_replaying); - mysql_cond_broadcast(&COND_wsrep_replaying); - mysql_mutex_unlock(&LOCK_wsrep_replaying); - } -} -extern "C" int wsrep_thd_retry_counter(THD *thd) -{ - return(thd->wsrep_retry_counter); -} - -extern int -wsrep_trx_order_before(void *thd1, void *thd2) -{ - if (wsrep_thd_trx_seqno((THD*)thd1) < wsrep_thd_trx_seqno((THD*)thd2)) { - WSREP_DEBUG("BF conflict, order: %lld %lld\n", - (long long)wsrep_thd_trx_seqno((THD*)thd1), - (long long)wsrep_thd_trx_seqno((THD*)thd2)); - return 1; - } - WSREP_DEBUG("waiting for BF, trx order: %lld %lld\n", - (long long)wsrep_thd_trx_seqno((THD*)thd1), - (long long)wsrep_thd_trx_seqno((THD*)thd2)); - return 0; -} -extern "C" int -wsrep_trx_is_aborting(void *thd_ptr) -{ - if (thd_ptr) { - if ((((THD *)thd_ptr)->wsrep_conflict_state == MUST_ABORT) || - (((THD *)thd_ptr)->wsrep_conflict_state == ABORTING)) { - return 1; - } - } - return 0; -} -#endif #if MARIA_PLUGIN_INTERFACE_VERSION < 0x0200 /** @@ -1069,7 +897,7 @@ THD::THD(bool is_applier) wsrep_client_thread(false), wsrep_po_handle(WSREP_PO_INITIALIZER), wsrep_po_cnt(0), - wsrep_po_in_trans(false), +// wsrep_po_in_trans(false), wsrep_apply_format(0), wsrep_apply_toi(false), #endif @@ -1243,13 +1071,9 @@ THD::THD(bool is_applier) my_rnd_init(&rand, tmp + (ulong) &rand, tmp + (ulong) ::global_query_id); substitute_null_with_insert_id = FALSE; thr_lock_info_init(&lock_info); /* safety: will be reset after start */ -#ifdef WITH_WSREP lock_info.mysql_thd= (void *)this; - lock_info.in_lock_tables= false; -#ifdef WSREP_PROC_INFO + wsrep_info[sizeof(wsrep_info) - 1] = '\0'; /* make sure it is 0-terminated */ -#endif /* WSREP_PROC_INFO */ -#endif /* WITH_WSREP */ m_internal_handler= NULL; m_binlog_invoker= INVOKER_NONE; @@ -1992,9 +1816,6 @@ void THD::awake(killed_state state_to_set) /* Interrupt target waiting inside a storage engine. */ if (state_to_set != NOT_KILLED) -#ifdef WITH_WSREP - /* TODO: prevent applier close here */ -#endif /* WITH_WSREP */ ha_kill_query(this, thd_kill_level(this)); /* Broadcast a condition to kick the target if it is waiting on it. */ @@ -2127,19 +1948,17 @@ bool THD::notify_shared_lock(MDL_context_owner *ctx_in_use, (e.g. see partitioning code). */ if (!thd_table->needs_reopen()) -#ifdef WITH_WSREP { signalled|= mysql_lock_abort_for_thread(this, thd_table); - if (this && WSREP(this) && wsrep_thd_is_BF((void *)this, FALSE)) +#if WITH_WSREP + if (WSREP_ON && this && WSREP(this) && wsrep_thd_is_BF((void *)this, FALSE)) { WSREP_DEBUG("remove_table_from_cache: %llu", (unsigned long long) this->real_id); wsrep_abort_thd((void *)this, (void *)in_use, FALSE); } +#endif /* WITH_WSREP */ } -#else - signalled|= mysql_lock_abort_for_thread(this, thd_table); -#endif } mysql_mutex_unlock(&in_use->LOCK_thd_data); } @@ -2322,11 +2141,10 @@ void THD::cleanup_after_query() table_map_for_update= 0; m_binlog_invoker= INVOKER_NONE; #ifdef WITH_WSREP - if (TOTAL_ORDER == wsrep_exec_mode) - { - wsrep_exec_mode = LOCAL_STATE; - } - //wsrep_trx_seqno = 0; + if (WSREP_ON && TOTAL_ORDER == wsrep_exec_mode) + { + wsrep_exec_mode = LOCAL_STATE; + } #endif /* WITH_WSREP */ #ifndef EMBEDDED_LIBRARY @@ -2751,7 +2569,7 @@ bool select_send::send_result_set_metadata(List &list, uint flags) { bool res; #ifdef WITH_WSREP - if (WSREP(thd) && thd->wsrep_retry_query) + if (WSREP_ON && WSREP(thd) && thd->wsrep_retry_query) { WSREP_DEBUG("skipping select metadata"); return FALSE; @@ -4502,12 +4320,9 @@ extern "C" int thd_non_transactional_update(const MYSQL_THD thd) extern "C" int thd_binlog_format(const MYSQL_THD thd) { -#ifdef WITH_WSREP - if (((WSREP(thd) && wsrep_emulate_bin_log) || mysql_bin_log.is_open()) && - (thd->variables.option_bits & OPTION_BIN_LOG)) -#else - if (mysql_bin_log.is_open() && (thd->variables.option_bits & OPTION_BIN_LOG)) -#endif + if (IF_WSREP(((WSREP(thd) && wsrep_emulate_bin_log) || mysql_bin_log.is_open()), + mysql_bin_log.is_open()) && + thd->variables.option_bits & OPTION_BIN_LOG) return (int) WSREP_FORMAT(thd->variables.binlog_format); else return BINLOG_FORMAT_UNSPEC; @@ -5494,14 +5309,10 @@ int THD::decide_logging_format(TABLE_LIST *tables) 5. Error: Cannot modify table that uses a storage engine limited to row-logging when binlog_format = STATEMENT */ -#ifdef WITH_WSREP - if (!WSREP(this) || wsrep_exec_mode == LOCAL_STATE) + if (IF_WSREP(WSREP_ON && (!WSREP(this) || wsrep_exec_mode == LOCAL_STATE),1)) { -#endif /* WITH_WSREP */ - my_error((error= ER_BINLOG_STMT_MODE_AND_ROW_ENGINE), MYF(0), ""); -#ifdef WITH_WSREP + my_error((error= ER_BINLOG_STMT_MODE_AND_ROW_ENGINE), MYF(0), ""); } -#endif /* WITH_WSREP */ } else if (is_write && (unsafe_flags= lex->get_stmt_unsafe_flags()) != 0) { @@ -5849,15 +5660,11 @@ CPP_UNNAMED_NS_END int THD::binlog_write_row(TABLE* table, bool is_trans, MY_BITMAP const* cols, size_t colcnt, uchar const *record) -{ -#ifdef WITH_WSREP - DBUG_ASSERT(is_current_stmt_binlog_format_row() && - ((WSREP(this) && wsrep_emulate_bin_log) || - mysql_bin_log.is_open())); -#else - DBUG_ASSERT(is_current_stmt_binlog_format_row() && mysql_bin_log.is_open()); -#endif +{ + DBUG_ASSERT(is_current_stmt_binlog_format_row() && + IF_WSREP(((WSREP_ON && WSREP(this) && wsrep_emulate_bin_log) || mysql_bin_log.is_open()), + mysql_bin_log.is_open())); /* Pack records into format for transfer. We are allocating more memory than needed, but that doesn't matter. @@ -5889,14 +5696,10 @@ int THD::binlog_update_row(TABLE* table, bool is_trans, MY_BITMAP const* cols, size_t colcnt, const uchar *before_record, const uchar *after_record) -{ -#ifdef WITH_WSREP - DBUG_ASSERT(is_current_stmt_binlog_format_row() && - ((WSREP(this) && wsrep_emulate_bin_log) - || mysql_bin_log.is_open())); -#else - DBUG_ASSERT(is_current_stmt_binlog_format_row() && mysql_bin_log.is_open()); -#endif +{ + DBUG_ASSERT(is_current_stmt_binlog_format_row() && + IF_WSREP(((WSREP_ON && WSREP(this) && wsrep_emulate_bin_log) || mysql_bin_log.is_open()), + mysql_bin_log.is_open())); size_t const before_maxlen = max_row_length(table, before_record); size_t const after_maxlen = max_row_length(table, after_record); @@ -5944,14 +5747,10 @@ int THD::binlog_update_row(TABLE* table, bool is_trans, int THD::binlog_delete_row(TABLE* table, bool is_trans, MY_BITMAP const* cols, size_t colcnt, uchar const *record) -{ -#ifdef WITH_WSREP - DBUG_ASSERT(is_current_stmt_binlog_format_row() && - ((WSREP(this) && wsrep_emulate_bin_log) - || mysql_bin_log.is_open())); -#else - DBUG_ASSERT(is_current_stmt_binlog_format_row() && mysql_bin_log.is_open()); -#endif +{ + DBUG_ASSERT(is_current_stmt_binlog_format_row() && + IF_WSREP(((WSREP_ON && WSREP(this) && wsrep_emulate_bin_log) || mysql_bin_log.is_open()), + mysql_bin_log.is_open())); /* Pack records into format for transfer. We are allocating more @@ -5986,11 +5785,8 @@ int THD::binlog_remove_pending_rows_event(bool clear_maps, { DBUG_ENTER("THD::binlog_remove_pending_rows_event"); -#ifdef WITH_WSREP - if (!(WSREP_EMULATE_BINLOG(this) || mysql_bin_log.is_open())) -#else - if (!mysql_bin_log.is_open()) -#endif + IF_WSREP(WSREP_ON && !(WSREP_EMULATE_BINLOG(this) || mysql_bin_log.is_open()), + !mysql_bin_log.is_open()); DBUG_RETURN(0); /* Ensure that all events in a GTID group are in the same cache */ @@ -6013,11 +5809,8 @@ int THD::binlog_flush_pending_rows_event(bool stmt_end, bool is_transactional) mode: it might be the case that we left row-based mode before flushing anything (e.g., if we have explicitly locked tables). */ -#ifdef WITH_WSREP - if (!(WSREP_EMULATE_BINLOG(this) || mysql_bin_log.is_open())) -#else - if (!mysql_bin_log.is_open()) -#endif + IF_WSREP(WSREP_ON && !(WSREP_EMULATE_BINLOG(this) || mysql_bin_log.is_open()), + !mysql_bin_log.is_open()); DBUG_RETURN(0); /* Ensure that all events in a GTID group are in the same cache */ @@ -6269,12 +6062,10 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg, DBUG_ENTER("THD::binlog_query"); DBUG_PRINT("enter", ("qtype: %s query: '%-.*s'", show_query_type(qtype), (int) query_len, query_arg)); -#ifdef WITH_WSREP - DBUG_ASSERT(query_arg && (WSREP_EMULATE_BINLOG(this) - || mysql_bin_log.is_open())); -#else - DBUG_ASSERT(query_arg && mysql_bin_log.is_open()); -#endif + + DBUG_ASSERT(query_arg && + IF_WSREP(WSREP_ON && (WSREP_EMULATE_BINLOG(this) || mysql_bin_log.is_open()), + mysql_bin_log.is_open())); /* If this is withing a BEGIN ... COMMIT group, don't log it */ if (variables.option_bits & OPTION_GTID_BEGIN) diff --git a/sql/sql_class.h b/sql/sql_class.h index 0f8ac303f3d..b2f7b459cb4 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -50,25 +50,14 @@ void set_thd_stage_info(void *thd, const char *calling_func, const char *calling_file, const unsigned int calling_line); - + #define THD_STAGE_INFO(thd, stage) \ (thd)->enter_stage(& stage, NULL, __func__, __FILE__, __LINE__) #include "my_apc.h" #include "rpl_gtid.h" - -#ifdef WITH_WSREP #include "wsrep_mysqld.h" -struct wsrep_thd_shadow { - ulonglong options; - uint server_status; - enum wsrep_exec_mode wsrep_exec_mode; - Vio *vio; - ulong tx_isolation; - char *db; - size_t db_length; -}; -#endif + class Reprepare_observer; class Relay_log_info; struct rpl_group_info; @@ -2746,6 +2735,9 @@ public: const bool wsrep_applier; /* dedicated slave applier thread */ bool wsrep_applier_closing; /* applier marked to close */ bool wsrep_client_thread; /* to identify client threads*/ + bool wsrep_PA_safe; + bool wsrep_converted_lock_session; + bool wsrep_apply_toi; /* applier processing in TOI */ enum wsrep_exec_mode wsrep_exec_mode; query_id_t wsrep_last_query_id; enum wsrep_query_state wsrep_query_state; @@ -2758,17 +2750,13 @@ public: uint32 wsrep_rand; Relay_log_info* wsrep_rli; rpl_group_info* wsrep_rgi; - bool wsrep_converted_lock_session; wsrep_ws_handle_t wsrep_ws_handle; -#ifdef WSREP_PROC_INFO char wsrep_info[128]; /* string for dynamic proc info */ -#endif /* WSREP_PROC_INFO */ ulong wsrep_retry_counter; // of autocommit - bool wsrep_PA_safe; char* wsrep_retry_query; size_t wsrep_retry_query_len; enum enum_server_command wsrep_retry_command; - enum wsrep_consistency_check_mode + enum wsrep_consistency_check_mode wsrep_consistency_check; wsrep_stats_var* wsrep_status_vars; int wsrep_mysql_replicated; @@ -2777,12 +2765,10 @@ public: size_t wsrep_TOI_pre_query_len; wsrep_po_handle_t wsrep_po_handle; size_t wsrep_po_cnt; - my_bool wsrep_po_in_trans; #ifdef GTID_SUPPORT rpl_sid wsrep_po_sid; #endif /* GTID_SUPPORT */ void* wsrep_apply_format; - bool wsrep_apply_toi; /* applier processing in TOI */ #endif /* WITH_WSREP */ /** Internal parser state. diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 357294a567a..0065edcc14d 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -37,6 +37,7 @@ // reset_host_errors #include "sql_acl.h" // acl_getroot, NO_ACCESS, SUPER_ACL #include "sql_callback.h" +#include "wsrep_mysqld.h" HASH global_user_stats, global_client_stats, global_table_stats; HASH global_index_stats; @@ -44,9 +45,6 @@ HASH global_index_stats; extern mysql_mutex_t LOCK_global_user_client_stats; extern mysql_mutex_t LOCK_global_table_stats; extern mysql_mutex_t LOCK_global_index_stats; -#ifdef WITH_WSREP -#include "wsrep_mysqld.h" -#endif /* Get structure for logging connection data for the current user @@ -1397,7 +1395,7 @@ void do_handle_one_connection(THD *thd_arg) break; } end_connection(thd); - + #ifdef WITH_WSREP if (WSREP(thd)) { diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 9a6ca541706..5eb4c405c4b 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -642,22 +642,19 @@ cleanup: if (!transactional_table && deleted > 0) thd->transaction.stmt.modified_non_trans_table= thd->transaction.all.modified_non_trans_table= TRUE; - + /* See similar binlogging code in sql_update.cc, for comments */ if ((error < 0) || thd->transaction.stmt.modified_non_trans_table) { -#ifdef WITH_WSREP - if ((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open())) -#else - if (mysql_bin_log.is_open()) -#endif + if(IF_WSREP((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()), + mysql_bin_log.is_open())) { int errcode= 0; if (error < 0) thd->clear_error(); else errcode= query_error_code(thd, killed_status == NOT_KILLED); - + /* [binlog]: If 'handler::delete_all_rows()' was called and the storage engine does not inject the rows itself, we replicate @@ -1111,17 +1108,14 @@ void multi_delete::abort_result_set() DBUG_ASSERT(error_handled); DBUG_VOID_RETURN; } - + if (thd->transaction.stmt.modified_non_trans_table) { - /* + /* there is only side effects; to binlog with the error */ -#ifdef WITH_WSREP - if (WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()) -#else - if (mysql_bin_log.is_open()) -#endif + if (IF_WSREP((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()), + mysql_bin_log.is_open())) { int errcode= query_error_code(thd, thd->killed == NOT_KILLED); /* possible error of writing binary log is ignored deliberately */ @@ -1297,11 +1291,8 @@ bool multi_delete::send_eof() } if ((local_error == 0) || thd->transaction.stmt.modified_non_trans_table) { -#ifdef WITH_WSREP - if (WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()) -#else - if (mysql_bin_log.is_open()) -#endif + if(IF_WSREP((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()), + mysql_bin_log.is_open())) { int errcode= 0; if (local_error == 0) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 2097f636dd2..5ee341435cf 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1014,11 +1014,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, thd->transaction.stmt.modified_non_trans_table || was_insert_delayed) { -#ifdef WITH_WSREP - if (WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()) -#else - if (mysql_bin_log.is_open()) -#endif + if(IF_WSREP((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()), + mysql_bin_log.is_open())) { int errcode= 0; if (error <= 0) @@ -3199,6 +3196,7 @@ bool Delayed_insert::handle_inserts(void) mysql_cond_broadcast(&cond_client); // If waiting clients } } + #ifdef WITH_WSREP if (WSREP((&thd))) thd_proc_info(&thd, "insert done"); @@ -3657,15 +3655,11 @@ bool select_insert::send_eof() DBUG_PRINT("enter", ("trans_table=%d, table_type='%s'", trans_table, table->file->table_type())); -#ifdef WITH_WSREP - error= (thd->wsrep_conflict_state == MUST_ABORT || - thd->wsrep_conflict_state == CERT_FAILURE) ? -1 : - (thd->locked_tables_mode <= LTM_LOCK_TABLES ? - table->file->ha_end_bulk_insert() : 0); -#else - error= (thd->locked_tables_mode <= LTM_LOCK_TABLES ? - table->file->ha_end_bulk_insert() : 0); -#endif /* WITH_WSREP */ + error = IF_WSREP((thd->wsrep_conflict_state == MUST_ABORT || + thd->wsrep_conflict_state == CERT_FAILURE) ? -1 :, ) + (thd->locked_tables_mode <= LTM_LOCK_TABLES ? + table->file->ha_end_bulk_insert() : 0); + if (!error && thd->is_error()) error= thd->get_stmt_da()->sql_errno(); @@ -3693,13 +3687,9 @@ bool select_insert::send_eof() events are in the transaction cache and will be written when ha_autocommit_or_rollback() is issued below. */ -#ifdef WITH_WSREP - if ((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()) && - (!error || thd->transaction.stmt.modified_non_trans_table)) -#else - if (mysql_bin_log.is_open() && - (!error || thd->transaction.stmt.modified_non_trans_table)) -#endif + if(IF_WSREP((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()), + mysql_bin_log.is_open()) && + (!error || thd->transaction.stmt.modified_non_trans_table)) { int errcode= 0; if (!error) @@ -3783,11 +3773,8 @@ void select_insert::abort_result_set() { if (!can_rollback_data()) thd->transaction.all.modified_non_trans_table= TRUE; -#ifdef WITH_WSREP - if (WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()) -#else - if (mysql_bin_log.is_open()) -#endif + if(IF_WSREP((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()), + mysql_bin_log.is_open())) { int errcode= query_error_code(thd, thd->killed == NOT_KILLED); /* error of writing binary log is ignored */ @@ -4195,11 +4182,8 @@ select_create::binlog_show_create_table(TABLE **tables, uint count) create_info->table_was_deleted); DBUG_ASSERT(result == 0); /* store_create_info() always return 0 */ -#ifdef WITH_WSREP - if (WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()) -#else - if (mysql_bin_log.is_open()) -#endif /* WITH_WSREP */ + if(IF_WSREP((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()), + mysql_bin_log.is_open())) { int errcode= query_error_code(thd, thd->killed == NOT_KILLED); result= thd->binlog_query(THD::STMT_QUERY_TYPE, @@ -4209,9 +4193,9 @@ select_create::binlog_show_create_table(TABLE **tables, uint count) /* suppress_use */ FALSE, errcode); } -#ifdef WITH_WSREP - ha_wsrep_fake_trx_id(thd); -#endif + + IF_WSREP(ha_wsrep_fake_trx_id(thd), ); + return result; } @@ -4242,16 +4226,19 @@ bool select_create::send_eof() if (!(thd->variables.option_bits & OPTION_GTID_BEGIN)) trans_commit_implicit(thd); #ifdef WITH_WSREP + if (WSREP_ON) + { mysql_mutex_lock(&thd->LOCK_wsrep_thd); if (thd->wsrep_conflict_state != NO_CONFLICT) { - WSREP_DEBUG("select_create commit failed, thd: %lu err: %d %s", + WSREP_DEBUG("select_create commit failed, thd: %lu err: %d %s", thd->thread_id, thd->wsrep_conflict_state, thd->query()); mysql_mutex_unlock(&thd->LOCK_wsrep_thd); abort_result_set(); return TRUE; } mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + } #endif /* WITH_WSREP */ } else if (!thd->is_current_stmt_binlog_format_row()) diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index ea6817ad0b2..926aa7d5e5a 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. - Copyright (c) 2009, 2013, Monty Program Ab. + Copyright (c) 2009, 2014, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1580,7 +1580,7 @@ int lex_one_token(void *arg, THD *thd) else { #ifdef WITH_WSREP - if (version == 99997 && thd->wsrep_exec_mode == LOCAL_STATE) + if (WSREP(thd) && version == 99997 && thd->wsrep_exec_mode == LOCAL_STATE) { WSREP_DEBUG("consistency check: %s", thd->query()); thd->wsrep_consistency_check= CONSISTENCY_CHECK_DECLARED; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index ad8418d5b59..87efbabe6f8 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. - Copyright (c) 2008, 2013, Monty Program Ab + Copyright (c) 2008, 2014, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -103,12 +103,14 @@ #include "../storage/maria/ha_maria.h" #endif -#ifdef WITH_WSREP #include "wsrep_mysqld.h" #include "wsrep_thd.h" + +#ifdef WITH_WSREP static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length, Parser_state *parser_state); #endif /* WITH_WSREP */ + /** @defgroup Runtime_Environment Runtime Environment @{ @@ -895,18 +897,20 @@ bool do_command(THD *thd) NET *net= &thd->net; enum enum_server_command command; DBUG_ENTER("do_command"); + #ifdef WITH_WSREP if (WSREP(thd)) { mysql_mutex_lock(&thd->LOCK_wsrep_thd); thd->wsrep_query_state= QUERY_IDLE; - if (thd->wsrep_conflict_state==MUST_ABORT) + if (thd->wsrep_conflict_state==MUST_ABORT) { wsrep_client_rollback(thd); } mysql_mutex_unlock(&thd->LOCK_wsrep_thd); } #endif /* WITH_WSREP */ + /* indicator of uninitialized lex => normal flow of errors handling (see my_message_sql) @@ -976,19 +980,17 @@ bool do_command(THD *thd) thd->wsrep_query_state= QUERY_EXEC; mysql_mutex_unlock(&thd->LOCK_wsrep_thd); } - - if ((WSREP(thd) && packet_length == packet_error) || - (!WSREP(thd) && (packet_length == packet_error))) -#else - if (packet_length == packet_error) #endif /* WITH_WSREP */ + + if (packet_length == packet_error) { DBUG_PRINT("info",("Got error %d reading command from socket %s", net->error, vio_description(net->vio))); #ifdef WITH_WSREP - if (WSREP(thd)) { + if (WSREP(thd)) + { mysql_mutex_lock(&thd->LOCK_wsrep_thd); if (thd->wsrep_conflict_state == MUST_ABORT) { @@ -998,6 +1000,7 @@ bool do_command(THD *thd) mysql_mutex_unlock(&thd->LOCK_wsrep_thd); } #endif /* WITH_WSREP */ + /* Instrument this broken statement as "statement/com/error" */ thd->m_statement_psi= MYSQL_REFINE_STATEMENT(thd->m_statement_psi, com_statement_info[COM_END]. @@ -1053,7 +1056,8 @@ bool do_command(THD *thd) command_name[command].str)); #ifdef WITH_WSREP - if (WSREP(thd)) { + if (WSREP(thd)) + { /* * bail out if DB snapshot has not been installed. We however, * allow queries "SET" and "SHOW", they are trapped later in execute_command @@ -1087,7 +1091,8 @@ bool do_command(THD *thd) DBUG_ASSERT(!thd->apc_target.is_enabled()); return_value= dispatch_command(command, thd, packet+1, (uint) (packet_length-1)); #ifdef WITH_WSREP - if (WSREP(thd)) { + if (WSREP(thd)) + { while (thd->wsrep_conflict_state== RETRY_AUTOCOMMIT) { WSREP_DEBUG("Retry autocommit for: %s\n", thd->wsrep_retry_query); @@ -1105,13 +1110,14 @@ bool do_command(THD *thd) thd->wsrep_retry_query_len); thd->variables.character_set_client = current_charset; } - } - if (thd->wsrep_retry_query && thd->wsrep_conflict_state != REPLAYING) - { - my_free(thd->wsrep_retry_query); - thd->wsrep_retry_query = NULL; - thd->wsrep_retry_query_len = 0; - thd->wsrep_retry_command = COM_CONNECT; + + if (thd->wsrep_retry_query && thd->wsrep_conflict_state != REPLAYING) + { + my_free(thd->wsrep_retry_query); + thd->wsrep_retry_query = NULL; + thd->wsrep_retry_query_len = 0; + thd->wsrep_retry_command = COM_CONNECT; + } } #endif /* WITH_WSREP */ DBUG_ASSERT(!thd->apc_target.is_enabled()); @@ -1137,7 +1143,7 @@ out: @retval FALSE The statement isn't updating any relevant tables. */ -static my_bool deny_updates_if_read_only_option(THD *thd, +my_bool deny_updates_if_read_only_option(THD *thd, TABLE_LIST *all_tables) { DBUG_ENTER("deny_updates_if_read_only_option"); @@ -1191,33 +1197,7 @@ static my_bool deny_updates_if_read_only_option(THD *thd, DBUG_RETURN(FALSE); } -#ifdef WITH_WSREP -static my_bool wsrep_read_only_option(THD *thd, TABLE_LIST *all_tables) -{ - int opt_readonly_saved = opt_readonly; - ulong flag_saved = (ulong)(thd->security_ctx->master_access & SUPER_ACL); - opt_readonly = 0; - thd->security_ctx->master_access &= ~SUPER_ACL; - - my_bool ret = !deny_updates_if_read_only_option(thd, all_tables); - - opt_readonly = opt_readonly_saved; - thd->security_ctx->master_access |= flag_saved; - - return ret; -} - -static void wsrep_copy_query(THD *thd) -{ - thd->wsrep_retry_command = thd->get_command(); - thd->wsrep_retry_query_len = thd->query_length(); - thd->wsrep_retry_query = (char *)my_malloc( - thd->wsrep_retry_query_len + 1, MYF(0)); - strncpy(thd->wsrep_retry_query, thd->query(), thd->wsrep_retry_query_len); - thd->wsrep_retry_query[thd->wsrep_retry_query_len] = '\0'; -} -#endif /* WITH_WSREP */ /** Perform one connection-level (COM_XXXX) command. @@ -1248,7 +1228,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, DBUG_PRINT("info", ("command: %d", command)); #ifdef WITH_WSREP - if (WSREP(thd)) { + if (WSREP(thd)) + { if (!thd->in_multi_stmt_transaction_mode()) { thd->wsrep_PA_safe= true; @@ -1480,10 +1461,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; #ifdef WITH_WSREP - wsrep_mysql_parse(thd, thd->query(), thd->query_length(), &parser_state); -#else - mysql_parse(thd, thd->query(), thd->query_length(), &parser_state); + if (WSREP_ON) + wsrep_mysql_parse(thd, thd->query(), thd->query_length(), &parser_state); + else #endif /* WITH_WSREP */ + mysql_parse(thd, thd->query(), thd->query_length(), &parser_state); while (!thd->killed && (parser_state.m_lip.found_semicolon != NULL) && ! thd->is_error()) @@ -1557,19 +1539,20 @@ bool dispatch_command(enum enum_server_command command, THD *thd, Count each statement from the client. */ statistic_increment(thd->status_var.questions, &LOCK_status); -#ifdef WITH_WSREP - if (!WSREP(thd)) + + if(IF_WSREP(!WSREP(thd), 1)) thd->set_time(); /* Reset the query start time. */ -#else - thd->set_time(); /* Reset the query start time. */ -#endif /* WITH_WSREP */ + parser_state.reset(beginning_of_next_stmt, length); /* TODO: set thd->lex->sql_command to SQLCOM_END here */ + #ifdef WITH_WSREP - wsrep_mysql_parse(thd, beginning_of_next_stmt, length, &parser_state); -#else - mysql_parse(thd, beginning_of_next_stmt, length, &parser_state); + if (WSREP_ON) + wsrep_mysql_parse(thd, beginning_of_next_stmt, length, &parser_state); + else #endif /* WITH_WSREP */ + mysql_parse(thd, beginning_of_next_stmt, length, &parser_state); + } DBUG_PRINT("info",("query ready")); @@ -1909,7 +1892,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, #ifdef WITH_WSREP dispatch_end: - if (WSREP(thd)) { + if (WSREP(thd)) + { /* wsrep BF abort in query exec phase */ mysql_mutex_lock(&thd->LOCK_wsrep_thd); if ((thd->wsrep_conflict_state != REPLAYING) && @@ -1919,25 +1903,25 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->update_server_status(); thd->protocol->end_statement(); query_cache_end_of_result(thd); - } + } else { mysql_mutex_unlock(&thd->LOCK_wsrep_thd); } - } else { /* if (WSREP(thd))... */ + } + else #endif /* WITH_WSREP */ - DBUG_ASSERT(thd->derived_tables == NULL && - (thd->open_tables == NULL || + { + DBUG_ASSERT(thd->derived_tables == NULL && + (thd->open_tables == NULL || (thd->locked_tables_mode == LTM_LOCK_TABLES))); - thd_proc_info(thd, "updating status"); - /* Finalize server status flags after executing a command. */ - thd->update_server_status(); - thd->protocol->end_statement(); - query_cache_end_of_result(thd); -#ifdef WITH_WSREP + thd_proc_info(thd, "updating status"); + /* Finalize server status flags after executing a command. */ + thd->update_server_status(); + thd->protocol->end_statement(); + query_cache_end_of_result(thd); } -#endif /* WITH_WSREP */ if (!thd->is_error() && !thd->killed_errno()) mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_RESULT, 0, 0); @@ -2389,13 +2373,6 @@ err: return TRUE; } -#ifdef WITH_WSREP -static bool wsrep_is_show_query(enum enum_sql_command command) -{ - DBUG_ASSERT(command >= 0 && command <= SQLCOM_END); - return (sql_command_flags[command] & CF_STATUS_COMMAND) != 0; -} -#endif /* WITH_WSREP */ /** Execute command saved in thd and lex->sql_command. @@ -2598,7 +2575,8 @@ mysql_execute_command(THD *thd) } /* endif unlikely slave */ #endif #ifdef WITH_WSREP - if (WSREP(thd)) { + if (WSREP(thd)) + { /* change LOCK TABLE WRITE to transaction */ @@ -2630,31 +2608,10 @@ mysql_execute_command(THD *thd) lex->sql_command != SQLCOM_SET_OPTION && !wsrep_is_show_query(lex->sql_command)) { -#if DIRTY_HACK - /* Dirty hack for lp:1002714 - trying to recognize mysqldump connection - * and allow it to continue. Actuall mysqldump_magic_str may be longer - * and is obviously version dependent and may be issued by any client - * connection after which connection becomes non-replicating. */ - static char const mysqldump_magic_str[]= -"SELECT LOGFILE_GROUP_NAME, FILE_NAME, TOTAL_EXTENTS, INITIAL_SIZE, ENGINE, EXTRA FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE = 'UNDO LOG' AND FILE_NAME IS NOT NULL"; - static const size_t mysqldump_magic_str_len= sizeof(mysqldump_magic_str) -1; - if (SQLCOM_SELECT != lex->sql_command || - thd->query_length() < mysqldump_magic_str_len || - strncmp(thd->query(), mysqldump_magic_str, mysqldump_magic_str_len)) - { -#endif /* DIRTY_HACK */ my_message(ER_UNKNOWN_COM_ERROR, "WSREP has not yet prepared node for application use", MYF(0)); goto error; -#if DIRTY_HACK - } - else - { - /* mysqldump connection, allow all further queries to pass */ - thd->variables.wsrep_on= FALSE; - } -#endif /* DIRTY_HACK */ } } #endif /* WITH_WSREP */ @@ -2701,16 +2658,14 @@ mysql_execute_command(THD *thd) if (trans_commit_implicit(thd)) { thd->mdl_context.release_transactional_locks(); -#ifdef WITH_WSREP WSREP_DEBUG("implicit commit failed, MDL released: %lu", thd->thread_id); -#endif /* WITH_WSREP */ goto error; } /* Release metadata locks acquired in this transaction. */ thd->mdl_context.release_transactional_locks(); } } - + #ifndef DBUG_OFF if (lex->sql_command != SQLCOM_SET_OPTION) DEBUG_SYNC(thd,"before_execute_sql_command"); @@ -2764,7 +2719,8 @@ mysql_execute_command(THD *thd) case SQLCOM_SHOW_STATUS: { #ifdef WITH_WSREP - if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd)) goto error; + if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd)) + goto error; #endif /* WITH_WSREP */ execute_show_status(thd, all_tables); break; @@ -2799,7 +2755,8 @@ mysql_execute_command(THD *thd) case SQLCOM_SHOW_STATUS_PROC: case SQLCOM_SHOW_STATUS_FUNC: #ifdef WITH_WSREP - if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd)) goto error; + if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd)) + goto error; #endif /* WITH_WSREP */ case SQLCOM_SHOW_DATABASES: @@ -2823,7 +2780,8 @@ mysql_execute_command(THD *thd) case SQLCOM_SHOW_INDEX_STATS: case SQLCOM_SELECT: #ifdef WITH_WSREP - if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd)) goto error; + if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd)) + goto error; case SQLCOM_SHOW_VARIABLES: case SQLCOM_SHOW_CHARSETS: case SQLCOM_SHOW_COLLATIONS: @@ -3187,7 +3145,7 @@ case SQLCOM_PREPARE: */ if(lex->ignore) lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_CREATE_IGNORE_SELECT); - + if(lex->duplicates == DUP_REPLACE) lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_CREATE_REPLACE_SELECT); @@ -3199,7 +3157,7 @@ case SQLCOM_PREPARE: raise a warning, as it may cause problems (see 'NAME_CONST issues' in 'Binary Logging of Stored Programs') */ - if (thd->query_name_consts && + if (thd->query_name_consts && mysql_bin_log.is_open() && WSREP_FORMAT(thd->variables.binlog_format) == BINLOG_FORMAT_STMT && !mysql_bin_log.is_query_in_union(thd, thd->query_id)) @@ -3320,8 +3278,8 @@ case SQLCOM_PREPARE: /* in STATEMENT format, we probably have to replicate also temporary tables, like mysql replication does */ - if (!thd->is_current_stmt_binlog_format_row() || - !(create_info.options & HA_LEX_CREATE_TMP_TABLE)) + if (WSREP_ON && (!thd->is_current_stmt_binlog_format_row() || + !(create_info.options & HA_LEX_CREATE_TMP_TABLE))) WSREP_TO_ISOLATION_BEGIN(create_table->db, create_table->table_name, NULL) #endif /* WITH_WSREP */ @@ -3510,7 +3468,8 @@ end_with_restore_list: #else { #ifdef WITH_WSREP - if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd)) goto error; + if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd)) + goto error; #endif /* WITH_WSREP */ /* @@ -3576,7 +3535,8 @@ end_with_restore_list: { DBUG_ASSERT(first_table == all_tables && first_table != 0); #ifdef WITH_WSREP - if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd)) goto error; + if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd)) + goto error; #endif /* WITH_WSREP */ if (check_table_access(thd, SELECT_ACL, all_tables, @@ -3790,14 +3750,14 @@ end_with_restore_list: if ((res= insert_precheck(thd, all_tables))) break; #ifdef WITH_WSREP - if (lex->sql_command == SQLCOM_INSERT_SELECT && + if (WSREP_ON && lex->sql_command == SQLCOM_INSERT_SELECT && thd->wsrep_consistency_check == CONSISTENCY_CHECK_DECLARED) { thd->wsrep_consistency_check = CONSISTENCY_CHECK_RUNNING; WSREP_TO_ISOLATION_BEGIN(first_table->db, first_table->table_name, NULL); } +#endif /* WITH_WSREP */ -#endif /* INSERT...SELECT...ON DUPLICATE KEY UPDATE/REPLACE SELECT/ INSERT...IGNORE...SELECT can be unsafe, unless ORDER BY PRIMARY KEY @@ -4015,14 +3975,17 @@ end_with_restore_list: thd->variables.option_bits|= OPTION_KEEP_LOG; } #ifdef WITH_WSREP - for (TABLE_LIST *table= all_tables; table; table= table->next_global) + if (WSREP_ON) { - if (!lex->drop_temporary && - (!thd->is_current_stmt_binlog_format_row() || - !find_temporary_table(thd, table))) + for (TABLE_LIST *table= all_tables; table; table= table->next_global) { - WSREP_TO_ISOLATION_BEGIN(NULL, NULL, all_tables); - break; + if (!lex->drop_temporary && + (!thd->is_current_stmt_binlog_format_row() || + !find_temporary_table(thd, table))) + { + WSREP_TO_ISOLATION_BEGIN(NULL, NULL, all_tables); + break; + } } } #endif /* WITH_WSREP */ @@ -4755,17 +4718,10 @@ end_with_restore_list: able to open it (with SQLCOM_HA_OPEN) in the first place. */ unit->set_limit(select_lex); -#ifdef WITH_WSREP - { char* tmp_info= NULL; - if (WSREP(thd)) tmp_info = (char *)thd_proc_info(thd, "mysql_ha_read()"); -#endif /* WITH_WSREP */ + res= mysql_ha_read(thd, first_table, lex->ha_read_mode, lex->ident.str, lex->insert_list, lex->ha_rkey_mode, select_lex->where, unit->select_limit_cnt, unit->offset_limit_cnt); -#ifdef WITH_WSREP - if (WSREP(thd)) thd_proc_info(thd, tmp_info); - } -#endif /* WITH_WSREP */ break; case SQLCOM_BEGIN: @@ -4773,9 +4729,7 @@ end_with_restore_list: if (trans_begin(thd, lex->start_transaction_opt)) { thd->mdl_context.release_transactional_locks(); -#ifdef WITH_WSREP WSREP_DEBUG("BEGIN failed, MDL released: %lu", thd->thread_id); -#endif /* WITH_WSREP */ goto error; } my_ok(thd); @@ -4793,9 +4747,7 @@ end_with_restore_list: if (trans_commit(thd)) { thd->mdl_context.release_transactional_locks(); -#ifdef WITH_WSREP WSREP_DEBUG("COMMIT failed, MDL released: %lu", thd->thread_id); -#endif /* WITH_WSREP */ goto error; } thd->mdl_context.release_transactional_locks(); @@ -4818,19 +4770,16 @@ end_with_restore_list: thd->print_aborted_warning(3, "RELEASE"); } #ifdef WITH_WSREP - if (WSREP(thd)) { - + if (WSREP(thd)) + { if (thd->wsrep_conflict_state == NO_CONFLICT || thd->wsrep_conflict_state == REPLAYING) { my_ok(thd); } - } else { -#endif /* WITH_WSREP */ - my_ok(thd); -#ifdef WITH_WSREP - } + } else #endif /* WITH_WSREP */ + my_ok(thd); break; } case SQLCOM_ROLLBACK: @@ -4847,9 +4796,7 @@ end_with_restore_list: if (trans_rollback(thd)) { thd->mdl_context.release_transactional_locks(); -#ifdef WITH_WSREP WSREP_DEBUG("rollback failed, MDL released: %lu", thd->thread_id); -#endif /* WITH_WSREP */ goto error; } thd->mdl_context.release_transactional_locks(); @@ -4869,16 +4816,15 @@ end_with_restore_list: if (tx_release) thd->killed= KILL_CONNECTION; #ifdef WITH_WSREP - if (WSREP(thd)) { + if (WSREP(thd)) + { if (thd->wsrep_conflict_state == NO_CONFLICT) { my_ok(thd); } - } else { -#endif /* WITH_WSREP */ - my_ok(thd); -#ifdef WITH_WSREP } + else #endif /* WITH_WSREP */ + my_ok(thd); break; } case SQLCOM_RELEASE_SAVEPOINT: @@ -5394,9 +5340,7 @@ create_sp_error: if (trans_xa_commit(thd)) { thd->mdl_context.release_transactional_locks(); -#ifdef WITH_WSREP WSREP_DEBUG("XA commit failed, MDL released: %lu", thd->thread_id); -#endif /* WITH_WSREP */ goto error; } thd->mdl_context.release_transactional_locks(); @@ -5412,9 +5356,7 @@ create_sp_error: if (trans_xa_rollback(thd)) { thd->mdl_context.release_transactional_locks(); -#ifdef WITH_WSREP WSREP_DEBUG("XA rollback failed, MDL released: %lu", thd->thread_id); -#endif /* WITH_WSREP */ goto error; } thd->mdl_context.release_transactional_locks(); @@ -5764,7 +5706,8 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables) else status_var_add(thd->status_var.rows_sent, thd->get_sent_row_count()); #ifdef WITH_WSREP - if (lex->sql_command == SQLCOM_SHOW_STATUS) wsrep_free_status(thd); + if (WSREP_ON && lex->sql_command == SQLCOM_SHOW_STATUS) + wsrep_free_status(thd); #endif /* WITH_WSREP */ return res; } @@ -6610,7 +6553,8 @@ void THD::reset_for_next_command() transactions. Appliers and replayers are either processing ROW events or get autoinc variable values from Query_log_event. */ - if (WSREP(thd) && thd->wsrep_exec_mode == LOCAL_STATE) { + if (WSREP(thd) && thd->wsrep_exec_mode == LOCAL_STATE) + { if (wsrep_auto_increment_control) { if (thd->variables.auto_increment_offset != @@ -6831,7 +6775,7 @@ void mysql_init_multi_delete(LEX *lex) static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length, Parser_state *parser_state) { - bool is_autocommit= + bool is_autocommit= !thd->in_multi_stmt_transaction_mode() && thd->wsrep_conflict_state == NO_CONFLICT && !thd->wsrep_applier && @@ -7959,14 +7903,9 @@ kill_one_thread(THD *thd, longlong id, killed_state kill_signal, killed_type typ faster and do a harder kill than KILL_SYSTEM_THREAD; */ -#ifdef WITH_WSREP if (((thd->security_ctx->master_access & SUPER_ACL) || thd->security_ctx->user_matches(tmp->security_ctx)) && - !wsrep_thd_is_BF((void *)tmp, true)) -#else - if ((thd->security_ctx->master_access & SUPER_ACL) || - thd->security_ctx->user_matches(tmp->security_ctx)) -#endif /* WITH_WSREP */ + IF_WSREP(!wsrep_thd_is_BF((void *)tmp, true), 1)) { tmp->awake(kill_signal); error=0; diff --git a/sql/sql_parse.h b/sql/sql_parse.h index 773ede9edee..87f8854e050 100644 --- a/sql/sql_parse.h +++ b/sql/sql_parse.h @@ -202,22 +202,5 @@ inline bool is_supported_parser_charset(CHARSET_INFO *cs) { return MY_TEST(cs->mbminlen == 1); } -#ifdef WITH_WSREP - -#define WSREP_MYSQL_DB (char *)"mysql" -#define WSREP_TO_ISOLATION_BEGIN(db_, table_, table_list_) \ - if (WSREP(thd) && wsrep_to_isolation_begin(thd, db_, table_, table_list_)) goto error; - -#define WSREP_TO_ISOLATION_END \ - if (WSREP(thd) || (thd && thd->wsrep_exec_mode==TOTAL_ORDER)) \ - wsrep_to_isolation_end(thd); - -#else - -#define WSREP_TO_ISOLATION_BEGIN(db_, table_, table_list_) -#define WSREP_TO_ISOLATION_END - -#endif /* WITH_WSREP */ - #endif /* SQL_PARSE_INCLUDED */ diff --git a/sql/sql_partition_admin.cc b/sql/sql_partition_admin.cc index ac67291fbd1..9db8b1c136a 100644 --- a/sql/sql_partition_admin.cc +++ b/sql/sql_partition_admin.cc @@ -1,4 +1,5 @@ /* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2014, SkySQL Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -764,18 +765,22 @@ bool Sql_cmd_alter_table_truncate_partition::execute(THD *thd) DBUG_RETURN(TRUE); #ifdef WITH_WSREP - TABLE *find_temporary_table(THD *thd, const TABLE_LIST *tl); - - if ((!thd->is_current_stmt_binlog_format_row() || - !find_temporary_table(thd, first_table)) && - wsrep_to_isolation_begin( - thd, first_table->db, first_table->table_name, NULL) - ) + if (WSREP_ON) { - WSREP_WARN("ALTER TABLE isolation failure"); - DBUG_RETURN(TRUE); + TABLE *find_temporary_table(THD *thd, const TABLE_LIST *tl); + + if ((!thd->is_current_stmt_binlog_format_row() || + !find_temporary_table(thd, first_table)) && + wsrep_to_isolation_begin( + thd, first_table->db, first_table->table_name, NULL) + ) + { + WSREP_WARN("ALTER TABLE isolation failure"); + DBUG_RETURN(TRUE); + } } #endif /* WITH_WSREP */ + if (open_tables(thd, &first_table, &table_counter, 0)) DBUG_RETURN(true); diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 3ebed0643a5..ea9748c8cb2 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -3087,21 +3087,19 @@ void plugin_thdvar_init(THD *thd) thd->variables.dynamic_variables_size= 0; thd->variables.dynamic_variables_ptr= 0; -#ifdef WITH_WSREP - if (!WSREP(thd) || !thd->wsrep_applier) { -#endif - mysql_mutex_lock(&LOCK_plugin); - thd->variables.table_plugin= + if (IF_WSREP((!WSREP(thd) || !thd->wsrep_applier),1)) + { + mysql_mutex_lock(&LOCK_plugin); + thd->variables.table_plugin= intern_plugin_lock(NULL, global_system_variables.table_plugin); - if (global_system_variables.tmp_table_plugin) - thd->variables.tmp_table_plugin= + if (global_system_variables.tmp_table_plugin) + thd->variables.tmp_table_plugin= intern_plugin_lock(NULL, global_system_variables.tmp_table_plugin); - intern_plugin_unlock(NULL, old_table_plugin); - intern_plugin_unlock(NULL, old_tmp_table_plugin); - mysql_mutex_unlock(&LOCK_plugin); -#ifdef WITH_WSREP + intern_plugin_unlock(NULL, old_table_plugin); + intern_plugin_unlock(NULL, old_tmp_table_plugin); + mysql_mutex_unlock(&LOCK_plugin); } -#endif + DBUG_VOID_RETURN; } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 8a6de8b6693..d9365e14494 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2002, 2013, Oracle and/or its affiliates. - Copyright (c) 2008, 2013, Monty Program Ab + Copyright (c) 2008, 2014, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -117,6 +117,7 @@ When one supplies long data for a placeholder: #include "lock.h" // MYSQL_OPEN_FORCE_SHARED_MDL #include "sql_handler.h" #include "transaction.h" // trans_rollback_implicit +#include "wsrep_mysqld.h" /** A result class used to send cursor rows using the binary protocol. @@ -3547,9 +3548,7 @@ Prepared_statement::set_parameters(String *expanded_query, return res; } -#ifdef WITH_WSREP -void wsrep_replay_transaction(THD *thd); -#endif /* WITH_WSREP */ + /** Execute a prepared statement. Re-prepare it a limited number of times if necessary. @@ -3629,20 +3628,25 @@ reexecute: thd->m_reprepare_observer= NULL; #ifdef WITH_WSREP - mysql_mutex_lock(&thd->LOCK_wsrep_thd); - switch (thd->wsrep_conflict_state) - { - case CERT_FAILURE: - WSREP_DEBUG("PS execute fail for CERT_FAILURE: thd: %ld err: %d", - thd->thread_id, thd->get_stmt_da()->sql_errno() ); - thd->wsrep_conflict_state = NO_CONFLICT; - break; - case MUST_REPLAY: - (void)wsrep_replay_transaction(thd); - default: break; + if (WSREP_ON) + { + mysql_mutex_lock(&thd->LOCK_wsrep_thd); + switch (thd->wsrep_conflict_state) + { + case CERT_FAILURE: + WSREP_DEBUG("PS execute fail for CERT_FAILURE: thd: %ld err: %d", + thd->thread_id, thd->get_stmt_da()->sql_errno() ); + thd->wsrep_conflict_state = NO_CONFLICT; + break; + + case MUST_REPLAY: + (void)wsrep_replay_transaction(thd); + default: + break; + } + mysql_mutex_unlock(&thd->LOCK_wsrep_thd); } - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); #endif /* WITH_WSREP */ if ((sql_command_flags[lex->sql_command] & CF_REEXECUTION_FRAGILE) && diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index eaed0660e46..d8db5c55c3b 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. - Copyright (c) 2008, 2013, Monty Program Ab + Copyright (c) 2008, 2014, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -2946,15 +2946,7 @@ int start_slave(THD* thd , Master_info* mi, bool net_report) err: unlock_slave_threads(mi); - -#ifdef WITH_WSREP - if (WSREP(thd)) - thd_proc_info(thd, "exit stop_slave()"); - else thd_proc_info(thd, 0); -#else /* WITH_WSREP */ - thd_proc_info(thd, 0); -#endif /* WITH_WSREP */ if (slave_errno) { diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 25c005539af..6ffb19256bf 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2972,13 +2972,9 @@ static bool show_status_array(THD *thd, const char *wild, DBUG_ASSERT(name_buffer[0] >= 'a'); DBUG_ASSERT(name_buffer[0] <= 'z'); -#ifdef WITH_WSREP - // TODO: remove once lp:1306875 has been addressed. - if (status_var && (is_wsrep_var == FALSE)) -#else - /* traditionally status variables have a first letter uppercased */ - if (status_var) -#endif /* WITH_WSREP */ + // WSREP_TODO: remove once lp:1306875 has been addressed. + if (IF_WSREP(WSREP_ON && is_wsrep_var == FALSE, 1) && + status_var) name_buffer[0]-= 'a' - 'A'; } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index e632a65b636..b86de2f6cc1 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -5265,58 +5265,9 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, DBUG_ENTER("mysql_create_like_table"); #ifdef WITH_WSREP - if (WSREP(thd) && !thd->wsrep_applier) - { - TABLE *tmp_table; - bool is_tmp_table= FALSE; - - for (tmp_table= thd->temporary_tables; tmp_table; tmp_table=tmp_table->next) - { - if (!strcmp(src_table->db, tmp_table->s->db.str) && - !strcmp(src_table->table_name, tmp_table->s->table_name.str)) - { - is_tmp_table= TRUE; - break; - } - } - if (create_info->options & HA_LEX_CREATE_TMP_TABLE) - { - /* CREATE TEMPORARY TABLE LIKE must be skipped from replication */ - WSREP_DEBUG("CREATE TEMPORARY TABLE LIKE... skipped replication\n %s", - thd->query()); - } - else if (!is_tmp_table) - { - /* this is straight CREATE TABLE LIKE... eith no tmp tables */ - WSREP_TO_ISOLATION_BEGIN(table->db, table->table_name, NULL); - } - else - { - /* here we have CREATE TABLE LIKE - the temporary table definition will be needed in slaves to - enable the create to succeed - */ - TABLE_LIST tbl; - bzero((void*) &tbl, sizeof(tbl)); - tbl.db= src_table->db; - tbl.table_name= tbl.alias= src_table->table_name; - tbl.table= tmp_table; - char buf[2048]; - String query(buf, sizeof(buf), system_charset_info); - query.length(0); // Have to zero it since constructor doesn't - - (void) store_create_info(thd, &tbl, &query, NULL, TRUE, FALSE); - WSREP_DEBUG("TMP TABLE: %s", query.ptr()); - - thd->wsrep_TOI_pre_query= query.ptr(); - thd->wsrep_TOI_pre_query_len= query.length(); - - WSREP_TO_ISOLATION_BEGIN(table->db, table->table_name, NULL); - - thd->wsrep_TOI_pre_query= NULL; - thd->wsrep_TOI_pre_query_len= 0; - } - } + if (WSREP_ON && !thd->wsrep_applier && + wsrep_create_like_table(thd, table, src_table, create_info)) + goto end; #endif /* @@ -5580,14 +5531,9 @@ err: thd->query_length(), is_trans)) res= 1; } + +end: DBUG_RETURN(res); - -#ifdef WITH_WSREP - error: - thd->wsrep_TOI_pre_query= NULL; - DBUG_RETURN(TRUE); -#endif /* WITH_WSREP */ - } @@ -8119,10 +8065,6 @@ simple_rename_or_index_change(THD *thd, TABLE_LIST *table_list, : HA_EXTRA_FORCE_REOPEN; DBUG_ENTER("simple_rename_or_index_change"); -#ifdef WITH_WSREP - bool do_log_write(true); -#endif /* WITH_WSREP */ - if (keys_onoff != Alter_info::LEAVE_AS_IS) { if (wait_while_table_is_used(thd, table, extra_func)) @@ -8182,13 +8124,7 @@ simple_rename_or_index_change(THD *thd, TABLE_LIST *table_list, if (!error) { -#ifdef WITH_WSREP - if (!WSREP(thd) || do_log_write) { -#endif /* WITH_WSREP */ - error= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); -#ifdef WITH_WSREP - } -#endif /* !WITH_WSREP */ + error= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); if (!error) my_ok(thd); diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index c3188305092..268fad5d90e 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -434,14 +434,9 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) binlogged, so they share the same danger, so trust_function_creators applies to them too. */ -#ifdef WITH_WSREP - if (!trust_function_creators && - (WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()) && + if (!trust_function_creators && + IF_WSREP((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()), mysql_bin_log.is_open()) && !(thd->security_ctx->master_access & SUPER_ACL)) -#else - if (!trust_function_creators && mysql_bin_log.is_open() && - !(thd->security_ctx->master_access & SUPER_ACL)) -#endif /* WITH_WSREP */ { my_error(ER_BINLOG_CREATE_ROUTINE_NEED_SUPER, MYF(0)); DBUG_RETURN(TRUE); @@ -2443,55 +2438,4 @@ bool load_table_name_for_trigger(THD *thd, DBUG_RETURN(FALSE); } -#ifdef WITH_WSREP -int wsrep_create_trigger_query(THD *thd, uchar** buf, size_t* buf_len) -{ - LEX *lex= thd->lex; - String stmt_query; - LEX_STRING definer_user; - LEX_STRING definer_host; - - if (!lex->definer) - { - if (!thd->slave_thread) - { - if (!(lex->definer= create_default_definer(thd, false))) - return 1; - } - } - - if (lex->definer) - { - /* SUID trigger. */ - - definer_user= lex->definer->user; - definer_host= lex->definer->host; - } - else - { - /* non-SUID trigger. */ - - definer_user.str= 0; - definer_user.length= 0; - - definer_host.str= 0; - definer_host.length= 0; - } - - stmt_query.append(STRING_WITH_LEN("CREATE ")); - - append_definer(thd, &stmt_query, &definer_user, &definer_host); - - LEX_STRING stmt_definition; - stmt_definition.str= (char*) thd->lex->stmt_definition_begin; - stmt_definition.length= thd->lex->stmt_definition_end - - thd->lex->stmt_definition_begin; - trim_whitespace(thd->charset(), & stmt_definition); - - stmt_query.append(stmt_definition.str, stmt_definition.length); - - return wsrep_to_buf_helper(thd, stmt_query.c_ptr(), stmt_query.length(), - buf, buf_len); -} -#endif /* WITH_WSREP */ diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc index 8046405a4b4..5e23c6ee32b 100644 --- a/sql/sql_truncate.cc +++ b/sql/sql_truncate.cc @@ -24,9 +24,7 @@ #include "sql_acl.h" // DROP_ACL #include "sql_parse.h" // check_one_table_access() #include "sql_truncate.h" -#ifdef WITH_WSREP #include "wsrep_mysqld.h" -#endif /* WITH_WSREP */ #include "sql_show.h" //append_identifier() diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 58d04674033..c458f01303d 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. - Copyright (c) 2011, 2013, Monty Program Ab. + Copyright (c) 2011, 2014, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -976,11 +976,8 @@ int mysql_update(THD *thd, */ if ((error < 0) || thd->transaction.stmt.modified_non_trans_table) { -#ifdef WITH_WSREP - if (WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()) -#else - if (mysql_bin_log.is_open()) -#endif + if (IF_WSREP((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()), + mysql_bin_log.is_open())) { int errcode= 0; if (error < 0) @@ -2223,11 +2220,8 @@ void multi_update::abort_result_set() The query has to binlog because there's a modified non-transactional table either from the query's list or via a stored routine: bug#13270,23333 */ -#ifdef WITH_WSREP - if (WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()) -#else - if (mysql_bin_log.is_open()) -#endif + if (IF_WSREP((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()), + mysql_bin_log.is_open())) { /* THD::killed status might not have been set ON at time of an error @@ -2496,11 +2490,8 @@ bool multi_update::send_eof() if (local_error == 0 || thd->transaction.stmt.modified_non_trans_table) { -#ifdef WITH_WSREP - if (WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()) -#else - if (mysql_bin_log.is_open()) -#endif + if (IF_WSREP((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()), + mysql_bin_log.is_open())) { int errcode= 0; if (local_error == 0) diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 1bf972d2c55..2c2d301f622 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -3338,9 +3338,7 @@ static bool fix_autocommit(sys_var *self, THD *thd, enum_var_type type) { thd->variables.option_bits&= ~OPTION_AUTOCOMMIT; thd->mdl_context.release_transactional_locks(); -#ifdef WITH_WSREP WSREP_DEBUG("autocommit, MDL TRX lock released: %lu", thd->thread_id); -#endif /* WITH_WSREP */ return true; } /* diff --git a/sql/table.cc b/sql/table.cc index 25dd9786d94..735dbf6eedd 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -40,9 +40,7 @@ #include "sql_statistics.h" #include "discover.h" #include "mdl.h" // MDL_wait_for_graph_visitor -#ifdef WITH_WSREP #include "ha_partition.h" -#endif /* WITH_WSREP */ /* INFORMATION_SCHEMA name */ LEX_STRING INFORMATION_SCHEMA_NAME= {C_STRING_WITH_LEN("information_schema")}; diff --git a/sql/transaction.cc b/sql/transaction.cc index 72a8c47cdd8..e7d3c0afc78 100644 --- a/sql/transaction.cc +++ b/sql/transaction.cc @@ -98,7 +98,8 @@ static bool xa_trans_force_rollback(THD *thd) */ thd->transaction.xid_state.rm_error= 0; #ifdef WITH_WSREP - wsrep_register_hton(thd, TRUE); + if (WSREP_ON) + wsrep_register_hton(thd, TRUE); #endif /* WITH_WSREP */ if (ha_rollback_trans(thd, true)) { @@ -139,14 +140,16 @@ bool trans_begin(THD *thd, uint flags) { thd->variables.option_bits&= ~OPTION_TABLE_LOCK; #ifdef WITH_WSREP - wsrep_register_hton(thd, TRUE); + if (WSREP_ON) + wsrep_register_hton(thd, TRUE); #endif /* WITH_WSREP */ thd->server_status&= ~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY); DBUG_PRINT("info", ("clearing SERVER_STATUS_IN_TRANS")); res= MY_TEST(ha_commit_trans(thd, TRUE)); #ifdef WITH_WSREP - wsrep_post_commit(thd, TRUE); + if (WSREP_ON) + wsrep_post_commit(thd, TRUE); #endif /* WITH_WSREP */ } @@ -228,14 +231,16 @@ bool trans_commit(THD *thd) DBUG_RETURN(TRUE); #ifdef WITH_WSREP - wsrep_register_hton(thd, TRUE); + if (WSREP_ON) + wsrep_register_hton(thd, TRUE); #endif /* WITH_WSREP */ thd->server_status&= ~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY); DBUG_PRINT("info", ("clearing SERVER_STATUS_IN_TRANS")); res= ha_commit_trans(thd, TRUE); #ifdef WITH_WSREP - wsrep_post_commit(thd, TRUE); + if (WSREP_ON) + wsrep_post_commit(thd, TRUE); #endif /* WITH_WSREP */ /* if res is non-zero, then ha_commit_trans has rolled back the @@ -283,14 +288,16 @@ bool trans_commit_implicit(THD *thd) if (!thd->locked_tables_mode) thd->variables.option_bits&= ~OPTION_TABLE_LOCK; #ifdef WITH_WSREP - wsrep_register_hton(thd, TRUE); + if (WSREP_ON) + wsrep_register_hton(thd, TRUE); #endif /* WITH_WSREP */ thd->server_status&= ~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY); DBUG_PRINT("info", ("clearing SERVER_STATUS_IN_TRANS")); res= MY_TEST(ha_commit_trans(thd, TRUE)); #ifdef WITH_WSREP - wsrep_post_commit(thd, TRUE); + if (WSREP_ON) + wsrep_post_commit(thd, TRUE); #endif /* WITH_WSREP */ } @@ -331,7 +338,8 @@ bool trans_rollback(THD *thd) DBUG_RETURN(TRUE); #ifdef WITH_WSREP - wsrep_register_hton(thd, TRUE); + if (WSREP_ON) + wsrep_register_hton(thd, TRUE); #endif /* WITH_WSREP */ thd->server_status&= ~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY); @@ -424,7 +432,8 @@ bool trans_commit_stmt(THD *thd) if (thd->transaction.stmt.ha_list) { #ifdef WITH_WSREP - wsrep_register_hton(thd, FALSE); + if (WSREP_ON) + wsrep_register_hton(thd, FALSE); #endif /* WITH_WSREP */ res= ha_commit_trans(thd, FALSE); if (! thd->in_active_multi_stmt_transaction()) @@ -432,7 +441,8 @@ bool trans_commit_stmt(THD *thd) thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation; thd->tx_read_only= thd->variables.tx_read_only; #ifdef WITH_WSREP - wsrep_post_commit(thd, FALSE); + if (WSREP_ON) + wsrep_post_commit(thd, FALSE); #endif /* WITH_WSREP */ } } @@ -475,7 +485,8 @@ bool trans_rollback_stmt(THD *thd) if (thd->transaction.stmt.ha_list) { #ifdef WITH_WSREP - wsrep_register_hton(thd, FALSE); + if (WSREP_ON) + wsrep_register_hton(thd, FALSE); #endif /* WITH_WSREP */ ha_rollback_trans(thd, FALSE); if (! thd->in_active_multi_stmt_transaction()) @@ -855,13 +866,15 @@ bool trans_xa_commit(THD *thd) else if (xa_state == XA_IDLE && thd->lex->xa_opt == XA_ONE_PHASE) { #ifdef WITH_WSREP - wsrep_register_hton(thd, TRUE); + if (WSREP_ON) + wsrep_register_hton(thd, TRUE); #endif /* WITH_WSREP */ int r= ha_commit_trans(thd, TRUE); if ((res= MY_TEST(r))) my_error(r == 1 ? ER_XA_RBROLLBACK : ER_XAER_RMERR, MYF(0)); #ifdef WITH_WSREP - wsrep_post_commit(thd, TRUE); + if (WSREP_ON) + wsrep_post_commit(thd, TRUE); #endif /* WITH_WSREP */ } else if (xa_state == XA_PREPARED && thd->lex->xa_opt == XA_NONE) @@ -882,7 +895,8 @@ bool trans_xa_commit(THD *thd) thd->variables.lock_wait_timeout)) { #ifdef WITH_WSREP - wsrep_register_hton(thd, TRUE); + if (WSREP_ON) + wsrep_register_hton(thd, TRUE); #endif /* WITH_WSREP */ ha_rollback_trans(thd, TRUE); my_error(ER_XAER_RMERR, MYF(0)); diff --git a/sql/tztime.cc b/sql/tztime.cc index 2a5a5d1681b..577474cd78f 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -2711,7 +2711,8 @@ main(int argc, char **argv) #ifdef WITH_WSREP // Replicate MyISAM DDL for this session, cf. lp:1161432 - printf("SET GLOBAL wsrep_replicate_myisam= ON;\n"); + // timezone info unfixable in XtraDB Cluster + printf("SET GLOBAL wsrep_replicate_myisam= ON;\n"); #endif /* WITH_WSREP */ if (argc == 1 && !opt_leap) diff --git a/sql/wsrep_binlog.cc b/sql/wsrep_binlog.cc index 5cb910248a2..ee8a9cb130b 100644 --- a/sql/wsrep_binlog.cc +++ b/sql/wsrep_binlog.cc @@ -15,7 +15,9 @@ #include "wsrep_binlog.h" #include "wsrep_priv.h" +#include "log.h" +extern handlerton *binlog_hton; /* Write the contents of a cache to a memory buffer. @@ -320,7 +322,6 @@ void wsrep_dump_rbr_buf(THD *thd, const void* rbr_buf, size_t buf_len) filename, errno, strerror(errno)); } } -extern handlerton *binlog_hton; /* wsrep exploits binlog's caches even if binlogging itself is not @@ -406,3 +407,8 @@ cleanup: // close file if (of) fclose(of); } + +void thd_binlog_flush_pending_rows_event(THD *thd, bool stmt_end) +{ + thd->binlog_flush_pending_rows_event(stmt_end); +} diff --git a/sql/wsrep_hton.cc b/sql/wsrep_hton.cc index 48577a9b5a1..96f1431a82f 100644 --- a/sql/wsrep_hton.cc +++ b/sql/wsrep_hton.cc @@ -539,7 +539,7 @@ static int wsrep_hton_init(void *p) wsrep_hton= (handlerton *)p; //wsrep_hton->state=opt_bin_log ? SHOW_OPTION_YES : SHOW_OPTION_NO; wsrep_hton->state= SHOW_OPTION_YES; - wsrep_hton->db_type=DB_TYPE_WSREP; + wsrep_hton->db_type=(legacy_db_type)0; wsrep_hton->savepoint_offset= sizeof(my_off_t); wsrep_hton->close_connection= wsrep_close_connection; wsrep_hton->savepoint_set= wsrep_savepoint_set; diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index a9344b0a946..a77f85cbbdb 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -1,4 +1,4 @@ -/* Copyright 2008-2013 Codership Oy +/* Copyright 2008-2014 Codership Oy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -16,6 +16,13 @@ #include #include #include +#include "slave.h" +#include "rpl_mi.h" +#include "sql_repl.h" +#include "rpl_filter.h" +#include "sql_callback.h" +#include "sp_head.h" +#include "sp.h" #include "wsrep_priv.h" #include "wsrep_thd.h" #include "wsrep_sst.h" @@ -40,6 +47,13 @@ my_bool wsrep_preordered_opt= FALSE; * Begin configuration options and their default values */ +extern int wsrep_replaying; +extern ulong wsrep_running_threads; +extern ulong my_bind_addr; +extern my_bool plugins_are_initialized; +extern uint kill_cached_threads; +extern mysql_cond_t COND_thread_cache; + const char* wsrep_data_home_dir = NULL; const char* wsrep_dbug_option = ""; @@ -1292,7 +1306,7 @@ static int wsrep_TOI_begin(THD *thd, char *db_, char *table_, { thd->wsrep_exec_mode= TOTAL_ORDER; wsrep_to_isolation++; - if (buf) my_free(buf); + my_free(buf); wsrep_keys_free(&key_arr); WSREP_DEBUG("TO BEGIN: %lld, %d",(long long)wsrep_thd_trx_seqno(thd), thd->wsrep_exec_mode); @@ -1407,13 +1421,14 @@ static void wsrep_RSU_end(THD *thd) int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_, const TABLE_LIST* table_list) { + int ret= 0; /* No isolation for applier or replaying threads. */ - if (thd->wsrep_exec_mode == REPL_RECV) return 0; + if (thd->wsrep_exec_mode == REPL_RECV) + return 0; - int ret= 0; mysql_mutex_lock(&thd->LOCK_wsrep_thd); if (thd->wsrep_conflict_state == MUST_ABORT) @@ -1501,8 +1516,8 @@ wsrep_grant_mdl_exception(MDL_context *requestor_ctx, ) { if (!WSREP_ON) return FALSE; - THD *request_thd = requestor_ctx->wsrep_get_thd(); - THD *granted_thd = ticket->get_ctx()->wsrep_get_thd(); + THD *request_thd = requestor_ctx->get_thd(); + THD *granted_thd = ticket->get_ctx()->get_thd(); bool ret = FALSE; mysql_mutex_lock(&request_thd->LOCK_wsrep_thd); @@ -1560,3 +1575,856 @@ wsrep_grant_mdl_exception(MDL_context *requestor_ctx, } return ret; } + + +pthread_handler_t start_wsrep_THD(void *arg) +{ + THD *thd; + rpl_sql_thread_info sql_info(NULL); + wsrep_thd_processor_fun processor= (wsrep_thd_processor_fun)arg; + + if (my_thread_init()) + { + WSREP_ERROR("Could not initialize thread"); + return(NULL); + } + + if (!(thd= new THD(true))) + { + return(NULL); + } + mysql_mutex_lock(&LOCK_thread_count); + thd->thread_id=thread_id++; + + thd->real_id=pthread_self(); // Keep purify happy + thread_count++; + thread_created++; + threads.append(thd); + + my_net_init(&thd->net,(st_vio*) 0, MYF(0)); + + DBUG_PRINT("wsrep",(("creating thread %lld"), (long long)thd->thread_id)); + thd->prior_thr_create_utime= thd->start_utime= microsecond_interval_timer(); + (void) mysql_mutex_unlock(&LOCK_thread_count); + + /* from bootstrap()... */ + thd->bootstrap=1; + thd->max_client_packet_length= thd->net.max_packet; + thd->security_ctx->master_access= ~(ulong)0; + thd->system_thread_info.rpl_sql_info= &sql_info; + + /* from handle_one_connection... */ + pthread_detach_this_thread(); + + mysql_thread_set_psi_id(thd->thread_id); + thd->thr_create_utime= microsecond_interval_timer(); + if (MYSQL_CALLBACK_ELSE(thread_scheduler, init_new_connection_thread, (), 0)) + { + close_connection(thd, ER_OUT_OF_RESOURCES); + statistic_increment(aborted_connects,&LOCK_status); + MYSQL_CALLBACK(thread_scheduler, end_thread, (thd, 0)); + + return(NULL); + } + +// + /* + handle_one_connection() is normally the only way a thread would + start and would always be on the very high end of the stack , + therefore, the thread stack always starts at the address of the + first local variable of handle_one_connection, which is thd. We + need to know the start of the stack so that we could check for + stack overruns. + */ + DBUG_PRINT("wsrep", ("handle_one_connection called by thread %lld\n", + (long long)thd->thread_id)); + /* now that we've called my_thread_init(), it is safe to call DBUG_* */ + + thd->thread_stack= (char*) &thd; + if (thd->store_globals()) + { + close_connection(thd, ER_OUT_OF_RESOURCES); + statistic_increment(aborted_connects,&LOCK_status); + MYSQL_CALLBACK(thread_scheduler, end_thread, (thd, 0)); + delete thd; + + return(NULL); + } + + thd->system_thread= SYSTEM_THREAD_SLAVE_SQL; + thd->security_ctx->skip_grants(); + + /* handle_one_connection() again... */ + //thd->version= refresh_version; + thd->proc_info= 0; + thd->set_command(COM_SLEEP); + thd->set_time(); + thd->init_for_queries(); + + mysql_mutex_lock(&LOCK_thread_count); + wsrep_running_threads++; + mysql_cond_broadcast(&COND_thread_count); + mysql_mutex_unlock(&LOCK_thread_count); + + processor(thd); + + close_connection(thd, 0); + + mysql_mutex_lock(&LOCK_thread_count); + wsrep_running_threads--; + WSREP_DEBUG("wsrep running threads now: %lu", wsrep_running_threads); + mysql_cond_broadcast(&COND_thread_count); + mysql_mutex_unlock(&LOCK_thread_count); + + // Note: We can't call THD destructor without crashing + // if plugins have not been initialized. However, in most of the + // cases this means that pre SE initialization SST failed and + // we are going to exit anyway. + if (plugins_are_initialized) + { + net_end(&thd->net); + MYSQL_CALLBACK(thread_scheduler, end_thread, (thd, 1)); + } + else + { + // TODO: lightweight cleanup to get rid of: + // 'Error in my_thread_global_end(): 2 threads didn't exit' + // at server shutdown + } + + my_thread_end(); + if (thread_handling > SCHEDULER_ONE_THREAD_PER_CONNECTION) + { + mysql_mutex_lock(&LOCK_thread_count); + delete thd; + thread_count--; + mysql_mutex_unlock(&LOCK_thread_count); + } + return(NULL); +} + + +/**/ +static bool abort_replicated(THD *thd) +{ + bool ret_code= false; + if (thd->wsrep_query_state== QUERY_COMMITTING) + { + if (wsrep_debug) WSREP_INFO("aborting replicated trx: %lu", thd->real_id); + + (void)wsrep_abort_thd(thd, thd, TRUE); + ret_code= true; + } + return ret_code; +} + + +/**/ +static inline bool is_client_connection(THD *thd) +{ + return (thd->wsrep_client_thread && thd->variables.wsrep_on); +} + + +static inline bool is_replaying_connection(THD *thd) +{ + bool ret; + + mysql_mutex_lock(&thd->LOCK_wsrep_thd); + ret= (thd->wsrep_conflict_state == REPLAYING) ? true : false; + mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + + return ret; +} + + +static inline bool is_committing_connection(THD *thd) +{ + bool ret; + + mysql_mutex_lock(&thd->LOCK_wsrep_thd); + ret= (thd->wsrep_query_state == QUERY_COMMITTING) ? true : false; + mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + + return ret; +} + + +static bool have_client_connections() +{ + THD *tmp; + + I_List_iterator it(threads); + while ((tmp=it++)) + { + DBUG_PRINT("quit",("Informing thread %ld that it's time to die", + tmp->thread_id)); + if (is_client_connection(tmp) && tmp->killed == KILL_CONNECTION) + { + (void)abort_replicated(tmp); + return true; + } + } + return false; +} + +/* + returns the number of wsrep appliers running. + However, the caller (thd parameter) is not taken in account + */ +static int have_wsrep_appliers(THD *thd) +{ + int ret= 0; + THD *tmp; + + I_List_iterator it(threads); + while ((tmp=it++)) + { + ret+= (tmp != thd && tmp->wsrep_applier); + } + return ret; +} + + +static void wsrep_close_thread(THD *thd) +{ + thd->killed= KILL_CONNECTION; + MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (thd)); + if (thd->mysys_var) + { + thd->mysys_var->abort=1; + mysql_mutex_lock(&thd->mysys_var->mutex); + if (thd->mysys_var->current_cond) + { + mysql_mutex_lock(thd->mysys_var->current_mutex); + mysql_cond_broadcast(thd->mysys_var->current_cond); + mysql_mutex_unlock(thd->mysys_var->current_mutex); + } + mysql_mutex_unlock(&thd->mysys_var->mutex); + } +} + + +static my_bool have_committing_connections() +{ + THD *tmp; + mysql_mutex_lock(&LOCK_thread_count); // For unlink from list + + I_List_iterator it(threads); + while ((tmp=it++)) + { + if (!is_client_connection(tmp)) + continue; + + if (is_committing_connection(tmp)) + { + mysql_mutex_unlock(&LOCK_thread_count); + return TRUE; + } + } + mysql_mutex_unlock(&LOCK_thread_count); + return FALSE; +} + + +int wsrep_wait_committing_connections_close(int wait_time) +{ + int sleep_time= 100; + + while (have_committing_connections() && wait_time > 0) + { + WSREP_DEBUG("wait for committing transaction to close: %d", wait_time); + my_sleep(sleep_time); + wait_time -= sleep_time; + } + if (have_committing_connections()) + { + return 1; + } + return 0; +} + + +void wsrep_close_client_connections(my_bool wait_to_end) +{ + /* + First signal all threads that it's time to die + */ + + THD *tmp; + mysql_mutex_lock(&LOCK_thread_count); // For unlink from list + + bool kill_cached_threads_saved= kill_cached_threads; + kill_cached_threads= true; // prevent future threads caching + mysql_cond_broadcast(&COND_thread_cache); // tell cached threads to die + + I_List_iterator it(threads); + while ((tmp=it++)) + { + DBUG_PRINT("quit",("Informing thread %ld that it's time to die", + tmp->thread_id)); + /* We skip slave threads & scheduler on this first loop through. */ + if (!is_client_connection(tmp)) + continue; + + if (is_replaying_connection(tmp)) + { + tmp->killed= KILL_CONNECTION; + continue; + } + + /* replicated transactions must be skipped */ + if (abort_replicated(tmp)) + continue; + + WSREP_DEBUG("closing connection %ld", tmp->thread_id); + wsrep_close_thread(tmp); + } + mysql_mutex_unlock(&LOCK_thread_count); + + if (thread_count) + sleep(2); // Give threads time to die + + mysql_mutex_lock(&LOCK_thread_count); + /* + Force remaining threads to die by closing the connection to the client + */ + + I_List_iterator it2(threads); + while ((tmp=it2++)) + { +#ifndef __bsdi__ // Bug in BSDI kernel + if (is_client_connection(tmp) && + !abort_replicated(tmp) && + !is_replaying_connection(tmp)) + { + WSREP_INFO("killing local connection: %ld",tmp->thread_id); + close_connection(tmp,0); + } +#endif + } + + DBUG_PRINT("quit",("Waiting for threads to die (count=%u)",thread_count)); + if (wsrep_debug) + WSREP_INFO("waiting for client connections to close: %u", thread_count); + + while (wait_to_end && have_client_connections()) + { + mysql_cond_wait(&COND_thread_count, &LOCK_thread_count); + DBUG_PRINT("quit",("One thread died (count=%u)", thread_count)); + } + + kill_cached_threads= kill_cached_threads_saved; + + mysql_mutex_unlock(&LOCK_thread_count); + + /* All client connection threads have now been aborted */ +} + + +void wsrep_close_applier(THD *thd) +{ + WSREP_DEBUG("closing applier %ld", thd->thread_id); + wsrep_close_thread(thd); +} + + +void wsrep_close_threads(THD *thd) +{ + THD *tmp; + mysql_mutex_lock(&LOCK_thread_count); // For unlink from list + + I_List_iterator it(threads); + while ((tmp=it++)) + { + DBUG_PRINT("quit",("Informing thread %ld that it's time to die", + tmp->thread_id)); + /* We skip slave threads & scheduler on this first loop through. */ + if (tmp->wsrep_applier && tmp != thd) + { + WSREP_DEBUG("closing wsrep thread %ld", tmp->thread_id); + wsrep_close_thread (tmp); + } + } + + mysql_mutex_unlock(&LOCK_thread_count); +} + + +void wsrep_close_applier_threads(int count) +{ + THD *tmp; + mysql_mutex_lock(&LOCK_thread_count); // For unlink from list + + I_List_iterator it(threads); + while ((tmp=it++) && count) + { + DBUG_PRINT("quit",("Informing thread %ld that it's time to die", + tmp->thread_id)); + /* We skip slave threads & scheduler on this first loop through. */ + if (tmp->wsrep_applier) + { + WSREP_DEBUG("closing wsrep applier thread %ld", tmp->thread_id); + tmp->wsrep_applier_closing= TRUE; + count--; + } + } + + mysql_mutex_unlock(&LOCK_thread_count); +} + + +void wsrep_wait_appliers_close(THD *thd) +{ + /* Wait for wsrep appliers to gracefully exit */ + mysql_mutex_lock(&LOCK_thread_count); + while (have_wsrep_appliers(thd) > 1) + // 1 is for rollbacker thread which needs to be killed explicitly. + // This gotta be fixed in a more elegant manner if we gonna have arbitrary + // number of non-applier wsrep threads. + { + if (thread_handling > SCHEDULER_ONE_THREAD_PER_CONNECTION) + { + mysql_mutex_unlock(&LOCK_thread_count); + my_sleep(100); + mysql_mutex_lock(&LOCK_thread_count); + } + else + mysql_cond_wait(&COND_thread_count,&LOCK_thread_count); + DBUG_PRINT("quit",("One applier died (count=%u)",thread_count)); + } + mysql_mutex_unlock(&LOCK_thread_count); + /* Now kill remaining wsrep threads: rollbacker */ + wsrep_close_threads (thd); + /* and wait for them to die */ + mysql_mutex_lock(&LOCK_thread_count); + while (have_wsrep_appliers(thd) > 0) + { + if (thread_handling > SCHEDULER_ONE_THREAD_PER_CONNECTION) + { + mysql_mutex_unlock(&LOCK_thread_count); + my_sleep(100); + mysql_mutex_lock(&LOCK_thread_count); + } + else + mysql_cond_wait(&COND_thread_count,&LOCK_thread_count); + DBUG_PRINT("quit",("One thread died (count=%u)",thread_count)); + } + mysql_mutex_unlock(&LOCK_thread_count); + + /* All wsrep applier threads have now been aborted. However, if this thread + is also applier, we are still running... + */ +} + + +void wsrep_kill_mysql(THD *thd) +{ + if (mysqld_server_started) + { + if (!shutdown_in_progress) + { + WSREP_INFO("starting shutdown"); + kill_mysql(); + } + } + else + { + unireg_abort(1); + } +} + + +int wsrep_create_sp(THD *thd, uchar** buf, size_t* buf_len) +{ + String log_query; + sp_head *sp = thd->lex->sphead; + ulong saved_mode= thd->variables.sql_mode; + String retstr(64); + retstr.set_charset(system_charset_info); + + log_query.set_charset(system_charset_info); + + if (sp->m_type == TYPE_ENUM_FUNCTION) + { + sp_returns_type(thd, retstr, sp); + } + + if (!create_string(thd, &log_query, + sp->m_type, + (sp->m_explicit_name ? sp->m_db.str : NULL), + (sp->m_explicit_name ? sp->m_db.length : 0), + sp->m_name.str, sp->m_name.length, + sp->m_params.str, sp->m_params.length, + retstr.c_ptr(), retstr.length(), + sp->m_body.str, sp->m_body.length, + sp->m_chistics, &(thd->lex->definer->user), + &(thd->lex->definer->host), + saved_mode)) + { + WSREP_WARN("SP create string failed: %s", thd->query()); + return 1; + } + + return wsrep_to_buf_helper(thd, log_query.ptr(), log_query.length(), buf, buf_len); +} + + +extern int wsrep_on(void *thd) +{ + return (int)(WSREP(((THD*)thd))); +} + + +extern "C" bool wsrep_thd_is_wsrep_on(THD *thd) +{ + return thd->variables.wsrep_on; +} + + +extern "C" bool wsrep_consistency_check(void *thd) +{ + return ((THD*)thd)->wsrep_consistency_check == CONSISTENCY_CHECK_RUNNING; +} + + +extern "C" void wsrep_thd_set_exec_mode(THD *thd, enum wsrep_exec_mode mode) +{ + thd->wsrep_exec_mode= mode; +} + + +extern "C" void wsrep_thd_set_query_state( + THD *thd, enum wsrep_query_state state) +{ + thd->wsrep_query_state= state; +} + + +extern "C" void wsrep_thd_set_conflict_state( + THD *thd, enum wsrep_conflict_state state) +{ + thd->wsrep_conflict_state= state; +} + + +extern "C" enum wsrep_exec_mode wsrep_thd_exec_mode(THD *thd) +{ + return thd->wsrep_exec_mode; +} + + +extern "C" const char *wsrep_thd_exec_mode_str(THD *thd) +{ + return + (!thd) ? "void" : + (thd->wsrep_exec_mode == LOCAL_STATE) ? "local" : + (thd->wsrep_exec_mode == REPL_RECV) ? "applier" : + (thd->wsrep_exec_mode == TOTAL_ORDER) ? "total order" : + (thd->wsrep_exec_mode == LOCAL_COMMIT) ? "local commit" : "void"; +} + + +extern "C" enum wsrep_query_state wsrep_thd_query_state(THD *thd) +{ + return thd->wsrep_query_state; +} + + +extern "C" const char *wsrep_thd_query_state_str(THD *thd) +{ + return + (!thd) ? "void" : + (thd->wsrep_query_state == QUERY_IDLE) ? "idle" : + (thd->wsrep_query_state == QUERY_EXEC) ? "executing" : + (thd->wsrep_query_state == QUERY_COMMITTING) ? "committing" : + (thd->wsrep_query_state == QUERY_EXITING) ? "exiting" : + (thd->wsrep_query_state == QUERY_ROLLINGBACK) ? "rolling back" : "void"; +} + + +extern "C" enum wsrep_conflict_state wsrep_thd_conflict_state(THD *thd) +{ + return thd->wsrep_conflict_state; +} + + +extern "C" const char *wsrep_thd_conflict_state_str(THD *thd) +{ + return + (!thd) ? "void" : + (thd->wsrep_conflict_state == NO_CONFLICT) ? "no conflict" : + (thd->wsrep_conflict_state == MUST_ABORT) ? "must abort" : + (thd->wsrep_conflict_state == ABORTING) ? "aborting" : + (thd->wsrep_conflict_state == MUST_REPLAY) ? "must replay" : + (thd->wsrep_conflict_state == REPLAYING) ? "replaying" : + (thd->wsrep_conflict_state == RETRY_AUTOCOMMIT) ? "retrying" : + (thd->wsrep_conflict_state == CERT_FAILURE) ? "cert failure" : "void"; +} + + +extern "C" wsrep_ws_handle_t* wsrep_thd_ws_handle(THD *thd) +{ + return &thd->wsrep_ws_handle; +} + + +extern "C" void wsrep_thd_LOCK(THD *thd) +{ + mysql_mutex_lock(&thd->LOCK_wsrep_thd); +} + + +extern "C" void wsrep_thd_UNLOCK(THD *thd) +{ + mysql_mutex_unlock(&thd->LOCK_wsrep_thd); +} + + +extern "C" time_t wsrep_thd_query_start(THD *thd) +{ + return thd->query_start(); +} + + +extern "C" uint32 wsrep_thd_wsrep_rand(THD *thd) +{ + return thd->wsrep_rand; +} + + +extern "C" my_thread_id wsrep_thd_thread_id(THD *thd) +{ + return thd->thread_id; +} + + +extern "C" wsrep_seqno_t wsrep_thd_trx_seqno(THD *thd) +{ + return (thd) ? thd->wsrep_trx_meta.gtid.seqno : WSREP_SEQNO_UNDEFINED; +} + + +extern "C" query_id_t wsrep_thd_query_id(THD *thd) +{ + return thd->query_id; +} + + +extern "C" char *wsrep_thd_query(THD *thd) +{ + return (thd) ? thd->query() : NULL; +} + + +extern "C" query_id_t wsrep_thd_wsrep_last_query_id(THD *thd) +{ + return thd->wsrep_last_query_id; +} + + +extern "C" void wsrep_thd_set_wsrep_last_query_id(THD *thd, query_id_t id) +{ + thd->wsrep_last_query_id= id; +} + + +extern "C" void wsrep_thd_awake(THD *thd, my_bool signal) +{ + if (signal) + { + mysql_mutex_lock(&thd->LOCK_thd_data); + thd->awake(KILL_QUERY); + mysql_mutex_unlock(&thd->LOCK_thd_data); + } + else + { + mysql_mutex_lock(&LOCK_wsrep_replaying); + mysql_cond_broadcast(&COND_wsrep_replaying); + mysql_mutex_unlock(&LOCK_wsrep_replaying); + } +} + + +extern "C" int wsrep_thd_retry_counter(THD *thd) +{ + return(thd->wsrep_retry_counter); +} + + +extern int +wsrep_trx_order_before(void *thd1, void *thd2) +{ + if (wsrep_thd_trx_seqno((THD*)thd1) < wsrep_thd_trx_seqno((THD*)thd2)) { + WSREP_DEBUG("BF conflict, order: %lld %lld\n", + (long long)wsrep_thd_trx_seqno((THD*)thd1), + (long long)wsrep_thd_trx_seqno((THD*)thd2)); + return 1; + } + WSREP_DEBUG("waiting for BF, trx order: %lld %lld\n", + (long long)wsrep_thd_trx_seqno((THD*)thd1), + (long long)wsrep_thd_trx_seqno((THD*)thd2)); + return 0; +} + + +extern "C" int +wsrep_trx_is_aborting(void *thd_ptr) +{ + if (thd_ptr) { + if ((((THD *)thd_ptr)->wsrep_conflict_state == MUST_ABORT) || + (((THD *)thd_ptr)->wsrep_conflict_state == ABORTING)) { + return 1; + } + } + return 0; +} + + +my_bool wsrep_read_only_option(THD *thd, TABLE_LIST *all_tables) +{ + int opt_readonly_saved = opt_readonly; + ulong flag_saved = (ulong)(thd->security_ctx->master_access & SUPER_ACL); + + opt_readonly = 0; + thd->security_ctx->master_access &= ~SUPER_ACL; + + my_bool ret = !deny_updates_if_read_only_option(thd, all_tables); + + opt_readonly = opt_readonly_saved; + thd->security_ctx->master_access |= flag_saved; + + return ret; +} + + +void wsrep_copy_query(THD *thd) +{ + thd->wsrep_retry_command = thd->get_command(); + thd->wsrep_retry_query_len = thd->query_length(); + thd->wsrep_retry_query = (char *)my_malloc( + thd->wsrep_retry_query_len + 1, MYF(0)); + strncpy(thd->wsrep_retry_query, thd->query(), thd->wsrep_retry_query_len); + thd->wsrep_retry_query[thd->wsrep_retry_query_len] = '\0'; +} + + +bool wsrep_is_show_query(enum enum_sql_command command) +{ + DBUG_ASSERT(command >= 0 && command <= SQLCOM_END); + return (sql_command_flags[command] & CF_STATUS_COMMAND) != 0; +} + +bool wsrep_create_like_table(THD* thd, TABLE_LIST* table, + TABLE_LIST* src_table, + HA_CREATE_INFO *create_info) +{ + TABLE *tmp_table; + bool is_tmp_table= FALSE; + + for (tmp_table= thd->temporary_tables; tmp_table; tmp_table=tmp_table->next) + { + if (!strcmp(src_table->db, tmp_table->s->db.str) && + !strcmp(src_table->table_name, tmp_table->s->table_name.str)) + { + is_tmp_table= TRUE; + break; + } + } + if (create_info->options & HA_LEX_CREATE_TMP_TABLE) + { + + /* CREATE TEMPORARY TABLE LIKE must be skipped from replication */ + WSREP_DEBUG("CREATE TEMPORARY TABLE LIKE... skipped replication\n %s", + thd->query()); + } + else if (!is_tmp_table) + { + /* this is straight CREATE TABLE LIKE... eith no tmp tables */ + WSREP_TO_ISOLATION_BEGIN(table->db, table->table_name, NULL); + } + else + { + /* here we have CREATE TABLE LIKE + the temporary table definition will be needed in slaves to + enable the create to succeed + */ + TABLE_LIST tbl; + bzero((void*) &tbl, sizeof(tbl)); + tbl.db= src_table->db; + tbl.table_name= tbl.alias= src_table->table_name; + tbl.table= tmp_table; + char buf[2048]; + String query(buf, sizeof(buf), system_charset_info); + query.length(0); // Have to zero it since constructor doesn't + + (void) store_create_info(thd, &tbl, &query, NULL, TRUE, FALSE); + WSREP_DEBUG("TMP TABLE: %s", query.ptr()); + + thd->wsrep_TOI_pre_query= query.ptr(); + thd->wsrep_TOI_pre_query_len= query.length(); + + WSREP_TO_ISOLATION_BEGIN(table->db, table->table_name, NULL); + + thd->wsrep_TOI_pre_query= NULL; + thd->wsrep_TOI_pre_query_len= 0; + } + + return(false); + +error: + thd->wsrep_TOI_pre_query= NULL; + return (true); +} + + +int wsrep_create_trigger_query(THD *thd, uchar** buf, size_t* buf_len) +{ + LEX *lex= thd->lex; + String stmt_query; + + LEX_STRING definer_user; + LEX_STRING definer_host; + + if (!lex->definer) + { + if (!thd->slave_thread) + { + if (!(lex->definer= create_default_definer(thd, false))) + return 1; + } + } + + if (lex->definer) + { + /* SUID trigger. */ + + definer_user= lex->definer->user; + definer_host= lex->definer->host; + } + else + { + /* non-SUID trigger. */ + + definer_user.str= 0; + definer_user.length= 0; + + definer_host.str= 0; + definer_host.length= 0; + } + + stmt_query.append(STRING_WITH_LEN("CREATE ")); + + append_definer(thd, &stmt_query, &definer_user, &definer_host); + + LEX_STRING stmt_definition; + stmt_definition.str= (char*) thd->lex->stmt_definition_begin; + stmt_definition.length= thd->lex->stmt_definition_end + - thd->lex->stmt_definition_begin; + trim_whitespace(thd->charset(), & stmt_definition); + + stmt_query.append(stmt_definition.str, stmt_definition.length); + + return wsrep_to_buf_helper(thd, stmt_query.c_ptr(), stmt_query.length(), + buf, buf_len); +} diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index 796f1aac0f1..18d525d2376 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -13,14 +13,18 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef WSREP_MYSQLD_H +#include + +#if !defined(WSREP_MYSQLD_H) && defined(WITH_WSREP) #define WSREP_MYSQLD_H -#include "mysqld.h" typedef struct st_mysql_show_var SHOW_VAR; #include //#include "rpl_gtid.h" #include "../wsrep/wsrep_api.h" +#include "mdl.h" +#include "mysqld.h" +#include "sql_table.h" #define WSREP_UNDEFINED_TRX_ID ULONGLONG_MAX @@ -59,6 +63,15 @@ enum wsrep_consistency_check_mode { CONSISTENCY_CHECK_RUNNING, }; +struct wsrep_thd_shadow { + ulonglong options; + uint server_status; + enum wsrep_exec_mode wsrep_exec_mode; + Vio *vio; + ulong tx_isolation; + char *db; + size_t db_length; +}; // Global wsrep parameters extern wsrep_t* wsrep; @@ -203,12 +216,6 @@ extern wsrep_seqno_t wsrep_locked_seqno; fun("WSREP: %s", msg); \ } -#define WSREP_DEBUG(...) \ - if (wsrep_debug) WSREP_LOG(sql_print_information, ##__VA_ARGS__) -#define WSREP_INFO(...) WSREP_LOG(sql_print_information, ##__VA_ARGS__) -#define WSREP_WARN(...) WSREP_LOG(sql_print_warning, ##__VA_ARGS__) -#define WSREP_ERROR(...) WSREP_LOG(sql_print_error, ##__VA_ARGS__) - #define WSREP_LOG_CONFLICT_THD(thd, role) \ WSREP_LOG(sql_print_information, \ "%s: \n " \ @@ -279,6 +286,7 @@ extern int wsrep_to_isolation; extern rpl_sidno wsrep_sidno; #endif /* GTID_SUPPORT */ extern my_bool wsrep_preordered_opt; +extern handlerton *wsrep_hton; #ifdef HAVE_PSI_INTERFACE extern PSI_mutex_key key_LOCK_wsrep_ready; @@ -317,4 +325,37 @@ const wsrep_uuid_t* wsrep_xid_uuid(const xid_t*); wsrep_seqno_t wsrep_xid_seqno(const xid_t*); extern "C" int wsrep_is_wsrep_xid(const void* xid); +extern "C" my_thread_id wsrep_thd_thread_id(THD *thd); +extern "C" char *wsrep_thd_query(THD *thd); + +extern bool +wsrep_grant_mdl_exception(MDL_context *requestor_ctx, + MDL_ticket *ticket); +IO_CACHE * get_trans_log(THD * thd); +bool wsrep_trans_cache_is_empty(THD *thd); +void thd_binlog_flush_pending_rows_event(THD *thd, bool stmt_end); +void thd_binlog_rollback_stmt(THD * thd); +void thd_binlog_trx_reset(THD * thd); + +typedef void (*wsrep_thd_processor_fun)(THD *); +pthread_handler_t start_wsrep_THD(void *arg); +int wsrep_wait_committing_connections_close(int wait_time); +void wsrep_close_client_connections(my_bool wait_to_end); +void wsrep_close_applier(THD *thd); +void wsrep_close_applier_threads(int count); +void wsrep_wait_appliers_close(THD *thd); +void wsrep_kill_mysql(THD *thd); +void wsrep_close_threads(THD *thd); +int wsrep_create_sp(THD *thd, uchar** buf, size_t* buf_len); +my_bool wsrep_read_only_option(THD *thd, TABLE_LIST *all_tables); +void wsrep_copy_query(THD *thd); +bool wsrep_is_show_query(enum enum_sql_command command); +void wsrep_replay_transaction(THD *thd); +bool wsrep_create_like_table(THD* thd, TABLE_LIST* table, + TABLE_LIST* src_table, + HA_CREATE_INFO *create_info); +int wsrep_create_trigger_query(THD *thd, uchar** buf, size_t* buf_len); + +extern my_bool deny_updates_if_read_only_option(THD *thd, + TABLE_LIST *all_tables); #endif /* WSREP_MYSQLD_H */ diff --git a/sql/wsrep_sst.h b/sql/wsrep_sst.h index 6b2b419e63a..d85fed97fca 100644 --- a/sql/wsrep_sst.h +++ b/sql/wsrep_sst.h @@ -13,7 +13,7 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef WSREP_SST_H +#if !defined(WSREP_SST_H) && defined(WITH_WSREP) #define WSREP_SST_H #include // my_bool diff --git a/sql/wsrep_thd.h b/sql/wsrep_thd.h index a7e34c35101..14fdfc97858 100644 --- a/sql/wsrep_thd.h +++ b/sql/wsrep_thd.h @@ -13,7 +13,7 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef WSREP_THD_H +#if !defined(WSREP_THD_H) && defined(WITH_WSREP) #define WSREP_THD_H #include "sql_class.h" diff --git a/sql/wsrep_var.h b/sql/wsrep_var.h index 2a5e94b6724..c62ea7781cc 100644 --- a/sql/wsrep_var.h +++ b/sql/wsrep_var.h @@ -13,7 +13,7 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef WSREP_VAR_H +#if !defined (WSREP_VAR_H) && defined(WITH_WSREP) #define WSREP_VAR_H #define WSREP_CLUSTER_NAME "my_wsrep_cluster" diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index ed562f5172d..9313a0bf232 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -17326,44 +17326,44 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr, if (!thd) { DBUG_PRINT("wsrep", ("no thd for conflicting lock")); - WSREP_WARN("no THD for trx: %llu", victim_trx->id); + WSREP_WARN("no THD for trx: %lu", victim_trx->id); DBUG_RETURN(1); } if (!bf_thd) { DBUG_PRINT("wsrep", ("no BF thd for conflicting lock")); - WSREP_WARN("no BF THD for trx: %llu", (bf_trx) ? bf_trx->id : 0); + WSREP_WARN("no BF THD for trx: %lu", (bf_trx) ? bf_trx->id : 0); DBUG_RETURN(1); } WSREP_LOG_CONFLICT(bf_thd, thd, TRUE); - WSREP_DEBUG("BF kill (%lu, seqno: %lld), victim: (%lu) trx: %llu", + WSREP_DEBUG("BF kill (%lu, seqno: %lld), victim: (%lu) trx: %lu", signal, (long long)bf_seqno, wsrep_thd_thread_id(thd), victim_trx->id); - WSREP_DEBUG("Aborting query: %s", + WSREP_DEBUG("Aborting query: %s", (thd && wsrep_thd_query(thd)) ? wsrep_thd_query(thd) : "void"); wsrep_thd_LOCK(thd); if (wsrep_thd_query_state(thd) == QUERY_EXITING) { - WSREP_DEBUG("kill trx EXITING for %llu", victim_trx->id); + WSREP_DEBUG("kill trx EXITING for %lu", victim_trx->id); wsrep_thd_UNLOCK(thd); DBUG_RETURN(0); } if(wsrep_thd_exec_mode(thd) != LOCAL_STATE) { - WSREP_DEBUG("withdraw for BF trx: %llu, state: %d", + WSREP_DEBUG("withdraw for BF trx: %lu, state: %d", victim_trx->id, wsrep_thd_conflict_state(thd)); } switch (wsrep_thd_conflict_state(thd)) { - case NO_CONFLICT: + case NO_CONFLICT: wsrep_thd_set_conflict_state(thd, MUST_ABORT); break; case MUST_ABORT: - WSREP_DEBUG("victim %llu in MUST ABORT state", + WSREP_DEBUG("victim %lu in MUST ABORT state", victim_trx->id); wsrep_thd_UNLOCK(thd); wsrep_thd_awake(thd, signal); @@ -17372,7 +17372,7 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr, case ABORTED: case ABORTING: // fall through default: - WSREP_DEBUG("victim %llu in state %d", + WSREP_DEBUG("victim %lu in state %d", victim_trx->id, wsrep_thd_conflict_state(thd)); wsrep_thd_UNLOCK(thd); DBUG_RETURN(0); @@ -17385,7 +17385,7 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr, WSREP_DEBUG("kill query for: %ld", wsrep_thd_thread_id(thd)); - WSREP_DEBUG("kill trx QUERY_COMMITTING for %llu", + WSREP_DEBUG("kill trx QUERY_COMMITTING for %lu", victim_trx->id); if (wsrep_thd_exec_mode(thd) == REPL_RECV) { @@ -17399,7 +17399,7 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr, switch (rcode) { case WSREP_WARNING: - WSREP_DEBUG("cancel commit warning: %llu", + WSREP_DEBUG("cancel commit warning: %lu", victim_trx->id); wsrep_thd_UNLOCK(thd); wsrep_thd_awake(thd, signal); @@ -17409,8 +17409,8 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr, break; default: WSREP_ERROR( - "cancel commit bad exit: %d %llu", - rcode, + "cancel commit bad exit: %d %lu", + rcode, victim_trx->id); /* unable to interrupt, must abort */ /* note: kill_mysql() will block, if we cannot. @@ -17424,10 +17424,10 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr, wsrep_thd_awake(thd, signal); break; case QUERY_EXEC: - /* it is possible that victim trx is itself waiting for some + /* it is possible that victim trx is itself waiting for some * other lock. We need to cancel this waiting */ - WSREP_DEBUG("kill trx QUERY_EXEC for %llu", victim_trx->id); + WSREP_DEBUG("kill trx QUERY_EXEC for %lu", victim_trx->id); victim_trx->lock.was_chosen_as_deadlock_victim= TRUE; if (victim_trx->lock.wait_lock) { @@ -17444,7 +17444,7 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr, wsrep_thd_awake(thd, signal); } else { /* abort currently executing query */ - DBUG_PRINT("wsrep",("sending KILL_QUERY to: %ld", + DBUG_PRINT("wsrep",("sending KILL_QUERY to: %ld", wsrep_thd_thread_id(thd))); WSREP_DEBUG("kill query for: %ld", wsrep_thd_thread_id(thd)); @@ -17464,8 +17464,8 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr, { bool skip_abort= false; wsrep_aborting_thd_t abortees; - - WSREP_DEBUG("kill IDLE for %llu", victim_trx->id); + + WSREP_DEBUG("kill IDLE for %lu", victim_trx->id); if (wsrep_thd_exec_mode(thd) == REPL_RECV) { WSREP_DEBUG("kill BF IDLE, seqno: %lld", @@ -17485,14 +17485,14 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr, /* check if we have a kill message for this already */ if (abortees->aborting_thd == thd) { skip_abort = true; - WSREP_WARN("duplicate thd aborter %lu", + WSREP_WARN("duplicate thd aborter %lu", wsrep_thd_thread_id(thd)); } abortees = abortees->next; } if (!skip_abort) { wsrep_aborting_thd_t aborting = (wsrep_aborting_thd_t) - my_malloc(sizeof(struct wsrep_aborting_thd), + my_malloc(sizeof(struct wsrep_aborting_thd), MYF(0)); aborting->aborting_thd = thd; aborting->next = wsrep_aborting_thd; @@ -17512,22 +17512,24 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr, break; } default: - WSREP_WARN("bad wsrep query state: %d", + WSREP_WARN("bad wsrep query state: %d", wsrep_thd_query_state(thd)); wsrep_thd_UNLOCK(thd); break; } - + DBUG_RETURN(0); } -static int -wsrep_abort_transaction(handlerton* hton, THD *bf_thd, THD *victim_thd, + +static +int +wsrep_abort_transaction(handlerton* hton, THD *bf_thd, THD *victim_thd, my_bool signal) { DBUG_ENTER("wsrep_innobase_abort_thd"); trx_t* victim_trx = thd_to_trx(victim_thd); trx_t* bf_trx = (bf_thd) ? thd_to_trx(bf_thd) : NULL; - WSREP_DEBUG("abort transaction: BF: %s victim: %s", + WSREP_DEBUG("abort transaction: BF: %s victim: %s", wsrep_thd_query(bf_thd), wsrep_thd_query(victim_thd));