diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2022-08-22 16:22:09 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2022-08-22 16:22:09 +0300 |
commit | b68ae6dc1d2bba7f5b9f12bff129cd8066fe6d21 (patch) | |
tree | b4d41c9ad711824e80fee8313bbc00a560cfc021 | |
parent | 316847eab72022cd11351ea1bfa91234bee75839 (diff) | |
parent | c7f8cfc9e733517cff4aaa6f6eaca625a3afc098 (diff) | |
download | mariadb-git-b68ae6dc1d2bba7f5b9f12bff129cd8066fe6d21.tar.gz |
Merge 10.3 into 10.4
-rw-r--r-- | storage/innobase/btr/btr0btr.cc | 5 | ||||
-rw-r--r-- | storage/innobase/btr/btr0sea.cc | 36 | ||||
-rw-r--r-- | storage/innobase/buf/buf0buf.cc | 13 | ||||
-rw-r--r-- | storage/innobase/include/btr0sea.h | 18 | ||||
-rw-r--r-- | storage/innobase/include/btr0sea.inl | 13 |
5 files changed, 63 insertions, 22 deletions
diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index 12666bdf18b..67ac5e357f6 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -732,8 +732,9 @@ void btr_page_free(dict_index_t* index, buf_block_t* block, mtr_t* mtr, bool blob) { ut_ad(mtr_memo_contains(mtr, 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 (block->index + && !btr_search_check_marked_free_index(block)) { ut_ad(!blob); ut_ad(page_is_leaf(block->frame)); } diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc index 9b9adf541e7..2e86d27cc0e 100644 --- a/storage/innobase/btr/btr0sea.cc +++ b/storage/innobase/btr/btr0sea.cc @@ -1095,8 +1095,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; @@ -1142,13 +1145,21 @@ 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_s_unlock(latch); rw_lock_x_lock(latch); - } else { - rw_lock_s_lock(latch); + if (index != block->index) { + rw_lock_x_unlock(latch); + goto retry; + } + } else if (garbage_collect) { + rw_lock_s_unlock(latch); + return; } assert_block_ahi_valid(block); @@ -2213,5 +2224,22 @@ btr_search_validate() return(true); } +#ifdef UNIV_DEBUG +bool btr_search_check_marked_free_index(const buf_block_t *block) +{ + const index_id_t index_id= btr_page_get_index_id(block->frame); + + rw_lock_t *ahi_latch= btr_get_search_latch( + index_id, block->page.id.space()); + + rw_lock_s_lock(ahi_latch); + + bool is_freed= block->index && block->index->freed(); + + rw_lock_s_unlock(ahi_latch); + + return is_freed; +} +#endif /* UNIV_DEBUG */ #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 a127e785cd9..060b5da362f 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -3915,18 +3915,14 @@ static void buf_defer_drop_ahi(buf_block_t *block, mtr_memo_type_t fix_type) /* Temporarily release our S-latch. */ rw_lock_s_unlock(&block->lock); rw_lock_x_lock(&block->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); rw_lock_x_unlock(&block->lock); rw_lock_s_lock(&block->lock); break; case MTR_MEMO_PAGE_SX_FIX: rw_lock_sx_unlock(&block->lock); rw_lock_x_lock(&block->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); rw_lock_x_unlock(&block->lock); rw_lock_sx_lock(&block->lock); break; @@ -3973,8 +3969,7 @@ static buf_block_t* buf_page_mtr_lock(buf_block_t *block, #ifdef BTR_CUR_HASH_ADAPT { - dict_index_t *index= block->index; - if (index && index->freed()) + if (block->index) buf_defer_drop_ahi(block, fix_type); } #endif /* BTR_CUR_HASH_ADAPT */ @@ -4899,7 +4894,7 @@ buf_page_get_known_nowait( # ifdef BTR_CUR_HASH_ADAPT ut_ad(!block->page.file_page_was_freed - || (block->index && block->index->freed())); + || btr_search_check_marked_free_index(block)); # else /* BTR_CUR_HASH_ADAPT */ ut_ad(!block->page.file_page_was_freed); # endif /* BTR_CUR_HASH_ADAPT */ diff --git a/storage/innobase/include/btr0sea.h b/storage/innobase/include/btr0sea.h index 8ed0a13f0b5..8277be8ac14 100644 --- a/storage/innobase/include/btr0sea.h +++ b/storage/innobase/include/btr0sea.h @@ -99,8 +99,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. @@ -173,16 +176,25 @@ A table is selected from an array of tables using pair of index-id, space-id. @param[in] index index handler @return hash table */ static inline hash_table_t* btr_get_search_table(const dict_index_t* index); + +#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(size) # 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/include/btr0sea.inl b/storage/innobase/include/btr0sea.inl index 9db0084ce59..b07f3882fd2 100644 --- a/storage/innobase/include/btr0sea.inl +++ b/storage/innobase/include/btr0sea.inl @@ -158,6 +158,14 @@ static inline bool btr_search_own_any() } #endif /* UNIV_DEBUG */ +static inline rw_lock_t* btr_get_search_latch( + index_id_t index_id, ulint space_id) +{ + ulint ifold = ut_fold_ulint_pair(ulint(index_id), space_id); + + return(btr_search_latches[ifold % btr_ahi_parts]); +} + /** Get the adaptive hash search index latch for a b-tree. @param[in] index b-tree index @return latch */ @@ -167,10 +175,7 @@ static inline rw_lock_t* btr_get_search_latch(const dict_index_t* index) ut_ad(!index->table->space || index->table->space->id == index->table->space_id); - ulint ifold = ut_fold_ulint_pair(ulint(index->id), - index->table->space_id); - - return(btr_search_latches[ifold % btr_ahi_parts]); + return btr_get_search_latch(index->id, index->table->space_id); } /** Get the hash-table based on index attributes. |