diff --git a/storage/innobase/include/trx0sys.ic b/storage/innobase/include/trx0sys.ic index ab1a61979c2..cd3f626d3cd 100644 --- a/storage/innobase/include/trx0sys.ic +++ b/storage/innobase/include/trx0sys.ic @@ -53,6 +53,9 @@ constexpr uint32_t TRX_SYS_RSEG_PAGE_NO = 4; /* Size of a rollback segment specification slot */ constexpr uint32_t TRX_SYS_RSEG_SLOT_SIZE = 8; +/** Prefetch TRX_SYS_PAGE_NO if meet the conditions */ +void prefetch_trx_sys_page(); + /** Writes the value of max_trx_id to the file based trx system header. */ void trx_sys_write_max_trx_id(void); diff --git a/storage/innobase/trx/trx0sys.cc b/storage/innobase/trx/trx0sys.cc index 7a507cdfb19..f04168ccdd4 100644 --- a/storage/innobase/trx/trx0sys.cc +++ b/storage/innobase/trx/trx0sys.cc @@ -96,6 +96,15 @@ void ReadView::check_trx_id_sanity(trx_id_t id, const table_name_t &name) { uint trx_rseg_n_slots_debug = 0; #endif /* UNIV_DEBUG */ +void prefetch_trx_sys_page() { + if ((trx_sys->next_trx_id_or_no.load() + + 1 % trx_sys_get_trx_id_write_margin()) == 0) { + buf_read_page_background(page_id_t(TRX_SYS_SPACE, TRX_SYS_PAGE_NO), + univ_page_size, false); + os_aio_simulated_wake_handler_threads(); + } +} + /** Writes the value of max_trx_id to the file based trx system header. */ void trx_sys_write_max_trx_id(void) { mtr_t mtr; diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 29a5a9be1a9..358a9722b4c 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -1229,6 +1229,8 @@ void trx_assign_rseg_temp(trx_t *trx) { srv_read_only_mode ? nullptr : get_next_temp_rseg(); if (trx->id == 0) { + prefetch_trx_sys_page(); + trx_sys_mutex_enter(); trx->id = trx_sys_allocate_trx_id(); @@ -1341,6 +1343,8 @@ static void trx_start_low( if (!trx->read_only && (trx->mysql_thd == nullptr || read_write || trx->ddl_operation)) { + prefetch_trx_sys_page(); + trx_assign_rseg_durable(trx); /* Temporary rseg is assigned only if the transaction @@ -1375,6 +1379,8 @@ static void trx_start_low( to write to the temporary table. */ if (read_write) { + prefetch_trx_sys_page(); + trx_sys_mutex_enter(); ut_ad(!srv_read_only_mode); @@ -1409,6 +1415,8 @@ which case still the trx->no is assigned. @param[in,out] trx the modified transaction @return true if added to the serialisation_list (non read-only trx) */ static inline bool trx_add_to_serialisation_list(trx_t *trx) { + prefetch_trx_sys_page(); + trx_sys_serialisation_mutex_enter(); trx->no = trx_sys_allocate_trx_no(); @@ -3394,6 +3402,8 @@ void trx_set_rw_mode(trx_t *trx) /*!< in/out: transaction that is RW */ looks at this trx object while it is being promoted then ensure that both threads are synced by acquiring trx->mutex to avoid decision based on in-consistent view formed during promotion. */ + + prefetch_trx_sys_page(); trx_assign_rseg_durable(trx);