summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
Diffstat (limited to 'storage')
-rw-r--r--storage/innobase/btr/btr0sea.cc71
1 files changed, 57 insertions, 14 deletions
diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc
index 79e6326ac1c..7b80d22c778 100644
--- a/storage/innobase/btr/btr0sea.cc
+++ b/storage/innobase/btr/btr0sea.cc
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
-Copyright (c) 2017, 2020, MariaDB Corporation.
+Copyright (c) 2017, 2021, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -624,6 +624,12 @@ btr_search_update_hash_ref(
return;
}
+ if (cursor->index != index) {
+ ut_ad(cursor->index->id == index->id);
+ btr_search_drop_page_hash_index(block);
+ return;
+ }
+
ut_ad(block->page.id.space() == index->space);
ut_a(index == cursor->index);
ut_ad(!dict_index_is_ibuf(index));
@@ -1139,18 +1145,28 @@ retry:
% btr_ahi_parts;
latch = btr_search_latches[ahi_slot];
+ dict_index_t* index = block->index;
ut_ad(!btr_search_own_any(RW_LOCK_S));
ut_ad(!btr_search_own_any(RW_LOCK_X));
- rw_lock_s_lock(latch);
+ bool is_freed = index && index->freed();
+ if (is_freed) {
+ rw_lock_x_lock(latch);
+ } else {
+ rw_lock_s_lock(latch);
+ }
+
assert_block_ahi_valid(block);
- if (!block->index || !btr_search_enabled) {
- rw_lock_s_unlock(latch);
+ if (!index || !btr_search_enabled) {
+ if (is_freed) {
+ rw_lock_x_unlock(latch);
+ } else {
+ rw_lock_s_unlock(latch);
+ }
return;
}
- dict_index_t* index = block->index;
#ifdef MYSQL_INDEX_DISABLE_AHI
ut_ad(!index->disable_ahi);
#endif
@@ -1167,7 +1183,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(latch);
+ if (!is_freed) {
+ rw_lock_s_unlock(latch);
+ }
ut_a(n_fields > 0 || n_bytes > 0);
@@ -1215,16 +1233,18 @@ next_rec:
mem_heap_free(heap);
}
- rw_lock_x_lock(latch);
+ if (!is_freed) {
+ rw_lock_x_lock(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) {
@@ -1544,19 +1564,25 @@ btr_search_move_or_delete_hash_entries(
rw_lock_s_lock(latch);
ut_a(!new_block->index || new_block->index == index);
- ut_a(!block->index || block->index == index);
+ ut_a(!block->index || block->index->id == index->id);
ut_ad(!(new_block->index || block->index)
|| !dict_index_is_ibuf(index));
assert_block_ahi_valid(block);
assert_block_ahi_valid(new_block);
if (new_block->index) {
+drop_exit:
rw_lock_s_unlock(latch);
btr_search_drop_page_hash_index(block);
return;
}
if (block->index) {
+
+ if (block->index != index) {
+ goto drop_exit;
+ }
+
ulint n_fields = block->curr_n_fields;
ulint n_bytes = block->curr_n_bytes;
ibool left_side = block->curr_left_side;
@@ -1576,7 +1602,6 @@ btr_search_move_or_delete_hash_entries(
ut_ad(left_side == block->curr_left_side);
return;
}
-
rw_lock_s_unlock(latch);
}
@@ -1616,6 +1641,12 @@ btr_search_update_hash_on_delete(btr_cur_t* cursor)
return;
}
+ if (index != cursor->index) {
+ ut_ad(index->id == cursor->index->id);
+ btr_search_drop_page_hash_index(block);
+ return;
+ }
+
ut_ad(block->page.id.space() == index->space);
ut_a(index == cursor->index);
ut_a(block->curr_n_fields > 0 || block->curr_n_bytes > 0);
@@ -1688,6 +1719,12 @@ btr_search_update_hash_node_on_insert(btr_cur_t* cursor)
return;
}
+ if (cursor->index != index) {
+ ut_ad(cursor->index->id == index->id);
+ btr_search_drop_page_hash_index(block);
+ return;
+ }
+
ut_a(cursor->index == index);
ut_ad(!dict_index_is_ibuf(index));
@@ -1774,6 +1811,12 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor)
#ifdef MYSQL_INDEX_DISABLE_AHI
ut_a(!index->disable_ahi);
#endif
+ if (index != cursor->index) {
+ ut_ad(index->id == cursor->index->id);
+ btr_search_drop_page_hash_index(block);
+ return;
+ }
+
ut_a(index == cursor->index);
ut_ad(!dict_index_is_ibuf(index));