From 0765e9d17322075fad16fb4601bf18fe68ccff7b Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Fri, 24 Jul 2020 16:52:42 +0530 Subject: MDEV-23233: Race condition for btr_search_drop_page_hash_index() in buf_page_create() commit ad6171b91cac33e70bb28fa6865488b2c65e858c (MDEV-22456) introduced code to buf_page_create() that would lazily drop adaptive hash index entries for an index that has been evicted from the data dictionary cache. Unfortunately, that call was missing adequate protection. While the btr_search_drop_page_hash_index(block) was executing, the block could be reused for something else. buf_page_create(): If btr_search_drop_page_hash_index() must be invoked, pin the block before releasing the buf_pool->page_hash lock, so that the block cannot be grabbed by other threads. --- storage/innobase/buf/buf0buf.cc | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 2456b9aeb5f..ad53a11ea66 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -5584,15 +5584,30 @@ buf_page_create( && !buf_pool_watch_is_sentinel(buf_pool, &block->page)) { ut_d(block->page.file_page_was_freed = FALSE); +#ifdef BTR_CUR_HASH_ADAPT + bool drop_hash_entry = + (block->page.state == BUF_BLOCK_FILE_PAGE + && block->index); + + if (drop_hash_entry) { + mutex_enter(&block->mutex); + buf_page_set_sticky(&block->page); + mutex_exit(&block->mutex); + } +#endif /* Page can be found in buf_pool */ buf_pool_mutex_exit(buf_pool); rw_lock_x_unlock(hash_lock); buf_block_free(free_block); #ifdef BTR_CUR_HASH_ADAPT - if (block->page.state == BUF_BLOCK_FILE_PAGE - && UNIV_LIKELY_NULL(block->index)) { + if (drop_hash_entry) { btr_search_drop_page_hash_index(block); + buf_pool_mutex_enter(buf_pool); + mutex_enter(&block->mutex); + buf_page_unset_sticky(&block->page); + mutex_exit(&block->mutex); + buf_pool_mutex_exit(buf_pool); } #endif /* BTR_CUR_HASH_ADAPT */ -- cgit v1.2.1