diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2022-11-15 16:56:13 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2022-11-15 16:56:13 +0200 |
commit | 0b25551a61878efb73e8b7802edf5cc69224846c (patch) | |
tree | 74816e742a6740f65fe628fd9563772754c8df49 /storage/innobase | |
parent | 72c728febaed52c98d8649a4e3259935f89452b4 (diff) | |
download | mariadb-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.cc | 20 |
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(); |