Skip to content

Commit d4187bd

Browse files
committed
Replace purge_iter_t with purge_sys_t::iterator
Also, remove the field undo_rseg_space. Apparently its purpose was to avoid problems with temporary undo logs, which MySQL 5.7 unnecessarily adds to the purge system. (Temporary undo log records are not purged.) MariaDB 10.2 fixed this in MDEV-12289 or earlier.
1 parent 28d844f commit d4187bd

File tree

2 files changed

+57
-100
lines changed

2 files changed

+57
-100
lines changed

storage/innobase/include/trx0purge.h

Lines changed: 18 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -219,36 +219,6 @@ struct TrxUndoRsegsIterator {
219219
static const TrxUndoRsegs NullElement;
220220
};
221221

222-
/** This is the purge pointer/iterator. We need both the undo no and the
223-
transaction no up to which purge has parsed and applied the records. */
224-
struct purge_iter_t {
225-
purge_iter_t()
226-
:
227-
trx_no(),
228-
undo_no(),
229-
undo_rseg_space(ULINT_UNDEFINED)
230-
{
231-
// Do nothing
232-
}
233-
234-
bool operator<=(const purge_iter_t& other) const
235-
{
236-
if (trx_no < other.trx_no) return true;
237-
if (trx_no > other.trx_no) return false;
238-
return undo_no <= other.undo_no;
239-
}
240-
241-
trx_id_t trx_no; /*!< Purge has advanced past all
242-
transactions whose number is less
243-
than this */
244-
undo_no_t undo_no; /*!< Purge has advanced past all records
245-
whose undo number is less than this */
246-
ulint undo_rseg_space;
247-
/*!< Last undo record resided in this
248-
space id. */
249-
};
250-
251-
252222
/* Namespace to hold all the related functions and variables need for truncate
253223
of undo tablespace. */
254224
namespace undo {
@@ -522,16 +492,29 @@ class purge_sys_t
522492
to the task queue */
523493
ulint n_completed; /*!< Count of total tasks completed */
524494

525-
/*------------------------------*/
526-
/* The following two fields form the 'purge pointer' which advances
527-
during a purge, and which is used in history list truncation */
495+
/** Iterator to the undo log records of committed transactions */
496+
struct iterator
497+
{
498+
bool operator<=(const iterator& other) const
499+
{
500+
if (trx_no < other.trx_no) return true;
501+
if (trx_no > other.trx_no) return false;
502+
return undo_no <= other.undo_no;
503+
}
504+
505+
/** The trx_t::no of the committed transaction */
506+
trx_id_t trx_no;
507+
/** The record number within the committed transaction's undo
508+
log, increasing, purged from from 0 onwards */
509+
undo_no_t undo_no;
510+
};
528511

529512
/** The tail of the purge queue; the last parsed undo log of a
530513
committed transaction. */
531-
purge_iter_t tail;
514+
iterator tail;
532515
/** The head of the purge queue; any older undo logs of committed
533516
transactions may be discarded (history list truncation). */
534-
purge_iter_t head;
517+
iterator head;
535518
/*-----------------------------*/
536519
bool next_stored; /*!< whether rseg holds the next record
537520
to purge */

storage/innobase/trx/trx0purge.cc

Lines changed: 39 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -455,10 +455,12 @@ trx_purge_free_segment(trx_rseg_t* rseg, fil_addr_t hdr_addr)
455455

456456
/** Remove unnecessary history data from a rollback segment.
457457
@param[in,out] rseg rollback segment
458-
@param[in] limit truncate offset */
458+
@param[in] limit truncate anything before this */
459459
static
460460
void
461-
trx_purge_truncate_rseg_history(trx_rseg_t* rseg, const purge_iter_t* limit)
461+
trx_purge_truncate_rseg_history(
462+
trx_rseg_t& rseg,
463+
const purge_sys_t::iterator& limit)
462464
{
463465
fil_addr_t hdr_addr;
464466
fil_addr_t prev_hdr_addr;
@@ -469,48 +471,37 @@ trx_purge_truncate_rseg_history(trx_rseg_t* rseg, const purge_iter_t* limit)
469471
mtr_t mtr;
470472
trx_id_t undo_trx_no;
471473

472-
mtr_start(&mtr);
473-
ut_ad(rseg->is_persistent());
474-
mutex_enter(&(rseg->mutex));
474+
mtr.start();
475+
ut_ad(rseg.is_persistent());
476+
mutex_enter(&rseg.mutex);
475477

476-
rseg_hdr = trx_rsegf_get(rseg->space, rseg->page_no, &mtr);
478+
rseg_hdr = trx_rsegf_get(rseg.space, rseg.page_no, &mtr);
477479

478480
hdr_addr = trx_purge_get_log_from_hist(
479481
flst_get_last(rseg_hdr + TRX_RSEG_HISTORY, &mtr));
480482
loop:
481483
if (hdr_addr.page == FIL_NULL) {
482-
483-
mutex_exit(&(rseg->mutex));
484-
485-
mtr_commit(&mtr);
486-
484+
func_exit:
485+
mutex_exit(&rseg.mutex);
486+
mtr.commit();
487487
return;
488488
}
489489

490-
undo_page = trx_undo_page_get(page_id_t(rseg->space, hdr_addr.page),
490+
undo_page = trx_undo_page_get(page_id_t(rseg.space, hdr_addr.page),
491491
&mtr);
492492

493493
log_hdr = undo_page + hdr_addr.boffset;
494494

495495
undo_trx_no = mach_read_from_8(log_hdr + TRX_UNDO_TRX_NO);
496496

497-
if (undo_trx_no >= limit->trx_no) {
498-
499-
/* limit space_id should match the rollback segment
500-
space id to avoid freeing of the page belongs to
501-
different rollback segment for the same trx_no. */
502-
if (undo_trx_no == limit->trx_no
503-
&& rseg->space == limit->undo_rseg_space) {
504-
497+
if (undo_trx_no >= limit.trx_no) {
498+
if (undo_trx_no == limit.trx_no) {
505499
trx_undo_truncate_start(
506-
rseg, hdr_addr.page,
507-
hdr_addr.boffset, limit->undo_no);
500+
&rseg, hdr_addr.page,
501+
hdr_addr.boffset, limit.undo_no);
508502
}
509503

510-
mutex_exit(&(rseg->mutex));
511-
mtr_commit(&mtr);
512-
513-
return;
504+
goto func_exit;
514505
}
515506

516507
prev_hdr_addr = trx_purge_get_log_from_hist(
@@ -523,24 +514,24 @@ trx_purge_truncate_rseg_history(trx_rseg_t* rseg, const purge_iter_t* limit)
523514

524515
/* We can free the whole log segment */
525516

526-
mutex_exit(&(rseg->mutex));
527-
mtr_commit(&mtr);
517+
mutex_exit(&rseg.mutex);
518+
mtr.commit();
528519

529520
/* calls the trx_purge_remove_log_hdr()
530521
inside trx_purge_free_segment(). */
531-
trx_purge_free_segment(rseg, hdr_addr);
522+
trx_purge_free_segment(&rseg, hdr_addr);
532523
} else {
533524
/* Remove the log hdr from the rseg history. */
534525
trx_purge_remove_log_hdr(rseg_hdr, log_hdr, &mtr);
535526

536-
mutex_exit(&(rseg->mutex));
537-
mtr_commit(&mtr);
527+
mutex_exit(&rseg.mutex);
528+
mtr.commit();
538529
}
539530

540-
mtr_start(&mtr);
541-
mutex_enter(&(rseg->mutex));
531+
mtr.start();
532+
mutex_enter(&rseg.mutex);
542533

543-
rseg_hdr = trx_rsegf_get(rseg->space, rseg->page_no, &mtr);
534+
rseg_hdr = trx_rsegf_get(rseg.space, rseg.page_no, &mtr);
544535

545536
hdr_addr = prev_hdr_addr;
546537

@@ -929,7 +920,7 @@ that resides in the tablespace are free.
929920
static
930921
void
931922
trx_purge_initiate_truncate(
932-
purge_iter_t* limit,
923+
const purge_sys_t::iterator& limit,
933924
undo::Truncate* undo_trunc)
934925
{
935926
/* Step-1: Early check to findout if any of the the UNDO tablespace
@@ -977,7 +968,7 @@ trx_purge_initiate_truncate(
977968
undo != NULL && all_free;
978969
undo = UT_LIST_GET_NEXT(undo_list, undo)) {
979970

980-
if (limit->trx_no < undo->trx_id) {
971+
if (limit.trx_no < undo->trx_id) {
981972
all_free = false;
982973
} else {
983974
cached_undo_size += undo->size;
@@ -1080,30 +1071,23 @@ trx_purge_initiate_truncate(
10801071
/**
10811072
Removes unnecessary history data from rollback segments. NOTE that when this
10821073
function is called, the caller must not have any latches on undo log pages!
1083-
1084-
@param[in] limit truncate limit
10851074
*/
1086-
static void trx_purge_truncate_history(purge_iter_t *limit)
1075+
static void trx_purge_truncate_history()
10871076
{
10881077
ut_ad(purge_sys->head <= purge_sys->tail);
1078+
purge_sys_t::iterator& head = purge_sys->head.trx_no
1079+
? purge_sys->head : purge_sys->tail;
10891080

1090-
/* We play safe and set the truncate limit at most to the purge view
1091-
low_limit number, though this is not necessary */
1092-
1093-
if (limit->trx_no >= purge_sys->view.low_limit_no()) {
1094-
limit->trx_no = purge_sys->view.low_limit_no();
1095-
limit->undo_no = 0;
1096-
limit->undo_rseg_space = ULINT_UNDEFINED;
1081+
if (head.trx_no >= purge_sys->view.low_limit_no()) {
1082+
/* This is sometimes necessary. TODO: find out why. */
1083+
head.trx_no = purge_sys->view.low_limit_no();
1084+
head.undo_no = 0;
10971085
}
10981086

1099-
ut_ad(limit->trx_no <= purge_sys->view.low_limit_no());
1100-
11011087
for (ulint i = 0; i < TRX_SYS_N_RSEGS; ++i) {
1102-
trx_rseg_t* rseg = trx_sys.rseg_array[i];
1103-
1104-
if (rseg != NULL) {
1105-
ut_a(rseg->id == i);
1106-
trx_purge_truncate_rseg_history(rseg, limit);
1088+
if (trx_rseg_t* rseg = trx_sys.rseg_array[i]) {
1089+
ut_ad(rseg->id == i);
1090+
trx_purge_truncate_rseg_history(*rseg, head);
11071091
}
11081092
}
11091093

@@ -1112,7 +1096,7 @@ static void trx_purge_truncate_history(purge_iter_t *limit)
11121096
try and truncate all the UNDO tablespaces. */
11131097
for (ulint i = srv_undo_tablespaces_active; i--; ) {
11141098
trx_purge_mark_undo_for_truncate(&purge_sys->undo_trunc);
1115-
trx_purge_initiate_truncate(limit, &purge_sys->undo_trunc);
1099+
trx_purge_initiate_truncate(head, &purge_sys->undo_trunc);
11161100
}
11171101
}
11181102

@@ -1139,7 +1123,6 @@ trx_purge_rseg_get_next_history_log(
11391123

11401124
purge_sys->tail.trx_no = rseg->last_trx_no + 1;
11411125
purge_sys->tail.undo_no = 0;
1142-
purge_sys->tail.undo_rseg_space = ULINT_UNDEFINED;
11431126
purge_sys->next_stored = false;
11441127

11451128
mtr_start(&mtr);
@@ -1216,7 +1199,6 @@ trx_purge_read_undo_rec()
12161199
ulint offset;
12171200
ulint page_no;
12181201
ib_uint64_t undo_no;
1219-
ulint undo_rseg_space;
12201202

12211203
purge_sys->hdr_offset = purge_sys->rseg->last_offset;
12221204
page_no = purge_sys->hdr_page_no = purge_sys->rseg->last_page_no;
@@ -1230,25 +1212,21 @@ trx_purge_read_undo_rec()
12301212

12311213
offset = page_offset(undo_rec);
12321214
undo_no = trx_undo_rec_get_undo_no(undo_rec);
1233-
undo_rseg_space = purge_sys->rseg->space;
12341215
page_no = page_get_page_no(page_align(undo_rec));
12351216
} else {
12361217
offset = 0;
12371218
undo_no = 0;
1238-
undo_rseg_space = ULINT_UNDEFINED;
12391219
}
12401220

12411221
mtr.commit();
12421222
} else {
12431223
offset = 0;
12441224
undo_no = 0;
1245-
undo_rseg_space = ULINT_UNDEFINED;
12461225
}
12471226

12481227
purge_sys->offset = offset;
12491228
purge_sys->page_no = page_no;
12501229
purge_sys->tail.undo_no = undo_no;
1251-
purge_sys->tail.undo_rseg_space = undo_rseg_space;
12521230

12531231
purge_sys->next_stored = true;
12541232
}
@@ -1352,7 +1330,6 @@ trx_purge_get_next_rec(
13521330
purge_sys->offset = rec2 - page;
13531331
purge_sys->page_no = page_get_page_no(page);
13541332
purge_sys->tail.undo_no = trx_undo_rec_get_undo_no(rec2);
1355-
purge_sys->tail.undo_rseg_space = space;
13561333

13571334
if (undo_page != page) {
13581335
/* We advance to a new page of the undo log: */
@@ -1667,10 +1644,7 @@ trx_purge(
16671644
ut_a(purge_sys->n_submitted == purge_sys->n_completed);
16681645

16691646
if (truncate) {
1670-
trx_purge_truncate_history(
1671-
purge_sys->head.trx_no
1672-
? &purge_sys->head
1673-
: &purge_sys->tail);
1647+
trx_purge_truncate_history();
16741648
}
16751649

16761650
MONITOR_INC_VALUE(MONITOR_PURGE_INVOKED, 1);

0 commit comments

Comments
 (0)