diff options
Diffstat (limited to 'storage')
-rw-r--r-- | storage/innobase/btr/btr0sea.cc | 71 |
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)); |