/********************************************************************//** Adds the update undo log as the first log in the history list. Removes the update undo log segment from the rseg slot if it is too big for reuse. */ UNIV_INTERN void trx_purge_add_update_undo_to_history( /*=================================*/ trx_t* trx, /*!< in: transaction */ page_t* undo_page, /*!< in: update undo log header page, x-latched */ mtr_t* mtr) /*!< in: mtr */ { trx_undo_t* undo; trx_rsegf_t* rseg_header; trx_ulogf_t* undo_header; undo = trx->update_undo; ut_ad(undo); ut_ad(mutex_own(&undo->rseg->mutex)); rseg_header = trx_rsegf_get( undo->rseg->space, undo->rseg->zip_size, undo->rseg->page_no, mtr); undo_header = undo_page + undo->hdr_offset; /* Add the log as the first in the history list */ if (undo->state != TRX_UNDO_CACHED) { ulint hist_size; #ifdef UNIV_DEBUG trx_usegf_t* seg_header = undo_page + TRX_UNDO_SEG_HDR; #endif /* UNIV_DEBUG */ /* The undo log segment will not be reused */ if (UNIV_UNLIKELY(undo->id >= TRX_RSEG_N_SLOTS)) { fprintf(stderr, "InnoDB: Error: undo->id is %lu\n", (ulong) undo->id); ut_error; } trx_rsegf_set_nth_undo(rseg_header, undo->id, FIL_NULL, mtr); hist_size = mtr_read_ulint( rseg_header + TRX_RSEG_HISTORY_SIZE, MLOG_4BYTES, mtr); ut_ad(undo->size == flst_get_len( seg_header + TRX_UNDO_PAGE_LIST, mtr)); mlog_write_ulint( rseg_header + TRX_RSEG_HISTORY_SIZE, hist_size + undo->size, MLOG_4BYTES, mtr); } flst_add_first( rseg_header + TRX_RSEG_HISTORY, undo_header + TRX_UNDO_HISTORY_NODE, mtr); /* Write the trx number to the undo log header */ mlog_write_ull(undo_header + TRX_UNDO_TRX_NO, trx->no, mtr); /* Write information about delete markings to the undo log header */ if (!undo->del_marks) { mlog_write_ulint( undo_header + TRX_UNDO_DEL_MARKS, FALSE, MLOG_2BYTES, mtr); } if (undo->rseg->last_page_no == FIL_NULL) { undo->rseg->last_trx_no = trx->no; undo->rseg->last_offset = undo->hdr_offset; undo->rseg->last_page_no = undo->hdr_page_no; undo->rseg->last_del_marks = undo->del_marks; /* FIXME: Add a bin heap validate function to check that the rseg exists. */ } mutex_enter(&kernel_mutex); trx_sys->rseg_history_len++; mutex_exit(&kernel_mutex); // if (!(trx_sys->rseg_history_len % srv_purge_batch_size)) { /*should wake up always*/ /* Inform the purge thread that there is work to do. */ srv_wake_purge_thread_if_not_active(); // } }
/********************************************************************//** Adds the update undo log as the first log in the history list. Removes the update undo log segment from the rseg slot if it is too big for reuse. */ UNIV_INTERN void trx_purge_add_update_undo_to_history( /*=================================*/ trx_t* trx, /*!< in: transaction */ page_t* undo_page, /*!< in: update undo log header page, x-latched */ mtr_t* mtr) /*!< in: mtr */ { trx_undo_t* undo; trx_rseg_t* rseg; trx_rsegf_t* rseg_header; #ifdef UNIV_DEBUG trx_usegf_t* seg_header; #endif /* UNIV_DEBUG */ trx_ulogf_t* undo_header; ulint hist_size; undo = trx->update_undo; ut_ad(undo); rseg = undo->rseg; ut_ad(mutex_own(&(rseg->mutex))); rseg_header = trx_rsegf_get(rseg->space, rseg->zip_size, rseg->page_no, mtr); undo_header = undo_page + undo->hdr_offset; #ifdef UNIV_DEBUG seg_header = undo_page + TRX_UNDO_SEG_HDR; #endif /* UNIV_DEBUG */ if (undo->state != TRX_UNDO_CACHED) { /* The undo log segment will not be reused */ if (undo->id >= TRX_RSEG_N_SLOTS) { fprintf(stderr, "InnoDB: Error: undo->id is %lu\n", (ulong) undo->id); ut_error; } trx_rsegf_set_nth_undo(rseg_header, undo->id, FIL_NULL, mtr); hist_size = mtr_read_ulint(rseg_header + TRX_RSEG_HISTORY_SIZE, MLOG_4BYTES, mtr); ut_ad(undo->size == flst_get_len( seg_header + TRX_UNDO_PAGE_LIST, mtr)); mlog_write_ulint(rseg_header + TRX_RSEG_HISTORY_SIZE, hist_size + undo->size, MLOG_4BYTES, mtr); } /* Add the log as the first in the history list */ flst_add_first(rseg_header + TRX_RSEG_HISTORY, undo_header + TRX_UNDO_HISTORY_NODE, mtr); mutex_enter(&kernel_mutex); trx_sys->rseg_history_len++; mutex_exit(&kernel_mutex); /* Write the trx number to the undo log header */ mlog_write_dulint(undo_header + TRX_UNDO_TRX_NO, trx->no, mtr); /* Write information about delete markings to the undo log header */ if (!undo->del_marks) { mlog_write_ulint(undo_header + TRX_UNDO_DEL_MARKS, FALSE, MLOG_2BYTES, mtr); } if (rseg->last_page_no == FIL_NULL) { rseg->last_page_no = undo->hdr_page_no; rseg->last_offset = undo->hdr_offset; rseg->last_trx_no = trx->no; rseg->last_del_marks = undo->del_marks; } }