summaryrefslogtreecommitdiff
path: root/storage/innobase/btr/btr0sea.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/btr/btr0sea.cc')
-rw-r--r--storage/innobase/btr/btr0sea.cc71
1 files changed, 58 insertions, 13 deletions
diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc
index 6a1163e5cf9..b541f92c648 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
@@ -666,6 +666,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->table->space_id);
ut_ad(index == cursor->index);
ut_ad(!dict_index_is_ibuf(index));
@@ -1125,15 +1131,26 @@ retry:
% btr_ahi_parts;
latch = btr_search_latches[ahi_slot];
- rw_lock_s_lock(latch);
+ dict_index_t* index = block->index;
+
+ 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
@@ -1149,7 +1166,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);
@@ -1200,16 +1219,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) {
@@ -1583,6 +1604,7 @@ btr_search_move_or_delete_hash_entries(
rw_lock_t* ahi_latch = index ? btr_get_search_latch(index) : NULL;
if (new_block->index) {
+drop_exit:
btr_search_drop_page_hash_index(block);
return;
}
@@ -1594,6 +1616,12 @@ btr_search_move_or_delete_hash_entries(
rw_lock_s_lock(ahi_latch);
if (block->index) {
+
+ if (block->index != index) {
+ rw_lock_s_unlock(ahi_latch);
+ goto drop_exit;
+ }
+
ulint n_fields = block->curr_n_fields;
ulint n_bytes = block->curr_n_bytes;
ibool left_side = block->curr_left_side;
@@ -1614,7 +1642,6 @@ btr_search_move_or_delete_hash_entries(
ut_ad(left_side == block->curr_left_side);
return;
}
-
rw_lock_s_unlock(ahi_latch);
}
@@ -1652,6 +1679,12 @@ void 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->table->space_id);
ut_a(index == cursor->index);
ut_a(block->curr_n_fields > 0 || block->curr_n_bytes > 0);
@@ -1725,6 +1758,12 @@ btr_search_update_hash_node_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch)
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));
rw_lock_x_lock(ahi_latch);
@@ -1814,6 +1853,12 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch)
#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));