Skip to content

Commit 2c381d8

Browse files
committed
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.
1 parent 9614fde commit 2c381d8

File tree

1 file changed

+10
-17
lines changed

1 file changed

+10
-17
lines changed

storage/innobase/lock/lock0lock.cc

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5050,25 +5050,25 @@ lock_rec_validate_page(
50505050
holding a space->latch. */
50515051
if (!sync_check_find(SYNC_FSP))
50525052
for (i = nth_bit; i < lock_rec_get_n_bits(lock); i++) {
5053-
5054-
if (i == PAGE_HEAP_NO_SUPREMUM
5055-
|| lock_rec_get_nth_bit(lock, i)) {
5053+
bool locked = lock_rec_get_nth_bit(lock, i);
5054+
if (locked || i == PAGE_HEAP_NO_SUPREMUM) {
50565055

50575056
rec = page_find_rec_with_heap_no(block->frame, i);
50585057
ut_a(rec);
5059-
ut_ad(!lock_rec_get_nth_bit(lock, i)
5060-
|| page_rec_is_leaf(rec));
5061-
offsets = rec_get_offsets(rec, lock->index, offsets,
5062-
lock->index->n_core_fields,
5063-
ULINT_UNDEFINED, &heap);
5058+
ut_ad(!locked || page_rec_is_leaf(rec));
50645059

50655060
/* If this thread is holding the file space
50665061
latch (fil_space_t::latch), the following
50675062
check WILL break the latching order and may
50685063
cause a deadlock of threads. */
50695064

5070-
lock_rec_queue_validate(
5071-
TRUE, block, rec, lock->index, offsets);
5065+
if (locked) {
5066+
offsets = rec_get_offsets(rec, lock->index,
5067+
offsets, lock->index->n_core_fields,
5068+
ULINT_UNDEFINED, &heap);
5069+
lock_rec_queue_validate(TRUE, block, rec,
5070+
lock->index, offsets);
5071+
}
50725072

50735073
nth_bit = i + 1;
50745074

@@ -5161,13 +5161,6 @@ lock_rec_block_validate(
51615161
BUF_GET_POSSIBLY_FREED,
51625162
__FILE__, __LINE__, &mtr, &err);
51635163

5164-
if (err != DB_SUCCESS) {
5165-
ib::error() << "Lock rec block validate failed for tablespace "
5166-
<< space->name
5167-
<< " space_id " << space_id
5168-
<< " page_no " << page_no << " err " << err;
5169-
}
5170-
51715164
if (block) {
51725165
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
51735166

0 commit comments

Comments
 (0)