summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorThirunarayanan Balathandayuthapani <thiru@mariadb.com>2021-02-25 20:51:30 +0530
committerThirunarayanan Balathandayuthapani <thiru@mariadb.com>2021-03-03 17:12:09 +0530
commit4b166ca901dedd928cf61949b4268b490a06a564 (patch)
treeb888c8aa779c6c7e1c0ca6d9da116bfdf8d84b68 /storage
parent01b44c054d608c7a7c3ee751a14782558d06275f (diff)
downloadmariadb-git-4b166ca901dedd928cf61949b4268b490a06a564.tar.gz
MDEV-24863 AHI entries mismatch with the index while reloading the evicted tables.
This is after-merge fix of f33e57a9e66f7e1790cb84b141381bb668e281a0. In btr_search_drop_page_hash_index(), InnoDB should take the exclusive lock on the AHI latch if index is already freed to avoid the freed memory access during buf_pool_resize()
Diffstat (limited to 'storage')
-rw-r--r--storage/innobase/btr/btr0sea.cc35
1 files changed, 25 insertions, 10 deletions
diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc
index 5c8f97b7bcf..b00009820a8 100644
--- a/storage/innobase/btr/btr0sea.cc
+++ b/storage/innobase/btr/btr0sea.cc
@@ -1279,13 +1279,24 @@ retry:
auto part = btr_search_sys.get_part(index_id,
block->page.id().space());
- rw_lock_s_lock(&part->latch);
+ dict_index_t* index = block->index;
+ bool is_freed = index && index->freed();
+
+ if (is_freed) {
+ rw_lock_x_lock(&part->latch);
+ } else {
+ rw_lock_s_lock(&part->latch);
+ }
+
assert_block_ahi_valid(block);
- dict_index_t* index = block->index;
if (!index || !btr_search_enabled) {
- rw_lock_s_unlock(&part->latch);
+ if (is_freed) {
+ rw_lock_x_unlock(&part->latch);
+ } else {
+ rw_lock_s_unlock(&part->latch);
+ }
return;
}
@@ -1304,7 +1315,9 @@ retry:
/* NOTE: The AHI fields of block must not be accessed after
releasing search latch, as the index page might only be s-latched! */
- rw_lock_s_unlock(&part->latch);
+ if (!is_freed) {
+ rw_lock_s_unlock(&part->latch);
+ }
ut_a(n_fields > 0 || n_bytes > 0);
@@ -1355,16 +1368,18 @@ next_rec:
mem_heap_free(heap);
}
- rw_lock_x_lock(&part->latch);
+ if (!is_freed) {
+ rw_lock_x_lock(&part->latch);
- if (UNIV_UNLIKELY(!block->index)) {
- /* Someone else has meanwhile dropped the hash index */
+ if (UNIV_UNLIKELY(!block->index)) {
+ /* Someone else has meanwhile dropped the
+ hash index */
+ goto cleanup;
+ }
- goto cleanup;
+ ut_a(block->index == index);
}
- ut_a(block->index == index);
-
if (block->curr_n_fields != n_fields
|| block->curr_n_bytes != n_bytes) {