diff options
author | Nirbhay Choubey <nirbhay@skysql.com> | 2014-03-27 16:26:00 -0400 |
---|---|---|
committer | Nirbhay Choubey <nirbhay@skysql.com> | 2014-03-27 16:26:00 -0400 |
commit | 02ba2bfdb444531e6fe61716a4eaeab40e210bbd (patch) | |
tree | 0b67ad5b8f6e8a901ed2b6cac8d4692d8db8f112 /storage | |
parent | 09e3094945694277a550cccc8bd1fd11338474b1 (diff) | |
parent | c5f7486654d7fd4941b202735799f9a7ec3c15eb (diff) | |
download | mariadb-git-02ba2bfdb444531e6fe61716a4eaeab40e210bbd.tar.gz |
Merging revision from codership-mysql/5.5 (r3928..3968) and
codership-mysql/5.6 (r4021..4065).
- Also contains fixes for some build failures.
Diffstat (limited to 'storage')
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 53 | ||||
-rw-r--r-- | storage/innobase/include/ha_prototypes.h | 2 | ||||
-rw-r--r-- | storage/innobase/include/lock0lock.h | 1 | ||||
-rw-r--r-- | storage/innobase/lock/lock0lock.cc | 143 | ||||
-rw-r--r-- | storage/innobase/lock/lock0wait.cc | 35 | ||||
-rw-r--r-- | storage/innobase/row/row0ins.cc | 27 | ||||
-rw-r--r-- | storage/innobase/row/row0upd.cc | 2 | ||||
-rw-r--r-- | storage/innobase/srv/srv0srv.cc | 21 | ||||
-rw-r--r-- | storage/innobase/trx/trx0sys.cc | 5 | ||||
-rw-r--r-- | storage/xtradb/handler/ha_innodb.cc | 53 | ||||
-rw-r--r-- | storage/xtradb/include/ha_prototypes.h | 2 | ||||
-rw-r--r-- | storage/xtradb/include/lock0lock.h | 1 | ||||
-rw-r--r-- | storage/xtradb/lock/lock0lock.cc | 144 | ||||
-rw-r--r-- | storage/xtradb/lock/lock0wait.cc | 35 | ||||
-rw-r--r-- | storage/xtradb/row/row0ins.cc | 28 | ||||
-rw-r--r-- | storage/xtradb/row/row0upd.cc | 2 | ||||
-rw-r--r-- | storage/xtradb/srv/srv0srv.cc | 21 | ||||
-rw-r--r-- | storage/xtradb/trx/trx0sys.cc | 5 |
18 files changed, 269 insertions, 311 deletions
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 6cb664dcb05..82da55d069a 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -1207,8 +1207,8 @@ innobase_srv_conc_enter_innodb( trx_t* trx) /*!< in: transaction handle */ { #ifdef WITH_WSREP - if (wsrep_on(trx->mysql_thd) && - wsrep_thd_is_brute_force(trx->mysql_thd)) return; + if (wsrep_on(trx->mysql_thd) && + wsrep_thd_is_BF(trx->mysql_thd, FALSE)) return; #endif /* WITH_WSREP */ if (srv_thread_concurrency) { if (trx->n_tickets_to_enter_innodb > 0) { @@ -1245,8 +1245,8 @@ innobase_srv_conc_exit_innodb( ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch)); #endif /* UNIV_SYNC_DEBUG */ #ifdef WITH_WSREP - if (wsrep_on(trx->mysql_thd) && - wsrep_thd_is_brute_force(trx->mysql_thd)) return; + if (wsrep_on(trx->mysql_thd) && + wsrep_thd_is_BF(trx->mysql_thd, FALSE)) return; #endif /* WITH_WSREP */ /* This is to avoid making an unnecessary function call. */ @@ -3534,11 +3534,6 @@ innobase_commit_low( /*================*/ trx_t* trx) /*!< in: transaction handle */ { - if (trx_is_started(trx)) { - - trx_commit_for_mysql(trx); - } - #ifdef WITH_WSREP THD* thd = (THD*)trx->mysql_thd; const char* tmp = 0; @@ -3556,7 +3551,10 @@ innobase_commit_low( #endif /* WSREP_PROC_INFO */ } #endif /* WITH_WSREP */ + if (trx_is_started(trx)) { + trx_commit_for_mysql(trx); + } #ifdef WITH_WSREP if (wsrep_on((void*)thd)) { thd_proc_info(thd, tmp); } #endif /* WITH_WSREP */ @@ -5608,7 +5606,7 @@ wsrep_innobase_mysql_sort( tmp_length = charset->coll->strnxfrm(charset, str, str_length, str_length, tmp_str, tmp_length, 0); /**/ - DBUG_ASSERT(tmp_length == str_length); + DBUG_ASSERT(tmp_length <= str_length); break; } @@ -7294,7 +7292,9 @@ ha_innobase::write_row( || sql_command == SQLCOM_CREATE_INDEX #ifdef WITH_WSREP || (wsrep_on(user_thd) && wsrep_load_data_splitting && - sql_command == SQLCOM_LOAD) + sql_command == SQLCOM_LOAD && + !thd_test_options( + user_thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) #endif /* WITH_WSREP */ || sql_command == SQLCOM_DROP_INDEX) && num_write_row >= 10000) { @@ -7304,7 +7304,6 @@ ha_innobase::write_row( wsrep_thd_query(user_thd)); } #endif /* WITH_WSREP */ - /* ALTER TABLE is COMMITted at every 10000 copied rows. The IX table lock for the original table has to be re-issued. As this method will be called on a temporary table where the @@ -7343,7 +7342,8 @@ no_commit: { case WSREP_TRX_OK: break; - case WSREP_TRX_ROLLBACK: + case WSREP_TRX_SIZE_EXCEEDED: + case WSREP_TRX_CERT_FAIL: case WSREP_TRX_ERROR: DBUG_RETURN(1); } @@ -7367,7 +7367,8 @@ no_commit: { case WSREP_TRX_OK: break; - case WSREP_TRX_ROLLBACK: + case WSREP_TRX_SIZE_EXCEEDED: + case WSREP_TRX_CERT_FAIL: case WSREP_TRX_ERROR: DBUG_RETURN(1); } @@ -7490,9 +7491,10 @@ no_commit: #ifdef WITH_WSREP /* workaround for LP bug #355000, retrying the insert */ case SQLCOM_INSERT: - if (wsrep_on(current_thd) && - auto_inc_inserted && - wsrep_drupal_282555_workaround && + if (wsrep_on(current_thd) && + auto_inc_inserted && + wsrep_drupal_282555_workaround && + wsrep_thd_retry_counter(current_thd) == 0 && !thd_test_options(current_thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { @@ -9620,6 +9622,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'}; @@ -9640,14 +9649,11 @@ 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()))) { - if (key_info->flags & HA_NOSAME || shared) - key_appended = true; - len = wsrep_store_key_val_for_row( table, i, key0, key_info->key_length, record0, &is_null); @@ -9656,6 +9662,10 @@ ha_innobase::wsrep_append_keys( thd, trx, table_share, table, keyval0, len+1, shared); if (rcode) DBUG_RETURN(rcode); + + if (key_info->flags & HA_NOSAME || shared) + key_appended = true; + } else { @@ -16853,6 +16863,7 @@ wsrep_abort_slave_trx(wsrep_seqno_t bf_seqno, wsrep_seqno_t victim_seqno) } /*******************************************************************//** This function is used to kill one transaction in BF. */ + int wsrep_innobase_kill_one_trx(void * const bf_thd_ptr, const trx_t * const bf_trx, diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h index 53c196b6f9e..e2c27acde31 100644 --- a/storage/innobase/include/ha_prototypes.h +++ b/storage/innobase/include/ha_prototypes.h @@ -291,7 +291,7 @@ UNIV_INTERN int wsrep_innobase_kill_one_trx(void *thd_ptr, const trx_t *bf_trx, trx_t *victim_trx, ibool signal); -extern "C" int wsrep_thd_is_brute_force(void *thd_ptr); +my_bool wsrep_thd_is_BF(void *thd_ptr, my_bool sync); 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 f34bfc3656a..6ef6685b371 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -894,7 +894,6 @@ lock_trx_has_rec_x_lock( 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.cc b/storage/innobase/lock/lock0lock.cc index 92cc5ee89a8..ae32738cb17 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -979,47 +979,6 @@ lock_rec_has_to_wait( && !lock_mode_compatible(static_cast<enum lock_mode>( LOCK_MODE_MASK & type_mode), lock_get_mode(lock2))) { -#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_brute_force(trx->mysql_thd) && - wsrep_thd_is_brute_force(lock2->trx->mysql_thd)) { - - 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 (wsrep_debug) { - fprintf(stderr, - "BF conflict, modes: %lu %lu\n", - type_mode, - lock2->type_mode); -#ifdef OUT - fprintf(stderr, - "seqnos %llu %llu\n", - (long long)wsrep_thd_trx_seqno( - trx->mysql_thd), - (long long)wsrep_thd_trx_seqno( - lock2->trx->mysql_thd)); -#endif - } - return FALSE; - } - } -#endif /* WITH_WSREP */ /* We have somewhat complex rules when gap type record locks cause waits */ @@ -1069,6 +1028,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); } @@ -1626,17 +1623,16 @@ lock_rec_other_has_expl_req( #endif /* UNIV_DEBUG */ #ifdef WITH_WSREP -static -void +static void wsrep_kill_victim(const trx_t * const trx, const lock_t *lock) { ut_ad(lock_mutex_own()); ut_ad(trx_mutex_own(lock->trx)); - my_bool bf_this = wsrep_thd_is_brute_force(trx->mysql_thd); - my_bool 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))) { - + if (lock->trx->lock.que_state == TRX_QUE_LOCK_WAIT) { if (wsrep_debug) fprintf(stderr, "WSREP: BF victim waiting\n"); @@ -1930,11 +1926,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; @@ -1954,12 +1945,12 @@ lock_rec_create( ut_ad(index->table->n_ref_count > 0 || !index->table->can_be_evicted); #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 = (lock_t *)c_lock->hash; lock_t *prev = NULL; while (hash && - wsrep_thd_is_brute_force(((lock_t *)hash)->trx->mysql_thd) && + wsrep_thd_is_BF(((lock_t *)hash)->trx->mysql_thd, TRUE) && wsrep_trx_order_before( ((lock_t *)hash)->trx->mysql_thd, trx->mysql_thd)) { @@ -2363,11 +2354,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); ut_ad(dict_index_is_clust(index) || !dict_index_is_online_ddl(index)); @@ -2386,8 +2372,7 @@ lock_rec_lock_fast( #else lock = lock_rec_create( mode, block, heap_no, index, trx, FALSE); -#endif - +#endif /* WITH_WSREP */ } status = LOCK_REC_SUCCESS_CREATED; } else { @@ -2455,11 +2440,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); ut_ad(dict_index_is_clust(index) || !dict_index_is_online_ddl(index)); @@ -2569,19 +2549,8 @@ 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 - ut_ad(dict_index_is_clust(index) || !dict_index_is_online_ddl(index)); /* We try a simplified and faster subroutine for the most @@ -4025,17 +3994,19 @@ lock_deadlock_select_victim( if (trx_weight_ge(ctx->wait_lock->trx, ctx->start)) { /* The joining transaction is 'smaller', choose it as the victim and roll it back. */ + #ifdef WITH_WSREP - if (!wsrep_thd_is_brute_force(ctx->start->mysql_thd)) { - return(ctx->start); - } + if (wsrep_thd_is_BF(ctx->start->mysql_thd, TRUE)) + return(ctx->wait_lock->trx); + else #endif /* WITH_WSREP */ return(ctx->start); } + #ifdef WITH_WSREP - if (wsrep_thd_is_brute_force(ctx->wait_lock->trx->mysql_thd)) + if (wsrep_thd_is_BF(ctx->wait_lock->trx->mysql_thd, TRUE)) return(ctx->start); - else + else #endif /* WITH_WSREP */ return(ctx->wait_lock->trx); } @@ -4167,7 +4138,7 @@ lock_deadlock_search( ctx->too_deep = TRUE; #ifdef WITH_WSREP - if (wsrep_thd_is_brute_force(ctx->start->mysql_thd)) + if (wsrep_thd_is_BF(ctx->start->mysql_thd, TRUE)) return(ctx->wait_lock->trx->id); else #endif /* WITH_WSREP */ @@ -4190,7 +4161,7 @@ lock_deadlock_search( ctx->too_deep = TRUE; #ifdef WITH_WSREP - if (wsrep_thd_is_brute_force(ctx->start->mysql_thd)) + if (wsrep_thd_is_BF(ctx->start->mysql_thd, TRUE)) return(lock->trx->id); else #endif /* WITH_WSREP */ @@ -4313,7 +4284,7 @@ lock_deadlock_check_and_resolve( ut_a(victim_trx_id == trx->id); #ifdef WITH_WSREP - if (!wsrep_thd_is_brute_force(ctx.start->mysql_thd)) + if (!wsrep_thd_is_BF(ctx.start->mysql_thd, TRUE)) { #endif /* WITH_WSREP */ if (!srv_read_only_mode) { @@ -4409,7 +4380,7 @@ lock_table_create( UT_LIST_ADD_LAST(trx_locks, trx->lock.trx_locks, lock); #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 { @@ -6489,7 +6460,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/lock/lock0wait.cc b/storage/innobase/lock/lock0wait.cc index a1c35e20ead..388c847f580 100644 --- a/storage/innobase/lock/lock0wait.cc +++ b/storage/innobase/lock/lock0wait.cc @@ -184,6 +184,28 @@ lock_wait_table_reserve_slot( return(NULL); } +#ifdef WITH_WSREP +/*********************************************************************//** +check if lock timeout was for priority thread, +as a side effect trigger lock monitor +@return false for regular lock timeout */ +static ibool +wsrep_is_BF_lock_timeout( +/*====================*/ + trx_t* trx) /* in: trx to check for lock priority */ +{ + if (wsrep_on(trx->mysql_thd) && + wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { + fprintf(stderr, "WSREP: BF lock wait long\n"); + srv_print_innodb_monitor = TRUE; + srv_print_innodb_lock_monitor = TRUE; + os_event_set(srv_monitor_event); + return TRUE; + } + return FALSE; + } +#endif /* WITH_WSREP */ + /***************************************************************//** Puts a user OS thread to wait for a lock to be released. If an error occurs during the wait trx->error_state associated with thr is @@ -375,9 +397,15 @@ lock_wait_suspend_thread( if (lock_wait_timeout < 100000000 && wait_time > (double) lock_wait_timeout) { +#ifdef WITH_WSREP + if (!wsrep_is_BF_lock_timeout(trx)) { +#endif /* WITH_WSREP */ trx->error_state = DB_LOCK_WAIT_TIMEOUT; +#ifdef WITH_WSREP + } +#endif /* WITH_WSREP */ MONITOR_INC(MONITOR_TIMEOUT); } @@ -461,8 +489,13 @@ lock_wait_check_and_cancel( if (trx->lock.wait_lock) { ut_a(trx->lock.que_state == TRX_QUE_LOCK_WAIT); - +#ifdef WITH_WSREP + if (!wsrep_is_BF_lock_timeout(trx)) { +#endif /* WITH_WSREP */ lock_cancel_waiting_and_release(trx->lock.wait_lock); +#ifdef WITH_WSREP + } +#endif /* WITH_WSREP */ } lock_mutex_exit(); diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 5d3f1dd8f24..8e60c11c8ca 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -1926,9 +1926,6 @@ row_ins_scan_sec_index_for_duplicate( mem_heap_t* offsets_heap) /*!< in/out: memory heap that can be emptied */ { -#ifdef WITH_WSREP - trx_t* trx = thr_get_trx(thr); -#endif ulint n_unique; int cmp; ulint n_fields_cmp; @@ -1997,16 +1994,8 @@ row_ins_scan_sec_index_for_duplicate( if (flags & BTR_NO_LOCKING_FLAG) { /* Set no locks when applying log in online table rebuild. */ -#ifdef WITH_WSREP - /* slave applier must not get duplicate error */ - } else if (allow_duplicates || - (wsrep_on(trx->mysql_thd) && - wsrep_thd_is_brute_force(trx->mysql_thd))) { -#else } else if (allow_duplicates) { -#endif - /* If the SQL-query will update or replace duplicate key we will take X-lock for duplicates ( REPLACE, LOAD DATAFILE REPLACE, @@ -2016,6 +2005,10 @@ row_ins_scan_sec_index_for_duplicate( lock_type, block, rec, index, offsets, thr); } else { +#ifdef WITH_WSREP + /* appliers don't need dupkey checks */ + if (!wsrep_thd_is_BF(thr_get_trx(thr)->mysql_thd, 0)) +#endif /* WITH_WSREP */ err = row_ins_set_shared_rec_lock( lock_type, block, rec, index, offsets, thr); } @@ -2211,13 +2204,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 @@ -2262,13 +2249,7 @@ duplicate: 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.cc b/storage/innobase/row/row0upd.cc index eb5d9e5feb6..d34ffdd5f6d 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -373,6 +373,8 @@ wsrep_row_upd_check_foreign_constraints( trx = thr_get_trx(thr); + /* 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.cc b/storage/innobase/srv/srv0srv.cc index 15730b4f00a..aab893df09b 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -2409,27 +2409,6 @@ suspend_thread: OS_THREAD_DUMMY_RETURN; /* Not reached, avoid compiler warning */ } -#ifdef WITH_WSREP_TODO -/*********************************************************************//** -check if lock timeout was for priority thread, -as a side effect trigger lock monitor -@return false for regular lock timeout */ -static ibool -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)) { - fprintf(stderr, "WSREP: BF lock wait long\n"); - srv_print_innodb_monitor = TRUE; - srv_print_innodb_lock_monitor = TRUE; - os_event_set(lock_sys->timeout_event); - return TRUE; - } - return FALSE; - } -#endif /* WITH_WSREP_TODO */ /*********************************************************************//** Check if purge should stop. @return true if it should shutdown. */ diff --git a/storage/innobase/trx/trx0sys.cc b/storage/innobase/trx/trx0sys.cc index cc1c095f16e..4af61d4869b 100644 --- a/storage/innobase/trx/trx0sys.cc +++ b/storage/innobase/trx/trx0sys.cc @@ -178,7 +178,12 @@ trx_sys_flush_max_trx_id(void) mtr_t mtr; trx_sysf_t* sys_header; +#ifndef WITH_WSREP + /* wsrep_fake_trx_id violates this assert + * Copied from trx_sys_get_new_trx_id + */ ut_ad(mutex_own(&trx_sys->mutex)); +#endif /* WITH_WSREP */ if (!srv_read_only_mode) { mtr_start(&mtr); diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 61287e73acc..a9c12d9259c 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -1437,8 +1437,8 @@ innobase_srv_conc_enter_innodb( trx_t* trx) /*!< in: transaction handle */ { #ifdef WITH_WSREP - if (wsrep_on(trx->mysql_thd) && - wsrep_thd_is_brute_force(trx->mysql_thd)) return; + if (wsrep_on(trx->mysql_thd) && + wsrep_thd_is_BF(trx->mysql_thd, FALSE)) return; #endif /* WITH_WSREP */ if (srv_thread_concurrency) { if (trx->n_tickets_to_enter_innodb > 0) { @@ -1475,8 +1475,8 @@ innobase_srv_conc_exit_innodb( ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch)); #endif /* UNIV_SYNC_DEBUG */ #ifdef WITH_WSREP - if (wsrep_on(trx->mysql_thd) && - wsrep_thd_is_brute_force(trx->mysql_thd)) return; + if (wsrep_on(trx->mysql_thd) && + wsrep_thd_is_BF(trx->mysql_thd, FALSE)) return; #endif /* WITH_WSREP */ /* This is to avoid making an unnecessary function call. */ @@ -3967,11 +3967,6 @@ innobase_commit_low( /*================*/ trx_t* trx) /*!< in: transaction handle */ { - if (trx_is_started(trx)) { - - trx_commit_for_mysql(trx); - } - #ifdef WITH_WSREP THD* thd = (THD*)trx->mysql_thd; const char* tmp = 0; @@ -3989,7 +3984,10 @@ innobase_commit_low( #endif /* WSREP_PROC_INFO */ } #endif /* WITH_WSREP */ + if (trx_is_started(trx)) { + trx_commit_for_mysql(trx); + } #ifdef WITH_WSREP if (wsrep_on((void*)thd)) { thd_proc_info(thd, tmp); } #endif /* WITH_WSREP */ @@ -6054,7 +6052,7 @@ wsrep_innobase_mysql_sort( tmp_length = charset->coll->strnxfrm(charset, str, str_length, str_length, tmp_str, tmp_length, 0); /**/ - DBUG_ASSERT(tmp_length == str_length); + DBUG_ASSERT(tmp_length <= str_length); break; } @@ -7755,7 +7753,6 @@ ha_innobase::write_row( wsrep_thd_query(user_thd)); } #endif /* WITH_WSREP */ - /* ALTER TABLE is COMMITted at every 10000 copied rows. The IX table lock for the original table has to be re-issued. As this method will be called on a temporary table where the @@ -7794,7 +7791,8 @@ no_commit: { case WSREP_TRX_OK: break; - case WSREP_TRX_ROLLBACK: + case WSREP_TRX_SIZE_EXCEEDED: + case WSREP_TRX_CERT_FAIL: case WSREP_TRX_ERROR: DBUG_RETURN(1); } @@ -7818,10 +7816,12 @@ no_commit: { case WSREP_TRX_OK: break; - case WSREP_TRX_ROLLBACK: + case WSREP_TRX_SIZE_EXCEEDED: + case WSREP_TRX_CERT_FAIL: case WSREP_TRX_ERROR: DBUG_RETURN(1); } + if (binlog_hton->commit(binlog_hton, user_thd, 1)) DBUG_RETURN(1); wsrep_post_commit(user_thd, TRUE); @@ -7949,9 +7949,10 @@ no_commit: #ifdef WITH_WSREP /* workaround for LP bug #355000, retrying the insert */ case SQLCOM_INSERT: - if (wsrep_on(current_thd) && - auto_inc_inserted && - wsrep_drupal_282555_workaround && + if (wsrep_on(current_thd) && + auto_inc_inserted && + wsrep_drupal_282555_workaround && + wsrep_thd_retry_counter(current_thd) == 0 && !thd_test_options(current_thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { @@ -7963,8 +7964,7 @@ no_commit: error= DB_SUCCESS; wsrep_thd_set_conflict_state( current_thd, MUST_ABORT); - innobase_srv_conc_exit_innodb( - prebuilt->trx); + innobase_srv_conc_exit_innodb(prebuilt->trx); /* jump straight to func exit over * later wsrep hooks */ goto func_exit; @@ -10133,6 +10133,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'}; @@ -10153,14 +10160,11 @@ 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()))) { - if (key_info->flags & HA_NOSAME || shared) - key_appended = true; - len = wsrep_store_key_val_for_row( table, i, key0, key_info->key_length, record0, &is_null); @@ -10169,6 +10173,10 @@ ha_innobase::wsrep_append_keys( thd, trx, table_share, table, keyval0, len+1, shared); if (rcode) DBUG_RETURN(rcode); + + if (key_info->flags & HA_NOSAME || shared) + key_appended = true; + } else { @@ -17759,6 +17767,7 @@ wsrep_abort_slave_trx(wsrep_seqno_t bf_seqno, wsrep_seqno_t victim_seqno) } /*******************************************************************//** This function is used to kill one transaction in BF. */ + int wsrep_innobase_kill_one_trx(void * const bf_thd_ptr, const trx_t * const bf_trx, diff --git a/storage/xtradb/include/ha_prototypes.h b/storage/xtradb/include/ha_prototypes.h index 7d8224820c6..d027deb6140 100644 --- a/storage/xtradb/include/ha_prototypes.h +++ b/storage/xtradb/include/ha_prototypes.h @@ -290,7 +290,7 @@ UNIV_INTERN int wsrep_innobase_kill_one_trx(void *thd_ptr, const trx_t *bf_trx, trx_t *victim_trx, ibool signal); -extern "C" int wsrep_thd_is_brute_force(void *thd_ptr); +my_bool wsrep_thd_is_BF(void *thd_ptr, my_bool sync); 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 d11f3b006d4..466e728f65b 100644 --- a/storage/xtradb/include/lock0lock.h +++ b/storage/xtradb/include/lock0lock.h @@ -906,7 +906,6 @@ lock_trx_has_rec_x_lock( 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.cc b/storage/xtradb/lock/lock0lock.cc index c6cb885ca4f..f78f25df895 100644 --- a/storage/xtradb/lock/lock0lock.cc +++ b/storage/xtradb/lock/lock0lock.cc @@ -55,7 +55,6 @@ extern my_bool wsrep_debug; extern my_bool wsrep_log_conflicts; #include "ha_prototypes.h" #endif - /* Restricts the length of search we will do in the waits-for graph of transactions */ #define LOCK_MAX_N_STEPS_IN_DEADLOCK_CHECK 1000000 @@ -981,47 +980,6 @@ lock_rec_has_to_wait( && !lock_mode_compatible(static_cast<enum lock_mode>( LOCK_MODE_MASK & type_mode), lock_get_mode(lock2))) { -#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_brute_force(trx->mysql_thd) && - wsrep_thd_is_brute_force(lock2->trx->mysql_thd)) { - - 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 (wsrep_debug) { - fprintf(stderr, - "BF conflict, modes: %lu %lu\n", - type_mode, - lock2->type_mode); -#ifdef OUT - fprintf(stderr, - "seqnos %llu %llu\n", - (long long)wsrep_thd_trx_seqno( - trx->mysql_thd), - (long long)wsrep_thd_trx_seqno( - lock2->trx->mysql_thd)); -#endif - } - return FALSE; - } - } -#endif /* WITH_WSREP */ /* We have somewhat complex rules when gap type record locks cause waits */ @@ -1071,6 +1029,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); } @@ -1578,8 +1574,7 @@ lock_rec_has_expl( static void lock_rec_discard(lock_t* in_lock); -#endif /* WITH_WSREP */ - +#endif #ifdef UNIV_DEBUG /*********************************************************************//** Checks if some other transaction has a lock request in the queue. @@ -1629,17 +1624,16 @@ lock_rec_other_has_expl_req( #endif /* UNIV_DEBUG */ #ifdef WITH_WSREP -static -void +static void wsrep_kill_victim(const trx_t * const trx, const lock_t *lock) { ut_ad(lock_mutex_own()); ut_ad(trx_mutex_own(lock->trx)); - my_bool bf_this = wsrep_thd_is_brute_force(trx->mysql_thd); - my_bool 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))) { - + if (lock->trx->lock.que_state == TRX_QUE_LOCK_WAIT) { if (wsrep_debug) fprintf(stderr, "WSREP: BF victim waiting\n"); @@ -1933,11 +1927,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; @@ -1957,12 +1946,12 @@ lock_rec_create( ut_ad(index->table->n_ref_count > 0 || !index->table->can_be_evicted); #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 = (lock_t *)c_lock->hash; lock_t *prev = NULL; while (hash && - wsrep_thd_is_brute_force(((lock_t *)hash)->trx->mysql_thd) && + wsrep_thd_is_BF(((lock_t *)hash)->trx->mysql_thd, TRUE) && wsrep_trx_order_before( ((lock_t *)hash)->trx->mysql_thd, trx->mysql_thd)) { @@ -2376,11 +2365,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); ut_ad(dict_index_is_clust(index) || !dict_index_is_online_ddl(index)); @@ -2468,11 +2452,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); ut_ad(dict_index_is_clust(index) || !dict_index_is_online_ddl(index)); @@ -2582,19 +2561,8 @@ 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 - ut_ad(dict_index_is_clust(index) || !dict_index_is_online_ddl(index)); /* We try a simplified and faster subroutine for the most @@ -4040,17 +4008,19 @@ lock_deadlock_select_victim( if (trx_weight_ge(ctx->wait_lock->trx, ctx->start)) { /* The joining transaction is 'smaller', choose it as the victim and roll it back. */ + #ifdef WITH_WSREP - if (!wsrep_thd_is_brute_force(ctx->start->mysql_thd)) - return(ctx->start); - else + if (wsrep_thd_is_BF(ctx->start->mysql_thd, TRUE)) + return(ctx->wait_lock->trx); + else #endif /* WITH_WSREP */ return(ctx->start); } + #ifdef WITH_WSREP - if (wsrep_thd_is_brute_force(ctx->wait_lock->trx->mysql_thd)) + if (wsrep_thd_is_BF(ctx->wait_lock->trx->mysql_thd, TRUE)) return(ctx->start); - else + else #endif /* WITH_WSREP */ return(ctx->wait_lock->trx); } @@ -4182,7 +4152,7 @@ lock_deadlock_search( ctx->too_deep = TRUE; #ifdef WITH_WSREP - if (wsrep_thd_is_brute_force(ctx->start->mysql_thd)) + if (wsrep_thd_is_BF(ctx->start->mysql_thd, TRUE)) return(ctx->wait_lock->trx->id); else #endif /* WITH_WSREP */ @@ -4205,7 +4175,7 @@ lock_deadlock_search( ctx->too_deep = TRUE; #ifdef WITH_WSREP - if (wsrep_thd_is_brute_force(ctx->start->mysql_thd)) + if (wsrep_thd_is_BF(ctx->start->mysql_thd, TRUE)) return(lock->trx->id); else #endif /* WITH_WSREP */ @@ -4328,7 +4298,7 @@ lock_deadlock_check_and_resolve( ut_a(victim_trx_id == trx->id); #ifdef WITH_WSREP - if (!wsrep_thd_is_brute_force(ctx.start->mysql_thd)) + if (!wsrep_thd_is_BF(ctx.start->mysql_thd, TRUE)) { #endif /* WITH_WSREP */ if (!srv_read_only_mode) { @@ -4426,7 +4396,7 @@ lock_table_create( UT_LIST_ADD_LAST(trx_locks, trx->lock.trx_locks, lock); #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 { @@ -6531,7 +6501,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/lock/lock0wait.cc b/storage/xtradb/lock/lock0wait.cc index a1c35e20ead..388c847f580 100644 --- a/storage/xtradb/lock/lock0wait.cc +++ b/storage/xtradb/lock/lock0wait.cc @@ -184,6 +184,28 @@ lock_wait_table_reserve_slot( return(NULL); } +#ifdef WITH_WSREP +/*********************************************************************//** +check if lock timeout was for priority thread, +as a side effect trigger lock monitor +@return false for regular lock timeout */ +static ibool +wsrep_is_BF_lock_timeout( +/*====================*/ + trx_t* trx) /* in: trx to check for lock priority */ +{ + if (wsrep_on(trx->mysql_thd) && + wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { + fprintf(stderr, "WSREP: BF lock wait long\n"); + srv_print_innodb_monitor = TRUE; + srv_print_innodb_lock_monitor = TRUE; + os_event_set(srv_monitor_event); + return TRUE; + } + return FALSE; + } +#endif /* WITH_WSREP */ + /***************************************************************//** Puts a user OS thread to wait for a lock to be released. If an error occurs during the wait trx->error_state associated with thr is @@ -375,9 +397,15 @@ lock_wait_suspend_thread( if (lock_wait_timeout < 100000000 && wait_time > (double) lock_wait_timeout) { +#ifdef WITH_WSREP + if (!wsrep_is_BF_lock_timeout(trx)) { +#endif /* WITH_WSREP */ trx->error_state = DB_LOCK_WAIT_TIMEOUT; +#ifdef WITH_WSREP + } +#endif /* WITH_WSREP */ MONITOR_INC(MONITOR_TIMEOUT); } @@ -461,8 +489,13 @@ lock_wait_check_and_cancel( if (trx->lock.wait_lock) { ut_a(trx->lock.que_state == TRX_QUE_LOCK_WAIT); - +#ifdef WITH_WSREP + if (!wsrep_is_BF_lock_timeout(trx)) { +#endif /* WITH_WSREP */ lock_cancel_waiting_and_release(trx->lock.wait_lock); +#ifdef WITH_WSREP + } +#endif /* WITH_WSREP */ } lock_mutex_exit(); diff --git a/storage/xtradb/row/row0ins.cc b/storage/xtradb/row/row0ins.cc index c29c1f56d3f..ff92162c452 100644 --- a/storage/xtradb/row/row0ins.cc +++ b/storage/xtradb/row/row0ins.cc @@ -1938,9 +1938,6 @@ row_ins_scan_sec_index_for_duplicate( mem_heap_t* offsets_heap) /*!< in/out: memory heap that can be emptied */ { -#ifdef WITH_WSREP - trx_t* trx = thr_get_trx(thr); -#endif ulint n_unique; int cmp; ulint n_fields_cmp; @@ -2009,16 +2006,7 @@ row_ins_scan_sec_index_for_duplicate( if (flags & BTR_NO_LOCKING_FLAG) { /* Set no locks when applying log in online table rebuild. */ - -#ifdef WITH_WSREP - /* slave applier must not get duplicate error */ - } else if (allow_duplicates || - (wsrep_on(trx->mysql_thd) && - wsrep_thd_is_brute_force(trx->mysql_thd))) { -#else - } else if (allow_duplicates) { -#endif /* If the SQL-query will update or replace duplicate key we will take X-lock for @@ -2029,6 +2017,10 @@ row_ins_scan_sec_index_for_duplicate( lock_type, block, rec, index, offsets, thr); } else { +#ifdef WITH_WSREP + /* appliers don't need dupkey checks */ + if (!wsrep_thd_is_BF(thr_get_trx(thr)->mysql_thd, 0)) +#endif /* WITH_WSREP */ err = row_ins_set_shared_rec_lock( lock_type, block, rec, index, offsets, thr); } @@ -2224,13 +2216,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 @@ -2275,13 +2261,7 @@ duplicate: 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.cc b/storage/xtradb/row/row0upd.cc index 9b733410c00..0f299228493 100644 --- a/storage/xtradb/row/row0upd.cc +++ b/storage/xtradb/row/row0upd.cc @@ -375,6 +375,8 @@ wsrep_row_upd_check_foreign_constraints( trx = thr_get_trx(thr); + /* 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.cc b/storage/xtradb/srv/srv0srv.cc index 46d81790fe8..6506daa3347 100644 --- a/storage/xtradb/srv/srv0srv.cc +++ b/storage/xtradb/srv/srv0srv.cc @@ -2998,27 +2998,6 @@ suspend_thread: OS_THREAD_DUMMY_RETURN; /* Not reached, avoid compiler warning */ } -#ifdef WITH_WSREP_TODO -/*********************************************************************//** -check if lock timeout was for priority thread, -as a side effect trigger lock monitor -@return false for regular lock timeout */ -static ibool -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)) { - fprintf(stderr, "WSREP: BF lock wait long\n"); - srv_print_innodb_monitor = TRUE; - srv_print_innodb_lock_monitor = TRUE; - os_event_set(lock_sys->timeout_event); - return TRUE; - } - return FALSE; - } -#endif /* WITH_WSREP_TODO */ /*********************************************************************//** Check if purge should stop. @return true if it should shutdown. */ diff --git a/storage/xtradb/trx/trx0sys.cc b/storage/xtradb/trx/trx0sys.cc index ed3d177820f..19d14bf6f38 100644 --- a/storage/xtradb/trx/trx0sys.cc +++ b/storage/xtradb/trx/trx0sys.cc @@ -178,7 +178,12 @@ trx_sys_flush_max_trx_id(void) mtr_t mtr; trx_sysf_t* sys_header; +#ifndef WITH_WSREP + /* wsrep_fake_trx_id violates this assert + * Copied from trx_sys_get_new_trx_id + */ ut_ad(mutex_own(&trx_sys->mutex)); +#endif /* WITH_WSREP */ if (!srv_read_only_mode) { mtr_start(&mtr); |