summaryrefslogtreecommitdiff
path: root/storage/innobase/trx/trx0undo.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/trx/trx0undo.cc')
-rw-r--r--storage/innobase/trx/trx0undo.cc120
1 files changed, 59 insertions, 61 deletions
diff --git a/storage/innobase/trx/trx0undo.cc b/storage/innobase/trx/trx0undo.cc
index 33b1f93ff65..20434d9fb9c 100644
--- a/storage/innobase/trx/trx0undo.cc
+++ b/storage/innobase/trx/trx0undo.cc
@@ -535,8 +535,6 @@ trx_undo_seg_create(fil_space_t *space, buf_block_t *rseg_hdr, ulint *id,
+ slot_no * TRX_RSEG_SLOT_SIZE + rseg_hdr->page.frame,
block->page.id().page_no());
- MONITOR_INC(MONITOR_NUM_UNDO_SLOT_USED);
-
*err = DB_SUCCESS;
return block;
}
@@ -996,7 +994,6 @@ static void trx_undo_seg_free(const trx_undo_t *undo)
static_assert(FIL_NULL == 0xffffffff, "compatibility");
mtr.memset(rseg_header, TRX_RSEG + TRX_RSEG_UNDO_SLOTS +
undo->id * TRX_RSEG_SLOT_SIZE, 4, 0xff);
- MONITOR_DEC(MONITOR_NUM_UNDO_SLOT_USED);
}
}
@@ -1155,7 +1152,6 @@ corrupted_type:
UT_LIST_ADD_LAST(rseg->undo_list, undo);
} else {
UT_LIST_ADD_LAST(rseg->undo_cached, undo);
- MONITOR_INC(MONITOR_NUM_UNDO_SLOT_CACHED);
}
mtr.commit();
@@ -1294,27 +1290,25 @@ trx_undo_create(trx_t* trx, trx_rseg_t* rseg, trx_undo_t** undo,
@param[in,out] rseg rollback segment
@param[out] pundo the undo log memory object
@param[in,out] mtr mini-transaction
+@param[out] err error code
@return the undo log block
@retval NULL if none cached */
static
buf_block_t*
trx_undo_reuse_cached(trx_t* trx, trx_rseg_t* rseg, trx_undo_t** pundo,
- mtr_t* mtr)
+ mtr_t* mtr, dberr_t *err)
{
- if (rseg->is_persistent()) {
- ut_ad(rseg->is_referenced());
- if (rseg->needs_purge <= trx->id) {
- /* trx_purge_truncate_history() compares
- rseg->needs_purge <= head.trx_no
- so we need to compensate for that.
- The rseg->needs_purge after crash
- recovery would be at least trx->id + 1,
- because that is the minimum possible value
- assigned by trx_serialise() on commit. */
- rseg->needs_purge = trx->id + 1;
- }
- } else {
- ut_ad(!rseg->is_referenced());
+ ut_ad(rseg->is_persistent());
+ ut_ad(rseg->is_referenced());
+ if (rseg->needs_purge <= trx->id) {
+ /* trx_purge_truncate_history() compares
+ rseg->needs_purge <= head.trx_no
+ so we need to compensate for that.
+ The rseg->needs_purge after crash
+ recovery would be at least trx->id + 1,
+ because that is the minimum possible value
+ assigned by trx_serialise() on commit. */
+ rseg->needs_purge = trx->id + 1;
}
trx_undo_t* undo = UT_LIST_GET_FIRST(rseg->undo_cached);
@@ -1325,15 +1319,15 @@ trx_undo_reuse_cached(trx_t* trx, trx_rseg_t* rseg, trx_undo_t** pundo,
ut_ad(undo->size == 1);
ut_ad(undo->id < TRX_RSEG_N_SLOTS);
- buf_block_t* block = buf_page_get(page_id_t(undo->rseg->space->id,
- undo->hdr_page_no),
- 0, RW_X_LATCH, mtr);
+ buf_block_t* block = buf_page_get_gen(page_id_t(undo->rseg->space->id,
+ undo->hdr_page_no),
+ 0, RW_X_LATCH, nullptr, BUF_GET,
+ mtr, err);
if (!block) {
return NULL;
}
UT_LIST_REMOVE(rseg->undo_cached, undo);
- MONITOR_DEC(MONITOR_NUM_UNDO_SLOT_CACHED);
*pundo = undo;
@@ -1379,11 +1373,12 @@ trx_undo_assign(trx_t* trx, dberr_t* err, mtr_t* mtr)
BUF_GET, mtr, err);
}
+ *err = DB_SUCCESS;
trx_rseg_t* rseg = trx->rsegs.m_redo.rseg;
rseg->latch.wr_lock(SRW_LOCK_CALL);
buf_block_t* block = trx_undo_reuse_cached(
- trx, rseg, &trx->rsegs.m_redo.undo, mtr);
+ trx, rseg, &trx->rsegs.m_redo.undo, mtr, err);
if (!block) {
block = trx_undo_create(trx, rseg, &trx->rsegs.m_redo.undo,
@@ -1392,8 +1387,6 @@ trx_undo_assign(trx_t* trx, dberr_t* err, mtr_t* mtr)
if (!block) {
goto func_exit;
}
- } else {
- *err = DB_SUCCESS;
}
UT_LIST_ADD_FIRST(rseg->undo_list, trx->rsegs.m_redo.undo);
@@ -1405,18 +1398,20 @@ func_exit:
/** Assign an undo log for a transaction.
A new undo log is created or a cached undo log reused.
+@tparam is_temp whether this is temporary undo log
@param[in,out] trx transaction
@param[in] rseg rollback segment
@param[out] undo the undo log
-@param[out] err error code
@param[in,out] mtr mini-transaction
+@param[out] err error code
@return the undo log block
-@retval NULL on error */
+@retval nullptr on error */
+template<bool is_temp>
buf_block_t*
-trx_undo_assign_low(trx_t* trx, trx_rseg_t* rseg, trx_undo_t** undo,
- dberr_t* err, mtr_t* mtr)
+trx_undo_assign_low(trx_t *trx, trx_rseg_t *rseg, trx_undo_t **undo,
+ mtr_t *mtr, dberr_t *err)
{
- ut_d(const bool is_temp = rseg == trx->rsegs.m_noredo.rseg);
+ ut_ad(is_temp == (rseg == trx->rsegs.m_noredo.rseg));
ut_ad(is_temp || rseg == trx->rsegs.m_redo.rseg);
ut_ad(undo == (is_temp
? &trx->rsegs.m_noredo.undo
@@ -1436,19 +1431,24 @@ trx_undo_assign_low(trx_t* trx, trx_rseg_t* rseg, trx_undo_t** undo,
*err = DB_TOO_MANY_CONCURRENT_TRXS; return NULL;
);
+ *err = DB_SUCCESS;
rseg->latch.wr_lock(SRW_LOCK_CALL);
- buf_block_t* block = trx_undo_reuse_cached(trx, rseg, undo, mtr);
-
- if (!block) {
- block = trx_undo_create(trx, rseg, undo, err, mtr);
- ut_ad(!block == (*err != DB_SUCCESS));
- if (!block) {
- goto func_exit;
- }
+ buf_block_t* block;
+ if (is_temp) {
+ ut_ad(!UT_LIST_GET_LEN(rseg->undo_cached));
} else {
- *err = DB_SUCCESS;
+ block = trx_undo_reuse_cached(trx, rseg, undo, mtr, err);
+ if (block) {
+ goto got_block;
+ }
+ }
+ block = trx_undo_create(trx, rseg, undo, err, mtr);
+ ut_ad(!block == (*err != DB_SUCCESS));
+ if (!block) {
+ goto func_exit;
}
+got_block:
UT_LIST_ADD_FIRST(rseg->undo_list, *undo);
func_exit:
@@ -1456,6 +1456,13 @@ func_exit:
return block;
}
+template buf_block_t*
+trx_undo_assign_low<false>(trx_t *trx, trx_rseg_t *rseg, trx_undo_t **undo,
+ mtr_t *mtr, dberr_t *err);
+template buf_block_t*
+trx_undo_assign_low<true>(trx_t *trx, trx_rseg_t *rseg, trx_undo_t **undo,
+ mtr_t *mtr, dberr_t *err);
+
/******************************************************************//**
Sets the state of the undo log segment at a transaction finish.
@return undo log segment header page, x-latched */
@@ -1466,6 +1473,7 @@ trx_undo_set_state_at_finish(
mtr_t* mtr) /*!< in: mtr */
{
ut_ad(undo->id < TRX_RSEG_N_SLOTS);
+ ut_ad(undo->rseg->is_persistent());
buf_block_t *block=
buf_page_get(page_id_t(undo->rseg->space->id, undo->hdr_page_no), 0,
@@ -1537,29 +1545,19 @@ the data can be discarded.
@param undo temporary undo log */
void trx_undo_commit_cleanup(trx_undo_t *undo)
{
- trx_rseg_t* rseg = undo->rseg;
- ut_ad(rseg->space == fil_system.temp_space);
-
- rseg->latch.wr_lock(SRW_LOCK_CALL);
-
- UT_LIST_REMOVE(rseg->undo_list, undo);
-
- if (undo->state == TRX_UNDO_CACHED) {
- UT_LIST_ADD_FIRST(rseg->undo_cached, undo);
- MONITOR_INC(MONITOR_NUM_UNDO_SLOT_CACHED);
- undo = nullptr;
- } else {
- ut_ad(undo->state == TRX_UNDO_TO_PURGE);
-
- /* Delete first the undo log segment in the file */
- trx_undo_seg_free(undo);
+ trx_rseg_t *rseg= undo->rseg;
+ ut_ad(rseg->space == fil_system.temp_space);
+ rseg->latch.wr_lock(SRW_LOCK_CALL);
- ut_ad(rseg->curr_size > undo->size);
- rseg->curr_size -= undo->size;
- }
+ UT_LIST_REMOVE(rseg->undo_list, undo);
+ ut_ad(undo->state == TRX_UNDO_TO_PURGE);
+ /* Delete first the undo log segment in the file */
+ trx_undo_seg_free(undo);
+ ut_ad(rseg->curr_size > undo->size);
+ rseg->curr_size-= undo->size;
- rseg->latch.wr_unlock();
- ut_free(undo);
+ rseg->latch.wr_unlock();
+ ut_free(undo);
}
/** At shutdown, frees the undo logs of a transaction. */