summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorNirbhay Choubey <nirbhay@skysql.com>2014-03-26 11:12:38 -0400
committerNirbhay Choubey <nirbhay@skysql.com>2014-03-26 11:12:38 -0400
commitb5871a51e99f2d591e944590f2e2332275064d07 (patch)
treee27d70c77ad6cd9f399c6063899c0d3d6d2735c6 /storage
parent7d892f69a565e583eb692d01e2e80a158ee795fe (diff)
downloadmariadb-git-b5871a51e99f2d591e944590f2e2332275064d07.tar.gz
* bzr merge -r4027..4061 codership/5.6
* Merged Innodb changes to xtradb
Diffstat (limited to 'storage')
-rw-r--r--storage/innobase/handler/ha_innodb.cc42
-rw-r--r--storage/innobase/include/ha_prototypes.h2
-rw-r--r--storage/innobase/include/lock0lock.h1
-rw-r--r--storage/innobase/lock/lock0lock.cc140
-rw-r--r--storage/innobase/lock/lock0wait.cc2
-rw-r--r--storage/innobase/row/row0ins.cc27
-rw-r--r--storage/innobase/row/row0upd.cc2
-rw-r--r--storage/innobase/trx/trx0sys.cc5
-rw-r--r--storage/xtradb/handler/ha_innodb.cc43
-rw-r--r--storage/xtradb/include/ha_prototypes.h28
-rw-r--r--storage/xtradb/include/lock0lock.h1
-rw-r--r--storage/xtradb/lock/lock0lock.cc142
-rw-r--r--storage/xtradb/lock/lock0wait.cc2
-rw-r--r--storage/xtradb/row/row0ins.cc28
-rw-r--r--storage/xtradb/row/row0upd.cc257
-rw-r--r--storage/xtradb/trx/trx0sys.cc5
16 files changed, 320 insertions, 407 deletions
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index abbdb94397c..241637bca8a 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -1184,8 +1184,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) {
@@ -1222,8 +1222,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. */
@@ -3466,11 +3466,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;
@@ -3488,7 +3483,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 */
@@ -5544,7 +5542,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;
}
@@ -7434,9 +7432,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)) {
@@ -9545,6 +9544,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'};
@@ -9565,14 +9571,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);
@@ -9581,6 +9584,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
{
@@ -16699,6 +16706,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 08ac2a74405..dc78964a873 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 24e612e63f5..2f89c02bb7a 100644
--- a/storage/innobase/include/lock0lock.h
+++ b/storage/innobase/include/lock0lock.h
@@ -873,7 +873,6 @@ lock_trx_has_sys_table_locks(
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 f6779ff5acd..0e4c1e7c82f 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -978,47 +978,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 */
@@ -1068,6 +1027,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);
}
@@ -1630,8 +1627,8 @@ 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))) {
@@ -1929,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;
@@ -1953,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)) {
@@ -2361,11 +2353,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));
@@ -2382,8 +2369,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 {
@@ -2451,11 +2437,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));
@@ -2564,11 +2545,6 @@ 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
@@ -4023,18 +3999,18 @@ lock_deadlock_select_victim(
/* 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
- return(ctx->start);
-#endif
+ 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)) {
- return(ctx->start);
- }
-#endif
+ if (wsrep_thd_is_BF(ctx->wait_lock->trx->mysql_thd, TRUE))
+ return(ctx->start);
+ else
+#endif /* WITH_WSREP */
return(ctx->wait_lock->trx);
}
@@ -4184,7 +4160,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 +4181,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 */
@@ -4342,7 +4318,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) {
@@ -4438,7 +4414,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 {
@@ -6476,7 +6452,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 f957c1855cc..5a793ae7af8 100644
--- a/storage/innobase/lock/lock0wait.cc
+++ b/storage/innobase/lock/lock0wait.cc
@@ -195,7 +195,7 @@ wsrep_is_BF_lock_timeout(
trx_t* trx) /* in: trx to check for lock priority */
{
if (wsrep_on(trx->mysql_thd) &&
- wsrep_thd_is_brute_force(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;
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index 57687e77b2b..14226d04eaa 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -1920,9 +1920,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;
@@ -1980,16 +1977,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,
@@ -2000,6 +1989,10 @@ row_ins_scan_sec_index_for_duplicate(
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_ORDINARY, block,
rec, index, offsets, thr);
@@ -2183,13 +2176,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
@@ -2234,13 +2221,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 5d236cc40e5..d3ca4ec6b8e 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/trx/trx0sys.cc b/storage/innobase/trx/trx0sys.cc
index 0b2837a09b5..2562064b51b 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 e3a3f71f559..ce3e8f250c9 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -1448,9 +1448,8 @@ innobase_srv_conc_enter_innodb(
{
#ifdef WITH_WSREP
if (wsrep_on(trx->mysql_thd) &&
- wsrep_thd_is_brute_force(trx->mysql_thd)) return;
+ wsrep_thd_is_BF(trx->mysql_thd, FALSE)) return;
#endif /* WITH_WSREP */
-
if (srv_thread_concurrency) {
if (trx->n_tickets_to_enter_innodb > 0) {
@@ -1482,14 +1481,13 @@ innobase_srv_conc_exit_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;
-#endif /* WITH_WSREP */
-
#ifdef UNIV_SYNC_DEBUG
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_BF(trx->mysql_thd, FALSE)) return;
+#endif /* WITH_WSREP */
/* This is to avoid making an unnecessary function call. */
if (trx->declared_to_be_inside_innodb
@@ -3937,12 +3935,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 */
@@ -6002,7 +5998,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;
}
@@ -7896,9 +7892,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)) {
@@ -7910,8 +7907,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;
@@ -10059,6 +10055,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'};
@@ -10079,14 +10082,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);
@@ -10095,6 +10095,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
{
@@ -17755,6 +17759,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 d1652c1f0d8..d027deb6140 100644
--- a/storage/xtradb/include/ha_prototypes.h
+++ b/storage/xtradb/include/ha_prototypes.h
@@ -285,6 +285,19 @@ innobase_casedn_str(
/*================*/
char* a); /*!< in/out: string to put in lower case */
+#ifdef WITH_WSREP
+UNIV_INTERN
+int
+wsrep_innobase_kill_one_trx(void *thd_ptr,
+ const trx_t *bf_trx, trx_t *victim_trx, ibool signal);
+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);
+int
+wsrep_on(void *thd_ptr);
+extern "C" int wsrep_is_wsrep_xid(const void*);
+#endif /* WITH_WSREP */
/**********************************************************************//**
Determines the connection character set.
@return connection character set */
@@ -375,21 +388,6 @@ thd_flush_log_at_trx_commit(
/*================================*/
void* thd);
-#ifdef WITH_WSREP
-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);
-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);
-//UNIV_INTERN
-int
-wsrep_on(void *thd_ptr);
-extern "C" int wsrep_is_wsrep_xid(const void*);
-#endif /* WITH_WSREP */
/**********************************************************************//**
Get the current setting of the lower_case_table_names global parameter from
mysqld.cc. We do a dirty read because for one there is no synchronization
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 8773e2e1868..67985c642c6 100644
--- a/storage/xtradb/lock/lock0lock.cc
+++ b/storage/xtradb/lock/lock0lock.cc
@@ -982,48 +982,6 @@ lock_rec_has_to_wait(
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 */
@@ -1072,6 +1030,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);
}
@@ -1634,10 +1630,8 @@ static void
wsrep_kill_victim(trx_t *trx, 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))) {
@@ -1935,13 +1929,8 @@ 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;
lock->un_member.rec_lock.page_no = page_no;
lock->un_member.rec_lock.n_bits = n_bytes * 8;
@@ -1959,12 +1948,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)) {
@@ -2378,11 +2367,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));
@@ -2454,11 +2438,11 @@ lock_rec_lock_slow(
que_thr_t* thr) /*!< in: query thread */
{
trx_t* trx;
- lock_t* lock;
- dberr_t err = DB_SUCCESS;
#ifdef WITH_WSREP
lock_t* c_lock = NULL;
#endif
+ lock_t* lock;
+ dberr_t err = DB_SUCCESS;
ut_ad(lock_mutex_own());
ut_ad((LOCK_MODE_MASK & mode) != LOCK_S
@@ -2469,11 +2453,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,11 +2561,6 @@ 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
@@ -4040,20 +4014,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)) {
- return(ctx->start);
- }
-#endif
+ if (wsrep_thd_is_BF(ctx->wait_lock->trx->mysql_thd, TRUE))
+ return(ctx->start);
+ else
+#endif /* WITH_WSREP */
return(ctx->wait_lock->trx);
}
@@ -4184,7 +4157,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 */
@@ -4207,7 +4180,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 */
@@ -4330,7 +4303,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,8 +4399,9 @@ lock_table_create(
ut_ad(table->n_ref_count > 0 || !table->can_be_evicted);
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 {
@@ -6533,7 +6507,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 0c1269f02d5..388c847f580 100644
--- a/storage/xtradb/lock/lock0wait.cc
+++ b/storage/xtradb/lock/lock0wait.cc
@@ -195,7 +195,7 @@ wsrep_is_BF_lock_timeout(
trx_t* trx) /* in: trx to check for lock priority */
{
if (wsrep_on(trx->mysql_thd) &&
- wsrep_thd_is_brute_force(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;
diff --git a/storage/xtradb/row/row0ins.cc b/storage/xtradb/row/row0ins.cc
index d36d589e6c6..9cf2a4fc00d 100644
--- a/storage/xtradb/row/row0ins.cc
+++ b/storage/xtradb/row/row0ins.cc
@@ -1939,9 +1939,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;
@@ -2010,16 +2007,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
@@ -2030,6 +2018,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);
}
@@ -2225,13 +2217,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
@@ -2276,13 +2262,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 9d40848c2fc..5725b229a07 100644
--- a/storage/xtradb/row/row0upd.cc
+++ b/storage/xtradb/row/row0upd.cc
@@ -175,27 +175,6 @@ func_exit:
return(is_referenced);
}
-#ifdef WITH_WSREP
-ulint
-wsrep_append_foreign_key(
- trx_t* trx,
- dict_foreign_t* foreign,
- const rec_t* clust_rec,
- dict_index_t* clust_index,
- ibool referenced,
- ibool shared);
-
-ulint
-wsrep_row_upd_check_foreign_constraints(
- upd_node_t* node, /*!< in: row update node */
- btr_pcur_t* pcur, /*!< in: cursor positioned on a record; NOTE: the
- cursor position is lost in this function! */
- dict_table_t* table, /*!< in: table in question */
- dict_index_t* index, /*!< in: index of the cursor */
- ulint* offsets,/*!< in/out: rec_get_offsets(pcur.rec, index) */
- que_thr_t* thr, /*!< in: query thread */
- mtr_t* mtr); /*!< in: mtr */
-#endif /* WITH_WSREP */
/*********************************************************************//**
Checks if possible foreign key constraints hold after a delete of the record
@@ -314,7 +293,125 @@ run_again:
}
err = DB_SUCCESS;
+func_exit:
+ if (got_s_lock) {
+ row_mysql_unfreeze_data_dictionary(trx);
+ }
+
+ mem_heap_free(heap);
+
+ return(err);
+}
+#ifdef WITH_WSREP
+static
+dberr_t
+wsrep_row_upd_check_foreign_constraints(
+/*=================================*/
+ upd_node_t* node, /*!< in: row update node */
+ btr_pcur_t* pcur, /*!< in: cursor positioned on a record; NOTE: the
+ cursor position is lost in this function! */
+ dict_table_t* table, /*!< in: table in question */
+ dict_index_t* index, /*!< in: index of the cursor */
+ ulint* offsets,/*!< in/out: rec_get_offsets(pcur.rec, index) */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr) /*!< in: mtr */
+{
+ dict_foreign_t* foreign;
+ mem_heap_t* heap;
+ dtuple_t* entry;
+ trx_t* trx;
+ const rec_t* rec;
+ ulint n_ext;
+ dberr_t err;
+ ibool got_s_lock = FALSE;
+
+ if (UT_LIST_GET_FIRST(table->foreign_list) == NULL) {
+
+ return(DB_SUCCESS);
+ }
+
+ 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));
+
+ heap = mem_heap_create(500);
+
+ entry = row_rec_to_index_entry(rec, index, offsets,
+ &n_ext, heap);
+
+ mtr_commit(mtr);
+
+ mtr_start(mtr);
+ if (trx->dict_operation_lock_mode == 0) {
+ got_s_lock = TRUE;
+
+ row_mysql_freeze_data_dictionary(trx);
+ }
+
+ foreign = UT_LIST_GET_FIRST(table->foreign_list);
+
+ while (foreign) {
+ /* Note that we may have an update which updates the index
+ record, but does NOT update the first fields which are
+ referenced in a foreign key constraint. Then the update does
+ NOT break the constraint. */
+
+ if (foreign->foreign_index == index
+ && (node->is_delete
+ || row_upd_changes_first_fields_binary(
+ entry, index, node->update,
+ foreign->n_fields))) {
+
+ if (foreign->referenced_table == NULL) {
+ foreign->referenced_table =
+ dict_table_open_on_name(
+ foreign->referenced_table_name_lookup,
+ FALSE, FALSE, DICT_ERR_IGNORE_NONE);
+ }
+
+ if (foreign->referenced_table) {
+ mutex_enter(&(dict_sys->mutex));
+
+ (foreign->referenced_table
+ ->n_foreign_key_checks_running)++;
+
+ mutex_exit(&(dict_sys->mutex));
+ }
+
+ /* NOTE that if the thread ends up waiting for a lock
+ we will release dict_operation_lock temporarily!
+ But the counter on the table protects 'foreign' from
+ being dropped while the check is running. */
+
+ err = row_ins_check_foreign_constraint(
+ TRUE, foreign, table, entry, thr);
+
+ if (foreign->referenced_table) {
+ mutex_enter(&(dict_sys->mutex));
+
+ ut_a(foreign->referenced_table
+ ->n_foreign_key_checks_running > 0);
+
+ (foreign->referenced_table
+ ->n_foreign_key_checks_running)--;
+
+ mutex_exit(&(dict_sys->mutex));
+ }
+
+ if (err != DB_SUCCESS) {
+
+ goto func_exit;
+ }
+ }
+
+ foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
+ }
+
+ err = DB_SUCCESS;
func_exit:
if (got_s_lock) {
row_mysql_unfreeze_data_dictionary(trx);
@@ -326,6 +423,7 @@ func_exit:
return(err);
}
+#endif /* WITH_WSREP */
/*********************************************************************//**
Creates an update node for a query graph.
@@ -2015,123 +2113,6 @@ row_upd_clust_rec_by_insert_inherit_func(
return(inherit);
}
-#ifdef WITH_WSREP
-ulint
-wsrep_row_upd_check_foreign_constraints(
-/*=================================*/
- upd_node_t* node, /*!< in: row update node */
- btr_pcur_t* pcur, /*!< in: cursor positioned on a record; NOTE: the
- cursor position is lost in this function! */
- dict_table_t* table, /*!< in: table in question */
- dict_index_t* index, /*!< in: index of the cursor */
- ulint* offsets,/*!< in/out: rec_get_offsets(pcur.rec, index) */
- que_thr_t* thr, /*!< in: query thread */
- mtr_t* mtr) /*!< in: mtr */
-{
- dict_foreign_t* foreign;
- mem_heap_t* heap;
- dtuple_t* entry;
- trx_t* trx;
- const rec_t* rec;
- ulint n_ext;
- ulint err;
- ibool got_s_lock = FALSE;
-
- if (UT_LIST_GET_FIRST(table->foreign_list) == NULL) {
-
- return(DB_SUCCESS);
- }
-
- trx = thr_get_trx(thr);
-
- rec = btr_pcur_get_rec(pcur);
- ut_ad(rec_offs_validate(rec, index, offsets));
-
- heap = mem_heap_create(500);
-
- entry = row_rec_to_index_entry(rec, index, offsets, &n_ext, heap);
-
- mtr_commit(mtr);
-
- mtr_start(mtr);
-
- if (trx->dict_operation_lock_mode == 0) {
- got_s_lock = TRUE;
-
- row_mysql_freeze_data_dictionary(trx);
- }
-
- foreign = UT_LIST_GET_FIRST(table->foreign_list);
-
- while (foreign) {
- /* Note that we may have an update which updates the index
- record, but does NOT update the first fields which are
- referenced in a foreign key constraint. Then the update does
- NOT break the constraint. */
-
- if (foreign->foreign_index == index
- && (node->is_delete
- || row_upd_changes_first_fields_binary(
- entry, index, node->update,
- foreign->n_fields))) {
-
- if (foreign->referenced_table == NULL) {
- foreign->referenced_table =
- dict_table_open_on_name(
- foreign->referenced_table_name_lookup,
- FALSE, FALSE, DICT_ERR_IGNORE_NONE);
- }
-
- if (foreign->referenced_table) {
- mutex_enter(&(dict_sys->mutex));
-
- (foreign->referenced_table
- ->n_foreign_key_checks_running)++;
-
- mutex_exit(&(dict_sys->mutex));
- }
-
- /* NOTE that if the thread ends up waiting for a lock
- we will release dict_operation_lock temporarily!
- But the counter on the table protects 'foreign' from
- being dropped while the check is running. */
-
- err = row_ins_check_foreign_constraint(
- TRUE, foreign, table, entry, thr);
-
- if (foreign->referenced_table) {
- mutex_enter(&(dict_sys->mutex));
-
- ut_a(foreign->referenced_table
- ->n_foreign_key_checks_running > 0);
-
- (foreign->referenced_table
- ->n_foreign_key_checks_running)--;
-
- mutex_exit(&(dict_sys->mutex));
- }
-
- if (err != DB_SUCCESS) {
-
- goto func_exit;
- }
- }
-
- foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
- }
-
- err = DB_SUCCESS;
-func_exit:
- if (got_s_lock) {
- row_mysql_unfreeze_data_dictionary(trx);
- }
-
- mem_heap_free(heap);
-
- return(err);
-}
-#endif /* WITH_WSREP */
-
/***********************************************************//**
Marks the clustered index record deleted and inserts the updated version
of the record to the index. This function should be used when the ordering
diff --git a/storage/xtradb/trx/trx0sys.cc b/storage/xtradb/trx/trx0sys.cc
index daa13b8b2c5..0a8d41c9a50 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);