summaryrefslogtreecommitdiff
path: root/storage/innobase/trx/trx0sys.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/trx/trx0sys.cc')
-rw-r--r--storage/innobase/trx/trx0sys.cc120
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());