summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorVlad Lesin <vlad_lesin@mail.ru>2022-04-14 14:27:23 +0300
committerVlad Lesin <vlad_lesin@mail.ru>2022-05-04 12:51:28 +0300
commit2c381d8cf65ad46936045fb7ee141de4e392cde7 (patch)
tree774d5f66af4af7bfd130670080d43d8cd698e7f0 /storage
parent9614fde1aac6ffa4745804342ff70a96b2418e30 (diff)
downloadmariadb-git-2c381d8cf65ad46936045fb7ee141de4e392cde7.tar.gz
MDEV-17843 Assertion `page_rec_is_leaf(rec)' failed in lock_rec_queue_validate upon SHOW ENGINE INNODB STATUS
lock_validate() accumulates page ids under locked lock_sys->mutex, then releases the latch, and invokes lock_rec_block_validate() for each page. Some other thread has ability to add/remove locks and change pages between releasing the latch in lock_validate() and acquiring it in lock_rec_validate_page(). lock_rec_validate_page() can invoke lock_rec_queue_validate() for non-locked supremum, what can cause ut_ad(page_rec_is_leaf(rec)) failure in lock_rec_queue_validate(). The fix is to invoke lock_rec_queue_validate() only for locked records in lock_rec_validate_page(). The error message in lock_rec_block_validate() is not necessary as BUF_GET_POSSIBLY_FREED mode is used to get block from buffer pool, and this is not error if a block was evicted. The test case would require new debug sync point. I think it's not necessary as the fixed code is debug-only.
Diffstat (limited to 'storage')
-rw-r--r--storage/innobase/lock/lock0lock.cc27
1 files changed, 10 insertions, 17 deletions
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index 3398f09b772..2fd2ef94365 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -5050,25 +5050,25 @@ loop:
holding a space->latch. */
if (!sync_check_find(SYNC_FSP))
for (i = nth_bit; i < lock_rec_get_n_bits(lock); i++) {
-
- if (i == PAGE_HEAP_NO_SUPREMUM
- || lock_rec_get_nth_bit(lock, i)) {
+ bool locked = lock_rec_get_nth_bit(lock, i);
+ if (locked || i == PAGE_HEAP_NO_SUPREMUM) {
rec = page_find_rec_with_heap_no(block->frame, i);
ut_a(rec);
- ut_ad(!lock_rec_get_nth_bit(lock, i)
- || page_rec_is_leaf(rec));
- offsets = rec_get_offsets(rec, lock->index, offsets,
- lock->index->n_core_fields,
- ULINT_UNDEFINED, &heap);
+ ut_ad(!locked || page_rec_is_leaf(rec));
/* If this thread is holding the file space
latch (fil_space_t::latch), the following
check WILL break the latching order and may
cause a deadlock of threads. */
- lock_rec_queue_validate(
- TRUE, block, rec, lock->index, offsets);
+ if (locked) {
+ offsets = rec_get_offsets(rec, lock->index,
+ offsets, lock->index->n_core_fields,
+ ULINT_UNDEFINED, &heap);
+ lock_rec_queue_validate(TRUE, block, rec,
+ lock->index, offsets);
+ }
nth_bit = i + 1;
@@ -5161,13 +5161,6 @@ lock_rec_block_validate(
BUF_GET_POSSIBLY_FREED,
__FILE__, __LINE__, &mtr, &err);
- if (err != DB_SUCCESS) {
- ib::error() << "Lock rec block validate failed for tablespace "
- << space->name
- << " space_id " << space_id
- << " page_no " << page_no << " err " << err;
- }
-
if (block) {
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);