diff options
author | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2020-07-24 16:52:42 +0530 |
---|---|---|
committer | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2020-07-27 22:17:51 +0530 |
commit | a1f899a8abb6bb0b046db28d6da9dd4b7fc3c8c4 (patch) | |
tree | 2602d073c9e4522d8e28233150749c7b54e70d0d /storage/innobase/buf/buf0buf.cc | |
parent | b4c742108f8cd2d2ebe70a98d8c621a34a8b891a (diff) | |
download | mariadb-git-a1f899a8abb6bb0b046db28d6da9dd4b7fc3c8c4.tar.gz |
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.
Diffstat (limited to 'storage/innobase/buf/buf0buf.cc')
-rw-r--r-- | storage/innobase/buf/buf0buf.cc | 19 |
1 files 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 */ |