diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2022-06-14 15:33:11 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2022-06-14 15:33:11 +0300 |
commit | 6c82ab4f726b83f09646c22afddd4c102e60607b (patch) | |
tree | 5e8a1857e25a87ca03f559e04aff7286ad565074 | |
parent | 6c669b9586f72d6d760cc3956c1a0cb09ace2367 (diff) | |
download | mariadb-git-6c82ab4f726b83f09646c22afddd4c102e60607b.tar.gz |
MDEV-28840 innodb_undo_log_truncate is not crash-safe
trx_purge_free_segment(): Do mark that the block will be modified.
It seems possible that this regression was introduced by the
changes to the page-freeing logic
in commit 4179f93d28035ea2798cb1c16feeaaef87ab4775 (MDEV-18976).
Tested by: Matthias Leich
-rw-r--r-- | storage/innobase/include/mtr0mtr.h | 2 | ||||
-rw-r--r-- | storage/innobase/include/mtr0mtr.inl | 2 | ||||
-rw-r--r-- | storage/innobase/trx/trx0purge.cc | 3 |
3 files changed, 4 insertions, 3 deletions
diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h index 02f469e3a53..8a2f862f47f 100644 --- a/storage/innobase/include/mtr0mtr.h +++ b/storage/innobase/include/mtr0mtr.h @@ -290,9 +290,9 @@ struct mtr_t { @param[in] type object type: MTR_MEMO_PAGE_X_FIX, ... */ void release_page(const void *ptr, mtr_memo_type_t type); -private: /** Note that the mini-transaction will modify data. */ void flag_modified() { m_modifications = true; } +private: /** Mark the given latched page as modified. @param block page that will be modified */ void modify(const buf_block_t& block); diff --git a/storage/innobase/include/mtr0mtr.inl b/storage/innobase/include/mtr0mtr.inl index 21ff912e9c7..71b476a2f5d 100644 --- a/storage/innobase/include/mtr0mtr.inl +++ b/storage/innobase/include/mtr0mtr.inl @@ -46,7 +46,7 @@ mtr_t::memo_push(void* object, mtr_memo_type_t type) ut_ad(object != NULL); ut_ad(type >= MTR_MEMO_PAGE_S_FIX); ut_ad(type <= MTR_MEMO_SPACE_S_LOCK); - ut_ad(ut_is_2pow(type)); + ut_ad(type == MTR_MEMO_PAGE_X_MODIFY || ut_is_2pow(type)); /* If this mtr has x-fixed a clean page then we set the made_dirty flag. This tells us if we need to diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc index 84d7d785490..e37efa733e2 100644 --- a/storage/innobase/trx/trx0purge.cc +++ b/storage/innobase/trx/trx0purge.cc @@ -402,8 +402,9 @@ static dberr_t trx_purge_free_segment(trx_rseg_t *rseg, fil_addr_t hdr_addr) block->fix(); mtr.commit(); mtr.start(); + mtr.flag_modified(); mtr.memo_push(rseg_hdr, MTR_MEMO_PAGE_X_FIX); - mtr.memo_push(block, MTR_MEMO_PAGE_X_FIX); + mtr.memo_push(block, MTR_MEMO_PAGE_X_MODIFY); rseg->latch.wr_lock(SRW_LOCK_CALL); rseg_hdr->page.lock.x_lock(); block->page.lock.x_lock(); |