📄 trx0undo.c
字号:
mlog_catenate_dulint_compressed(mtr, trx_id);} /*******************************************************************Creates a new undo log header in file. NOTE that this function has its ownlog record type MLOG_UNDO_HDR_CREATE. You must NOT change the operation ofthis function! */staticulinttrx_undo_header_create(/*===================*/ /* out: header byte offset on page */ page_t* undo_page, /* in: undo log segment header page, x-latched; it is assumed that there are TRX_UNDO_LOG_XA_HDR_SIZE bytes free space on it */ dulint trx_id, /* in: transaction id */ mtr_t* mtr) /* in: mtr */{ trx_upagef_t* page_hdr; trx_usegf_t* seg_hdr; trx_ulogf_t* log_hdr; trx_ulogf_t* prev_log_hdr; ulint prev_log; ulint free; ulint new_free; ut_ad(mtr && undo_page); page_hdr = undo_page + TRX_UNDO_PAGE_HDR; seg_hdr = undo_page + TRX_UNDO_SEG_HDR; free = mach_read_from_2(page_hdr + TRX_UNDO_PAGE_FREE); log_hdr = undo_page + free; new_free = free + TRX_UNDO_LOG_OLD_HDR_SIZE; ut_a(free + TRX_UNDO_LOG_XA_HDR_SIZE < UNIV_PAGE_SIZE - 100); mach_write_to_2(page_hdr + TRX_UNDO_PAGE_START, new_free); mach_write_to_2(page_hdr + TRX_UNDO_PAGE_FREE, new_free); mach_write_to_2(seg_hdr + TRX_UNDO_STATE, TRX_UNDO_ACTIVE); prev_log = mach_read_from_2(seg_hdr + TRX_UNDO_LAST_LOG); if (prev_log != 0) { prev_log_hdr = undo_page + prev_log; mach_write_to_2(prev_log_hdr + TRX_UNDO_NEXT_LOG, free); } mach_write_to_2(seg_hdr + TRX_UNDO_LAST_LOG, free); log_hdr = undo_page + free; mach_write_to_2(log_hdr + TRX_UNDO_DEL_MARKS, TRUE); mach_write_to_8(log_hdr + TRX_UNDO_TRX_ID, trx_id); mach_write_to_2(log_hdr + TRX_UNDO_LOG_START, new_free); mach_write_to_1(log_hdr + TRX_UNDO_XID_EXISTS, FALSE); mach_write_to_1(log_hdr + TRX_UNDO_DICT_TRANS, FALSE); mach_write_to_2(log_hdr + TRX_UNDO_NEXT_LOG, 0); mach_write_to_2(log_hdr + TRX_UNDO_PREV_LOG, prev_log); /* Write the log record about the header creation */ trx_undo_header_create_log(undo_page, trx_id, mtr); return(free);}/************************************************************************Write X/Open XA Transaction Identification (XID) to undo log header */staticvoidtrx_undo_write_xid(/*===============*/ trx_ulogf_t* log_hdr,/* in: undo log header */ const XID* xid, /* in: X/Open XA Transaction Identification */ mtr_t* mtr) /* in: mtr */{ mlog_write_ulint(log_hdr + TRX_UNDO_XA_FORMAT, (ulint)xid->formatID, MLOG_4BYTES, mtr); mlog_write_ulint(log_hdr + TRX_UNDO_XA_TRID_LEN, (ulint)xid->gtrid_length, MLOG_4BYTES, mtr); mlog_write_ulint(log_hdr + TRX_UNDO_XA_BQUAL_LEN, (ulint)xid->bqual_length, MLOG_4BYTES, mtr); mlog_write_string(log_hdr + TRX_UNDO_XA_XID, (const byte*) xid->data, XIDDATASIZE, mtr);}/************************************************************************Read X/Open XA Transaction Identification (XID) from undo log header */staticvoidtrx_undo_read_xid(/*==============*/ trx_ulogf_t* log_hdr,/* in: undo log header */ XID* xid) /* out: X/Open XA Transaction Identification */{ xid->formatID = (long)mach_read_from_4(log_hdr + TRX_UNDO_XA_FORMAT); xid->gtrid_length = (long)mach_read_from_4(log_hdr + TRX_UNDO_XA_TRID_LEN); xid->bqual_length = (long)mach_read_from_4(log_hdr + TRX_UNDO_XA_BQUAL_LEN); memcpy(xid->data, log_hdr + TRX_UNDO_XA_XID, XIDDATASIZE);}/*******************************************************************Adds space for the XA XID after an undo log old-style header. */staticvoidtrx_undo_header_add_space_for_xid(/*==============================*/ page_t* undo_page,/* in: undo log segment header page */ trx_ulogf_t* log_hdr,/* in: undo log header */ mtr_t* mtr) /* in: mtr */{ trx_upagef_t* page_hdr; ulint free; ulint new_free; page_hdr = undo_page + TRX_UNDO_PAGE_HDR; free = mach_read_from_2(page_hdr + TRX_UNDO_PAGE_FREE); /* free is now the end offset of the old style undo log header */ ut_a(free == (ulint)(log_hdr - undo_page) + TRX_UNDO_LOG_OLD_HDR_SIZE); new_free = free + (TRX_UNDO_LOG_XA_HDR_SIZE - TRX_UNDO_LOG_OLD_HDR_SIZE); /* Add space for a XID after the header, update the free offset fields on the undo log page and in the undo log header */ mlog_write_ulint(page_hdr + TRX_UNDO_PAGE_START, new_free, MLOG_2BYTES, mtr); mlog_write_ulint(page_hdr + TRX_UNDO_PAGE_FREE, new_free, MLOG_2BYTES, mtr); mlog_write_ulint(log_hdr + TRX_UNDO_LOG_START, new_free, MLOG_2BYTES, mtr);}/**************************************************************************Writes the mtr log entry of an undo log header reuse. */UNIV_INLINEvoidtrx_undo_insert_header_reuse_log(/*=============================*/ page_t* undo_page, /* in: undo log header page */ dulint trx_id, /* in: transaction id */ mtr_t* mtr) /* in: mtr */{ mlog_write_initial_log_record(undo_page, MLOG_UNDO_HDR_REUSE, mtr); mlog_catenate_dulint_compressed(mtr, trx_id);} /***************************************************************Parses the redo log entry of an undo log page header create or reuse. */byte*trx_undo_parse_page_header(/*=======================*/ /* out: end of log record or NULL */ ulint type, /* in: MLOG_UNDO_HDR_CREATE or MLOG_UNDO_HDR_REUSE */ byte* ptr, /* in: buffer */ byte* end_ptr,/* in: buffer end */ page_t* page, /* in: page or NULL */ mtr_t* mtr) /* in: mtr or NULL */{ dulint trx_id; ptr = mach_dulint_parse_compressed(ptr, end_ptr, &trx_id); if (ptr == NULL) { return(NULL); } if (page) { if (type == MLOG_UNDO_HDR_CREATE) { trx_undo_header_create(page, trx_id, mtr); } else { ut_ad(type == MLOG_UNDO_HDR_REUSE); trx_undo_insert_header_reuse(page, trx_id, mtr); } } return(ptr);} /*******************************************************************Initializes a cached insert undo log header page for new use. NOTE that thisfunction has its own log record type MLOG_UNDO_HDR_REUSE. You must NOT changethe operation of this function! */staticulinttrx_undo_insert_header_reuse(/*=========================*/ /* out: undo log header byte offset on page */ page_t* undo_page, /* in: insert undo log segment header page, x-latched */ dulint trx_id, /* in: transaction id */ mtr_t* mtr) /* in: mtr */{ trx_upagef_t* page_hdr; trx_usegf_t* seg_hdr; trx_ulogf_t* log_hdr; ulint free; ulint new_free; ut_ad(mtr && undo_page); page_hdr = undo_page + TRX_UNDO_PAGE_HDR; seg_hdr = undo_page + TRX_UNDO_SEG_HDR; free = TRX_UNDO_SEG_HDR + TRX_UNDO_SEG_HDR_SIZE; ut_a(free + TRX_UNDO_LOG_XA_HDR_SIZE < UNIV_PAGE_SIZE - 100); log_hdr = undo_page + free; new_free = free + TRX_UNDO_LOG_OLD_HDR_SIZE; /* Insert undo data is not needed after commit: we may free all the space on the page */ ut_a(mach_read_from_2(undo_page + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE) == TRX_UNDO_INSERT); mach_write_to_2(page_hdr + TRX_UNDO_PAGE_START, new_free); mach_write_to_2(page_hdr + TRX_UNDO_PAGE_FREE, new_free); mach_write_to_2(seg_hdr + TRX_UNDO_STATE, TRX_UNDO_ACTIVE); log_hdr = undo_page + free; mach_write_to_8(log_hdr + TRX_UNDO_TRX_ID, trx_id); mach_write_to_2(log_hdr + TRX_UNDO_LOG_START, new_free); mach_write_to_1(log_hdr + TRX_UNDO_XID_EXISTS, FALSE); mach_write_to_1(log_hdr + TRX_UNDO_DICT_TRANS, FALSE); /* Write the log record MLOG_UNDO_HDR_REUSE */ trx_undo_insert_header_reuse_log(undo_page, trx_id, mtr); return(free);} /**************************************************************************Writes the redo log entry of an update undo log header discard. */UNIV_INLINEvoidtrx_undo_discard_latest_log(/*========================*/ page_t* undo_page, /* in: undo log header page */ mtr_t* mtr) /* in: mtr */{ mlog_write_initial_log_record(undo_page, MLOG_UNDO_HDR_DISCARD, mtr);} /***************************************************************Parses the redo log entry of an undo log page header discard. */byte*trx_undo_parse_discard_latest(/*==========================*/ /* out: end of log record or NULL */ byte* ptr, /* in: buffer */ byte* end_ptr __attribute__((unused)), /* in: buffer end */ page_t* page, /* in: page or NULL */ mtr_t* mtr) /* in: mtr or NULL */{ ut_ad(end_ptr); if (page) { trx_undo_discard_latest_update_undo(page, mtr); } return(ptr);} /**************************************************************************If an update undo log can be discarded immediately, this function frees thespace, resetting the page to the proper state for caching. */staticvoidtrx_undo_discard_latest_update_undo(/*================================*/ page_t* undo_page, /* in: header page of an undo log of size 1 */ mtr_t* mtr) /* in: mtr */{ trx_usegf_t* seg_hdr; trx_upagef_t* page_hdr; trx_ulogf_t* log_hdr; trx_ulogf_t* prev_log_hdr; ulint free; ulint prev_hdr_offset; seg_hdr = undo_page + TRX_UNDO_SEG_HDR; page_hdr = undo_page + TRX_UNDO_PAGE_HDR; free = mach_read_from_2(seg_hdr + TRX_UNDO_LAST_LOG); log_hdr = undo_page + free; prev_hdr_offset = mach_read_from_2(log_hdr + TRX_UNDO_PREV_LOG); if (prev_hdr_offset != 0) { prev_log_hdr = undo_page + prev_hdr_offset; mach_write_to_2(page_hdr + TRX_UNDO_PAGE_START, mach_read_from_2(prev_log_hdr + TRX_UNDO_LOG_START)); mach_write_to_2(prev_log_hdr + TRX_UNDO_NEXT_LOG, 0); } mach_write_to_2(page_hdr + TRX_UNDO_PAGE_FREE, free); mach_write_to_2(seg_hdr + TRX_UNDO_STATE, TRX_UNDO_CACHED); mach_write_to_2(seg_hdr + TRX_UNDO_LAST_LOG, prev_hdr_offset); trx_undo_discard_latest_log(undo_page, mtr);}/************************************************************************Tries to add a page to the undo log segment where the undo log is placed. */ulinttrx_undo_add_page(/*==============*/ /* out: page number if success, else FIL_NULL */ trx_t* trx, /* in: transaction */ trx_undo_t* undo, /* in: undo log memory object */ mtr_t* mtr) /* in: mtr which does not have a latch to any undo log page; the caller must have reserved the rollback segment mutex */{ page_t* header_page; page_t* new_page; trx_rseg_t* rseg; ulint page_no; ulint n_reserved; ibool success; #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(trx->undo_mutex))); ut_ad(!mutex_own(&kernel_mutex)); ut_ad(mutex_own(&(trx->rseg->mutex)));#endif /* UNIV_SYNC_DEBUG */ rseg = trx->rseg; if (rseg->curr_size == rseg->max_size) { return(FIL_NULL); } header_page = trx_undo_page_get(undo->space, undo->hdr_page_no, mtr); success = fsp_reserve_free_extents(&n_reserved, undo->space, 1, FSP_UNDO, mtr); if (!success) { return(FIL_NULL); } page_no = fseg_alloc_free_page_general(header_page + TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER, undo->top_page_no + 1, FSP_UP, TRUE, mtr); fil_space_release_free_extents(undo->space, n_reserved); if (page_no == FIL_NULL) { /* No space left */ return(FIL_NULL); } undo->last_page_no = page_no; new_page = trx_undo_page_get(undo->space, page_no, mtr); trx_undo_page_init(new_page, undo->type, mtr); flst_add_last(header_page + TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST, new_page + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_NODE, mtr); undo->size++; rseg->curr_size++; return(page_no);}/************************************************************************Frees an undo log page that is not the header page. */staticulinttrx_undo_free_page(/*===============*/ /* out: last page number in remaining log */ trx_rseg_t* rseg, /* in: rollback segment */ ibool in_history, /* in: TRUE if the undo log is in the history list */ ulint space, /* in: space */ ulint hdr_page_no, /* in: header page number */ ulint page_no, /* in: page number to free: must not be the header page */ mtr_t* mtr) /* in: mtr which does not have a latch to any undo log page; the caller must have reserved the rollback segment mutex */{ page_t* header_page; page_t* undo_page; fil_addr_t last_addr; trx_rsegf_t* rseg_header; ulint hist_size; ut_a(hdr_page_no != page_no);#ifdef UNIV_SYNC_DEBUG ut_ad(!mutex_own(&kernel_mutex)); ut_ad(mutex_own(&(rseg->mutex)));#endif /* UNIV_SYNC_DEBUG */ undo_page = trx_undo_page_get(space, page_no, mtr); header_page = trx_undo_page_get(space, hdr_page_no, mtr); flst_remove(header_page + TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST, undo_page + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_NODE, mtr); fseg_free_page(header_page + TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER, space, page_no, mtr); last_addr = flst_get_last(header_page + TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST, mtr); rseg->curr_size--; if (in_history) { rseg_header = trx_rsegf_get(space, rseg->page_no, mtr); hist_size = mtr_read_ulint(rseg_header + TRX_RSEG_HISTORY_SIZE, MLOG_4BYTES, mtr); ut_ad(hist_size > 0); mlog_write_ulint(rseg_header + TRX_RSEG_HISTORY_SIZE, hist_size - 1, MLOG_4BYTES, mtr); } return(last_addr.page);}/************************************************************************Frees an undo log page when there is also the memory object for the undolog. */staticvoidtrx_undo_free_page_in_rollback(/*===========================*/ trx_t* trx __attribute__((unused)), /* in: transaction */ trx_undo_t* undo, /* in: undo log memory copy */ ulint page_no,/* in: page number to free: must not be the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -