diff options
-rw-r--r-- | cmake/wsrep.cmake | 2 | ||||
-rw-r--r-- | include/thr_lock.h | 2 | ||||
-rw-r--r-- | mysys/thr_lock.c | 206 | ||||
-rw-r--r-- | sql/mdl.cc | 8 | ||||
-rw-r--r-- | sql/sql_base.cc | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 2 | ||||
-rw-r--r-- | sql/wsrep_mysqld.cc | 2 | ||||
-rw-r--r-- | sql/wsrep_thd.cc | 62 | ||||
-rw-r--r-- | sql/wsrep_thd.h | 4 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 3 | ||||
-rw-r--r-- | storage/innobase/include/ha_prototypes.h | 3 | ||||
-rw-r--r-- | storage/innobase/include/lock0lock.h | 1 | ||||
-rw-r--r-- | storage/innobase/lock/lock0lock.c | 69 | ||||
-rw-r--r-- | storage/innobase/row/row0ins.c | 22 | ||||
-rw-r--r-- | storage/innobase/row/row0upd.c | 6 | ||||
-rw-r--r-- | storage/innobase/srv/srv0srv.c | 6 | ||||
-rw-r--r-- | storage/xtradb/handler/ha_innodb.cc | 17 | ||||
-rw-r--r-- | storage/xtradb/include/ha_prototypes.h | 3 | ||||
-rw-r--r-- | storage/xtradb/include/lock0lock.h | 1 | ||||
-rw-r--r-- | storage/xtradb/lock/lock0lock.c | 126 | ||||
-rw-r--r-- | storage/xtradb/row/row0ins.c | 23 | ||||
-rw-r--r-- | storage/xtradb/row/row0upd.c | 6 | ||||
-rw-r--r-- | storage/xtradb/srv/srv0srv.c | 6 |
23 files changed, 293 insertions, 289 deletions
diff --git a/cmake/wsrep.cmake b/cmake/wsrep.cmake index 849da4e555d..391cf505313 100644 --- a/cmake/wsrep.cmake +++ b/cmake/wsrep.cmake @@ -23,7 +23,7 @@ SET(WSREP_PATCH_VERSION "9") # MariaDB addition: Revision number of the last revision merged from # codership branch visible in @@visible_comment. # Branch : codership-mysql/5.5 -SET(WSREP_PATCH_REVNO "3932") # Should be updated on every merge. +SET(WSREP_PATCH_REVNO "3944") # Should be updated on every merge. # MariaDB: Obtain patch revision number: # Update WSREP_PATCH_REVNO if WSREP_REV environment variable is set. diff --git a/include/thr_lock.h b/include/thr_lock.h index 4551a3160ff..f05db666da9 100644 --- a/include/thr_lock.h +++ b/include/thr_lock.h @@ -22,7 +22,7 @@ extern "C" { #endif #ifdef WITH_WSREP #include <my_sys.h> - typedef int (* wsrep_thd_is_brute_force_fun)(void *); + 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( diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index 7c10b0abe8c..914990551b0 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -662,8 +662,111 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data, DBUG_RETURN(result); } +#ifdef WITH_WSREP +/* + * If brute force applier would need to wait for a thr lock, + * it needs to make sure that it will get the lock without (too much) + * delay. + * We identify here the owners of blocking locks and ask them to + * abort. We then put our lock request in the first place in the + * wait queue. When lock holders abort (one by one) the lock release + * algorithm should grant the lock to us. We rely on this and proceed + * to wait_for_locks(). + * wsrep_break_locks() should be called in all the cases, where lock + * wait would happen. + * + * TODO: current implementation might not cover all possible lock wait + * situations. This needs an review still. + * TODO: lock release, might favor some other lock (instead our bf). + * 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 +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) +{ + if (wsrep_on(data->owner->mysql_thd) && + wsrep_thd_is_brute_force && + wsrep_thd_is_brute_force(data->owner->mysql_thd, TRUE)) + { + THR_LOCK_DATA *holder; -static enum enum_thr_lock_result + /* if locking session conversion to transaction has been enabled, + 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 + if (wsrep_convert_LOCK_to_trx && + (THD*)(data->owner->mysql_thd)->in_lock_tables) + { + if (wsrep_debug) + fprintf(stderr,"WSREP wsrep_break_lock read lock untouched\n"); + return FALSE; + } +#endif + if (wsrep_debug) + fprintf(stderr,"WSREP wsrep_break_lock aborting locks\n"); + + /* aborting lock holder(s) here */ + for (holder=(lock_queue1) ? lock_queue1->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; + } + } + 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) + { + wait_queue->last=&data->next; + assert(wait_queue->data==0); + } + else + { + assert(wait_queue->data!=0); + wait_queue->data->prev=&data->next; + } + data->next=wait_queue->data; + data->prev=&wait_queue->data; + wait_queue->data=data; + data->cond=get_cond(); + + statistic_increment(locks_immediate,&THR_LOCK_lock); + return TRUE; + } + return FALSE; +} +#endif + +static + enum enum_thr_lock_result thr_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner, ulong lock_wait_timeout) { THR_LOCK *lock=data->lock; @@ -1164,108 +1267,7 @@ static void sort_locks(THR_LOCK_DATA **data,uint count) } } -#ifdef WITH_WSREP -/* - * If brute force applier would need to wait for a thr lock, - * it needs to make sure that it will get the lock without (too much) - * delay. - * We identify here the owners of blocking locks and ask them to - * abort. We then put our lock request in the first place in the - * wait queue. When lock holders abort (one by one) the lock release - * algorithm should grant the lock to us. We rely on this and proceed - * to wait_for_locks(). - * wsrep_break_locks() should be called in all the cases, where lock - * wait would happen. - * - * TODO: current implementation might not cover all possible lock wait - * situations. This needs an review still. - * TODO: lock release, might favor some other lock (instead our bf). - * 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 -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) -{ - if (wsrep_on(data->owner->mysql_thd) && - wsrep_thd_is_brute_force && - wsrep_thd_is_brute_force(data->owner->mysql_thd)) - { - THR_LOCK_DATA *holder; - - /* if locking session conversion to transaction has been enabled, - 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 - if (wsrep_convert_LOCK_to_trx && - (THD*)(data->owner->mysql_thd)->in_lock_tables) - { - if (wsrep_debug) - fprintf(stderr,"WSREP wsrep_break_lock read lock untouched\n"); - return FALSE; - } -#endif - if (wsrep_debug) - fprintf(stderr,"WSREP wsrep_break_lock aborting locks\n"); - /* aborting lock holder(s) here */ - for (holder=(lock_queue1) ? lock_queue1->data : NULL; - holder; - holder=holder->next) - { - if (!wsrep_thd_is_brute_force(holder->owner->mysql_thd)) - { - 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; - } - } - for (holder=(lock_queue2) ? lock_queue2->data : NULL; - holder; - holder=holder->next) - { - if (!wsrep_thd_is_brute_force(holder->owner->mysql_thd)) - { - 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) - { - wait_queue->last=&data->next; - assert(wait_queue->data==0); - } - else - { - assert(wait_queue->data!=0); - wait_queue->data->prev=&data->next; - } - data->next=wait_queue->data; - data->prev=&wait_queue->data; - wait_queue->data=data; - data->cond=get_cond(); - - statistic_increment(locks_immediate,&THR_LOCK_lock); - return TRUE; - } - return FALSE; -} -#endif enum enum_thr_lock_result thr_multi_lock(THR_LOCK_DATA **data, uint count, THR_LOCK_INFO *owner, diff --git a/sql/mdl.cc b/sql/mdl.cc index b35a9a08e09..56f005d0eeb 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -1267,7 +1267,7 @@ 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_brute_force((void *)(ticket->get_ctx()->get_thd()))) + 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); @@ -1278,7 +1278,7 @@ void MDL_lock::Ticket_list::add_ticket(MDL_ticket *ticket) while ((waiting= itw++) && !added) { - if (!wsrep_thd_is_brute_force((void *)(waiting->get_ctx()->get_thd()))) + 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()->get_thd()), @@ -1669,7 +1669,7 @@ MDL_lock::can_grant_lock(enum_mdl_type type_arg, ticket->is_incompatible_when_granted(type_arg)) #ifdef WITH_WSREP { - if (wsrep_thd_is_brute_force((void *)(requestor_ctx->get_thd())) && + 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", @@ -1710,7 +1710,7 @@ MDL_lock::can_grant_lock(enum_mdl_type type_arg, #ifdef WITH_WSREP else { - if (wsrep_thd_is_brute_force((void *)(requestor_ctx->get_thd())) && + 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", diff --git a/sql/sql_base.cc b/sql/sql_base.cc index b2a22152149..9eb88e90b6b 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -9386,7 +9386,7 @@ bool mysql_notify_thread_having_shared_lock(THD *thd, THD *in_use, #ifdef WITH_WSREP { signalled|= mysql_lock_abort_for_thread(thd, thd_table); - if (thd && WSREP(thd) && wsrep_thd_is_brute_force((void *)thd)) + if (thd && WSREP(thd) && wsrep_thd_is_BF((void *)thd, true)) { WSREP_DEBUG("remove_table_from_cache: %llu", (unsigned long long) thd->real_id); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 45581e6a9c3..52de2659a9f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -7254,7 +7254,7 @@ uint kill_one_thread(THD *thd, ulong id, killed_state kill_signal) #ifdef WITH_WSREP if (((thd->security_ctx->master_access & SUPER_ACL) || thd->security_ctx->user_matches(tmp->security_ctx)) && - !wsrep_thd_is_brute_force((void *)tmp)) + !wsrep_thd_is_BF((void *)tmp, true)) #else if ((thd->security_ctx->master_access & SUPER_ACL) || thd->security_ctx->user_matches(tmp->security_ctx)) diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 9b204172f3e..708409a40f9 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -642,7 +642,7 @@ void wsrep_init_startup (bool first) { if (wsrep_init()) unireg_abort(1); - wsrep_thr_lock_init(wsrep_thd_is_brute_force, wsrep_abort_thd, + wsrep_thr_lock_init(wsrep_thd_is_BF, wsrep_abort_thd, wsrep_debug, wsrep_convert_LOCK_to_trx, wsrep_on); /* Skip replication start if no cluster address */ diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc index d9c30e501e6..3fed6db6d0d 100644 --- a/sql/wsrep_thd.cc +++ b/sql/wsrep_thd.cc @@ -406,27 +406,51 @@ void wsrep_create_rollbacker() } extern "C" -int wsrep_thd_is_brute_force(void *thd_ptr) +my_bool wsrep_thd_is_BF(void *thd_ptr, my_bool sync) +{ + my_bool status = FALSE; + if (thd_ptr) + { + THD* thd = (THD*)thd_ptr; + if (sync) mysql_mutex_lock(&thd->LOCK_wsrep_thd); + + status = ((thd->wsrep_exec_mode == REPL_RECV) || + (thd->wsrep_exec_mode == TOTAL_ORDER)); + if (sync) mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + } + return status; +} + +extern "C" +my_bool wsrep_thd_is_BF_or_commit(void *thd_ptr, my_bool sync) { - /* - Brute force: - Appliers and replaying are running in REPL_RECV mode. TOI statements - in TOTAL_ORDER mode. Locally committing transaction that has got - past wsrep->pre_commit() without error is running in LOCAL_COMMIT mode. - - Everything else is running in LOCAL_STATE and should not be considered - brute force. - */ - if (thd_ptr) { - switch (((THD *)thd_ptr)->wsrep_exec_mode) { - case LOCAL_STATE: return 0; - case REPL_RECV: return 1; - case TOTAL_ORDER: return 2; - case LOCAL_COMMIT: return 3; - } + bool status = FALSE; + if (thd_ptr) + { + THD* thd = (THD*)thd_ptr; + if (sync) mysql_mutex_lock(&thd->LOCK_wsrep_thd); + + status = ((thd->wsrep_exec_mode == REPL_RECV) || + (thd->wsrep_exec_mode == TOTAL_ORDER) || + (thd->wsrep_exec_mode == LOCAL_COMMIT)); + if (sync) mysql_mutex_unlock(&thd->LOCK_wsrep_thd); } - DBUG_ASSERT(0); - return 0; + return status; +} + +extern "C" +my_bool wsrep_thd_is_local(void *thd_ptr, my_bool sync) +{ + bool status = FALSE; + if (thd_ptr) + { + THD* thd = (THD*)thd_ptr; + if (sync) mysql_mutex_lock(&thd->LOCK_wsrep_thd); + + status = (thd->wsrep_exec_mode == LOCAL_STATE); + if (sync) mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + } + return status; } extern "C" diff --git a/sql/wsrep_thd.h b/sql/wsrep_thd.h index bded13b5684..74e3bff120c 100644 --- a/sql/wsrep_thd.h +++ b/sql/wsrep_thd.h @@ -24,7 +24,9 @@ void wsrep_replay_transaction(THD *thd); void wsrep_create_appliers(long threads); void wsrep_create_rollbacker(); -extern "C" int wsrep_thd_is_brute_force(void *thd_ptr); +extern "C" my_bool wsrep_thd_is_BF(void *thd_ptr, my_bool sync); +extern "C" my_bool wsrep_thd_is_BF_or_commit(void *thd_ptr, my_bool sync); +extern "C" my_bool wsrep_thd_is_local(void *thd_ptr, my_bool sync); extern "C" int wsrep_abort_thd(void *bf_thd_ptr, void *victim_thd_ptr, my_bool signal); extern "C" int wsrep_thd_in_locking_session(void *thd_ptr); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 0cf6f10c143..f4b437e7668 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -12566,8 +12566,7 @@ wsrep_abort_slave_trx(wsrep_seqno_t bf_seqno, wsrep_seqno_t victim_seqno) (long long)bf_seqno, (long long)victim_seqno); abort(); } -/*******************************************************************//** -This function is used to kill one transaction in BF. */ + int wsrep_innobase_kill_one_trx( void *bf_thd_ptr, /*!< in: BF thd */ diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h index 4ed11d8e410..7b6774fd53b 100644 --- a/storage/innobase/include/ha_prototypes.h +++ b/storage/innobase/include/ha_prototypes.h @@ -288,7 +288,8 @@ thd_set_lock_wait_time( #ifdef WITH_WSREP UNIV_INTERN int wsrep_innobase_kill_one_trx(void *thd, trx_t *bf_trx, trx_t *victim_trx, ibool signal, ibool have_kernel_mutex); -int wsrep_thd_is_brute_force(void *thd_ptr); +my_bool wsrep_thd_is_BF(void *thd_ptr, my_bool sync); +//int64_t wsrep_thd_trx_seqno(THD *thd); int wsrep_trx_order_before(void *thd1, void *thd2); void wsrep_innobase_mysql_sort(int mysql_type, uint charset_number, unsigned char* str, unsigned int str_length); diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h index e2033470c3c..237e43b7882 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -799,7 +799,6 @@ lock_rec_get_page_no( record */ #define LOCK_CONV_BY_OTHER 4096 /*!< this bit is set when the lock is created by other transaction */ -#define WSREP_BF 8192 #if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION|LOCK_CONV_BY_OTHER)&LOCK_TYPE_MASK # error #endif diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c index 71b3097d012..98cb239befc 100644 --- a/storage/innobase/lock/lock0lock.c +++ b/storage/innobase/lock/lock0lock.c @@ -932,11 +932,6 @@ lock_rec_has_to_wait( if (trx != lock2->trx && !lock_mode_compatible(LOCK_MODE_MASK & type_mode, lock_get_mode(lock2))) { -#ifdef WITH_WSREP - if ((type_mode & WSREP_BF) && (lock2->type_mode & WSREP_BF)) { - return FALSE; - } -#endif /* WITH_WSREP */ /* We have somewhat complex rules when gap type record locks cause waits */ @@ -1565,9 +1560,8 @@ lock_rec_other_has_expl_req( #ifdef WITH_WSREP static void wsrep_kill_victim(trx_t *trx, lock_t *lock) { - int bf_this = wsrep_thd_is_brute_force(trx->mysql_thd); - int bf_other = - wsrep_thd_is_brute_force(lock->trx->mysql_thd); + my_bool bf_this = wsrep_thd_is_BF(trx->mysql_thd, FALSE); + my_bool bf_other = wsrep_thd_is_BF(lock->trx->mysql_thd, TRUE); if ((bf_this && !bf_other) || (bf_this && bf_other && wsrep_trx_order_before( trx->mysql_thd, lock->trx->mysql_thd))) { @@ -1842,11 +1836,6 @@ lock_rec_create( lock->trx = trx; lock->type_mode = (type_mode & ~LOCK_TYPE_MASK) | LOCK_REC; -#ifdef WITH_WSREP - if (wsrep_thd_is_brute_force(trx->mysql_thd)) { - lock->type_mode |= WSREP_BF; - } -#endif /* WITH_WSREP */ lock->index = index; lock->un_member.rec_lock.space = space; @@ -1862,13 +1851,15 @@ lock_rec_create( lock_rec_set_nth_bit(lock, heap_no); #ifdef WITH_WSREP - if (c_lock && wsrep_thd_is_brute_force(trx->mysql_thd)) { + if (c_lock && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { lock_t *hash = c_lock->hash; lock_t *prev = NULL; while (hash && - wsrep_thd_is_brute_force(hash->trx->mysql_thd) && - wsrep_trx_order_before(hash->trx->mysql_thd, trx->mysql_thd)){ + wsrep_thd_is_BF(hash->trx->mysql_thd, TRUE) && + wsrep_trx_order_before( + hash->trx->mysql_thd, trx->mysql_thd)) + { prev = hash; hash = hash->hash; } @@ -2208,11 +2199,6 @@ lock_rec_lock_fast( || (LOCK_MODE_MASK & mode) == LOCK_X); ut_ad(mode - (LOCK_MODE_MASK & mode) == LOCK_GAP || mode - (LOCK_MODE_MASK & mode) == 0 -#ifdef WITH_WSREP - || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == 0 - || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == LOCK_GAP - || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == LOCK_REC_NOT_GAP -#endif /* WITH_WSREP */ || mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP); DBUG_EXECUTE_IF("innodb_report_deadlock", return(LOCK_REC_FAIL);); @@ -2297,11 +2283,6 @@ lock_rec_lock_slow( || (LOCK_MODE_MASK & mode) == LOCK_X); ut_ad(mode - (LOCK_MODE_MASK & mode) == LOCK_GAP || mode - (LOCK_MODE_MASK & mode) == 0 -#ifdef WITH_WSREP - || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == 0 - || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == LOCK_GAP - || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == LOCK_REC_NOT_GAP -#endif /* WITH_WSREP */ || mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP); trx = thr_get_trx(thr); @@ -2400,17 +2381,7 @@ lock_rec_lock( || (LOCK_MODE_MASK & mode) == LOCK_X); ut_ad(mode - (LOCK_MODE_MASK & mode) == LOCK_GAP || mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP -#ifdef WITH_WSREP - || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == 0 - || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == LOCK_GAP - || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == LOCK_REC_NOT_GAP -#endif /* WITH_WSREP */ || mode - (LOCK_MODE_MASK & mode) == 0); -#ifdef WITH_WSREP - if (wsrep_thd_is_brute_force(thr_get_trx(thr)->mysql_thd)) { - mode |= WSREP_BF; - } -#endif /* We try a simplified and faster subroutine for the most common cases */ switch (lock_rec_lock_fast(impl, mode, block, heap_no, index, thr)) { @@ -3845,11 +3816,11 @@ lock_deadlock_recursive( #ifdef WITH_WSREP if (wsrep_debug) fputs("WSREP: Deadlock detected\n", stderr); - if (wsrep_thd_is_brute_force(start->mysql_thd) && - wsrep_thd_is_brute_force( - wait_lock->trx->mysql_thd) && - (start != wait_lock->trx)) { - + if ((start != wait_lock->trx) && + wsrep_thd_is_BF(start->mysql_thd, TRUE) && + wsrep_thd_is_BF( + wait_lock->trx->mysql_thd, TRUE)) + { if (wsrep_trx_order_before( start->mysql_thd, wait_lock->trx->mysql_thd)) { @@ -3870,8 +3841,9 @@ lock_deadlock_recursive( back it */ #ifdef WITH_WSREP - if (!wsrep_thd_is_brute_force( - start->mysql_thd)) { + if (!wsrep_thd_is_BF( + start->mysql_thd, FALSE)) + { return(LOCK_VICTIM_IS_START); } #else @@ -3879,8 +3851,9 @@ lock_deadlock_recursive( #endif } #ifdef WITH_WSREP - if (wsrep_thd_is_brute_force( - wait_lock->trx->mysql_thd)) { + if (wsrep_thd_is_BF( + wait_lock->trx->mysql_thd, TRUE)) + { return(LOCK_VICTIM_IS_START); } #endif @@ -4008,7 +3981,7 @@ lock_table_create( lock->un_member.tab_lock.table = table; #ifdef WITH_WSREP - if (c_lock && wsrep_thd_is_brute_force(trx->mysql_thd)) { + if (c_lock && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { UT_LIST_INSERT_AFTER( un_member.tab_lock.locks, table->locks, c_lock, lock); } else { @@ -5641,7 +5614,7 @@ lock_rec_insert_check_and_lock( #ifdef WITH_WSREP if ((c_lock = lock_rec_other_has_conflicting( - LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION | WSREP_BF, + LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION, block, next_rec_heap_no, trx))) { #else if (lock_rec_other_has_conflicting( @@ -5745,7 +5718,7 @@ lock_rec_convert_impl_to_expl( if (rec_get_deleted_flag(rec, rec_offs_comp(offsets)) #ifdef WITH_WSREP - && !wsrep_thd_is_brute_force(impl_trx->mysql_thd) + && !wsrep_thd_is_BF(impl_trx->mysql_thd, FALSE) /* BF-BF conflict is possible if advancing into lock_rec_other_has_conflicting*/ #endif /* WITH_WSREP */ diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c index 758a1ed5189..67cc68738a9 100644 --- a/storage/innobase/row/row0ins.c +++ b/storage/innobase/row/row0ins.c @@ -1682,9 +1682,6 @@ row_ins_scan_sec_index_for_duplicate( dtuple_t* entry, /*!< in: index entry */ que_thr_t* thr) /*!< in: query thread */ { -#ifdef WITH_WSREP - trx_t* trx = thr_get_trx(thr); -#endif ulint n_unique; ulint i; int cmp; @@ -1748,15 +1745,8 @@ row_ins_scan_sec_index_for_duplicate( } else { lock_type = LOCK_ORDINARY; } -#ifdef WITH_WSREP - /* slave applier must not get duplicate error */ - if (allow_duplicates || - (wsrep_on(trx->mysql_thd) && - wsrep_thd_is_brute_force(trx->mysql_thd))) { -#else if (allow_duplicates) { -#endif /* If the SQL-query will update or replace duplicate key we will take X-lock for @@ -1872,13 +1862,7 @@ row_ins_duplicate_error_in_clust( sure that in roll-forward we get the same duplicate errors as in original execution */ -#ifdef WITH_WSREP - if (trx->duplicates || - (wsrep_on(trx->mysql_thd) && - wsrep_thd_is_brute_force(trx->mysql_thd))) { -#else if (trx->duplicates) { -#endif /* If the SQL-query will update or replace duplicate key we will take X-lock for @@ -1922,13 +1906,7 @@ row_ins_duplicate_error_in_clust( offsets = rec_get_offsets(rec, cursor->index, offsets, ULINT_UNDEFINED, &heap); -#ifdef WITH_WSREP - if (trx->duplicates || - (wsrep_on(trx->mysql_thd) && - wsrep_thd_is_brute_force(trx->mysql_thd))) { -#else if (trx->duplicates) { -#endif /* If the SQL-query will update or replace duplicate key we will take X-lock for diff --git a/storage/innobase/row/row0upd.c b/storage/innobase/row/row0upd.c index 186be33d2bd..bcb5837198b 100644 --- a/storage/innobase/row/row0upd.c +++ b/storage/innobase/row/row0upd.c @@ -370,6 +370,12 @@ wsrep_row_upd_check_foreign_constraints( } trx = thr_get_trx(thr); + if (wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { + + return(DB_SUCCESS); + } + + /* TODO: make native slave thread bail out here */ rec = btr_pcur_get_rec(pcur); ut_ad(rec_offs_validate(rec, index, offsets)); diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index c231e697c3d..ff69ed4a386 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -1214,7 +1214,7 @@ srv_conc_enter_innodb( #ifdef WITH_WSREP if (wsrep_on(trx->mysql_thd) && - wsrep_thd_is_brute_force(trx->mysql_thd)) { + wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { srv_conc_force_enter_innodb(trx); return; } @@ -1844,7 +1844,7 @@ srv_suspend_mysql_thread( #ifdef WITH_WSREP if (wsrep_on(trx->mysql_thd) && - wsrep_thd_is_brute_force(trx->mysql_thd)) { + wsrep_thd_is_BF(trx->mysql_thd, TRUE)) { fprintf(stderr, "WSREP: BF long lock wait ended after %.f sec\n", wait_time); @@ -2421,7 +2421,7 @@ wsrep_is_BF_lock_timeout( srv_slot_t* slot) /* in: lock slot to check for lock priority */ { if (wsrep_on(thr_get_trx(slot->thr)->mysql_thd) && - wsrep_thd_is_brute_force((thr_get_trx(slot->thr))->mysql_thd)) { + wsrep_thd_is_BF((thr_get_trx(slot->thr))->mysql_thd, TRUE)) { fprintf(stderr, "WSREP: BF lock wait long\n"); srv_print_innodb_monitor = TRUE; srv_print_innodb_lock_monitor = TRUE; diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 322a5b722e6..696a426cdd2 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -4172,6 +4172,9 @@ ha_innobase::max_supported_key_length() const is 16 kB; but currently MySQL does not work with keys whose size is > MAX_KEY_LENGTH */ #ifdef WITH_WSREP + /* this may look like obsolete code, but this ifdef is here + just to make sure we will see bzr merge conflict, if Oracle + changes max key length */ return(3500); #else return(3500); @@ -5335,7 +5338,7 @@ wsrep_innobase_mysql_sort( tmp_length = charset->coll->strnxfrm(charset, str, str_length, tmp_str, str_length); - DBUG_ASSERT(tmp_length == str_length); + DBUG_ASSERT(tmp_length <= str_length); break; } @@ -8486,6 +8489,13 @@ ha_innobase::wsrep_append_keys( } else { ut_a(table->s->keys <= 256); uint i; + bool hasPK= false; + + for (i=0; i<table->s->keys && !hasPK; ++i) { + KEY* key_info = table->key_info + i; + if (key_info->flags & HA_NOSAME) hasPK = true; + } + for (i=0; i<table->s->keys; ++i) { uint len; char keyval0[WSREP_MAX_SUPPORTED_KEY_LENGTH+1] = {'\0'}; @@ -8506,7 +8516,7 @@ ha_innobase::wsrep_append_keys( table->s->table_name.str, key_info->name); } - if (key_info->flags & HA_NOSAME || + if (!hasPK || key_info->flags & HA_NOSAME || ((tab && dict_table_get_referenced_constraint(tab, idx)) || (!tab && referenced_by_foreign_key()))) { @@ -13891,8 +13901,7 @@ wsrep_abort_slave_trx(wsrep_seqno_t bf_seqno, wsrep_seqno_t victim_seqno) (long long)bf_seqno, (long long)victim_seqno); abort(); } -/*******************************************************************//** -This function is used to kill one transaction in BF. */ + int wsrep_innobase_kill_one_trx( void *bf_thd_ptr, /*!< in: BF thd */ diff --git a/storage/xtradb/include/ha_prototypes.h b/storage/xtradb/include/ha_prototypes.h index 7d98401a093..cff6478570f 100644 --- a/storage/xtradb/include/ha_prototypes.h +++ b/storage/xtradb/include/ha_prototypes.h @@ -303,7 +303,8 @@ thd_flush_log_at_trx_commit( #ifdef WITH_WSREP UNIV_INTERN int wsrep_innobase_kill_one_trx(void *thd, trx_t *bf_trx, trx_t *victim_trx, ibool signal, ibool have_kernel_mutex); -int wsrep_thd_is_brute_force(void *thd_ptr); +my_bool wsrep_thd_is_BF(void *thd_ptr, my_bool sync); +//int64_t wsrep_thd_trx_seqno(THD *thd); int wsrep_trx_order_before(void *thd1, void *thd2); void wsrep_innobase_mysql_sort(int mysql_type, uint charset_number, unsigned char* str, unsigned int str_length); diff --git a/storage/xtradb/include/lock0lock.h b/storage/xtradb/include/lock0lock.h index 7a0b000bcfe..0d6d45c5ad4 100644 --- a/storage/xtradb/include/lock0lock.h +++ b/storage/xtradb/include/lock0lock.h @@ -800,7 +800,6 @@ lock_rec_get_page_no( record */ #define LOCK_CONV_BY_OTHER 4096 /*!< this bit is set when the lock is created by other transaction */ -#define WSREP_BF 8192 #if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION|LOCK_CONV_BY_OTHER)&LOCK_TYPE_MASK # error #endif diff --git a/storage/xtradb/lock/lock0lock.c b/storage/xtradb/lock/lock0lock.c index 12694687180..35196559595 100644 --- a/storage/xtradb/lock/lock0lock.c +++ b/storage/xtradb/lock/lock0lock.c @@ -910,6 +910,9 @@ UNIV_INLINE ibool lock_rec_has_to_wait( /*=================*/ +#ifdef WITH_WSREP + ibool for_locking, /*!< is caller locking or releasing */ +#endif /* WITH_WSREP */ const trx_t* trx, /*!< in: trx of new lock */ ulint type_mode,/*!< in: precise mode of the new lock to set: LOCK_S or LOCK_X, possibly @@ -930,11 +933,6 @@ lock_rec_has_to_wait( if (trx != lock2->trx && !lock_mode_compatible(LOCK_MODE_MASK & type_mode, lock_get_mode(lock2))) { -#ifdef WITH_WSREP - if ((type_mode & WSREP_BF) && (lock2->type_mode & WSREP_BF)) { - return FALSE; - } -#endif /* WITH_WSREP */ /* We have somewhat complex rules when gap type record locks cause waits */ @@ -984,6 +982,44 @@ lock_rec_has_to_wait( return(FALSE); } +#ifdef WITH_WSREP + /* if BF thread is locking and has conflict with another BF + thread, we need to look at trx ordering and lock types */ + if (for_locking && + wsrep_thd_is_BF(trx->mysql_thd, FALSE) && + wsrep_thd_is_BF(lock2->trx->mysql_thd, TRUE)) { + + if (wsrep_debug) { + fprintf(stderr, "\n BF-BF lock conflict \n"); + lock_rec_print(stderr, lock2); + } + + if (wsrep_trx_order_before(trx->mysql_thd, + lock2->trx->mysql_thd) && + (type_mode & LOCK_MODE_MASK) == LOCK_X && + (lock2->type_mode & LOCK_MODE_MASK) == LOCK_X) + { + /* exclusive lock conflicts are not accepted */ + fprintf(stderr, "BF-BF X lock conflict\n"); + lock_rec_print(stderr, lock2); + abort(); + } else { + /* if lock2->index->n_uniq <= + lock2->index->n_user_defined_cols + operation is on uniq index + */ + if (wsrep_debug) fprintf(stderr, + "BF conflict, modes: %lu %lu, " + "idx: %s-%s n_uniq %u n_user %u\n", + type_mode, lock2->type_mode, + lock2->index->name, + lock2->index->table_name, + lock2->index->n_uniq, + lock2->index->n_user_defined_cols); + return FALSE; + } + } +#endif /* WITH_WSREP */ return(TRUE); } @@ -1014,7 +1050,11 @@ lock_has_to_wait( /* If this lock request is for a supremum record then the second bit on the lock bitmap is set */ +#ifdef WITH_WSREP + return(lock_rec_has_to_wait(FALSE, lock1->trx, +#else return(lock_rec_has_to_wait(lock1->trx, +#endif /* WITH_WSREP */ lock1->type_mode, lock2, lock_rec_get_nth_bit( lock1, 1))); @@ -1521,9 +1561,8 @@ lock_rec_other_has_expl_req( #ifdef WITH_WSREP static void wsrep_kill_victim(trx_t *trx, lock_t *lock) { - int bf_this = wsrep_thd_is_brute_force(trx->mysql_thd); - int bf_other = - wsrep_thd_is_brute_force(lock->trx->mysql_thd); + my_bool bf_this = wsrep_thd_is_BF(trx->mysql_thd, FALSE); + my_bool bf_other = wsrep_thd_is_BF(lock->trx->mysql_thd, TRUE); if ((bf_this && !bf_other) || (bf_this && bf_other && wsrep_trx_order_before( trx->mysql_thd, lock->trx->mysql_thd))) { @@ -1593,7 +1632,11 @@ lock_rec_other_has_conflicting( if (UNIV_UNLIKELY(heap_no == PAGE_HEAP_NO_SUPREMUM)) { do { - if (lock_rec_has_to_wait(trx, mode, lock, +#ifdef WITH_WSREP + if (lock_rec_has_to_wait(TRUE, trx, mode, lock, +#else + if (lock_rec_has_to_wait(trx, mode, lock, +#endif /* WITH_WSREP */ TRUE)) { #ifdef WITH_WSREP wsrep_kill_victim(trx, lock); @@ -1606,7 +1649,11 @@ lock_rec_other_has_conflicting( } else { do { - if (lock_rec_has_to_wait(trx, mode, lock, +#ifdef WITH_WSREP + if (lock_rec_has_to_wait(TRUE, trx, mode, lock, +#else + if (lock_rec_has_to_wait(trx, mode, lock, +#endif /* WITH_WSREP */ FALSE)) { #ifdef WITH_WSREP wsrep_kill_victim(trx, lock); @@ -1790,11 +1837,6 @@ lock_rec_create( lock->trx = trx; lock->type_mode = (type_mode & ~LOCK_TYPE_MASK) | LOCK_REC; -#ifdef WITH_WSREP - if (wsrep_thd_is_brute_force(trx->mysql_thd)) { - lock->type_mode |= WSREP_BF; - } -#endif /* WITH_WSREP */ lock->index = index; lock->un_member.rec_lock.space = space; @@ -1810,13 +1852,15 @@ lock_rec_create( lock_rec_set_nth_bit(lock, heap_no); #ifdef WITH_WSREP - if (c_lock && wsrep_thd_is_brute_force(trx->mysql_thd)) { + if (c_lock && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { lock_t *hash = c_lock->hash; lock_t *prev = NULL; while (hash && - wsrep_thd_is_brute_force(hash->trx->mysql_thd) && - wsrep_trx_order_before(hash->trx->mysql_thd, trx->mysql_thd)){ + wsrep_thd_is_BF(hash->trx->mysql_thd, TRUE) && + wsrep_trx_order_before( + hash->trx->mysql_thd, trx->mysql_thd)) + { prev = hash; hash = hash->hash; } @@ -2162,11 +2206,6 @@ lock_rec_lock_fast( || (LOCK_MODE_MASK & mode) == LOCK_X); ut_ad(mode - (LOCK_MODE_MASK & mode) == LOCK_GAP || mode - (LOCK_MODE_MASK & mode) == 0 -#ifdef WITH_WSREP - || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == 0 - || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == LOCK_GAP - || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == LOCK_REC_NOT_GAP -#endif /* WITH_WSREP */ || mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP); DBUG_EXECUTE_IF("innodb_report_deadlock", return(LOCK_REC_FAIL);); @@ -2251,11 +2290,6 @@ lock_rec_lock_slow( || (LOCK_MODE_MASK & mode) == LOCK_X); ut_ad(mode - (LOCK_MODE_MASK & mode) == LOCK_GAP || mode - (LOCK_MODE_MASK & mode) == 0 -#ifdef WITH_WSREP - || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == 0 - || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == LOCK_GAP - || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == LOCK_REC_NOT_GAP -#endif /* WITH_WSREP */ || mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP); trx = thr_get_trx(thr); @@ -2354,17 +2388,7 @@ lock_rec_lock( || (LOCK_MODE_MASK & mode) == LOCK_X); ut_ad(mode - (LOCK_MODE_MASK & mode) == LOCK_GAP || mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP -#ifdef WITH_WSREP - || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == 0 - || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == LOCK_GAP - || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == LOCK_REC_NOT_GAP -#endif /* WITH_WSREP */ || mode - (LOCK_MODE_MASK & mode) == 0); -#ifdef WITH_WSREP - if (wsrep_thd_is_brute_force(thr_get_trx(thr)->mysql_thd)) { - mode |= WSREP_BF; - } -#endif /* We try a simplified and faster subroutine for the most common cases */ switch (lock_rec_lock_fast(impl, mode, block, heap_no, index, thr)) { @@ -3802,11 +3826,11 @@ lock_deadlock_recursive( #ifdef WITH_WSREP if (wsrep_debug) fputs("WSREP: Deadlock detected\n", stderr); - if (wsrep_thd_is_brute_force(start->mysql_thd) && - wsrep_thd_is_brute_force( - wait_lock->trx->mysql_thd) && - (start != wait_lock->trx)) { - + if ((start != wait_lock->trx) && + wsrep_thd_is_BF(start->mysql_thd, TRUE) && + wsrep_thd_is_BF( + wait_lock->trx->mysql_thd, TRUE)) + { if (wsrep_trx_order_before( start->mysql_thd, wait_lock->trx->mysql_thd)) { @@ -3827,8 +3851,9 @@ lock_deadlock_recursive( back it */ #ifdef WITH_WSREP - if (!wsrep_thd_is_brute_force( - start->mysql_thd)) { + if (!wsrep_thd_is_BF( + start->mysql_thd, FALSE)) + { return(LOCK_VICTIM_IS_START); } #else @@ -3836,8 +3861,9 @@ lock_deadlock_recursive( #endif } #ifdef WITH_WSREP - if (wsrep_thd_is_brute_force( - wait_lock->trx->mysql_thd)) { + if (wsrep_thd_is_BF( + wait_lock->trx->mysql_thd, TRUE)) + { return(LOCK_VICTIM_IS_START); } #endif @@ -3965,7 +3991,7 @@ lock_table_create( lock->un_member.tab_lock.table = table; #ifdef WITH_WSREP - if (c_lock && wsrep_thd_is_brute_force(trx->mysql_thd)) { + if (c_lock && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { UT_LIST_INSERT_AFTER( un_member.tab_lock.locks, table->locks, c_lock, lock); } else { @@ -5619,7 +5645,7 @@ lock_rec_insert_check_and_lock( #ifdef WITH_WSREP if ((c_lock = lock_rec_other_has_conflicting( - LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION | WSREP_BF, + LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION, block, next_rec_heap_no, trx))) { #else if (lock_rec_other_has_conflicting( @@ -5723,7 +5749,7 @@ lock_rec_convert_impl_to_expl( if (rec_get_deleted_flag(rec, rec_offs_comp(offsets)) #ifdef WITH_WSREP - && !wsrep_thd_is_brute_force(impl_trx->mysql_thd) + && !wsrep_thd_is_BF(impl_trx->mysql_thd, FALSE) /* BF-BF conflict is possible if advancing into lock_rec_other_has_conflicting*/ #endif /* WITH_WSREP */ diff --git a/storage/xtradb/row/row0ins.c b/storage/xtradb/row/row0ins.c index dcc4447e8e0..077730ab1ce 100644 --- a/storage/xtradb/row/row0ins.c +++ b/storage/xtradb/row/row0ins.c @@ -1694,9 +1694,6 @@ row_ins_scan_sec_index_for_duplicate( dtuple_t* entry, /*!< in: index entry */ que_thr_t* thr) /*!< in: query thread */ { -#ifdef WITH_WSREP - trx_t* trx = thr_get_trx(thr); -#endif ulint n_unique; ulint i; int cmp; @@ -1760,14 +1757,8 @@ row_ins_scan_sec_index_for_duplicate( } else { lock_type = LOCK_ORDINARY; } -#ifdef WITH_WSREP - /* slave applier must not get duplicate error */ - if (allow_duplicates || - (wsrep_on(trx->mysql_thd) && - wsrep_thd_is_brute_force(trx->mysql_thd))) { -#else + if (allow_duplicates) { -#endif /* If the SQL-query will update or replace duplicate key we will take X-lock for @@ -1883,13 +1874,7 @@ row_ins_duplicate_error_in_clust( sure that in roll-forward we get the same duplicate errors as in original execution */ -#ifdef WITH_WSREP - if (trx->duplicates || - (wsrep_on(trx->mysql_thd) && - wsrep_thd_is_brute_force(trx->mysql_thd))) { -#else if (trx->duplicates) { -#endif /* If the SQL-query will update or replace duplicate key we will take X-lock for @@ -1933,13 +1918,7 @@ row_ins_duplicate_error_in_clust( offsets = rec_get_offsets(rec, cursor->index, offsets, ULINT_UNDEFINED, &heap); -#ifdef WITH_WSREP - if (trx->duplicates || - (wsrep_on(trx->mysql_thd) && - wsrep_thd_is_brute_force(trx->mysql_thd))) { -#else if (trx->duplicates) { -#endif /* If the SQL-query will update or replace duplicate key we will take X-lock for diff --git a/storage/xtradb/row/row0upd.c b/storage/xtradb/row/row0upd.c index 36215c1fd46..e145b604a33 100644 --- a/storage/xtradb/row/row0upd.c +++ b/storage/xtradb/row/row0upd.c @@ -370,6 +370,12 @@ wsrep_row_upd_check_foreign_constraints( } trx = thr_get_trx(thr); + if (wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { + + return(DB_SUCCESS); + } + + /* TODO: make native slave thread bail out here */ rec = btr_pcur_get_rec(pcur); ut_ad(rec_offs_validate(rec, index, offsets)); diff --git a/storage/xtradb/srv/srv0srv.c b/storage/xtradb/srv/srv0srv.c index a402b182391..de0da290225 100644 --- a/storage/xtradb/srv/srv0srv.c +++ b/storage/xtradb/srv/srv0srv.c @@ -1401,7 +1401,7 @@ srv_conc_enter_innodb( #ifdef WITH_WSREP if (wsrep_on(trx->mysql_thd) && - wsrep_thd_is_brute_force(trx->mysql_thd)) { + wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { srv_conc_force_enter_innodb(trx); return; } @@ -2070,7 +2070,7 @@ srv_suspend_mysql_thread( #ifdef WITH_WSREP if (wsrep_on(trx->mysql_thd) && - wsrep_thd_is_brute_force(trx->mysql_thd)) { + wsrep_thd_is_BF(trx->mysql_thd, TRUE)) { fprintf(stderr, "WSREP: BF long lock wait ended after %.f sec\n", wait_time); @@ -2891,7 +2891,7 @@ wsrep_is_BF_lock_timeout( srv_slot_t* slot) /* in: lock slot to check for lock priority */ { if (wsrep_on(thr_get_trx(slot->thr)->mysql_thd) && - wsrep_thd_is_brute_force((thr_get_trx(slot->thr))->mysql_thd)) { + wsrep_thd_is_BF((thr_get_trx(slot->thr))->mysql_thd, TRUE)) { fprintf(stderr, "WSREP: BF lock wait long\n"); srv_print_innodb_monitor = TRUE; srv_print_innodb_lock_monitor = TRUE; |