diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc index 4a98dee573e..b06e3cb3e1b 100644 --- a/storage/innobase/trx/trx0purge.cc +++ b/storage/innobase/trx/trx0purge.cc @@ -365,8 +365,10 @@ void trx_purge_free_segment(mtr_t &mtr, trx_rseg_t* rseg, fil_addr_t hdr_addr) while (!fseg_free_step_not_header(TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER + block->frame, &mtr)) { - block->fix(); - const page_id_t id{block->page.id()}; + buf_block_buf_fix_inc(rseg_hdr, __FILE__, __LINE__); + buf_block_buf_fix_inc(block, __FILE__, __LINE__); + ut_d(const page_id_t rseg_hdr_id{rseg_hdr->page.id()}); + ut_d(const page_id_t id{block->page.id()}); mtr.commit(); /* NOTE: If the server is killed after the log that was produced up to this point was written, and before the log from the mtr.commit() @@ -376,19 +378,12 @@ void trx_purge_free_segment(mtr_t &mtr, trx_rseg_t* rseg, fil_addr_t hdr_addr) This does not matter when using multiple innodb_undo_tablespaces; innodb_undo_log_truncate=ON will be able to reclaim the space. */ mtr.start(); - ut_ad(rw_lock_s_lock_nowait(block->debug_latch, __FILE__, __LINE__)); + rw_lock_x_lock(&rseg_hdr->lock); rw_lock_x_lock(&block->lock); - if (UNIV_UNLIKELY(block->page.id() != id)) - { - block->unfix(); - rw_lock_x_unlock(&block->lock); - ut_d(rw_lock_s_unlock(block->debug_latch)); - block= buf_page_get(id, 0, RW_X_LATCH, &mtr); - if (!block) - return; - } - else - mtr_memo_push(&mtr, block, MTR_MEMO_PAGE_X_FIX); + ut_ad(rseg_hdr->page.id() == rseg_hdr_id); + ut_ad(block->page.id() == id); + mtr_memo_push(&mtr, rseg_hdr, MTR_MEMO_PAGE_X_FIX); + mtr_memo_push(&mtr, block, MTR_MEMO_PAGE_X_FIX); } while (!fseg_free_step(TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER +