Skip to content

Commit 6b58ee7

Browse files
committed
MDEV-35049: Fix bogus BTR_CUR_HASH_FAIL on contention
btr_search_guess_on_hash(): Only set BTR_CUR_HASH_FAIL on actual mismatch. If the page latch cannot be acquired, the hash search might very well have succeeded. Do not count that as a failure, that is, do not unnecessarily invoke btr_search_update_hash_ref() after a normal search. Set cursor->flag=BTR_CUR_HASH_ABORT if the current parameters of the adaptive hash index are not suitable for the search and a call to btr_cur_t::search_info_update() might help. btr_cur_t::search_leaf(): Do not invoke search_info_update() if btr_search_guess_on_hash() failed due to contention. btr_cur_t::pessimistic_search_leaf(): Do not invoke search_info_update() on the change buffer tree. Preivously, this condition was being checked inside search_info_update().
1 parent 68cac26 commit 6b58ee7

File tree

3 files changed

+30
-20
lines changed

3 files changed

+30
-20
lines changed

storage/innobase/btr/btr0cur.cc

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1423,18 +1423,14 @@ dberr_t btr_cur_t::search_leaf(const dtuple_t *tuple, page_cur_mode_t mode,
14231423
goto need_opposite_intention;
14241424

14251425
#ifdef BTR_CUR_HASH_ADAPT
1426-
/* We do a dirty read of btr_search.enabled here. We will recheck in
1427-
btr_search_build_page_hash_index() before building a page hash
1428-
index, while holding search latch. */
1429-
if (!btr_search.enabled);
1430-
else if (tuple->info_bits & REC_INFO_MIN_REC_FLAG)
1431-
/* This may be a search tuple for btr_pcur_t::restore_position(). */
1432-
ut_ad(tuple->is_metadata() ||
1433-
(tuple->is_metadata(tuple->info_bits ^ REC_STATUS_INSTANT)));
1434-
else if (index()->table->is_temporary());
1435-
else if (!rec_is_metadata(page_cur.rec, *index()) &&
1436-
index()->search_info.hash_analysis_useful())
1437-
search_info_update();
1426+
if (flag != BTR_CUR_BINARY)
1427+
{
1428+
ut_ad(!(tuple->info_bits & REC_INFO_MIN_REC_FLAG));
1429+
ut_ad(!index()->table->is_temporary());
1430+
if (!rec_is_metadata(page_cur.rec, *index()) &&
1431+
index()->search_info.hash_analysis_useful())
1432+
search_info_update();
1433+
}
14381434
#endif /* BTR_CUR_HASH_ADAPT */
14391435

14401436
goto func_exit;

storage/innobase/btr/btr0sea.cc

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -501,10 +501,11 @@ static void btr_search_update_hash_ref(const btr_cur_t &cursor,
501501
@retval 0 if the adaptive hash index should not be rebuilt */
502502
static uint32_t btr_search_info_update_hash(const btr_cur_t &cursor) noexcept
503503
{
504-
ut_ad(cursor.flag != BTR_CUR_HASH);
504+
ut_ad(cursor.flag == BTR_CUR_HASH_FAIL ||
505+
cursor.flag == BTR_CUR_HASH_ABORT ||
506+
cursor.flag == BTR_CUR_BINARY);
505507

506508
dict_index_t *const index= cursor.index();
507-
508509
const uint16_t n_uniq{dict_index_get_n_unique_in_tree(index)};
509510
dict_index_t::ahi &info= index->search_info;
510511

@@ -1046,11 +1047,19 @@ btr_search_guess_on_hash(
10461047
ut_ad(mtr->is_active());
10471048
ut_ad(index->is_btree());
10481049
ut_ad(latch_mode == BTR_SEARCH_LEAF || latch_mode == BTR_MODIFY_LEAF);
1050+
ut_ad(cursor->flag == BTR_CUR_BINARY);
1051+
1052+
if ((tuple->info_bits & REC_INFO_MIN_REC_FLAG))
1053+
return false;
10491054

1050-
if ((tuple->info_bits & REC_INFO_MIN_REC_FLAG) ||
1051-
!index->search_info.last_hash_succ ||
1055+
if (!index->search_info.last_hash_succ ||
10521056
!index->search_info.n_hash_potential)
1057+
{
1058+
ahi_unusable:
1059+
if (!index->table->is_temporary() && btr_search.enabled)
1060+
cursor->flag= BTR_CUR_HASH_ABORT;
10531061
return false;
1062+
}
10541063

10551064
ut_ad(!index->table->is_temporary());
10561065

@@ -1061,7 +1070,7 @@ btr_search_guess_on_hash(
10611070
~buf_block_t::LEFT_SIDE;
10621071

10631072
if (dtuple_get_n_fields(tuple) < btr_search_get_n_fields(cursor))
1064-
return false;
1073+
goto ahi_unusable;
10651074

10661075
const index_id_t index_id= index->id;
10671076

@@ -1070,7 +1079,6 @@ btr_search_guess_on_hash(
10701079
#endif
10711080
const uint32_t fold= dtuple_fold(tuple, cursor);
10721081
cursor->fold= fold;
1073-
cursor->flag= BTR_CUR_HASH;
10741082
btr_sea::partition &part= btr_search.get_part(*index);
10751083

10761084
part.latch.rd_lock(SRW_LOCK_CALL);
@@ -1080,8 +1088,6 @@ btr_search_guess_on_hash(
10801088
ahi_release_and_fail:
10811089
part.latch.rd_unlock();
10821090
fail:
1083-
cursor->flag= BTR_CUR_HASH_FAIL;
1084-
10851091
#ifdef UNIV_SEARCH_PERF_STAT
10861092
++index->search_info.n_hash_fail;
10871093
if (index->search_info.n_hash_succ > 0)
@@ -1096,7 +1102,10 @@ btr_search_guess_on_hash(
10961102
{ return node->fold == fold; });
10971103

10981104
if (!node)
1105+
{
1106+
cursor->flag= BTR_CUR_HASH_FAIL;
10991107
goto ahi_release_and_fail;
1108+
}
11001109

11011110
const rec_t *rec= node->rec;
11021111
buf_block_t *block= buf_pool.block_from_ahi(rec);
@@ -1127,6 +1136,7 @@ btr_search_guess_on_hash(
11271136
block->page.lock.s_unlock();
11281137
else
11291138
block->page.lock.x_unlock();
1139+
cursor->flag= BTR_CUR_HASH_FAIL;
11301140
goto ahi_release_and_fail;
11311141
}
11321142

@@ -1137,6 +1147,7 @@ btr_search_guess_on_hash(
11371147
if (index != block_index && index_id == block_index->id)
11381148
{
11391149
ut_a(block_index->freed());
1150+
cursor->flag= BTR_CUR_HASH_FAIL;
11401151
goto block_and_ahi_release_and_fail;
11411152
}
11421153

@@ -1169,6 +1180,7 @@ btr_search_guess_on_hash(
11691180
default:
11701181
mismatch:
11711182
mtr->release_last_page();
1183+
cursor->flag= BTR_CUR_HASH_FAIL;
11721184
goto fail;
11731185
}
11741186

@@ -1183,6 +1195,7 @@ btr_search_guess_on_hash(
11831195
index->search_info.n_hash_potential= n_hash_potential;
11841196

11851197
index->search_info.last_hash_succ= true;
1198+
cursor->flag= BTR_CUR_HASH;
11861199

11871200
#ifdef UNIV_SEARCH_PERF_STAT
11881201
btr_search_n_succ++;

storage/innobase/include/btr0cur.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,7 @@ enum btr_cur_method {
649649
#ifdef BTR_CUR_HASH_ADAPT
650650
BTR_CUR_HASH, /*!< successful shortcut using
651651
the hash index */
652+
BTR_CUR_HASH_ABORT, /*!< the hash index could not be used */
652653
BTR_CUR_HASH_FAIL, /*!< failure using hash, success using
653654
binary search: the misleading hash
654655
reference is stored in the field

0 commit comments

Comments
 (0)