/******************************************************************** Creates the memory copies for the rollback segments and initializes the rseg list and array in trx_sys at a database startup. */ static void trx_rseg_create_instance( /*=====================*/ trx_sysf_t* sys_header, /*!< in: trx system header */ mtr_t* mtr) /*!< in: mtr */ { ulint i; for (i = 0; i < TRX_SYS_N_RSEGS; i++) { ulint page_no; 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 { ulint space; ulint zip_size; trx_rseg_t* rseg = NULL; ut_a(!trx_rseg_get_on_id(i)); space = trx_sysf_rseg_get_space(sys_header, i, mtr); zip_size = space ? fil_space_get_zip_size(space) : 0; rseg = trx_rseg_mem_create( i, space, zip_size, page_no, mtr); ut_a(rseg->id == i); } } }
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); } } }
/***********************************************************************//** Free's an instance of the rollback segment in memory. */ UNIV_INTERN void trx_rseg_mem_free( /*==============*/ trx_rseg_t* rseg) /* in, own: instance to free */ { trx_undo_t* undo; mutex_free(&rseg->mutex); if (!srv_apply_log_only) { /* There can't be any active transactions. */ ut_a(UT_LIST_GET_LEN(rseg->update_undo_list) == 0); ut_a(UT_LIST_GET_LEN(rseg->insert_undo_list) == 0); } undo = UT_LIST_GET_FIRST(rseg->update_undo_cached); while (undo != NULL) { trx_undo_t* prev_undo = undo; undo = UT_LIST_GET_NEXT(undo_list, undo); UT_LIST_REMOVE(undo_list, rseg->update_undo_cached, prev_undo); trx_undo_mem_free(prev_undo); } undo = UT_LIST_GET_FIRST(rseg->insert_undo_cached); while (undo != NULL) { trx_undo_t* prev_undo = undo; undo = UT_LIST_GET_NEXT(undo_list, undo); UT_LIST_REMOVE(undo_list, rseg->insert_undo_cached, prev_undo); trx_undo_mem_free(prev_undo); } trx_sys_set_nth_rseg(trx_sys, rseg->id, NULL); mem_free(rseg); }
/*************************************************************************** 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. @return own: rollback segment object */ static trx_rseg_t* trx_rseg_mem_create( /*================*/ ulint id, /*!< in: rollback segment id */ ulint space, /*!< in: space where the segment placed */ ulint zip_size, /*!< in: compressed page size in bytes or 0 for uncompressed pages */ ulint page_no, /*!< in: page number of the segment header */ mtr_t* mtr) /*!< in: mtr */ { ulint len; trx_rseg_t* rseg; fil_addr_t node_addr; trx_rsegf_t* rseg_header; trx_ulogf_t* undo_log_hdr; ulint sum_of_undo_sizes; ut_ad(mutex_own(&kernel_mutex)); rseg = mem_zalloc(sizeof(trx_rseg_t)); rseg->id = id; rseg->space = space; rseg->zip_size = zip_size; rseg->page_no = page_no; mutex_create(rseg_mutex_key, &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, zip_size, 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, rseg->zip_size, 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); }