summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-10-06 22:35:43 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2020-10-06 22:35:43 +0300
commit1595189250e71d5902fc0f378b0e6b14c5b26901 (patch)
treee83837dba7f800a4200103dd03465984c14bf1aa
parent2b832151ad66556cb07ed232b139411f4b6defe3 (diff)
downloadmariadb-git-1595189250e71d5902fc0f378b0e6b14c5b26901.tar.gz
MDEV-23897 SIGSEGV on commit with innodb_lock_schedule_algorithm=VATS
This regression for debug builds was introduced by MDEV-23101 (commit 224c950462a22e09f4e2e37d19218c9129bccba6). Due to MDEV-16664, the parameter innodb_lock_schedule_algorithm=VATS is not enabled by default. The purpose of the added assertions was to enforce the invariant that Galera replication cannot be enabled together with VATS due to MDEV-12837. However, upon closer inspection, it is obvious that the variable 'lock' may be assigned to the null pointer if no match is found in the previous->hash list. lock_grant_and_move_on_page(), lock_grant_and_move_on_rec(): Assert !lock->trx->is_wsrep() only after ensuring that lock is not a null pointer.
-rw-r--r--mysql-test/suite/innodb/t/update-cascade.combinations5
-rw-r--r--storage/innobase/lock/lock0lock.cc7
2 files changed, 8 insertions, 4 deletions
diff --git a/mysql-test/suite/innodb/t/update-cascade.combinations b/mysql-test/suite/innodb/t/update-cascade.combinations
new file mode 100644
index 00000000000..8fb4862675b
--- /dev/null
+++ b/mysql-test/suite/innodb/t/update-cascade.combinations
@@ -0,0 +1,5 @@
+[FCFS]
+--innodb-lock-schedule-algorithm=FCFS
+
+[VATS]
+--innodb-lock-schedule-algorithm=VATS
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index e48ac6bcc92..913c80027bf 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -2306,12 +2306,12 @@ lock_grant_and_move_on_page(ulint rec_fold, ulint space, ulint page_no)
lock = previous->hash;
}
- ut_ad(!lock->trx->is_wsrep());
ut_ad(previous->hash == lock || previous == lock);
/* Grant locks if there are no conflicting locks ahead.
Move granted locks to the head of the list. */
while (lock) {
/* If the lock is a wait lock on this page, and it does not need to wait. */
+ ut_ad(!lock->trx->is_wsrep());
if (lock_get_wait(lock)
&& lock->un_member.rec_lock.space == space
&& lock->un_member.rec_lock.page_no == page_no
@@ -4211,11 +4211,10 @@ lock_grant_and_move_on_rec(
}
lock = previous->hash;
}
- ut_ad(!lock->trx->is_wsrep());
/* Grant locks if there are no conflicting locks ahead.
Move granted locks to the head of the list. */
- for (;lock != NULL;) {
-
+ while (lock) {
+ ut_ad(!lock->trx->is_wsrep());
/* If the lock is a wait lock on this page, and it does not need to wait. */
if (lock->un_member.rec_lock.space == space
&& lock->un_member.rec_lock.page_no == page_no