mirror of
https://github.com/MariaDB/server.git
synced 2026-05-15 19:37:16 +02:00
MDEV-26672 innodb_undo_log_truncate may reset transaction ID sequence
trx_rseg_header_create(): Add a parameter for the value that is
to be written to TRX_RSEG_MAX_TRX_ID. If we omit this write, then
the updated test innodb.undo_truncate will fail for the 4k, 8k, 16k
page sizes. This was broken ever since
commit 947efe17ed (MDEV-15158)
removed the writes of transaction identifiers to the TRX_SYS page.
srv_do_purge(): Truncate undo tablespaces also during slow shutdown
(innodb_fast_shutdown=0).
Thanks to Krunal Bauskar for noticing this problem.
This commit is contained in:
parent
b46cf33ab8
commit
4bfdba2e89
8 changed files with 37 additions and 37 deletions
|
|
@ -71,6 +71,7 @@ trx_rsegf_undo_find_free(const trx_rsegf_t* rsegf);
|
|||
/** Create a rollback segment header.
|
||||
@param[in,out] space system, undo, or temporary tablespace
|
||||
@param[in] rseg_id rollback segment identifier
|
||||
@param[in] max_trx_id new value of TRX_RSEG_MAX_TRX_ID
|
||||
@param[in,out] sys_header the TRX_SYS page (NULL for temporary rseg)
|
||||
@param[in,out] mtr mini-transaction
|
||||
@return the created rollback segment
|
||||
|
|
@ -79,6 +80,7 @@ buf_block_t*
|
|||
trx_rseg_header_create(
|
||||
fil_space_t* space,
|
||||
ulint rseg_id,
|
||||
trx_id_t max_trx_id,
|
||||
buf_block_t* sys_header,
|
||||
mtr_t* mtr);
|
||||
|
||||
|
|
|
|||
|
|
@ -2640,6 +2640,8 @@ static ulint srv_do_purge(ulint* n_total_purged
|
|||
n_pages_purged = trx_purge(
|
||||
n_use_threads,
|
||||
(++count % rseg_truncate_frequency) == 0
|
||||
|| (srv_shutdown_state != SRV_SHUTDOWN_NONE
|
||||
&& srv_fast_shutdown == 0)
|
||||
#ifdef UNIV_DEBUG
|
||||
, slot
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1029,6 +1029,8 @@ srv_undo_tablespaces_init(bool create_new_db)
|
|||
return DB_CORRUPTION;
|
||||
}
|
||||
|
||||
const trx_id_t max_trx_id = trx_sys.get_max_trx_id();
|
||||
|
||||
for (undo::undo_spaces_t::const_iterator it
|
||||
= undo::Truncate::s_fix_up_spaces.begin();
|
||||
it != undo::Truncate::s_fix_up_spaces.end();
|
||||
|
|
@ -1046,7 +1048,8 @@ srv_undo_tablespaces_init(bool create_new_db)
|
|||
if (trx_sysf_rseg_get_space(sys_header, i)
|
||||
== *it) {
|
||||
trx_rseg_header_create(
|
||||
space, i, sys_header, &mtr);
|
||||
space, i, max_trx_id,
|
||||
sys_header, &mtr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -977,7 +977,8 @@ not_found:
|
|||
for (ulint i = 0; i < undo_trunc->rsegs_size(); ++i) {
|
||||
trx_rseg_t* rseg = undo_trunc->get_ith_rseg(i);
|
||||
buf_block_t* rblock = trx_rseg_header_create(
|
||||
space, rseg->id, sys_header, &mtr);
|
||||
space, rseg->id, trx_sys.get_max_trx_id(),
|
||||
sys_header, &mtr);
|
||||
ut_ad(rblock);
|
||||
rseg->page_no = rblock ? rblock->page.id.page_no() : FIL_NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -286,6 +286,7 @@ void trx_rseg_format_upgrade(trx_rsegf_t* rseg_header, mtr_t* mtr)
|
|||
/** Create a rollback segment header.
|
||||
@param[in,out] space system, undo, or temporary tablespace
|
||||
@param[in] rseg_id rollback segment identifier
|
||||
@param[in] max_trx_id new value of TRX_RSEG_MAX_TRX_ID
|
||||
@param[in,out] sys_header the TRX_SYS page (NULL for temporary rseg)
|
||||
@param[in,out] mtr mini-transaction
|
||||
@return the created rollback segment
|
||||
|
|
@ -294,6 +295,7 @@ buf_block_t*
|
|||
trx_rseg_header_create(
|
||||
fil_space_t* space,
|
||||
ulint rseg_id,
|
||||
trx_id_t max_trx_id,
|
||||
buf_block_t* sys_header,
|
||||
mtr_t* mtr)
|
||||
{
|
||||
|
|
@ -319,6 +321,12 @@ trx_rseg_header_create(
|
|||
|
||||
mlog_write_ulint(TRX_RSEG + TRX_RSEG_HISTORY_SIZE + block->frame, 0,
|
||||
MLOG_4BYTES, mtr);
|
||||
|
||||
if (max_trx_id) {
|
||||
mlog_write_ull(TRX_RSEG + TRX_RSEG_MAX_TRX_ID + block->frame,
|
||||
max_trx_id, mtr);
|
||||
}
|
||||
|
||||
flst_init(TRX_RSEG + TRX_RSEG_HISTORY + block->frame, mtr);
|
||||
trx_rsegf_t* rsegf = TRX_RSEG + block->frame;
|
||||
|
||||
|
|
@ -684,7 +692,7 @@ trx_rseg_create(ulint space_id)
|
|||
ulint rseg_id = trx_sys_rseg_find_free(sys_header);
|
||||
if (buf_block_t* rblock = rseg_id == ULINT_UNDEFINED
|
||||
? NULL
|
||||
: trx_rseg_header_create(space, rseg_id, sys_header,
|
||||
: trx_rseg_header_create(space, rseg_id, 0, sys_header,
|
||||
&mtr)) {
|
||||
ut_ad(trx_sysf_rseg_get_space(sys_header, rseg_id)
|
||||
== space_id);
|
||||
|
|
@ -714,7 +722,7 @@ trx_temp_rseg_create()
|
|||
mtr_x_lock_space(fil_system.temp_space, &mtr);
|
||||
|
||||
buf_block_t* rblock = trx_rseg_header_create(
|
||||
fil_system.temp_space, i, NULL, &mtr);
|
||||
fil_system.temp_space, i, 0, NULL, &mtr);
|
||||
trx_rseg_t* rseg = trx_rseg_mem_create(
|
||||
i, fil_system.temp_space, rblock->page.id.page_no());
|
||||
ut_ad(!rseg->is_persistent());
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ trx_sysf_create(
|
|||
/* Create the first rollback segment in the SYSTEM tablespace */
|
||||
slot_no = trx_sys_rseg_find_free(block);
|
||||
buf_block_t* rblock = trx_rseg_header_create(fil_system.sys_space,
|
||||
slot_no, block, mtr);
|
||||
slot_no, 0, block, mtr);
|
||||
|
||||
ut_a(slot_no == TRX_SYS_SYSTEM_RSEG_ID);
|
||||
ut_a(rblock->page.id.page_no() == FSP_FIRST_RSEG_PAGE_NO);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue