mirror of
https://github.com/MariaDB/server.git
synced 2025-01-15 19:42:28 +01:00
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().
This commit is contained in:
parent
68cac26108
commit
6b58ee769f
3 changed files with 31 additions and 21 deletions
|
@ -1423,18 +1423,14 @@ release_tree:
|
|||
goto need_opposite_intention;
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
/* We do a dirty read of btr_search.enabled here. We will recheck in
|
||||
btr_search_build_page_hash_index() before building a page hash
|
||||
index, while holding search latch. */
|
||||
if (!btr_search.enabled);
|
||||
else if (tuple->info_bits & REC_INFO_MIN_REC_FLAG)
|
||||
/* This may be a search tuple for btr_pcur_t::restore_position(). */
|
||||
ut_ad(tuple->is_metadata() ||
|
||||
(tuple->is_metadata(tuple->info_bits ^ REC_STATUS_INSTANT)));
|
||||
else if (index()->table->is_temporary());
|
||||
else if (!rec_is_metadata(page_cur.rec, *index()) &&
|
||||
index()->search_info.hash_analysis_useful())
|
||||
search_info_update();
|
||||
if (flag != BTR_CUR_BINARY)
|
||||
{
|
||||
ut_ad(!(tuple->info_bits & REC_INFO_MIN_REC_FLAG));
|
||||
ut_ad(!index()->table->is_temporary());
|
||||
if (!rec_is_metadata(page_cur.rec, *index()) &&
|
||||
index()->search_info.hash_analysis_useful())
|
||||
search_info_update();
|
||||
}
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
goto func_exit;
|
||||
|
|
|
@ -501,10 +501,11 @@ skip:
|
|||
@retval 0 if the adaptive hash index should not be rebuilt */
|
||||
static uint32_t btr_search_info_update_hash(const btr_cur_t &cursor) noexcept
|
||||
{
|
||||
ut_ad(cursor.flag != BTR_CUR_HASH);
|
||||
ut_ad(cursor.flag == BTR_CUR_HASH_FAIL ||
|
||||
cursor.flag == BTR_CUR_HASH_ABORT ||
|
||||
cursor.flag == BTR_CUR_BINARY);
|
||||
|
||||
dict_index_t *const index= cursor.index();
|
||||
|
||||
const uint16_t n_uniq{dict_index_get_n_unique_in_tree(index)};
|
||||
dict_index_t::ahi &info= index->search_info;
|
||||
|
||||
|
@ -1046,12 +1047,20 @@ btr_search_guess_on_hash(
|
|||
ut_ad(mtr->is_active());
|
||||
ut_ad(index->is_btree());
|
||||
ut_ad(latch_mode == BTR_SEARCH_LEAF || latch_mode == BTR_MODIFY_LEAF);
|
||||
ut_ad(cursor->flag == BTR_CUR_BINARY);
|
||||
|
||||
if ((tuple->info_bits & REC_INFO_MIN_REC_FLAG) ||
|
||||
!index->search_info.last_hash_succ ||
|
||||
!index->search_info.n_hash_potential)
|
||||
if ((tuple->info_bits & REC_INFO_MIN_REC_FLAG))
|
||||
return false;
|
||||
|
||||
if (!index->search_info.last_hash_succ ||
|
||||
!index->search_info.n_hash_potential)
|
||||
{
|
||||
ahi_unusable:
|
||||
if (!index->table->is_temporary() && btr_search.enabled)
|
||||
cursor->flag= BTR_CUR_HASH_ABORT;
|
||||
return false;
|
||||
}
|
||||
|
||||
ut_ad(!index->table->is_temporary());
|
||||
|
||||
static_assert(ulint{BTR_SEARCH_LEAF} == ulint{RW_S_LATCH}, "");
|
||||
|
@ -1061,7 +1070,7 @@ btr_search_guess_on_hash(
|
|||
~buf_block_t::LEFT_SIDE;
|
||||
|
||||
if (dtuple_get_n_fields(tuple) < btr_search_get_n_fields(cursor))
|
||||
return false;
|
||||
goto ahi_unusable;
|
||||
|
||||
const index_id_t index_id= index->id;
|
||||
|
||||
|
@ -1070,7 +1079,6 @@ btr_search_guess_on_hash(
|
|||
#endif
|
||||
const uint32_t fold= dtuple_fold(tuple, cursor);
|
||||
cursor->fold= fold;
|
||||
cursor->flag= BTR_CUR_HASH;
|
||||
btr_sea::partition &part= btr_search.get_part(*index);
|
||||
|
||||
part.latch.rd_lock(SRW_LOCK_CALL);
|
||||
|
@ -1080,8 +1088,6 @@ btr_search_guess_on_hash(
|
|||
ahi_release_and_fail:
|
||||
part.latch.rd_unlock();
|
||||
fail:
|
||||
cursor->flag= BTR_CUR_HASH_FAIL;
|
||||
|
||||
#ifdef UNIV_SEARCH_PERF_STAT
|
||||
++index->search_info.n_hash_fail;
|
||||
if (index->search_info.n_hash_succ > 0)
|
||||
|
@ -1096,7 +1102,10 @@ btr_search_guess_on_hash(
|
|||
{ return node->fold == fold; });
|
||||
|
||||
if (!node)
|
||||
{
|
||||
cursor->flag= BTR_CUR_HASH_FAIL;
|
||||
goto ahi_release_and_fail;
|
||||
}
|
||||
|
||||
const rec_t *rec= node->rec;
|
||||
buf_block_t *block= buf_pool.block_from_ahi(rec);
|
||||
|
@ -1127,6 +1136,7 @@ btr_search_guess_on_hash(
|
|||
block->page.lock.s_unlock();
|
||||
else
|
||||
block->page.lock.x_unlock();
|
||||
cursor->flag= BTR_CUR_HASH_FAIL;
|
||||
goto ahi_release_and_fail;
|
||||
}
|
||||
|
||||
|
@ -1137,6 +1147,7 @@ btr_search_guess_on_hash(
|
|||
if (index != block_index && index_id == block_index->id)
|
||||
{
|
||||
ut_a(block_index->freed());
|
||||
cursor->flag= BTR_CUR_HASH_FAIL;
|
||||
goto block_and_ahi_release_and_fail;
|
||||
}
|
||||
|
||||
|
@ -1169,6 +1180,7 @@ btr_search_guess_on_hash(
|
|||
default:
|
||||
mismatch:
|
||||
mtr->release_last_page();
|
||||
cursor->flag= BTR_CUR_HASH_FAIL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -1183,6 +1195,7 @@ btr_search_guess_on_hash(
|
|||
index->search_info.n_hash_potential= n_hash_potential;
|
||||
|
||||
index->search_info.last_hash_succ= true;
|
||||
cursor->flag= BTR_CUR_HASH;
|
||||
|
||||
#ifdef UNIV_SEARCH_PERF_STAT
|
||||
btr_search_n_succ++;
|
||||
|
|
|
@ -649,6 +649,7 @@ enum btr_cur_method {
|
|||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
BTR_CUR_HASH, /*!< successful shortcut using
|
||||
the hash index */
|
||||
BTR_CUR_HASH_ABORT, /*!< the hash index could not be used */
|
||||
BTR_CUR_HASH_FAIL, /*!< failure using hash, success using
|
||||
binary search: the misleading hash
|
||||
reference is stored in the field
|
||||
|
|
Loading…
Reference in a new issue