diff options
author | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2021-02-25 20:51:30 +0530 |
---|---|---|
committer | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2021-03-03 17:12:09 +0530 |
commit | 4b166ca901dedd928cf61949b4268b490a06a564 (patch) | |
tree | b888c8aa779c6c7e1c0ca6d9da116bfdf8d84b68 /storage | |
parent | 01b44c054d608c7a7c3ee751a14782558d06275f (diff) | |
download | mariadb-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.cc | 35 |
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) { |