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 6697135c6d03935118c3dfa1c97faea7fa76afa6.
This commit is contained in:
parent
18a62eb76d
commit
4a5be2e94e
@ -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 @@ evict_from_pool:
|
||||
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 @@ tablespace_deleted:
|
||||
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())) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user