diff options
author | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2020-02-24 19:30:06 +0530 |
---|---|---|
committer | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2020-03-03 15:15:11 +0530 |
commit | 8cc94e1f467c151c1152776dfc1a893b5e62363e (patch) | |
tree | 7805f01a30cb0b942233f435ce542faba70bfe53 | |
parent | 364045b2e8b6f1fcc9c2413d2f9d37b9536e10a9 (diff) | |
download | mariadb-git-8cc94e1f467c151c1152776dfc1a893b5e62363e.tar.gz |
MDEV-15528 Punch holes when pages are freed
- Addressed marko's review comments.
-rw-r--r-- | storage/innobase/buf/buf0buf.cc | 57 | ||||
-rw-r--r-- | storage/innobase/buf/buf0flu.cc | 10 | ||||
-rw-r--r-- | storage/innobase/fsp/fsp0fsp.cc | 29 | ||||
-rw-r--r-- | storage/innobase/include/buf0buf.h | 14 | ||||
-rw-r--r-- | storage/innobase/include/mtr0log.h | 13 | ||||
-rw-r--r-- | storage/innobase/include/mtr0mtr.h | 5 |
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 */ |