Commit 4a5be2e9 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-22495 Assertion ...status != buf_page_t::FREED in ibuf_read_merge_pages()

ibuf_read_merge_pages(): Request a possibly freed page.
The change buffer is discarded lazily for freed pages either
by this function or when buf_page_create() reuses a page.

buf_page_get_low(): Relax a debug assertion.
Do not attempt change buffer merge on freed pages.

ibuf_merge_or_delete_for_page(): Assert that the page state is NORMAL.
INIT_ON_FLUSH is not possible, because in that case buf_page_create()
should have removed any buffered changes for the page.

buf_page_get_gen(): Apply buffered changes also in the case when
we can avoid reading the page based on buffered redo log records.
This addresses a hard-to-reproduce scenario that was broken in
commit 6697135c.
parent 18a62eb7
......@@ -3298,6 +3298,7 @@ buf_page_get_low(
|| (rw_latch == RW_NO_LATCH));
ut_ad(!allow_ibuf_merge
|| mode == BUF_GET
|| mode == BUF_GET_POSSIBLY_FREED
|| mode == BUF_GET_IF_IN_POOL
|| mode == BUF_GET_IF_IN_POOL_OR_WATCH);
......@@ -3907,7 +3908,8 @@ buf_page_get_low(
return NULL;
}
if (allow_ibuf_merge
if (fix_block->page.status != buf_page_t::FREED
&& allow_ibuf_merge
&& fil_page_get_type(fix_block->frame) == FIL_PAGE_INDEX
&& page_is_leaf(fix_block->frame)) {
rw_lock_x_lock_inline(&fix_block->lock, 0, file, line);
......@@ -3974,9 +3976,27 @@ buf_page_get_gen(
{
block->fix();
ut_ad(rw_lock_s_lock_nowait(block->debug_latch, file, line));
block= buf_page_mtr_lock(block, rw_latch, mtr, file, line);
if (err)
*err= DB_SUCCESS;
const bool must_merge= allow_ibuf_merge &&
ibuf_page_exists(page_id, block->zip_size());
if (block->page.status == buf_page_t::FREED)
ut_ad(mode == BUF_GET_POSSIBLY_FREED || mode == BUF_PEEK_IF_IN_POOL);
else if (must_merge && fil_page_get_type(block->frame) == FIL_PAGE_INDEX &&
page_is_leaf(block->frame))
{
rw_lock_x_lock_inline(&block->lock, 0, file, line);
block->page.ibuf_exist= false;
ibuf_merge_or_delete_for_page(block, page_id, block->zip_size(), true);
if (rw_latch == RW_X_LATCH)
{
mtr->memo_push(block, MTR_MEMO_PAGE_X_FIX);
return block;
}
rw_lock_x_unlock(&block->lock);
}
block= buf_page_mtr_lock(block, rw_latch, mtr, file, line);
return block;
}
......
......@@ -2325,8 +2325,8 @@ static void ibuf_read_merge_pages(const ulint* space_ids,
mtr.start();
dberr_t err;
buf_page_get_gen(page_id_t(space_id, page_nos[i]),
zip_size,
RW_X_LATCH, NULL, BUF_GET,
zip_size, RW_X_LATCH, nullptr,
BUF_GET_POSSIBLY_FREED,
__FILE__, __LINE__, &mtr, &err, true);
mtr.commit();
if (err == DB_TABLESPACE_DELETED) {
......@@ -4221,8 +4221,9 @@ ibuf_merge_or_delete_for_page(
ulint mops[IBUF_OP_COUNT];
ulint dops[IBUF_OP_COUNT];
ut_ad(block == NULL || page_id == block->page.id);
ut_ad(!block || page_id == block->page.id);
ut_ad(!block || buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
ut_ad(!block || block->page.status == buf_page_t::NORMAL);
if (trx_sys_hdr_page(page_id)
|| fsp_is_system_temporary(page_id.space())) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment