summaryrefslogtreecommitdiff
path: root/storage/innobase
diff options
context:
space:
mode:
authorOleksandr Byelkin <sanja@mariadb.com>2023-01-18 16:37:40 +0100
committerOleksandr Byelkin <sanja@mariadb.com>2023-01-18 16:37:40 +0100
commit26d8485244bcf94923ab5bbd754276c9010dd569 (patch)
tree77c74bf4703d0673430ab3a46395b3447e78afd3 /storage/innobase
parent88c35781cc9f5f3c63de98a8b6e7eb3378d4fae5 (diff)
parent795ff0daf0f1ba691735f64f6e3a08e9ecd0160b (diff)
downloadmariadb-git-26d8485244bcf94923ab5bbd754276c9010dd569.tar.gz
Merge branch '10.7' into 10.8
Diffstat (limited to 'storage/innobase')
-rw-r--r--storage/innobase/handler/ha_innodb.cc10
-rw-r--r--storage/innobase/lock/lock0lock.cc47
2 files changed, 41 insertions, 16 deletions
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 71ee54b7094..a1fcab0a53b 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -18599,7 +18599,15 @@ void lock_wait_wsrep_kill(trx_t *bf_trx, ulong thd_id, trx_id_t trx_id)
lock_sys.cancel_lock_wait_for_trx(vtrx);
DEBUG_SYNC(bf_thd, "before_wsrep_thd_abort");
- wsrep_thd_bf_abort(bf_thd, vthd, true);
+ if (!wsrep_thd_bf_abort(bf_thd, vthd, true))
+ {
+ wsrep_thd_LOCK(vthd);
+ wsrep_thd_set_wsrep_aborter(NULL, vthd);
+ wsrep_thd_UNLOCK(vthd);
+
+ WSREP_DEBUG("wsrep_thd_bf_abort has failed, victim %lu will survive",
+ thd_get_thread_id(vthd));
+ }
}
wsrep_thd_kill_UNLOCK(vthd);
}
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index 46cfb6e5c88..9577dfc62aa 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -693,22 +693,31 @@ lock_rec_has_to_wait(
#endif /* HAVE_REPLICATION */
#ifdef WITH_WSREP
- /* New lock request from a transaction is using unique key
- scan and this transaction is a wsrep high priority transaction
- (brute force). If conflicting transaction is also wsrep high
- priority transaction we should avoid lock conflict because
- ordering of these transactions is already decided and
- conflicting transaction will be later replayed. */
- if (trx->is_wsrep_UK_scan()
- && wsrep_thd_is_BF(lock2->trx->mysql_thd, false)) {
- return false;
- }
+ /* New lock request from a transaction is using unique key
+ scan and this transaction is a wsrep high priority transaction
+ (brute force). If conflicting transaction is also wsrep high
+ priority transaction we should avoid lock conflict because
+ ordering of these transactions is already decided and
+ conflicting transaction will be later replayed. */
+ if (trx->is_wsrep_UK_scan()
+ && wsrep_thd_is_BF(lock2->trx->mysql_thd, false)) {
+ return false;
+ }
+
+ /* if BF-BF conflict, we have to look at write set order */
+ if (trx->is_wsrep() &&
+ (type_mode & LOCK_MODE_MASK) == LOCK_X &&
+ (lock2->type_mode & LOCK_MODE_MASK) == LOCK_X &&
+ wsrep_thd_order_before(trx->mysql_thd,
+ lock2->trx->mysql_thd)) {
+ return false;
+ }
- /* We very well can let bf to wait normally as other
- BF will be replayed in case of conflict. For debug
- builds we will do additional sanity checks to catch
- unsupported bf wait if any. */
- ut_d(wsrep_assert_no_bf_bf_wait(lock2, trx));
+ /* We very well can let bf to wait normally as other
+ BF will be replayed in case of conflict. For debug
+ builds we will do additional sanity checks to catch
+ unsupported bf wait if any. */
+ ut_d(wsrep_assert_no_bf_bf_wait(lock2, trx));
#endif /* WITH_WSREP */
return true;
@@ -1600,6 +1609,14 @@ lock_rec_has_to_wait_in_queue(const hash_cell_t &cell, const lock_t *wait_lock)
if (heap_no < lock_rec_get_n_bits(lock)
&& (p[bit_offset] & bit_mask)
&& lock_has_to_wait(wait_lock, lock)) {
+#ifdef WITH_WSREP
+ if (lock->trx->is_wsrep() &&
+ wsrep_thd_order_before(wait_lock->trx->mysql_thd,
+ lock->trx->mysql_thd)) {
+ /* don't wait for another BF lock */
+ continue;
+ }
+#endif
return(lock);
}
}