diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2023-02-28 10:52:42 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2023-02-28 10:52:42 +0200 |
commit | 95d51369c9b1d5b759be630003ab12e9615ea0cc (patch) | |
tree | 451285d8f22400863de120ac22a3f9aea0d46716 /storage/innobase/trx/trx0trx.cc | |
parent | 8460eb25d1f897d403136e75b75ef595470d641c (diff) | |
parent | f14d9fa09a33b6989c211dc4792b7d895142236c (diff) | |
download | mariadb-git-95d51369c9b1d5b759be630003ab12e9615ea0cc.tar.gz |
Merge 10.10 into 10.11
Diffstat (limited to 'storage/innobase/trx/trx0trx.cc')
-rw-r--r-- | storage/innobase/trx/trx0trx.cc | 72 |
1 files changed, 28 insertions, 44 deletions
diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 475ae887d23..3352447ea63 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -651,6 +651,7 @@ static dberr_t trx_resurrect(trx_undo_t *undo, trx_rseg_t *rseg, uint64_t *rows_to_undo) { trx_state_t state; + ut_ad(rseg->needs_purge >= undo->trx_id); /* This is single-threaded startup code, we do not need the protection of trx->mutex here. @@ -673,6 +674,7 @@ static dberr_t trx_resurrect(trx_undo_t *undo, trx_rseg_t *rseg, return DB_SUCCESS; } + rseg->acquire(); trx_t *trx= trx_create(); trx->state= state; ut_d(trx->start_file= __FILE__); @@ -681,12 +683,6 @@ static dberr_t trx_resurrect(trx_undo_t *undo, trx_rseg_t *rseg, trx->rsegs.m_redo.undo= undo; trx->undo_no= undo->top_undo_no + 1; trx->rsegs.m_redo.rseg= rseg; - /* - For transactions with active data will not have rseg size = 1 - or will not qualify for purge limit criteria. So it is safe to increment - this trx_ref_count w/o mutex protection. - */ - trx->rsegs.m_redo.rseg->acquire(); trx->xid= undo->xid; trx->id= undo->trx_id; trx->is_recovered= true; @@ -765,6 +761,7 @@ func_exit: ut_ad(trx->is_recovered); ut_ad(trx->rsegs.m_redo.rseg == &rseg); ut_ad(rseg.is_referenced()); + ut_ad(rseg.needs_purge); trx->rsegs.m_redo.undo = undo; if (undo->top_undo_no >= trx->undo_no) { @@ -799,20 +796,18 @@ func_exit: /** Assign a persistent rollback segment in a round-robin fashion, evenly distributed between 0 and innodb_undo_logs-1 -@return persistent rollback segment -@retval NULL if innodb_read_only */ -static trx_rseg_t* trx_assign_rseg_low() +@param trx transaction */ +static void trx_assign_rseg_low(trx_t *trx) { - if (high_level_read_only) { - ut_ad(!srv_available_undo_logs); - return(NULL); - } - + ut_ad(!trx->rsegs.m_redo.rseg); ut_ad(srv_available_undo_logs == TRX_SYS_N_RSEGS); /* The first slot is always assigned to the system tablespace. */ ut_ad(trx_sys.rseg_array[0].space == fil_system.sys_space); + trx_sys.register_rw(trx); + ut_ad(trx->id); + /* Choose a rollback segment evenly distributed between 0 and innodb_undo_logs-1 in a round-robin fashion, skipping those undo tablespaces that are scheduled for truncation. */ @@ -826,7 +821,7 @@ static trx_rseg_t* trx_assign_rseg_low() bool look_for_rollover = false; #endif /* UNIV_DEBUG */ - bool allocated = false; + bool allocated; do { for (;;) { @@ -875,9 +870,7 @@ static trx_rseg_t* trx_assign_rseg_low() allocated = rseg->acquire_if_available(); } while (!allocated); - ut_ad(rseg->is_referenced()); - ut_ad(rseg->is_persistent()); - return(rseg); + trx->rsegs.m_redo.rseg = rseg; } /** Assign a rollback segment for modifying temporary tables. @@ -960,15 +953,11 @@ trx_start_low( if (!trx->read_only && (!trx->mysql_thd || read_write || trx->dict_operation)) { - /* Temporary rseg is assigned only if the transaction updates a temporary table */ - trx->rsegs.m_redo.rseg = trx_assign_rseg_low(); - ut_ad(trx->rsegs.m_redo.rseg != 0 - || srv_read_only_mode - || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO); - - trx_sys.register_rw(trx); + if (!high_level_read_only) { + trx_assign_rseg_low(trx); + } } else { if (!trx->is_autocommit_non_locking()) { @@ -1059,25 +1048,21 @@ trx_write_serialisation_history( trx_undo_t*& undo = trx->rsegs.m_redo.undo; - if (!undo) { - return; - } - ut_ad(!trx->read_only); - ut_ad(!undo || undo->rseg == rseg); - rseg->latch.wr_lock(SRW_LOCK_CALL); /* Assign the transaction serialisation number and add any undo log to the purge queue. */ - trx_serialise(trx); if (undo) { + rseg->latch.wr_lock(SRW_LOCK_CALL); + ut_ad(undo->rseg == rseg); + trx_serialise(trx); UT_LIST_REMOVE(rseg->undo_list, undo); trx_purge_add_undo_to_history(trx, undo, mtr); + MONITOR_INC(MONITOR_TRX_COMMIT_UNDO); + rseg->latch.wr_unlock(); } - rseg->latch.wr_unlock(); - - MONITOR_INC(MONITOR_TRX_COMMIT_UNDO); + rseg->release(); } /******************************************************************** @@ -1313,10 +1298,6 @@ TRANSACTIONAL_INLINE inline void trx_t::commit_in_memory(const mtr_t *mtr) release_locks(); } - if (trx_rseg_t *rseg= rsegs.m_redo.rseg) - /* This is safe due to us having detached the persistent undo log. */ - rseg->release(); - if (mtr) { if (trx_undo_t *&undo= rsegs.m_noredo.undo) @@ -1454,6 +1435,13 @@ TRANSACTIONAL_TARGET void trx_t::commit_low(mtr_t *mtr) mtr->commit(); } + else if (trx_rseg_t *rseg= rsegs.m_redo.rseg) + { + ut_ad(id); + ut_ad(!rsegs.m_redo.undo); + rseg->release(); + } + #ifdef ENABLED_DEBUG_SYNC if (debug_sync) DEBUG_SYNC_C("before_trx_state_committed_in_memory"); @@ -2170,11 +2158,7 @@ trx_set_rw_mode( return; } - trx->rsegs.m_redo.rseg = trx_assign_rseg_low(); - ut_ad(trx->rsegs.m_redo.rseg != 0); - - trx_sys.register_rw(trx); - ut_ad(trx->id); + trx_assign_rseg_low(trx); /* So that we can see our own changes. */ if (trx->read_view.is_open()) { |