summaryrefslogtreecommitdiff
path: root/storage/innobase/trx/trx0trx.cc
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2023-02-28 10:52:42 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2023-02-28 10:52:42 +0200
commit95d51369c9b1d5b759be630003ab12e9615ea0cc (patch)
tree451285d8f22400863de120ac22a3f9aea0d46716 /storage/innobase/trx/trx0trx.cc
parent8460eb25d1f897d403136e75b75ef595470d641c (diff)
parentf14d9fa09a33b6989c211dc4792b7d895142236c (diff)
downloadmariadb-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.cc72
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()) {