Skip to content

Commit 5f7b2a3

Browse files
committed
MDEV-35049: Improve btr_search_drop_page_hash_index()
btr_search_drop_page_hash_index(): Replace the Boolean parameter with const dict_index_t *not_garbage. If buf_block_t::index points to that, there is no need to acquire btr_sea::partition::latch. The old parameter bool garbage_collect=false is equivalent to the parameter not_garbage=nullptr. The parameter garbage_collect=true will be replaced either with the actual index that is associated with the buffer page, or with a bogus pointer not_garbage=-1 to indicate that any lazily entries for a freed index need to be removed. buf_page_get_low(), buf_page_get_gen(), mtr_t::page_lock(), mtr_t::upgrade_buffer_fix(): Do not invoke btr_search_drop_page_hash_index(). Our caller will have to do it when appropriate. buf_page_create_low(): Keep invoking btr_search_drop_page_hash_index(). This is the normal way of lazily dropping the adaptive hash index after a DDL operation such as DROP INDEX operation. btr_block_get(), btr_root_block_get(), btr_root_adjust_on_import(), btr_read_autoinc_with_fallback(), btr_cur_instant_init_low(), btr_cur_t::search_leaf(), btr_cur_t::pessimistic_search_leaf(), btr_pcur_optimistic_latch_leaves(), dict_stats_analyze_index_below_cur(): Invoke btr_search_drop_page_hash_index(block, index) for pages that may be leaf pages. No adaptive hash index may have been created on anything else than a B-tree leaf page. btr_cur_search_to_nth_level(): Do not invoke btr_search_drop_page_hash_index(), because we are only accessing non-leaf pages and the adaptive hash index may only have been created on leaf pages. btr_page_alloc_for_ibuf() and many other callers of buf_page_get_gen() or similar functions do not invoke btr_search_drop_page_hash_index(), because the adaptive hash index is never created on such pages. If a page in the tablespace was freed as part of a DDL operation and reused for something else, then buf_page_create_low() will take care of dropping the adaptive hash index before the freed page will be modified. It is notable that while the flst_ functions may access pages that are related to allocating B-tree index pages (the BTR_SEG_TOP and BTR_SEG_LEAF linked from the index root page), those pages themselves can never be stored in the adaptive hash index. Therefore, it is not necessary to invoke btr_search_drop_page_hash_index() on them. Reviewed by: Vladislav Lesin
1 parent c942b31 commit 5f7b2a3

File tree

12 files changed

+100
-79
lines changed

12 files changed

+100
-79
lines changed

storage/innobase/btr/btr0btr.cc

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ buf_block_t *btr_block_get(const dict_index_t &index, uint32_t page,
238238

239239
if (UNIV_LIKELY(block != nullptr))
240240
{
241+
btr_search_drop_page_hash_index(block, &index);
241242
if (!!page_is_comp(block->page.frame) != index.table->not_redundant() ||
242243
btr_page_get_index_id(block->page.frame) != index.id ||
243244
!fil_page_index_page_check(block->page.frame) ||
@@ -291,6 +292,7 @@ btr_root_block_get(
291292

292293
if (UNIV_LIKELY(block != nullptr))
293294
{
295+
btr_search_drop_page_hash_index(block, index);
294296
if (!!page_is_comp(block->page.frame) !=
295297
index->table->not_redundant() ||
296298
btr_page_get_index_id(block->page.frame) != index->id ||
@@ -397,6 +399,7 @@ btr_root_adjust_on_import(
397399
goto func_exit;
398400
}
399401

402+
btr_search_drop_page_hash_index(block, index);
400403
page = buf_block_get_frame(block);
401404
page_zip = buf_block_get_page_zip(block);
402405

@@ -865,7 +868,7 @@ static void btr_free_root(buf_block_t *block, const fil_space_t &space,
865868
MTR_MEMO_PAGE_SX_FIX));
866869
ut_ad(mtr->is_named_space(&space));
867870

868-
btr_search_drop_page_hash_index(block, false);
871+
btr_search_drop_page_hash_index(block, nullptr);
869872

870873
if (btr_root_fseg_validate(PAGE_HEADER + PAGE_BTR_SEG_TOP, *block, space))
871874
{
@@ -893,15 +896,18 @@ buf_block_t *btr_free_root_check(const page_id_t page_id, ulint zip_size,
893896
buf_block_t *block= buf_page_get_gen(page_id, zip_size, RW_X_LATCH,
894897
nullptr, BUF_GET_POSSIBLY_FREED, mtr);
895898

896-
if (!block);
897-
else if (fil_page_index_page_check(block->page.frame) &&
898-
index_id == btr_page_get_index_id(block->page.frame))
899-
/* This should be a root page. It should not be possible to
900-
reassign the same index_id for some other index in the
901-
tablespace. */
902-
ut_ad(!page_has_siblings(block->page.frame));
903-
else
904-
block= nullptr;
899+
if (block)
900+
{
901+
btr_search_drop_page_hash_index(block,reinterpret_cast<dict_index_t*>(-1));
902+
if (fil_page_index_page_check(block->page.frame) &&
903+
index_id == btr_page_get_index_id(block->page.frame))
904+
/* This should be a root page. It should not be possible to
905+
reassign the same index_id for some other index in the
906+
tablespace. */
907+
ut_ad(!page_has_siblings(block->page.frame));
908+
else
909+
block= nullptr;
910+
}
905911

906912
return block;
907913
}
@@ -1098,7 +1104,7 @@ dberr_t dict_index_t::clear(que_thr_t *thr)
10981104
,any_ahi_pages()
10991105
#endif
11001106
);
1101-
btr_search_drop_page_hash_index(root_block, false);
1107+
btr_search_drop_page_hash_index(root_block, nullptr);
11021108
#ifdef BTR_CUR_HASH_ADAPT
11031109
ut_ad(!any_ahi_pages());
11041110
#endif
@@ -1211,12 +1217,13 @@ uint64_t btr_read_autoinc_with_fallback(const dict_table_t *table,
12111217
uint64_t autoinc= 0;
12121218
mtr_t mtr;
12131219
mtr.start();
1220+
const dict_index_t *const first_index= dict_table_get_first_index(table);
12141221

12151222
if (buf_block_t *block=
1216-
buf_page_get(page_id_t(table->space_id,
1217-
dict_table_get_first_index(table)->page),
1223+
buf_page_get(page_id_t(table->space_id, first_index->page),
12181224
table->space->zip_size(), RW_SX_LATCH, &mtr))
12191225
{
1226+
btr_search_drop_page_hash_index(block, first_index);
12201227
autoinc= page_get_autoinc(block->page.frame);
12211228

12221229
if (autoinc > 0 && autoinc <= max && mysql_version >= 100210);
@@ -1269,6 +1276,9 @@ btr_write_autoinc(dict_index_t* index, ib_uint64_t autoinc, bool reset)
12691276
if (buf_block_t *root= buf_page_get(page_id_t(space->id, index->page),
12701277
space->zip_size(), RW_SX_LATCH, &mtr))
12711278
{
1279+
#ifdef BTR_CUR_HASH_ADAPT
1280+
ut_d(if (dict_index_t *ri= root->index)) ut_ad(ri == index);
1281+
#endif /* BTR_CUR_HASH_ADAPT */
12721282
buf_page_make_young_if_needed(&root->page);
12731283
mtr.set_named_space(space);
12741284
page_set_autoinc(root, autoinc, &mtr, reset);
@@ -1299,7 +1309,7 @@ static dberr_t btr_page_reorganize_low(page_cur_t *cursor, mtr_t *mtr)
12991309
if (UNIV_UNLIKELY(pos == ULINT_UNDEFINED))
13001310
return DB_CORRUPTION;
13011311

1302-
btr_search_drop_page_hash_index(block, false);
1312+
btr_search_drop_page_hash_index(block, nullptr);
13031313

13041314
buf_block_t *old= buf_block_alloc();
13051315
/* Copy the old page to temporary space */
@@ -1613,7 +1623,7 @@ btr_page_empty(
16131623
|| page_zip_validate(page_zip, block->page.frame, index));
16141624
#endif /* UNIV_ZIP_DEBUG */
16151625

1616-
btr_search_drop_page_hash_index(block, false);
1626+
btr_search_drop_page_hash_index(block, nullptr);
16171627

16181628
/* Recreate the page: note that global data on page (possible
16191629
segment headers, next page-field, etc.) is preserved intact */
@@ -3384,7 +3394,7 @@ btr_lift_page_up(
33843394
mem_heap_free(heap);
33853395
}
33863396

3387-
btr_search_drop_page_hash_index(block, false);
3397+
btr_search_drop_page_hash_index(block, nullptr);
33883398

33893399
/* Make the father empty */
33903400
btr_page_empty(father_block, father_page_zip, index, page_level, mtr);
@@ -3702,7 +3712,7 @@ btr_compress(
37023712
goto err_exit;
37033713
}
37043714

3705-
btr_search_drop_page_hash_index(block, false);
3715+
btr_search_drop_page_hash_index(block, nullptr);
37063716

37073717
/* Remove the page from the level list */
37083718
err = btr_level_list_remove(*block, *index, mtr);
@@ -3805,7 +3815,7 @@ btr_compress(
38053815
goto err_exit;
38063816
}
38073817

3808-
btr_search_drop_page_hash_index(block, false);
3818+
btr_search_drop_page_hash_index(block, nullptr);
38093819

38103820
if (merge_page_zip && left_page_no == FIL_NULL) {
38113821

@@ -3967,7 +3977,7 @@ btr_discard_only_page_on_level(
39673977
ut_ad(fil_page_index_page_check(page));
39683978
ut_ad(block->page.id().space() == index->table->space->id);
39693979
ut_ad(mtr->memo_contains_flagged(block, MTR_MEMO_PAGE_X_FIX));
3970-
btr_search_drop_page_hash_index(block, false);
3980+
btr_search_drop_page_hash_index(block, nullptr);
39713981
cursor.page_cur.index = index;
39723982
cursor.page_cur.block = block;
39733983

@@ -4163,7 +4173,7 @@ btr_discard_page(
41634173
return DB_CORRUPTION;
41644174
}
41654175

4166-
btr_search_drop_page_hash_index(block, false);
4176+
btr_search_drop_page_hash_index(block, nullptr);
41674177

41684178
if (dict_index_is_spatial(index)) {
41694179
rtr_node_ptr_delete(&parent_cursor, mtr);

storage/innobase/btr/btr0cur.cc

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,8 @@ static dberr_t btr_cur_instant_init_low(dict_index_t* index, mtr_t* mtr)
358358
goto incompatible;
359359
}
360360

361+
btr_search_drop_page_hash_index(block, index);
362+
361363
if (fil_page_get_type(block->page.frame) != FIL_PAGE_TYPE_BLOB
362364
|| mach_read_from_4(&block->page.frame
363365
[FIL_PAGE_DATA
@@ -1232,6 +1234,8 @@ dberr_t btr_cur_t::search_leaf(const dtuple_t *tuple, page_cur_mode_t mode,
12321234
goto func_exit;
12331235
}
12341236

1237+
btr_search_drop_page_hash_index(block, index());
1238+
12351239
if (!!page_is_comp(block->page.frame) != index()->table->not_redundant() ||
12361240
btr_page_get_index_id(block->page.frame) != index()->id ||
12371241
fil_page_get_type(block->page.frame) == FIL_PAGE_RTREE ||
@@ -1344,9 +1348,7 @@ dberr_t btr_cur_t::search_leaf(const dtuple_t *tuple, page_cur_mode_t mode,
13441348
mtr->rollback_to_savepoint(savepoint, savepoint + 1);
13451349
reached_index_root_and_leaf:
13461350
ut_ad(rw_latch == RW_X_LATCH);
1347-
#ifdef BTR_CUR_HASH_ADAPT
1348-
btr_search_drop_page_hash_index(block, true);
1349-
#endif
1351+
btr_search_drop_page_hash_index(block, index());
13501352
if (page_cur_search_with_match(tuple, mode, &up_match, &low_match,
13511353
&page_cur, nullptr))
13521354
goto corrupted;
@@ -1631,6 +1633,7 @@ dberr_t btr_cur_t::pessimistic_search_leaf(const dtuple_t *tuple,
16311633
const page_cur_mode_t page_mode{btr_cur_nonleaf_mode(mode)};
16321634

16331635
mtr->page_lock(block, RW_X_LATCH);
1636+
btr_search_drop_page_hash_index(block, index());
16341637

16351638
up_match= 0;
16361639
up_bytes= 0;
@@ -1700,6 +1703,8 @@ dberr_t btr_cur_t::pessimistic_search_leaf(const dtuple_t *tuple,
17001703
goto func_exit;
17011704
}
17021705

1706+
btr_search_drop_page_hash_index(block, index());
1707+
17031708
if (!!page_is_comp(block->page.frame) != index()->table->not_redundant() ||
17041709
btr_page_get_index_id(block->page.frame) != index()->id ||
17051710
fil_page_get_type(block->page.frame) == FIL_PAGE_RTREE ||
@@ -1808,7 +1813,10 @@ dberr_t btr_cur_search_to_nth_level(ulint level,
18081813
goto func_exit;
18091814
}
18101815
else
1816+
{
1817+
btr_search_drop_page_hash_index(block, index);
18111818
btr_cur_nonleaf_make_young(&block->page);
1819+
}
18121820

18131821
#ifdef UNIV_ZIP_DEBUG
18141822
if (const page_zip_des_t *page_zip= buf_block_get_page_zip(block))
@@ -3335,6 +3343,9 @@ static void btr_cur_trim_alter_metadata(dtuple_t* entry,
33353343
mtr.commit();
33363344
return;
33373345
}
3346+
3347+
btr_search_drop_page_hash_index(block, index);
3348+
33383349
ut_ad(fil_page_get_type(block->page.frame) == FIL_PAGE_TYPE_BLOB);
33393350
ut_ad(mach_read_from_4(&block->page.frame
33403351
[FIL_PAGE_DATA + BTR_BLOB_HDR_NEXT_PAGE_NO])

storage/innobase/btr/btr0pcur.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ Created 2/23/1996 Heikki Tuuri
2626

2727
#include "btr0pcur.h"
2828
#include "buf0rea.h"
29+
#include "btr0sea.h"
2930
#include "rem0cmp.h"
30-
#include "trx0trx.h"
3131
#include "ibuf0ibuf.h"
3232

3333
/**************************************************************//**
@@ -259,11 +259,13 @@ static bool btr_pcur_optimistic_latch_leaves(btr_pcur_t *pcur,
259259
memcmp_aligned<2>(block->page.frame + PAGE_HEADER + PAGE_INDEX_ID,
260260
prev->page.frame + PAGE_HEADER + PAGE_INDEX_ID, 8))
261261
goto fail;
262+
btr_search_drop_page_hash_index(prev, pcur->index());
262263
}
263264
else
264265
prev= nullptr;
265266

266267
mtr->upgrade_buffer_fix(savepoint, RW_S_LATCH);
268+
btr_search_drop_page_hash_index(block, pcur->index());
267269

268270
if (UNIV_UNLIKELY(block->modify_clock != modify_clock) ||
269271
UNIV_UNLIKELY(block->page.is_freed()) ||

storage/innobase/btr/btr0sea.cc

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,7 @@ static uint32_t btr_search_info_update_hash(const btr_cur_t &cursor) noexcept
633633
else if (UNIV_UNLIKELY(block_index != index))
634634
{
635635
ut_ad(block_index->id == index->id);
636-
btr_search_drop_page_hash_index(block, false);
636+
btr_search_drop_page_hash_index(block, nullptr);
637637
}
638638
else if (cursor.flag == BTR_CUR_HASH_FAIL)
639639
btr_search_update_hash_ref(cursor, block, left_bytes_fields);
@@ -1220,15 +1220,15 @@ static constexpr size_t REC_FOLD_IN_STACK= 128;
12201220
/** Drop any adaptive hash index entries that point to an index page.
12211221
@param block latched block containing index page, or a buffer-unfixed
12221222
index page or a block in state BUF_BLOCK_REMOVE_HASH
1223-
@param garbage_collect drop ahi only if the index is marked as freed
1223+
@param not_garbage drop only if the index is set and NOT this
12241224
@param folds work area for REC_FOLD_IN_STACK rec_fold() values */
12251225
static void btr_search_drop_page_hash_index(buf_block_t *block,
1226-
bool garbage_collect,
1226+
const dict_index_t *not_garbage,
12271227
uint32_t *folds) noexcept
12281228
{
12291229
retry:
12301230
dict_index_t *index= block->index;
1231-
if (!index)
1231+
if (!index || index == not_garbage)
12321232
return;
12331233

12341234
ut_d(const auto state= block->page.state());
@@ -1268,8 +1268,12 @@ static void btr_search_drop_page_hash_index(buf_block_t *block,
12681268
goto retry;
12691269
}
12701270
}
1271-
else if (garbage_collect)
1271+
else if (not_garbage != nullptr)
1272+
{
1273+
ut_ad(!index || index == not_garbage ||
1274+
not_garbage == reinterpret_cast<dict_index_t*>(-1));
12721275
goto unlock_and_return;
1276+
}
12731277

12741278
assert_block_ahi_valid(block);
12751279

@@ -1394,10 +1398,10 @@ static void btr_search_drop_page_hash_index(buf_block_t *block,
13941398
}
13951399

13961400
void btr_search_drop_page_hash_index(buf_block_t *block,
1397-
bool garbage_collect) noexcept
1401+
const dict_index_t *not_garbage) noexcept
13981402
{
13991403
uint32_t folds[REC_FOLD_IN_STACK];
1400-
btr_search_drop_page_hash_index(block, garbage_collect, folds);
1404+
btr_search_drop_page_hash_index(block, not_garbage, folds);
14011405
}
14021406

14031407
void btr_search_drop_page_hash_when_freed(const page_id_t page_id) noexcept
@@ -1411,14 +1415,11 @@ void btr_search_drop_page_hash_when_freed(const page_id_t page_id) noexcept
14111415
if (buf_block_t *block= buf_page_get_gen(page_id, 0, RW_X_LATCH, nullptr,
14121416
BUF_PEEK_IF_IN_POOL, &mtr))
14131417
{
1414-
if (IF_DBUG(dict_index_t *index=,) block->index)
1415-
{
1416-
/* In all our callers, the table handle should be open, or we
1417-
should be in the process of dropping the table (preventing
1418-
eviction). */
1419-
DBUG_ASSERT(index->table->get_ref_count() || dict_sys.locked());
1420-
btr_search_drop_page_hash_index(block, false);
1421-
}
1418+
/* In all our callers, the table handle should be open, or we
1419+
should be in the process of dropping the table (preventing eviction). */
1420+
ut_d(if (dict_index_t *i= block->index))
1421+
ut_ad(i->table->get_ref_count() || dict_sys.locked());
1422+
btr_search_drop_page_hash_index(block, nullptr);
14221423
}
14231424

14241425
mtr.commit();
@@ -1465,7 +1466,7 @@ static void btr_search_build_page_hash_index(dict_index_t *index,
14651466
struct{uint32_t fold;uint32_t offset;} fr[REC_FOLD_IN_STACK / 2];
14661467

14671468
if (rebuild)
1468-
btr_search_drop_page_hash_index(block, false, &fr[0].fold);
1469+
btr_search_drop_page_hash_index(block, nullptr, &fr[0].fold);
14691470

14701471
const uint32_t n_bytes_fields{left_bytes_fields & ~buf_block_t::LEFT_SIDE};
14711472

@@ -1613,7 +1614,7 @@ void btr_search_move_or_delete_hash_entries(buf_block_t *new_block,
16131614
{
16141615
ut_ad(!index || index == new_block_index);
16151616
drop_exit:
1616-
btr_search_drop_page_hash_index(block, false);
1617+
btr_search_drop_page_hash_index(block, nullptr);
16171618
return;
16181619
}
16191620

@@ -1660,7 +1661,7 @@ void btr_search_update_hash_on_delete(btr_cur_t *cursor) noexcept
16601661

16611662
if (UNIV_UNLIKELY(index != cursor->index()))
16621663
{
1663-
btr_search_drop_page_hash_index(block, false);
1664+
btr_search_drop_page_hash_index(block, nullptr);
16641665
return;
16651666
}
16661667

@@ -1715,7 +1716,7 @@ void btr_search_update_hash_on_insert(btr_cur_t *cursor, bool reorg) noexcept
17151716
{
17161717
ut_ad(index->id == cursor->index()->id);
17171718
drop:
1718-
btr_search_drop_page_hash_index(block, false);
1719+
btr_search_drop_page_hash_index(block, nullptr);
17191720
return;
17201721
}
17211722

0 commit comments

Comments
 (0)