Details
-
Bug
-
Status: Closed (View Workflow)
-
Major
-
Resolution: Fixed
-
10.5.5, 10.6, 10.7(EOL), 10.8(EOL)
Description
mleich found a race condition between buffer pool resizing and an update of the adaptive hash index, while testing MDEV-14425.
==3752116==ERROR: AddressSanitizer: heap-use-after-free on address 0x61d00000d300 at pc 0x5588ff9718a7 bp 0x5038216570b0 sp 0x5038216570a0
|
READ of size 8 at 0x61d00000d300 thread T26
|
#0 0x5588ff9718a6 in buf_pool_t::is_block_field(void const*) const /data/Server/preview-10.8-MDEV-14425-innodbF/storage/innobase/include/buf0buf.h:1308
|
#1 0x5588ff97190a in buf_pool_t::is_uncompressed(buf_block_t const*) const /data/Server/preview-10.8-MDEV-14425-innodbF/storage/innobase/include/buf0buf.h:1449
|
#2 0x5588ffcd648f in btr_search_update_block_hash_info /data/Server/preview-10.8-MDEV-14425-innodbF/storage/innobase/btr/btr0sea.cc:415
|
The function is being called as part of a debug assertion there, so this particular failure only affects debug builds. The culprit (found by setting a hardware watchpoint on the AddressSanitizer reported poison byte and executing reverse-continue in rr) is buffer pool resizing:
Thread 50 (Thread 3752116.3794577):
|
#0 __memset_avx2_unaligned_erms () at ../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S:200
|
#1 0x00007ff70bf479d9 in ?? () from /lib/x86_64-linux-gnu/libasan.so.5
|
#2 0x00007ff70c028799 in free () from /lib/x86_64-linux-gnu/libasan.so.5
|
#3 0x00005588ffd17b0b in buf_pool_t::resize (this=0x558901d978c0 <buf_pool>) at /data/Server/preview-10.8-MDEV-14425-innodbF/storage/innobase/buf/buf0buf.cc:1894
|
#4 0x00005588ffcf9ab8 in buf_resize_callback () at /data/Server/preview-10.8-MDEV-14425-innodbF/storage/innobase/buf/buf0buf.cc:1989
|
During the time of this, the thread that is going to fail is already executing that function:
Thread 3 (Thread 3752116.3757608):
|
#0 0x00005588ff971864 in buf_pool_t::is_block_field (this=0x558901d978c0 <buf_pool>, ptr=0x304715439930) at /data/Server/preview-10.8-MDEV-14425-innodbF/storage/innobase/include/buf0buf.h:1307
|
#1 0x00005588ff97190b in buf_pool_t::is_uncompressed (this=0x558901d978c0 <buf_pool>, block=0x304715439930) at /data/Server/preview-10.8-MDEV-14425-innodbF/storage/innobase/include/buf0buf.h:1449
|
#2 0x00005588ffcd6490 in btr_search_update_block_hash_info (info=0x61a000553a68, block=0x304715439930) at /data/Server/preview-10.8-MDEV-14425-innodbF/storage/innobase/btr/btr0sea.cc:415
|
Most invocations of buf_pool_t::is_uncompressed() are in debug assertions, and this faulty debug assertion was introduced in 10.6.
MDEV-27058 in 10.6 would allow the buf_pool.is_uncompressed(block) assertions to be rewritten simply as block->page.frame. That would be a null pointer for blocks of ROW_FORMAT=COMPRESSED tables whose uncompressed page frame has been discarded.
The calls to buf_pool.is_uncompressed() outside assertions seem to be protected correctly by buf_pool.page_hash latch. Those are in Block_hint::buffer_fix_block_if_still_valid() and buf_page_get_low().
The failing debug assertion was added in MDEV-27058.
A similar assertion had been added to mtr_t::modify() already in MDEV-22110 (MariaDB Server 10.5.5). That one is best removed.
This bug only affects debug builds during buffer pool resizing, possibly only when running with ASAN.
Attachments
Issue Links
- is caused by
-
MDEV-22110 InnoDB unnecessarily writes unmodified pages
- Closed
-
MDEV-27058 Buffer page descriptors are too large
- Closed
- relates to
-
MDEV-23158 False negatives from buf_pool.is_uncompressed() cause unnecessary lookups
- Closed