summaryrefslogtreecommitdiff
path: root/storage/innobase/mtr/mtr0mtr.cc
diff options
context:
space:
mode:
authorThirunarayanan Balathandayuthapani <thiru@mariadb.com>2020-06-11 22:52:47 +0530
committerThirunarayanan Balathandayuthapani <thiru@mariadb.com>2020-06-12 09:17:51 +0530
commitc92f7e287fc0e21dc1b181284b1f8e2139d1c331 (patch)
tree259aa446838140f83ec4d5f8fd8d6aa9301d2652 /storage/innobase/mtr/mtr0mtr.cc
parent07d1c8567cbfe94398a9857c47fb9919cad42651 (diff)
downloadmariadb-git-c92f7e287fc0e21dc1b181284b1f8e2139d1c331.tar.gz
MDEV-8139 Fix Scrubbing
fil_space_t::freed_ranges: Store ranges of freed page numbers. fil_space_t::last_freed_lsn: Store the most recent LSN of freeing a page. fil_space_t::freed_mutex: Protects freed_ranges, last_freed_lsn. fil_space_create(): Initialize the freed_range mutex. fil_space_free_low(): Frees the freed_range mutex. range_set: Ranges of page numbers. buf_page_create(): Removes the page from freed_ranges when page is being reused. btr_free_root(): Remove the PAGE_INDEX_ID invalidation. Because btr_free_root() and dict_drop_index_tree() are executed in the same atomic mini-transaction, there is no need to invalidate the root page. buf_release_freed_page(): Split from buf_flush_freed_page(). Skip any I/O buf_flush_freed_pages(): Get the freed ranges from tablespace and Write punch-hole or zeroes of the freed ranges. buf_flush_try_neighbors(): Handles the flushing of freed ranges. mtr_t::freed_pages: Variable to store the list of freed pages. mtr_t::add_freed_pages(): To add freed pages. mtr_t::clear_freed_pages(): To clear the freed pages. mtr_t::m_freed_in_system_tablespace: Variable to indicate whether page has been freed in system tablespace. mtr_t::m_trim_pages: Variable to indicate whether the space has been trimmed. mtr_t::commit(): Add the freed page and update the last freed lsn in the tablespace and clear the tablespace freed range if space is trimmed. file_name_t::freed_pages: Store the freed pages during recovery. file_name_t::add_freed_page(), file_name_t::remove_freed_page(): To add and remove freed page during recovery. store_freed_or_init_rec(): Store or remove the freed pages while encountering FREE_PAGE or INIT_PAGE redo log record. recv_init_crash_recovery_spaces(): Add the freed page encountered during recovery to respective tablespace.
Diffstat (limited to 'storage/innobase/mtr/mtr0mtr.cc')
-rw-r--r--storage/innobase/mtr/mtr0mtr.cc28
1 files changed, 28 insertions, 0 deletions
diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc
index 8ca0fe65f1e..32e31ee84f4 100644
--- a/storage/innobase/mtr/mtr0mtr.cc
+++ b/storage/innobase/mtr/mtr0mtr.cc
@@ -372,6 +372,7 @@ void mtr_t::start()
ut_d(m_user_space_id= TRX_SYS_SPACE);
m_user_space= nullptr;
m_commit_lsn= 0;
+ m_freed_in_system_tablespace= m_trim_pages= false;
}
/** Release the resources */
@@ -381,6 +382,7 @@ inline void mtr_t::release_resources()
ut_d(m_memo.for_each_block_in_reverse(CIterate<DebugCheck>()));
m_log.erase();
m_memo.erase();
+ clear_freed_ranges();
ut_d(m_commit= true);
}
@@ -413,6 +415,30 @@ void mtr_t::commit()
to insert into the flush list. */
log_mutex_exit();
+ if (!m_freed_ranges.empty())
+ {
+ fil_space_t *freed_space= m_user_space;
+ /* Get the freed tablespace in case of predefined tablespace */
+ if (!freed_space)
+ {
+ ut_ad(is_freed_system_tablespace_page());
+ freed_space= fil_system.sys_space;
+ }
+
+ ut_ad(memo_contains(freed_space->latch, MTR_MEMO_X_LOCK));
+ /* Update the last freed lsn */
+ freed_space->update_last_freed_lsn(m_commit_lsn);
+
+ for (const auto &range : m_freed_ranges)
+ freed_space->add_free_range(range);
+ }
+
+ if (is_trim_pages())
+ {
+ ut_ad(m_user_space != nullptr);
+ m_user_space->clear_freed_ranges();
+ }
+
m_memo.for_each_block_in_reverse(CIterate<const ReleaseBlocks>
(ReleaseBlocks(start_lsn, m_commit_lsn)));
if (m_made_dirty)
@@ -441,6 +467,8 @@ void mtr_t::commit_files(lsn_t checkpoint_lsn)
ut_ad(!m_made_dirty);
ut_ad(m_memo.size() == 0);
ut_ad(!srv_read_only_mode);
+ ut_ad(m_freed_ranges.empty());
+ ut_ad(!m_freed_in_system_tablespace);
if (checkpoint_lsn) {
byte* ptr = m_log.push<byte*>(SIZE_OF_FILE_CHECKPOINT);