summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2021-08-17 09:28:27 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2021-08-17 09:28:27 +0300
commit3e9eca31e7a8e9e51ac44a55a12914ef818f89dc (patch)
tree5c3c260675455c898b7edc71d7c0ac76d941e25f
parent255313048ca00c48fe78250014570034475a9178 (diff)
downloadmariadb-git-bb-10.5-xa-prepare.tar.gz
Experiment: Release non-essential locks on XA PREPAREbb-10.5-xa-prepare
There is a design issue that the explicit locks of XA PREPARE transactions will be lost on server restart. Only the records that were modified by the transaction will be recovered with exclusive implicit locks. For the purpose of experimenting, we will make XA PREPARE release all locks that would be released on server restart. We do this only on the READ UNCOMMITED or READ COMMITTED isolation levels. lock_release_on_prepare(): Release non-exclusive locks on XA PREPARE. trx_prepare(): Invoke lock_release_on_prepare() if the isolation level is READ UNCOMMITTED or READ COMMITTED. Note: I do not think that this is a good idea. This patch exists only for the purpose of experimenting.
-rw-r--r--storage/innobase/include/lock0lock.h6
-rw-r--r--storage/innobase/lock/lock0lock.cc59
-rw-r--r--storage/innobase/trx/trx0trx.cc5
3 files changed, 69 insertions, 1 deletions
diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h
index 3b63b06a9bb..225c246f4e7 100644
--- a/storage/innobase/include/lock0lock.h
+++ b/storage/innobase/include/lock0lock.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2020, MariaDB Corporation.
+Copyright (c) 2017, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -478,6 +478,10 @@ lock_rec_unlock(
and release possible other transactions waiting because of these locks. */
void lock_release(trx_t* trx);
+/** Release non-exclusive locks on XA PREPARE,
+and release possible other transactions waiting because of these locks. */
+void lock_release_on_prepare(trx_t *trx);
+
/*************************************************************//**
Get the lock hash table */
UNIV_INLINE
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index 8dc2d7c585a..7b1af2e6a6c 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -4219,6 +4219,65 @@ void lock_release(trx_t* trx)
#endif
}
+/** Release non-exclusive locks on XA PREPARE,
+and release possible other transactions waiting because of these locks. */
+void lock_release_on_prepare(trx_t *trx)
+{
+ ulint count= 0;
+ lock_mutex_enter();
+ ut_ad(!trx_mutex_own(trx));
+
+ for (lock_t *lock= UT_LIST_GET_LAST(trx->lock.trx_locks); lock; )
+ {
+ ut_ad(lock->trx == trx);
+
+ if (lock_get_type_low(lock) == LOCK_REC)
+ {
+ ut_ad(!lock->index->table->is_temporary());
+ if (lock_rec_get_gap(lock) || lock_get_mode(lock) != LOCK_X)
+ lock_rec_dequeue_from_page(lock);
+ else
+ {
+ ut_ad(trx->dict_operation ||
+ lock->index->table->id >= DICT_HDR_FIRST_ID);
+retain_lock:
+ lock= UT_LIST_GET_PREV(trx_locks, lock);
+ continue;
+ }
+ }
+ else
+ {
+ ut_ad(lock_get_type_low(lock) & LOCK_TABLE);
+ dict_table_t *table= lock->un_member.tab_lock.table;
+ ut_ad(!table->is_temporary());
+
+ switch (lock_get_mode(lock)) {
+ case LOCK_IS:
+ case LOCK_S:
+ lock_table_dequeue(lock);
+ break;
+ case LOCK_IX:
+ case LOCK_X:
+ ut_ad(table->id >= DICT_HDR_FIRST_ID || trx->dict_operation);
+ /* fall through */
+ default:
+ goto retain_lock;
+ }
+ }
+
+ if (++count == LOCK_RELEASE_INTERVAL)
+ {
+ lock_mutex_exit();
+ count= 0;
+ lock_mutex_enter();
+ }
+
+ lock= UT_LIST_GET_LAST(trx->lock.trx_locks);
+ }
+
+ lock_mutex_exit();
+}
+
/* True if a lock mode is S or X */
#define IS_LOCK_S_OR_X(lock) \
(lock_get_mode(lock) == LOCK_S \
diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc
index cf8fa17cf1a..3cb9ab5f320 100644
--- a/storage/innobase/trx/trx0trx.cc
+++ b/storage/innobase/trx/trx0trx.cc
@@ -1971,6 +1971,11 @@ trx_prepare(
We must not be holding any mutexes or latches here. */
trx_flush_log_if_needed(lsn, trx);
+
+ if (UT_LIST_GET_LEN(trx->lock.trx_locks)
+ && trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
+ lock_release_on_prepare(trx);
+ }
}
}