summaryrefslogtreecommitdiff
path: root/sql/wsrep_mysqld.cc
diff options
context:
space:
mode:
authorJan Lindström <jan.lindstrom@mariadb.com>2021-03-03 12:14:23 +0200
committerJan Lindström <jan.lindstrom@mariadb.com>2021-03-30 08:58:10 +0300
commitd217a925b267727936bd0a08dce1863ab6d1ed19 (patch)
tree1cd2d1a00faf051cfc7f51f1f2cc1b06b3f40ac0 /sql/wsrep_mysqld.cc
parentc44273329ed7292e2fdd4039aa4ad20035583f89 (diff)
downloadmariadb-git-d217a925b267727936bd0a08dce1863ab6d1ed19.tar.gz
MDEV-24923 : Port selected Galera conflict resolution changes from 10.6
Add condition on trx->state == TRX_STATE_COMMITTED_IN_MEMORY in order to avoid unnecessary work. If a transaction has already been committed or rolled back, it will release its locks in lock_release() and let the waiting thread(s) continue execution. Let BF wait on lock_rec_has_to_wait and if necessary other BF is replayed. wsrep_trx_order_before If BF is not even replicated yet then they are ordered correctly. bg_wsrep_kill_trx Make sure victim_trx is found and check also its state. If state is TRX_STATE_COMMITTED_IN_MEMORY transaction is already committed or rolled back and will release it locks soon. wsrep_assert_no_bf_bf_wait Transaction requesting new record lock should be TRX_STATE_ACTIVE Conflicting transaction can be in states TRX_STATE_ACTIVE, TRX_STATE_COMMITTED_IN_MEMORY or in TRX_STATE_PREPARED. If conflicting transaction is already committed in memory or prepared we should wait. When transaction is committed in memory we held trx mutex, but not lock_sys->mutex. Therefore, we could end here before transaction has time to do lock_release() that is protected with lock_sys->mutex. lock_rec_has_to_wait 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. wsrep_kill_victim Check is victim already in TRX_STATE_COMMITTED_IN_MEMORY state and if it is we can return. lock_rec_dequeue_from_page lock_rec_unlock Remove unnecessary wsrep_assert_no_bf_bf_wait function calls. We can very well let BF wait here.
Diffstat (limited to 'sql/wsrep_mysqld.cc')
-rw-r--r--sql/wsrep_mysqld.cc22
1 files changed, 12 insertions, 10 deletions
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index c033f7e1464..f22d8bf0f5a 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -2788,16 +2788,18 @@ extern "C" bool wsrep_thd_ignore_table(THD *thd)
extern int
wsrep_trx_order_before(THD *thd1, THD *thd2)
{
- if (wsrep_thd_trx_seqno(thd1) < wsrep_thd_trx_seqno(thd2)) {
- WSREP_DEBUG("BF conflict, order: %lld %lld\n",
- (long long)wsrep_thd_trx_seqno(thd1),
- (long long)wsrep_thd_trx_seqno(thd2));
- return 1;
- }
- WSREP_DEBUG("waiting for BF, trx order: %lld %lld\n",
- (long long)wsrep_thd_trx_seqno(thd1),
- (long long)wsrep_thd_trx_seqno(thd2));
- return 0;
+ const longlong trx1_seqno= wsrep_thd_trx_seqno(thd1);
+ const longlong trx2_seqno= wsrep_thd_trx_seqno(thd2);
+ WSREP_DEBUG("BF conflict, order: %lld %lld\n",
+ trx1_seqno, trx2_seqno);
+
+ if (trx1_seqno == WSREP_SEQNO_UNDEFINED ||
+ trx2_seqno == WSREP_SEQNO_UNDEFINED)
+ return 1; /* trx is not yet replicated */
+ else if (trx1_seqno < trx2_seqno)
+ return 1;
+
+ return 0;
}