Description:
When we run our program on the MySQL 8.0.22, the database report the assertion failure and restart. Here is the error log info.
2025-04-24T11:20:44.332531+08:00 48726389 140591358375680 [ERROR] [MY-013183] [InnoDB] Assertion failure: btr0cur.cc:311:page_is_comp(get_block->frame) == page_is_comp(page) thread 140591358375680
InnoDB: We intentionally generate a memory trap.
InnoDB: Submit a detailed bug report to http://bugs.mysql.com.
InnoDB: If you get repeated assertion failures or crashes, even
InnoDB: immediately after the mysqld startup, there may be
InnoDB: corruption in the InnoDB tablespace. Please refer to
InnoDB: http://dev.mysql.com/doc/refman/8.0/en/forcing-innodb-recovery.html
InnoDB: about forcing recovery.
error, set config faild while getting storage gid.
03:20:44 UTC - mysqld got signal 6 ;
Most likely, you have hit a bug, but this error can also be caused by malfunctioning hardware.
Thread pointer: 0x7fde692b8000
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
stack_bottom = 7fddf9f943f0 thread_stack 0x46000
/usr/local/engine/bin/mysqld(my_print_stacktrace(unsigned char const*, unsigned long)+0x2e) [0x214569e]
/usr/local/engine/bin/mysqld(handle_fatal_signal+0x208) [0x13cbc98]
/lib64/libpthread.so.0(+0xf700) [0x7fe0f9a9f700]
/lib64/libc.so.6(gsignal+0x37) [0x7fe0f6a314e7]
/lib64/libc.so.6(abort+0x148) [0x7fe0f6a32bd8]
/usr/local/engine/bin/mysqld(ut_dbg_assertion_failed(char const*, char const*, unsigned long)+0x1c7) [0x240d627]
/usr/local/engine/bin/mysqld() [0x6d4bb4c]
/usr/local/engine/bin/mysqld(btr_cur_search_to_nth_level(dict_index_t*, unsigned long, dtuple_t const*, page_cur_mode_t, unsigned long, btr_cur_t*, unsigned long, char const*, unsigned long, mtr_t*, btr_ndp_t*)+0x1d9c) [0x661305c]
/usr/local/engine/bin/mysqld() [0x676fc75]
/usr/local/engine/bin/mysqld(btr_pcur_t::restore_position(unsigned long, mtr_t*, char const*, unsigned long)+0x2f6) [0x6608794]
/usr/local/engine/bin/mysqld(btr_pcur_t::move_backward_from_page(mtr_t*)+0x122) [0x24552e2]
/usr/local/engine/bin/mysqld() [0x6db21b0]
/usr/local/engine/bin/mysqld(row_search_mvcc(unsigned char*, page_cur_mode_t, row_prebuilt_t*, unsigned long, unsigned long)+0xb75) [0x660e3c5]
/usr/local/engine/bin/mysqld(ha_innobase::general_fetch(unsigned char*, unsigned int, unsigned int)+0xac) [0x660d6c4]
/usr/local/engine/bin/mysqld(handler::ha_index_prev(unsigned char*)+0x19d) [0x147c56d]
/usr/local/engine/bin/mysqld(IndexScanIterator<true>::Read()+0x55) [0x1232b95]
/usr/local/engine/bin/mysqld(FilterIterator::Read()+0x43d) [0x660d0fd]
/usr/local/engine/bin/mysqld(LimitOffsetIterator::Read()+0x20) [0x674ad7a]
/usr/local/engine/bin/mysqld(SELECT_LEX_UNIT::ExecuteIteratorQuery(THD*)+0xe2f) [0x6626d2f]
/usr/local/engine/bin/mysqld(Sql_cmd_dml::execute(THD*)+0x35e) [0x667629e]
/usr/local/engine/bin/mysqld(mysql_execute_command(THD*, bool)+0x6cf) [0x66cbbcf]
/usr/local/engine/bin/mysqld(mysql_parse(THD*, Parser_state*, bool)+0x75a) [0x663cef2]
/usr/local/engine/bin/mysqld(dispatch_command(THD*, COM_DATA const*, enum_server_command)+0x76c) [0x676252c]
/usr/local/engine/bin/mysqld(do_command(THD*)+0x2dd) [0x676111d]
/usr/local/engine/bin/mysqld() [0x676024a]
/usr/local/engine/bin/mysqld() [0x68921df]
/lib64/libpthread.so.0(+0x7e15) [0x7fe0f9a97e15]
/lib64/libc.so.6(clone+0x6d) [0x7fe0f6afcfed]
Trying to get some variables.
Some pointers may be invalid and cause the dump to abort.
Query (7fde8d8f4828): SELECT id FROM RecordContraction07 WHERE user_id=120761197 ORDER BY id DESC LIMIT 1
Connection ID (thread ID): 48726389
Status: NOT_KILLED
The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains
information that should help you find out what is causing the crash.
https://bugs.mysql.com/bug.php?id=75124 report an similar bugs and this commit https://github.com/mysql/mysql-server/commit/777bf2aab05fb58fad7838aed4ef307b50722786 seem to fix it in 5.7. However,it only fixs the case BTR_MODIFY_TREE case
if (latch_leaves.blocks[0] != nullptr) {
ut_a(page_is_comp(latch_leaves.blocks[0]->frame) == page_is_comp(page));
ut_a(btr_page_get_next(latch_leaves.blocks[0]->frame, mtr) ==
page_get_page_no(page));
}
In the BTR_MODIFY_PREV case, it still use the original code
ut_a(page_is_comp(get_block->frame) == page_is_comp(page));
ut_a(btr_page_get_next(get_block->frame, mtr) ==
page_get_page_no(page));
How to repeat:
When I enter the same SQL, it does not crash. We dont have the test case to repeat it.
Suggested fix:
I am not sure in which situation the get_block will be 0x00. Is it correct to use the code BTR_MODIFY_TREE in the BTR_MODIFY_PREV case