summaryrefslogtreecommitdiff
path: root/storage/innobase/buf/buf0buf.cc
diff options
context:
space:
mode:
authorThirunarayanan Balathandayuthapani <thiru@mariadb.com>2020-07-24 16:52:42 +0530
committerThirunarayanan Balathandayuthapani <thiru@mariadb.com>2020-07-27 22:17:51 +0530
commita1f899a8abb6bb0b046db28d6da9dd4b7fc3c8c4 (patch)
tree2602d073c9e4522d8e28233150749c7b54e70d0d /storage/innobase/buf/buf0buf.cc
parentb4c742108f8cd2d2ebe70a98d8c621a34a8b891a (diff)
downloadmariadb-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.cc19
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 */