diff options
Diffstat (limited to 'storage/innobase/trx/trx0sys.cc')
-rw-r--r-- | storage/innobase/trx/trx0sys.cc | 120 |
1 files changed, 99 insertions, 21 deletions
diff --git a/storage/innobase/trx/trx0sys.cc b/storage/innobase/trx/trx0sys.cc index bcde969eb41..52e246c5c4f 100644 --- a/storage/innobase/trx/trx0sys.cc +++ b/storage/innobase/trx/trx0sys.cc @@ -154,14 +154,13 @@ trx_sysf_create( then enter the kernel: we must do it in this order to conform to the latching order rules. */ - mtr_x_lock_space(fil_system.sys_space, mtr); + mtr->x_lock_space(fil_system.sys_space); compile_time_assert(TRX_SYS_SPACE == 0); /* Create the trx sys file block in a new allocated file segment */ block = fseg_create(fil_system.sys_space, TRX_SYS + TRX_SYS_FSEG_HEADER, mtr); - buf_block_dbg_add_level(block, SYNC_TRX_SYS_HEADER); ut_a(block->page.id() == page_id_t(0, TRX_SYS_PAGE_NO)); @@ -198,17 +197,67 @@ trx_sysf_create( ut_a(rblock->page.id() == page_id_t(0, FSP_FIRST_RSEG_PAGE_NO)); } -/** Create the instance */ -void -trx_sys_t::create() +void trx_sys_t::create() +{ + ut_ad(this == &trx_sys); + ut_ad(!is_initialised()); + m_initialised= true; + trx_list.create(); + rw_trx_hash.init(); +} + +uint32_t trx_sys_t::history_size() +{ + ut_ad(is_initialised()); + uint32_t size= 0; + for (auto &rseg : rseg_array) + { + rseg.latch.rd_lock(); + size+= rseg.history_size; + } + for (auto &rseg : rseg_array) + rseg.latch.rd_unlock(); + return size; +} + +bool trx_sys_t::history_exceeds(uint32_t threshold) { - ut_ad(this == &trx_sys); - ut_ad(!is_initialised()); - m_initialised = true; - trx_list.create(); - rseg_history_len= 0; + ut_ad(is_initialised()); + uint32_t size= 0; + bool exceeds= false; + size_t i; + for (i= 0; i < array_elements(rseg_array); i++) + { + rseg_array[i].latch.rd_lock(); + size+= rseg_array[i].history_size; + if (size > threshold) + { + exceeds= true; + i++; + break; + } + } + while (i) + rseg_array[--i].latch.rd_unlock(); + return exceeds; +} - rw_trx_hash.init(); +TPOOL_SUPPRESS_TSAN bool trx_sys_t::history_exists() +{ + ut_ad(is_initialised()); + for (auto &rseg : rseg_array) + if (rseg.history_size) + return true; + return false; +} + +TPOOL_SUPPRESS_TSAN uint32_t trx_sys_t::history_size_approx() const +{ + ut_ad(is_initialised()); + uint32_t size= 0; + for (auto &rseg : rseg_array) + size+= rseg.history_size; + return size; } /*****************************************************************//** @@ -226,10 +275,42 @@ trx_sys_create_sys_pages(void) mtr_commit(&mtr); } +/** Create a persistent rollback segment. +@param space_id system or undo tablespace id +@return pointer to new rollback segment +@retval nullptr on failure */ +static trx_rseg_t *trx_rseg_create(ulint space_id) +{ + trx_rseg_t *rseg= nullptr; + mtr_t mtr; + + mtr.start(); + + if (fil_space_t *space= mtr.x_lock_space(space_id)) + { + ut_ad(space->purpose == FIL_TYPE_TABLESPACE); + if (buf_block_t *sys_header= trx_sysf_get(&mtr)) + { + ulint rseg_id= trx_sys_rseg_find_free(sys_header); + if (buf_block_t *rblock= rseg_id == ULINT_UNDEFINED + ? nullptr : trx_rseg_header_create(space, rseg_id, 0, sys_header, + &mtr)) + { + ut_ad(trx_sysf_rseg_get_space(sys_header, rseg_id) == space_id); + rseg= &trx_sys.rseg_array[rseg_id]; + rseg->init(space, rblock->page.id().page_no()); + ut_ad(rseg->is_persistent()); + } + } + } + + mtr.commit(); + return rseg; +} + /** Create the rollback segments. @return whether the creation succeeded */ -bool -trx_sys_create_rsegs() +bool trx_sys_create_rsegs() { /* srv_available_undo_logs reflects the number of persistent rollback segments that have been initialized in the @@ -309,14 +390,11 @@ trx_sys_t::close() /* There can't be any active transactions. */ - for (ulint i = 0; i < TRX_SYS_N_RSEGS; ++i) { - if (trx_rseg_t* rseg = rseg_array[i]) { - trx_rseg_mem_free(rseg); - } - - if (trx_rseg_t* rseg = temp_rsegs[i]) { - trx_rseg_mem_free(rseg); - } + for (ulint i = 0; i < array_elements(temp_rsegs); ++i) { + temp_rsegs[i].destroy(); + } + for (ulint i = 0; i < array_elements(rseg_array); ++i) { + rseg_array[i].destroy(); } ut_a(trx_list.empty()); |