summaryrefslogtreecommitdiff
path: root/storage/innobase
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2022-11-15 16:56:13 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2022-11-15 16:56:13 +0200
commit0b25551a61878efb73e8b7802edf5cc69224846c (patch)
tree74816e742a6740f65fe628fd9563772754c8df49 /storage/innobase
parent72c728febaed52c98d8649a4e3259935f89452b4 (diff)
downloadmariadb-git-0b25551a61878efb73e8b7802edf5cc69224846c.tar.gz
MDEV-29999 innodb_undo_log_truncate=ON is not crash safe
If a log checkpoint occurs at the end LSN of mtr.commit_shrink(space) in trx_purge_truncate_history(), then recovery may fail because it could try to apply too old log records to too old copies of undo log pages. This was repeated with the following test: ./mtr innodb.undo_log_truncate,4k,strict_full_crc32 recv_sys_t::trim(): Move some code to the caller. recv_sys_t::apply(): For undo tablespace truncation, discard all old redo log for the undo tablespace, and then truncate the file to the desired size. Tested by: Matthias Leich
Diffstat (limited to 'storage/innobase')
-rw-r--r--storage/innobase/log/log0recv.cc20
1 files changed, 11 insertions, 9 deletions
diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc
index 8c8d87b974c..826ddf3ff49 100644
--- a/storage/innobase/log/log0recv.cc
+++ b/storage/innobase/log/log0recv.cc
@@ -745,14 +745,6 @@ inline void recv_sys_t::trim(const page_id_t page_id, lsn_t lsn)
pages.erase(r);
}
}
- if (fil_space_t* space = fil_space_get(page_id.space())) {
- ut_ad(UT_LIST_GET_LEN(space->chain) == 1);
- fil_node_t* file = UT_LIST_GET_FIRST(space->chain);
- ut_ad(file->is_open());
- os_file_truncate(file->name, file->handle,
- os_offset_t{page_id.page_no()}
- << srv_page_size_shift, true);
- }
DBUG_VOID_RETURN;
}
@@ -2694,7 +2686,17 @@ void recv_sys_t::apply(bool last_batch)
{
const trunc& t= truncated_undo_spaces[id];
if (t.lsn)
- trim(page_id_t(id + srv_undo_space_id_start, t.pages), t.lsn);
+ {
+ trim(page_id_t(id + srv_undo_space_id_start, 0), t.lsn);
+ if (fil_space_t *space = fil_space_get(id + srv_undo_space_id_start))
+ {
+ ut_ad(UT_LIST_GET_LEN(space->chain) == 1);
+ fil_node_t *file= UT_LIST_GET_FIRST(space->chain);
+ ut_ad(file->is_open());
+ os_file_truncate(file->name, file->handle,
+ os_offset_t{t.pages} << srv_page_size_shift, true);
+ }
+ }
}
fil_system.extend_to_recv_size();