trx0rseg.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:6k
- /******************************************************
- Rollback segment
- (c) 1996 Innobase Oy
- Created 3/26/1996 Heikki Tuuri
- *******************************************************/
- #include "trx0rseg.h"
- #ifdef UNIV_NONINL
- #include "trx0rseg.ic"
- #endif
- #include "trx0undo.h"
- #include "fut0lst.h"
- #include "srv0srv.h"
- #include "trx0purge.h"
- /**********************************************************************
- Looks for a rollback segment, based on the rollback segment id. */
- trx_rseg_t*
- trx_rseg_get_on_id(
- /*===============*/
- /* out: rollback segment */
- ulint id) /* in: rollback segment id */
- {
- trx_rseg_t* rseg;
- rseg = UT_LIST_GET_FIRST(trx_sys->rseg_list);
- ut_ad(rseg);
- while (rseg->id != id) {
- rseg = UT_LIST_GET_NEXT(rseg_list, rseg);
- ut_ad(rseg);
- }
- return(rseg);
- }
- /********************************************************************
- Creates a rollback segment header. This function is called only when
- a new rollback segment is created in the database. */
- ulint
- trx_rseg_header_create(
- /*===================*/
- /* out: page number of the created segment,
- FIL_NULL if fail */
- ulint space, /* in: space id */
- ulint max_size, /* in: max size in pages */
- ulint* slot_no, /* out: rseg id == slot number in trx sys */
- mtr_t* mtr) /* in: mtr */
- {
- ulint page_no;
- trx_rsegf_t* rsegf;
- trx_sysf_t* sys_header;
- ulint i;
- page_t* page;
-
- ut_ad(mtr);
- #ifdef UNIV_SYNC_DEBUG
- ut_ad(mutex_own(&kernel_mutex));
- #endif /* UNIV_SYNC_DEBUG */
- ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space),
- MTR_MEMO_X_LOCK));
- sys_header = trx_sysf_get(mtr);
- *slot_no = trx_sysf_rseg_find_free(mtr);
- if (*slot_no == ULINT_UNDEFINED) {
- return(FIL_NULL);
- }
- /* Allocate a new file segment for the rollback segment */
- page = fseg_create(space, 0, TRX_RSEG + TRX_RSEG_FSEG_HEADER, mtr);
- if (page == NULL) {
- /* No space left */
- return(FIL_NULL);
- }
- #ifdef UNIV_SYNC_DEBUG
- buf_page_dbg_add_level(page, SYNC_RSEG_HEADER_NEW);
- #endif /* UNIV_SYNC_DEBUG */
- page_no = buf_frame_get_page_no(page);
- /* Get the rollback segment file page */
- rsegf = trx_rsegf_get_new(space, page_no, mtr);
-
- /* Initialize max size field */
- mlog_write_ulint(rsegf + TRX_RSEG_MAX_SIZE, max_size, MLOG_4BYTES, mtr);
-
- /* Initialize the history list */
- mlog_write_ulint(rsegf + TRX_RSEG_HISTORY_SIZE, 0, MLOG_4BYTES, mtr);
- flst_init(rsegf + TRX_RSEG_HISTORY, mtr);
- /* Reset the undo log slots */
- for (i = 0; i < TRX_RSEG_N_SLOTS; i++) {
- trx_rsegf_set_nth_undo(rsegf, i, FIL_NULL, mtr);
- }
- /* Add the rollback segment info to the free slot in the trx system
- header */
- trx_sysf_rseg_set_space(sys_header, *slot_no, space, mtr);
- trx_sysf_rseg_set_page_no(sys_header, *slot_no, page_no, mtr);
- return(page_no);
- }
- /***************************************************************************
- Creates and initializes a rollback segment object. The values for the
- fields are read from the header. The object is inserted to the rseg
- list of the trx system object and a pointer is inserted in the rseg
- array in the trx system object. */
- static
- trx_rseg_t*
- trx_rseg_mem_create(
- /*================*/
- /* out, own: rollback segment object */
- ulint id, /* in: rollback segment id */
- ulint space, /* in: space where the segment placed */
- ulint page_no, /* in: page number of the segment header */
- mtr_t* mtr) /* in: mtr */
- {
- trx_rsegf_t* rseg_header;
- trx_rseg_t* rseg;
- trx_ulogf_t* undo_log_hdr;
- fil_addr_t node_addr;
- ulint sum_of_undo_sizes;
- ulint len;
- #ifdef UNIV_SYNC_DEBUG
- ut_ad(mutex_own(&kernel_mutex));
- #endif /* UNIV_SYNC_DEBUG */
- rseg = mem_alloc(sizeof(trx_rseg_t));
- rseg->id = id;
- rseg->space = space;
- rseg->page_no = page_no;
-
- mutex_create(&(rseg->mutex));
- mutex_set_level(&(rseg->mutex), SYNC_RSEG);
- UT_LIST_ADD_LAST(rseg_list, trx_sys->rseg_list, rseg);
- trx_sys_set_nth_rseg(trx_sys, id, rseg);
- rseg_header = trx_rsegf_get_new(space, page_no, mtr);
- rseg->max_size = mtr_read_ulint(rseg_header + TRX_RSEG_MAX_SIZE,
- MLOG_4BYTES, mtr);
- /* Initialize the undo log lists according to the rseg header */
- sum_of_undo_sizes = trx_undo_lists_init(rseg);
- rseg->curr_size = mtr_read_ulint(rseg_header + TRX_RSEG_HISTORY_SIZE,
- MLOG_4BYTES, mtr)
- + 1 + sum_of_undo_sizes;
- len = flst_get_len(rseg_header + TRX_RSEG_HISTORY, mtr);
- if (len > 0) {
- trx_sys->rseg_history_len += len;
- node_addr = trx_purge_get_log_from_hist(
- flst_get_last(rseg_header + TRX_RSEG_HISTORY,
- mtr));
- rseg->last_page_no = node_addr.page;
- rseg->last_offset = node_addr.boffset;
- undo_log_hdr = trx_undo_page_get(rseg->space, node_addr.page,
- mtr)
- + node_addr.boffset;
-
- rseg->last_trx_no = mtr_read_dulint(
- undo_log_hdr + TRX_UNDO_TRX_NO, mtr);
- rseg->last_del_marks = mtr_read_ulint(
- undo_log_hdr + TRX_UNDO_DEL_MARKS,
- MLOG_2BYTES, mtr);
- } else {
- rseg->last_page_no = FIL_NULL;
- }
- return(rseg);
- }
- /*************************************************************************
- Creates the memory copies for rollback segments and initializes the
- rseg list and array in trx_sys at a database startup. */
- void
- trx_rseg_list_and_array_init(
- /*=========================*/
- trx_sysf_t* sys_header, /* in: trx system header */
- mtr_t* mtr) /* in: mtr */
- {
- ulint i;
- ulint page_no;
- ulint space;
- UT_LIST_INIT(trx_sys->rseg_list);
- trx_sys->rseg_history_len = 0;
- for (i = 0; i < TRX_SYS_N_RSEGS; i++) {
- page_no = trx_sysf_rseg_get_page_no(sys_header, i, mtr);
- if (page_no == FIL_NULL) {
- trx_sys_set_nth_rseg(trx_sys, i, NULL);
- } else {
- space = trx_sysf_rseg_get_space(sys_header, i, mtr);
- trx_rseg_mem_create(i, space, page_no, mtr);
- }
- }
- }
- /********************************************************************
- Creates a new rollback segment to the database. */
- trx_rseg_t*
- trx_rseg_create(
- /*============*/
- /* out: the created segment object, NULL if
- fail */
- ulint space, /* in: space id */
- ulint max_size, /* in: max size in pages */
- ulint* id, /* out: rseg id */
- mtr_t* mtr) /* in: mtr */
- {
- ulint page_no;
- trx_rseg_t* rseg;
- mtr_x_lock(fil_space_get_latch(space), mtr);
- mutex_enter(&kernel_mutex);
- page_no = trx_rseg_header_create(space, max_size, id, mtr);
- if (page_no == FIL_NULL) {
- mutex_exit(&kernel_mutex);
- return(NULL);
- }
- rseg = trx_rseg_mem_create(*id, space, page_no, mtr);
- mutex_exit(&kernel_mutex);
- return(rseg);
- }