summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2022-06-14 15:33:11 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2022-06-14 15:33:11 +0300
commit6c82ab4f726b83f09646c22afddd4c102e60607b (patch)
tree5e8a1857e25a87ca03f559e04aff7286ad565074
parent6c669b9586f72d6d760cc3956c1a0cb09ace2367 (diff)
downloadmariadb-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.h2
-rw-r--r--storage/innobase/include/mtr0mtr.inl2
-rw-r--r--storage/innobase/trx/trx0purge.cc3
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();