summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThirunarayanan Balathandayuthapani <thiru@mariadb.com>2020-02-24 19:30:06 +0530
committerThirunarayanan Balathandayuthapani <thiru@mariadb.com>2020-03-03 15:15:11 +0530
commit8cc94e1f467c151c1152776dfc1a893b5e62363e (patch)
tree7805f01a30cb0b942233f435ce542faba70bfe53
parent364045b2e8b6f1fcc9c2413d2f9d37b9536e10a9 (diff)
downloadmariadb-git-8cc94e1f467c151c1152776dfc1a893b5e62363e.tar.gz
MDEV-15528 Punch holes when pages are freed
- Addressed marko's review comments.
-rw-r--r--storage/innobase/buf/buf0buf.cc57
-rw-r--r--storage/innobase/buf/buf0flu.cc10
-rw-r--r--storage/innobase/fsp/fsp0fsp.cc29
-rw-r--r--storage/innobase/include/buf0buf.h14
-rw-r--r--storage/innobase/include/mtr0log.h13
-rw-r--r--storage/innobase/include/mtr0mtr.h5
6 files changed, 91 insertions, 37 deletions
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index c4a9b1a8176..984b9982324 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -4507,6 +4507,63 @@ buf_page_try_get_func(
return(block);
}
+/** Mark the page status as FREED for the given tablespace id and
+page number. If the page is not in the buffer pool then ignore it.
+@param[in] page_id page id
+@param[in,out] mtr mini-transaction
+@param[in] file file name
+@param[in] line line where called */
+void buf_page_free(
+ const page_id_t page_id,
+ mtr_t* mtr,
+ const char* file,
+ unsigned line)
+{
+ buf_block_t* block;
+ rw_lock_t* hash_lock;
+
+ ut_ad(mtr);
+ ut_ad(mtr->is_active());
+
+ buf_pool->stat.n_page_gets++;
+ hash_lock = buf_page_hash_lock_get(page_id);
+ rw_lock_s_lock(hash_lock);
+
+ /* page_hash can be changed. */
+ hash_lock = buf_page_hash_lock_s_confirm(hash_lock, page_id);
+
+ block = (buf_block_t*) buf_page_hash_get_low(page_id);
+
+ if (!block) {
+ /* Page is not in buffer pool */
+ rw_lock_s_unlock(hash_lock);
+ return;
+ }
+ block->fix();
+
+ /* Now safe to release page_hash mutex */
+ rw_lock_s_unlock(hash_lock);
+
+ ut_ad(block->page.buf_fix_count > 0);
+
+#ifdef UNIV_DEBUG
+ if (!fsp_is_system_temporary(page_id.space())) {
+ ibool ret;
+ ret = rw_lock_s_lock_nowait(
+ block->debug_latch, file, line);
+ ut_a(ret);
+ }
+#endif /* UNIV_DEBUG */
+
+ mtr_memo_type_t fix_type = MTR_MEMO_PAGE_X_FIX;
+ rw_lock_x_lock_inline(&block->lock, 0, file, line);
+ mtr_memo_push(mtr, block, fix_type);
+
+ block->page.status = FREED;
+ buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
+ buf_pool->stat.n_page_gets++;
+}
+
/********************************************************************//**
Initialize some fields of a control block. */
UNIV_INLINE
diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc
index 8c929c44a94..07e60eee5d1 100644
--- a/storage/innobase/buf/buf0flu.cc
+++ b/storage/innobase/buf/buf0flu.cc
@@ -1117,7 +1117,7 @@ buf_flush_write_block_low(
if (bpage->status == FREED) {
/** Zero out the page if the page is freed */
- memset(frame, 0, bpage->physical_size());
+ frame = const_cast<byte*>(field_ref_zero);
}
const bool use_doublewrite = (bpage->status == NORMAL)
@@ -1203,6 +1203,7 @@ bool buf_flush_page(buf_page_t* bpage, buf_flush_t flush_type, bool sync)
shutting down */
if (!srv_undo_sources
&& fsp_is_system_temporary(bpage->id.space())) {
+remove_flush:
buf_flush_remove(bpage);
return false;
}
@@ -1210,13 +1211,12 @@ bool buf_flush_page(buf_page_t* bpage, buf_flush_t flush_type, bool sync)
/* Ignore the flushing of freed page */
if (bpage->status == FREED) {
if (!srv_immediate_scrub_data_uncompressed) {
- buf_flush_remove(bpage);
- return false;
+ goto remove_flush;
}
}
- bool is_uncompressed = (buf_page_get_state(bpage)
- == BUF_BLOCK_FILE_PAGE);
+ const bool is_uncompressed = (buf_page_get_state(bpage)
+ == BUF_BLOCK_FILE_PAGE);
ut_ad(is_uncompressed == (block_mutex != &buf_pool->zip_mutex));
diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc
index bcf76cc1f84..5b0cc94cbb4 100644
--- a/storage/innobase/fsp/fsp0fsp.cc
+++ b/storage/innobase/fsp/fsp0fsp.cc
@@ -1262,14 +1262,11 @@ static void fsp_free_page(fil_space_t* space, page_no_t offset, mtr_t* mtr)
return;
}
- page_id_t drop_page_id(space->id, offset);
-
- buf_block_t* block = buf_page_get_gen(
- drop_page_id, 0, RW_X_LATCH, NULL,
- BUF_GET_IF_IN_POOL, __FILE__, __LINE__,
- mtr, NULL);
-
- mtr->free(drop_page_id, block);
+ {
+ const page_id_t page_id(space->id, offset);
+ mtr->free(page_id);
+ buf_page_free(page_id, mtr, __FILE__, __LINE__);
+ }
const ulint bit = offset % FSP_EXTENT_SIZE;
@@ -2733,14 +2730,10 @@ fseg_free_extent(
for (ulint i = 0; i < FSP_EXTENT_SIZE; i++) {
if (!xdes_is_free(descr, i)) {
- const page_id_t drop_page_id(
+ const page_id_t page_id(
space->id, first_page_in_extent + i);
-
- buf_block_t* block = buf_page_get_gen(
- drop_page_id, 0, RW_X_LATCH, NULL,
- BUF_GET_IF_IN_POOL, __FILE__, __LINE__,
- mtr, NULL);
- mtr->free(drop_page_id, block);
+ mtr->free(page_id);
+ buf_page_free(page_id, mtr, __FILE__, __LINE__);
}
}
@@ -2840,10 +2833,10 @@ fseg_free_step_func(
DBUG_RETURN(true);
}
- ulint offset = fseg_get_nth_frag_page_no(inode, n, mtr);
-
fseg_free_page_low(
- inode, iblock, space, offset, ahi, mtr);
+ inode, iblock, space,
+ fseg_get_nth_frag_page_no(inode, n, mtr),
+ ahi, mtr);
n = fseg_find_last_used_frag_page_slot(inode, mtr);
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index a8968259bfd..5fb76cb3027 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -336,6 +336,18 @@ the same set of mutexes or latches.
@return pointer to the block */
buf_page_t* buf_page_get_zip(const page_id_t page_id, ulint zip_size);
+/** Mark the page status as FREED for the given tablespace id and
+page number. If the page is not in the buffer pool then ignore it.
+@param[in] page_id page id
+@param[in,out] mtr mini-transaction
+@param[in] file file name
+@param[in] line line where called */
+void buf_page_free(
+ const page_id_t page_id,
+ mtr_t* mtr,
+ const char* file,
+ unsigned line);
+
/** This is the general function used to get access to a database page.
@param[in] page_id page id
@param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0
@@ -1192,7 +1204,7 @@ enum page_status_t {
X-latch and reset during page flush, while io_fix is in effect. */
INIT_ON_FLUSH,
/** FSP frees a page in buffer pool. protected by
- buf_pool->zip_mutex or buf_block_t::mutex */
+ buf_pool_t::zip_mutex or buf_block_t::mutex */
FREED
};
diff --git a/storage/innobase/include/mtr0log.h b/storage/innobase/include/mtr0log.h
index fffe776327b..1ea760e528a 100644
--- a/storage/innobase/include/mtr0log.h
+++ b/storage/innobase/include/mtr0log.h
@@ -510,22 +510,15 @@ inline void mtr_t::init(buf_block_t *b)
m_log.close(log_write<INIT_PAGE>(b->page.id, &b->page));
m_last_offset= FIL_PAGE_TYPE;
- b->page.status = INIT_ON_FLUSH;
+ b->page.status= INIT_ON_FLUSH;
}
/** Free a page.
-@param id page identifier
-@param block block descriptor or NULL if drop page
- doesn't exist in buffer pool */
-inline void mtr_t::free(const page_id_t id, buf_block_t* block)
+@param id page identifier */
+inline void mtr_t::free(const page_id_t id)
{
if (m_log_mode == MTR_LOG_ALL)
m_log.close(log_write<FREE_PAGE>(id, nullptr));
-
- fprintf(stderr, "freeing id %d:%d block %p\n",
- id.space(), id.page_no(), block);
- if (block)
- block->page.status = FREED;
}
/** Write an EXTENDED log record.
diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h
index 245fa974608..f434bd8a535 100644
--- a/storage/innobase/include/mtr0mtr.h
+++ b/storage/innobase/include/mtr0mtr.h
@@ -488,9 +488,8 @@ struct mtr_t {
@param[in,out] b buffer page */
void init(buf_block_t *b);
/** Free a page.
- @param id page identifier
- @param block buffer block */
- inline void free(const page_id_t id, buf_block_t *block);
+ @param id page identifier */
+ inline void free(const page_id_t id);
/** Partly initialize a B-tree page.
@param block B-tree page
@param comp false=ROW_FORMAT=REDUNDANT, true=COMPACT or DYNAMIC */