@@ -369,19 +369,6 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr)
369369undo = NULL ;
370370}
371371
372- MY_ATTRIBUTE ((nonnull, warn_unused_result))
373- /* * Remove undo log header from the history list.
374- @param[in,out] rseg rollback segment header page
375- @param[in] log undo log segment header page
376- @param[in] offset byte offset in the undo log segment header page
377- @param[in,out] mtr mini-transaction */
378- static dberr_t trx_purge_remove_log_hdr(buf_block_t *rseg, buf_block_t * log,
379- uint16_t offset, mtr_t *mtr)
380- {
381- return flst_remove (rseg, TRX_RSEG + TRX_RSEG_HISTORY, log,
382- uint16_t (offset + TRX_UNDO_HISTORY_NODE), mtr);
383- }
384-
385372/* * Free an undo log segment.
386373@param block rollback segment header page
387374@param mtr mini-transaction */
@@ -391,7 +378,7 @@ static void trx_purge_free_segment(buf_block_t *block, mtr_t &mtr)
391378 block->page .frame , &mtr))
392379 {
393380 block->fix ();
394- const page_id_t id{block->page .id ()};
381+ ut_d ( const page_id_t id{block->page .id ()}) ;
395382 mtr.commit ();
396383 /* NOTE: If the server is killed after the log that was produced
397384 up to this point was written, and before the log from the mtr.commit()
@@ -403,29 +390,22 @@ static void trx_purge_free_segment(buf_block_t *block, mtr_t &mtr)
403390 log_free_check ();
404391 mtr.start ();
405392 block->page .lock .x_lock ();
406- if (UNIV_UNLIKELY (block->page .id () != id))
407- {
408- block->unfix ();
409- block->page .lock .x_unlock ();
410- block= buf_page_get_gen (id, 0 , RW_X_LATCH, nullptr , BUF_GET, &mtr);
411- if (!block)
412- return ;
413- }
414- else
415- mtr.memo_push (block, MTR_MEMO_PAGE_X_MODIFY);
393+ ut_ad (block->page .id () == id);
394+ mtr.memo_push (block, MTR_MEMO_PAGE_X_MODIFY);
416395 }
417396
418397 while (!fseg_free_step (TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER +
419398 block->page .frame , &mtr));
420399}
421400
422401/* * Remove unnecessary history data from a rollback segment.
423- @param[in,out] rseg rollback segment
424- @param[in] limit truncate anything before this
402+ @param rseg rollback segment
403+ @param limit truncate anything before this
404+ @param all whether everything can be truncated
425405@return error code */
426406static dberr_t
427- trx_purge_truncate_rseg_history (trx_rseg_t & rseg,
428- const purge_sys_t ::iterator& limit)
407+ trx_purge_truncate_rseg_history (trx_rseg_t & rseg,
408+ const purge_sys_t ::iterator & limit, bool all )
429409{
430410 fil_addr_t hdr_addr;
431411 mtr_t mtr;
@@ -434,7 +414,6 @@ trx_purge_truncate_rseg_history(trx_rseg_t& rseg,
434414 mtr.start ();
435415
436416 dberr_t err;
437- reget:
438417 buf_block_t *rseg_hdr= rseg.get (&mtr, &err);
439418 if (!rseg_hdr)
440419 {
@@ -469,23 +448,24 @@ trx_purge_truncate_rseg_history(trx_rseg_t& rseg,
469448 goto func_exit;
470449 }
471450
451+ if (!all)
452+ goto func_exit;
453+
472454 fil_addr_t prev_hdr_addr=
473455 flst_get_prev_addr (b->page .frame + hdr_addr.boffset +
474456 TRX_UNDO_HISTORY_NODE);
475457 prev_hdr_addr.boffset = static_cast <uint16_t >(prev_hdr_addr.boffset -
476458 TRX_UNDO_HISTORY_NODE);
477- err= trx_purge_remove_log_hdr (rseg_hdr, b, hdr_addr.boffset , &mtr);
459+
460+ err= flst_remove (rseg_hdr, TRX_RSEG + TRX_RSEG_HISTORY, b,
461+ uint16_t (hdr_addr.boffset + TRX_UNDO_HISTORY_NODE), &mtr);
478462 if (UNIV_UNLIKELY (err != DB_SUCCESS))
479463 goto func_exit;
480464
481465 rseg_hdr->fix ();
482466
483- if (mach_read_from_2 (b->page .frame + hdr_addr.boffset + TRX_UNDO_NEXT_LOG) ||
484- rseg.is_referenced () ||
485- rseg.needs_purge > (purge_sys.head .trx_no
486- ? purge_sys.head .trx_no
487- : purge_sys.tail .trx_no ))
488- /* We cannot free the entire undo page. */ ;
467+ if (mach_read_from_2 (b->page .frame + hdr_addr.boffset + TRX_UNDO_NEXT_LOG))
468+ /* We cannot free the entire undo log segment. */ ;
489469 else
490470 {
491471 const uint32_t seg_size=
@@ -535,12 +515,7 @@ trx_purge_truncate_rseg_history(trx_rseg_t& rseg,
535515 log_free_check ();
536516 mtr.start ();
537517 rseg_hdr->page .lock .x_lock ();
538- if (UNIV_UNLIKELY (rseg_hdr->page .id () != rseg.page_id ()))
539- {
540- rseg_hdr->unfix ();
541- rseg_hdr->page .lock .x_unlock ();
542- goto reget;
543- }
518+ ut_ad (rseg_hdr->page .id () == rseg.page_id ());
544519 mtr.memo_push (rseg_hdr, MTR_MEMO_PAGE_X_MODIFY);
545520
546521 goto loop;
@@ -613,7 +588,10 @@ TRANSACTIONAL_TARGET static void trx_purge_truncate_history()
613588 {
614589 ut_ad (rseg.is_persistent ());
615590 rseg.latch .wr_lock (SRW_LOCK_CALL);
616- if (dberr_t e= trx_purge_truncate_rseg_history (rseg, head))
591+ if (dberr_t e=
592+ trx_purge_truncate_rseg_history (rseg, head,
593+ !rseg.is_referenced () &&
594+ rseg.needs_purge <= head.trx_no ))
617595 err= e;
618596 rseg.latch .wr_unlock ();
619597 }
0 commit comments