summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--storage/innobase/btr/btr0btr.cc4
-rw-r--r--storage/innobase/btr/btr0cur.cc7
-rw-r--r--storage/innobase/btr/btr0sea.cc39
-rw-r--r--storage/innobase/buf/buf0buf.cc12
-rw-r--r--storage/innobase/include/btr0sea.h17
-rw-r--r--storage/innobase/mtr/mtr0mtr.cc13
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: