diff options
-rw-r--r-- | storage/innobase/btr/btr0btr.cc | 4 | ||||
-rw-r--r-- | storage/innobase/btr/btr0cur.cc | 7 | ||||
-rw-r--r-- | storage/innobase/btr/btr0sea.cc | 39 | ||||
-rw-r--r-- | storage/innobase/buf/buf0buf.cc | 12 | ||||
-rw-r--r-- | storage/innobase/include/btr0sea.h | 17 | ||||
-rw-r--r-- | storage/innobase/mtr/mtr0mtr.cc | 13 |
6 files changed, 60 insertions, 32 deletions
diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index 7334a2e1757..3b994c5fa98 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -584,8 +584,8 @@ dberr_t btr_page_free(dict_index_t* index, buf_block_t* block, mtr_t* mtr, bool blob, bool space_latched) { ut_ad(mtr->memo_contains_flagged(block, MTR_MEMO_PAGE_X_FIX)); -#ifdef BTR_CUR_HASH_ADAPT - if (block->index && !block->index->freed()) +#if defined BTR_CUR_HASH_ADAPT && defined UNIV_DEBUG + if (btr_search_check_marked_free_index(block)) { ut_ad(!blob); ut_ad(page_is_leaf(block->page.frame)); diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index 7a9480cdf4e..4272c760f8d 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -283,7 +283,7 @@ latch_block: block->page.fix(); block->page.lock.x_lock(); #ifdef BTR_CUR_HASH_ADAPT - ut_ad(!block->index || !block->index->freed()); + ut_ad(!btr_search_check_marked_free_index(block)); #endif if (UNIV_LIKELY_NULL(rtr_info)) { @@ -7024,7 +7024,8 @@ btr_store_big_rec_extern_fields( rec_block->page.fix(); rec_block->page.lock.x_lock(); #ifdef BTR_CUR_HASH_ADAPT - ut_ad(!rec_block->index || !rec_block->index->freed()); + ut_ad(!btr_search_check_marked_free_index( + rec_block)); #endif uint32_t hint_prev = prev_page_no; @@ -7401,7 +7402,7 @@ skip_free: block->fix(); block->page.lock.x_lock(); #ifdef BTR_CUR_HASH_ADAPT - ut_ad(!block->index || !block->index->freed()); + ut_ad(!btr_search_check_marked_free_index(block)); #endif const page_t* page = buf_block_get_frame(ext_block); diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc index 137a8b10d9f..4fb3cfd5f68 100644 --- a/storage/innobase/btr/btr0sea.cc +++ b/storage/innobase/btr/btr0sea.cc @@ -1279,8 +1279,11 @@ fail_and_release_page: index page for which we know that block->buf_fix_count == 0 or it is an index page which has already been removed from the buf_pool.page_hash - i.e.: it is in state BUF_BLOCK_REMOVE_HASH */ -void btr_search_drop_page_hash_index(buf_block_t* block) + i.e.: it is in state BUF_BLOCK_REMOVE_HASH +@param[in] garbage_collect drop ahi only if the index is marked + as freed */ +void btr_search_drop_page_hash_index(buf_block_t* block, + bool garbage_collect) { ulint n_fields; ulint n_bytes; @@ -1316,13 +1319,21 @@ retry: auto part = btr_search_sys.get_part(index_id, block->page.id().space()); + part->latch.rd_lock(SRW_LOCK_CALL); + dict_index_t* index = block->index; bool is_freed = index && index->freed(); if (is_freed) { + part->latch.rd_unlock(); part->latch.wr_lock(SRW_LOCK_CALL); - } else { - part->latch.rd_lock(SRW_LOCK_CALL); + if (index != block->index) { + part->latch.wr_unlock(); + goto retry; + } + } else if (garbage_collect) { + part->latch.rd_unlock(); + return; } assert_block_ahi_valid(block); @@ -1797,12 +1808,13 @@ drop_exit: return; } + ahi_latch->rd_lock(SRW_LOCK_CALL); + if (index->freed()) { + ahi_latch->rd_unlock(); goto drop_exit; } - ahi_latch->rd_lock(SRW_LOCK_CALL); - if (block->index) { uint16_t n_fields = block->curr_n_fields; uint16_t n_bytes = block->curr_n_bytes; @@ -2394,5 +2406,20 @@ btr_search_validate() return(true); } +#ifdef UNIV_DEBUG +bool btr_search_check_marked_free_index(const buf_block_t *block) +{ + if (!block->index) + return false; + + btr_search_s_lock_all(); + + bool is_freed = block->index && block->index->freed(); + + btr_search_s_unlock_all(); + + return is_freed; +} +#endif #endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */ #endif /* BTR_CUR_HASH_ADAPT */ diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 42055246a12..c26bbda9473 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -2761,11 +2761,7 @@ re_evict: && state < buf_page_t::WRITE_FIX)); #ifdef BTR_CUR_HASH_ADAPT - if (dict_index_t* index = block->index) { - if (index->freed()) { - btr_search_drop_page_hash_index(block); - } - } + btr_search_drop_page_hash_index(block, true); #endif /* BTR_CUR_HASH_ADAPT */ dberr_t e; @@ -2823,10 +2819,8 @@ get_latch: } get_latch_valid: #ifdef BTR_CUR_HASH_ADAPT - if (dict_index_t* index = block->index) { - if (index->freed()) { - mtr_t::defer_drop_ahi(block, fix_type); - } + if (block->index) { + mtr_t::defer_drop_ahi(block, fix_type); } #endif /* BTR_CUR_HASH_ADAPT */ mtr->memo_push(block, fix_type); diff --git a/storage/innobase/include/btr0sea.h b/storage/innobase/include/btr0sea.h index 106582286a9..c66e412c27c 100644 --- a/storage/innobase/include/btr0sea.h +++ b/storage/innobase/include/btr0sea.h @@ -100,8 +100,11 @@ btr_search_move_or_delete_hash_entries( index page for which we know that block->buf_fix_count == 0 or it is an index page which has already been removed from the buf_pool.page_hash - i.e.: it is in state BUF_BLOCK_REMOVE_HASH */ -void btr_search_drop_page_hash_index(buf_block_t* block); + i.e.: it is in state BUF_BLOCK_REMOVE_HASH +@param[in] garbage_collect drop ahi only if the index is marked + as freed */ +void btr_search_drop_page_hash_index(buf_block_t* block, + bool garbage_collect= false); /** Drop possible adaptive hash index entries when a page is evicted from the buffer pool or freed in a file, or the index is being dropped. @@ -146,16 +149,24 @@ static inline void btr_search_s_lock_all(); /** Unlock all search latches from shared mode. */ static inline void btr_search_s_unlock_all(); +#ifdef UNIV_DEBUG +/** @return if the index is marked as freed */ +bool btr_search_check_marked_free_index(const buf_block_t *block); +#endif /* UNIV_DEBUG */ + #else /* BTR_CUR_HASH_ADAPT */ # define btr_search_sys_create() # define btr_search_sys_free() -# define btr_search_drop_page_hash_index(block) +# define btr_search_drop_page_hash_index(block,garbage_collect) # define btr_search_s_lock_all(index) # define btr_search_s_unlock_all(index) # define btr_search_info_update(index, cursor) # define btr_search_move_or_delete_hash_entries(new_block, block) # define btr_search_update_hash_on_insert(cursor, ahi_latch) # define btr_search_update_hash_on_delete(cursor) +#ifdef UNIV_DEBUG +# define btr_search_check_marked_free_index(block) +#endif /* UNIV_DEBUG */ #endif /* BTR_CUR_HASH_ADAPT */ #ifdef BTR_CUR_ADAPT diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc index 594982f07c2..108504f6353 100644 --- a/storage/innobase/mtr/mtr0mtr.cc +++ b/storage/innobase/mtr/mtr0mtr.cc @@ -1282,18 +1282,14 @@ void mtr_t::defer_drop_ahi(buf_block_t *block, mtr_memo_type_t fix_type) /* Temporarily release our S-latch. */ block->page.lock.s_unlock(); block->page.lock.x_lock(); - if (dict_index_t *index= block->index) - if (index->freed()) - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, true); block->page.lock.x_unlock(); block->page.lock.s_lock(); ut_ad(!block->page.is_read_fixed()); break; case MTR_MEMO_PAGE_SX_FIX: block->page.lock.u_x_upgrade(); - if (dict_index_t *index= block->index) - if (index->freed()) - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, true); block->page.lock.x_u_downgrade(); break; case MTR_MEMO_PAGE_X_FIX: @@ -1383,9 +1379,8 @@ void mtr_t::page_lock(buf_block_t *block, ulint rw_latch) } #ifdef BTR_CUR_HASH_ADAPT - if (dict_index_t *index= block->index) - if (index->freed()) - defer_drop_ahi(block, fix_type); + if (block->index) + defer_drop_ahi(block, fix_type); #endif /* BTR_CUR_HASH_ADAPT */ done: |