MDEV-14952 Avoid repeated calls to btr_get_search_latch()
btr_cur_search_to_nth_level(), btr_search_guess_on_hash(), btr_pcur_open_with_no_init_func(), row_sel_open_pcur(): Replace the parameter has_search_latch with the ahi_latch (passed as NULL if the caller does not hold the latch). btr_search_update_hash_node_on_insert(), btr_search_update_hash_on_insert(), btr_search_build_page_hash_index(): Add the parameter ahi_latch. btr_search_x_lock(), btr_search_x_unlock(), btr_search_s_lock(), btr_search_s_unlock(): Remove.
This commit is contained in:
parent
4beb699a36
commit
0664d633e4
@ -919,8 +919,7 @@ search tuple should be performed in the B-tree. InnoDB does an insert
|
||||
immediately after the cursor. Thus, the cursor may end up on a user record,
|
||||
or on a page infimum record. */
|
||||
dberr_t
|
||||
btr_cur_search_to_nth_level(
|
||||
/*========================*/
|
||||
btr_cur_search_to_nth_level_func(
|
||||
dict_index_t* index, /*!< in: index */
|
||||
ulint level, /*!< in: the tree level of search */
|
||||
const dtuple_t* tuple, /*!< in: data tuple; NOTE: n_fields_cmp in
|
||||
@ -935,17 +934,16 @@ btr_cur_search_to_nth_level(
|
||||
cursor->left_block is used to store a pointer
|
||||
to the left neighbor page, in the cases
|
||||
BTR_SEARCH_PREV and BTR_MODIFY_PREV;
|
||||
NOTE that if has_search_latch
|
||||
is != 0, we maybe do not have a latch set
|
||||
on the cursor page, we assume
|
||||
the caller uses his search latch
|
||||
to protect the record! */
|
||||
NOTE that if ahi_latch, we might not have a
|
||||
cursor page latch, we assume that ahi_latch
|
||||
protects the record! */
|
||||
btr_cur_t* cursor, /*!< in/out: tree cursor; the cursor page is
|
||||
s- or x-latched, but see also above! */
|
||||
ulint has_search_latch,
|
||||
/*!< in: info on the latch mode the
|
||||
caller currently has on search system:
|
||||
RW_S_LATCH, or 0 */
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
rw_lock_t* ahi_latch,
|
||||
/*!< in: currently held btr_search_latch
|
||||
(in RW_S_LATCH mode), or NULL */
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
const char* file, /*!< in: file name */
|
||||
unsigned line, /*!< in: line where called */
|
||||
mtr_t* mtr, /*!< in: mtr */
|
||||
@ -1123,7 +1121,7 @@ btr_cur_search_to_nth_level(
|
||||
&& mode != PAGE_CUR_LE_OR_EXTENDS
|
||||
# endif /* PAGE_CUR_LE_OR_EXTENDS */
|
||||
&& !dict_index_is_spatial(index)
|
||||
/* If !has_search_latch, we do a dirty read of
|
||||
/* If !ahi_latch, we do a dirty read of
|
||||
btr_search_enabled below, and btr_search_guess_on_hash()
|
||||
will have to check it again. */
|
||||
&& btr_search_enabled
|
||||
@ -1131,7 +1129,7 @@ btr_cur_search_to_nth_level(
|
||||
&& !(tuple->info_bits & REC_INFO_MIN_REC_FLAG)
|
||||
&& btr_search_guess_on_hash(index, info, tuple, mode,
|
||||
latch_mode, cursor,
|
||||
has_search_latch, mtr)) {
|
||||
ahi_latch, mtr)) {
|
||||
|
||||
/* Search using the hash index succeeded */
|
||||
|
||||
@ -1152,10 +1150,12 @@ btr_cur_search_to_nth_level(
|
||||
/* If the hash search did not succeed, do binary search down the
|
||||
tree */
|
||||
|
||||
if (has_search_latch) {
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
if (ahi_latch) {
|
||||
/* Release possible search latch to obey latching order */
|
||||
btr_search_s_unlock(index);
|
||||
rw_lock_s_unlock(ahi_latch);
|
||||
}
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
/* Store the position of the tree latch we push to mtr so that we
|
||||
know how to release it when we have latched leaf node(s) */
|
||||
@ -2222,15 +2222,17 @@ func_exit:
|
||||
ut_free(prev_tree_savepoints);
|
||||
}
|
||||
|
||||
if (has_search_latch) {
|
||||
btr_search_s_lock(index);
|
||||
}
|
||||
|
||||
if (mbr_adj) {
|
||||
/* remember that we will need to adjust parent MBR */
|
||||
cursor->rtr_info->mbr_adj = true;
|
||||
}
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
if (ahi_latch) {
|
||||
rw_lock_s_lock(ahi_latch);
|
||||
}
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
DBUG_RETURN(err);
|
||||
}
|
||||
|
||||
@ -3300,10 +3302,14 @@ fail_err:
|
||||
ut_ad(entry->info_bits == REC_INFO_DEFAULT_ROW);
|
||||
ut_ad(index->is_instant());
|
||||
ut_ad(flags == BTR_NO_LOCKING_FLAG);
|
||||
} else if (!reorg && cursor->flag == BTR_CUR_HASH) {
|
||||
btr_search_update_hash_node_on_insert(cursor);
|
||||
} else {
|
||||
btr_search_update_hash_on_insert(cursor);
|
||||
rw_lock_t* ahi_latch = btr_get_search_latch(index);
|
||||
if (!reorg && cursor->flag == BTR_CUR_HASH) {
|
||||
btr_search_update_hash_node_on_insert(
|
||||
cursor, ahi_latch);
|
||||
} else {
|
||||
btr_search_update_hash_on_insert(cursor, ahi_latch);
|
||||
}
|
||||
}
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
@ -3509,7 +3515,8 @@ btr_cur_pessimistic_insert(
|
||||
ut_ad((flags & ~BTR_KEEP_IBUF_BITMAP)
|
||||
== BTR_NO_LOCKING_FLAG);
|
||||
} else {
|
||||
btr_search_update_hash_on_insert(cursor);
|
||||
btr_search_update_hash_on_insert(
|
||||
cursor, btr_get_search_latch(index));
|
||||
}
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
if (inherit && !(flags & BTR_NO_LOCKING_FLAG)) {
|
||||
|
@ -353,7 +353,11 @@ btr_pcur_restore_position_func(
|
||||
}
|
||||
|
||||
btr_pcur_open_with_no_init_func(index, tuple, mode, latch_mode,
|
||||
cursor, 0, file, line, mtr);
|
||||
cursor,
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
NULL,
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
file, line, mtr);
|
||||
|
||||
/* Restore the old search mode */
|
||||
cursor->search_mode = old_mode;
|
||||
|
@ -48,7 +48,7 @@ Search system is protected by array of latches. */
|
||||
char btr_search_enabled = true;
|
||||
|
||||
/** Number of adaptive hash index partition. */
|
||||
ulong btr_ahi_parts = 8;
|
||||
ulong btr_ahi_parts;
|
||||
|
||||
#ifdef UNIV_SEARCH_PERF_STAT
|
||||
/** Number of successful adaptive hash index lookups */
|
||||
@ -177,23 +177,6 @@ btr_search_get_n_fields(
|
||||
return(btr_search_get_n_fields(cursor->n_fields, cursor->n_bytes));
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Builds a hash index on a page with the given parameters. If the page already
|
||||
has a hash index with different parameters, the old hash index is removed.
|
||||
If index is non-NULL, this function checks if n_fields and n_bytes are
|
||||
sensible values, and does not build a hash index if not. */
|
||||
static
|
||||
void
|
||||
btr_search_build_page_hash_index(
|
||||
/*=============================*/
|
||||
dict_index_t* index, /*!< in: index for which to build, or NULL if
|
||||
not known */
|
||||
buf_block_t* block, /*!< in: index page, s- or x-latched */
|
||||
ulint n_fields,/*!< in: hash this many full fields */
|
||||
ulint n_bytes,/*!< in: hash this many bytes from the next
|
||||
field */
|
||||
ibool left_side);/*!< in: hash for searches from left side? */
|
||||
|
||||
/** This function should be called before reserving any btr search mutex, if
|
||||
the intended operation might add nodes to the search system hash table.
|
||||
Because of the latching order, once we have reserved the btr search system
|
||||
@ -224,8 +207,9 @@ btr_search_check_free_space_in_heap(dict_index_t* index)
|
||||
|
||||
if (heap->free_block == NULL) {
|
||||
buf_block_t* block = buf_block_alloc(NULL);
|
||||
rw_lock_t* ahi_latch = btr_get_search_latch(index);
|
||||
|
||||
btr_search_x_lock(index);
|
||||
rw_lock_x_lock(ahi_latch);
|
||||
|
||||
if (btr_search_enabled
|
||||
&& heap->free_block == NULL) {
|
||||
@ -234,7 +218,7 @@ btr_search_check_free_space_in_heap(dict_index_t* index)
|
||||
buf_block_free(block);
|
||||
}
|
||||
|
||||
btr_search_x_unlock(index);
|
||||
rw_lock_x_unlock(ahi_latch);
|
||||
}
|
||||
}
|
||||
|
||||
@ -457,12 +441,10 @@ btr_search_info_get_ref_count(
|
||||
|
||||
ut_ad(info);
|
||||
|
||||
ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_S));
|
||||
ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_X));
|
||||
|
||||
btr_search_s_lock(index);
|
||||
rw_lock_t* ahi_latch = btr_get_search_latch(index);
|
||||
rw_lock_s_lock(ahi_latch);
|
||||
ret = info->ref_count;
|
||||
btr_search_s_unlock(index);
|
||||
rw_lock_s_unlock(ahi_latch);
|
||||
|
||||
return(ret);
|
||||
}
|
||||
@ -723,61 +705,6 @@ btr_search_update_hash_ref(
|
||||
}
|
||||
}
|
||||
|
||||
/** Updates the search info.
|
||||
@param[in,out] info search info
|
||||
@param[in] cursor cursor which was just positioned */
|
||||
void
|
||||
btr_search_info_update_slow(
|
||||
btr_search_t* info,
|
||||
btr_cur_t* cursor)
|
||||
{
|
||||
buf_block_t* block;
|
||||
ibool build_index;
|
||||
|
||||
ut_ad(!rw_lock_own(btr_get_search_latch(cursor->index), RW_LOCK_S));
|
||||
ut_ad(!rw_lock_own(btr_get_search_latch(cursor->index), RW_LOCK_X));
|
||||
|
||||
block = btr_cur_get_block(cursor);
|
||||
|
||||
/* NOTE that the following two function calls do NOT protect
|
||||
info or block->n_fields etc. with any semaphore, to save CPU time!
|
||||
We cannot assume the fields are consistent when we return from
|
||||
those functions! */
|
||||
|
||||
btr_search_info_update_hash(info, cursor);
|
||||
|
||||
build_index = btr_search_update_block_hash_info(info, block, cursor);
|
||||
|
||||
if (build_index || (cursor->flag == BTR_CUR_HASH_FAIL)) {
|
||||
|
||||
btr_search_check_free_space_in_heap(cursor->index);
|
||||
}
|
||||
|
||||
if (cursor->flag == BTR_CUR_HASH_FAIL) {
|
||||
/* Update the hash node reference, if appropriate */
|
||||
|
||||
#ifdef UNIV_SEARCH_PERF_STAT
|
||||
btr_search_n_hash_fail++;
|
||||
#endif /* UNIV_SEARCH_PERF_STAT */
|
||||
|
||||
btr_search_x_lock(cursor->index);
|
||||
|
||||
btr_search_update_hash_ref(info, block, cursor);
|
||||
|
||||
btr_search_x_unlock(cursor->index);
|
||||
}
|
||||
|
||||
if (build_index) {
|
||||
/* Note that since we did not protect block->n_fields etc.
|
||||
with any semaphore, the values can be inconsistent. We have
|
||||
to check inside the function call that they make sense. */
|
||||
btr_search_build_page_hash_index(cursor->index, block,
|
||||
block->n_fields,
|
||||
block->n_bytes,
|
||||
block->left_side);
|
||||
}
|
||||
}
|
||||
|
||||
/** Checks if a guessed position for a tree cursor is right. Note that if
|
||||
mode is PAGE_CUR_LE, which is used in inserts, and the function returns
|
||||
TRUE, then cursor->up_match and cursor->low_match both have sensible values.
|
||||
@ -947,12 +874,11 @@ both have sensible values.
|
||||
we assume the caller uses his search latch
|
||||
to protect the record!
|
||||
@param[out] cursor tree cursor
|
||||
@param[in] has_search_latch
|
||||
latch mode the caller currently has on
|
||||
search system: RW_S/X_LATCH or 0
|
||||
@param[in] ahi_latch the adaptive hash index latch being held,
|
||||
or NULL
|
||||
@param[in] mtr mini transaction
|
||||
@return TRUE if succeeded */
|
||||
ibool
|
||||
@return whether the search succeeded */
|
||||
bool
|
||||
btr_search_guess_on_hash(
|
||||
dict_index_t* index,
|
||||
btr_search_t* info,
|
||||
@ -960,7 +886,7 @@ btr_search_guess_on_hash(
|
||||
ulint mode,
|
||||
ulint latch_mode,
|
||||
btr_cur_t* cursor,
|
||||
ulint has_search_latch,
|
||||
rw_lock_t* ahi_latch,
|
||||
mtr_t* mtr)
|
||||
{
|
||||
const rec_t* rec;
|
||||
@ -970,6 +896,8 @@ btr_search_guess_on_hash(
|
||||
btr_cur_t cursor2;
|
||||
btr_pcur_t pcur;
|
||||
#endif
|
||||
ut_ad(!ahi_latch || rw_lock_own(ahi_latch, RW_LOCK_S)
|
||||
|| rw_lock_own(ahi_latch, RW_LOCK_X));
|
||||
|
||||
if (!btr_search_enabled) {
|
||||
return(FALSE);
|
||||
@ -977,6 +905,7 @@ btr_search_guess_on_hash(
|
||||
|
||||
ut_ad(index && info && tuple && cursor && mtr);
|
||||
ut_ad(!dict_index_is_ibuf(index));
|
||||
ut_ad(!ahi_latch || ahi_latch == btr_get_search_latch(index));
|
||||
ut_ad((latch_mode == BTR_SEARCH_LEAF)
|
||||
|| (latch_mode == BTR_MODIFY_LEAF));
|
||||
|
||||
@ -1009,27 +938,27 @@ btr_search_guess_on_hash(
|
||||
cursor->fold = fold;
|
||||
cursor->flag = BTR_CUR_HASH;
|
||||
|
||||
if (!has_search_latch) {
|
||||
btr_search_s_lock(index);
|
||||
rw_lock_t* use_latch = ahi_latch ? NULL : btr_get_search_latch(index);
|
||||
|
||||
if (use_latch) {
|
||||
rw_lock_s_lock(use_latch);
|
||||
|
||||
if (!btr_search_enabled) {
|
||||
btr_search_s_unlock(index);
|
||||
|
||||
btr_search_failure(info, cursor);
|
||||
|
||||
return(FALSE);
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
ut_ad(btr_search_enabled);
|
||||
}
|
||||
|
||||
ut_ad(rw_lock_own(btr_get_search_latch(index), RW_LOCK_S));
|
||||
|
||||
rec = (rec_t*) ha_search_and_get_data(
|
||||
btr_get_search_table(index), fold);
|
||||
btr_get_search_table(index), fold);
|
||||
|
||||
if (rec == NULL) {
|
||||
|
||||
if (!has_search_latch) {
|
||||
btr_search_s_unlock(index);
|
||||
if (use_latch) {
|
||||
fail:
|
||||
rw_lock_s_unlock(use_latch);
|
||||
}
|
||||
|
||||
btr_search_failure(info, cursor);
|
||||
@ -1039,22 +968,15 @@ btr_search_guess_on_hash(
|
||||
|
||||
buf_block_t* block = buf_block_from_ahi(rec);
|
||||
|
||||
if (!has_search_latch) {
|
||||
if (use_latch) {
|
||||
|
||||
if (!buf_page_get_known_nowait(
|
||||
latch_mode, block, BUF_MAKE_YOUNG,
|
||||
__FILE__, __LINE__, mtr)) {
|
||||
|
||||
if (!has_search_latch) {
|
||||
btr_search_s_unlock(index);
|
||||
}
|
||||
|
||||
btr_search_failure(info, cursor);
|
||||
|
||||
return(FALSE);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
btr_search_s_unlock(index);
|
||||
rw_lock_s_unlock(use_latch);
|
||||
|
||||
buf_block_dbg_add_level(block, SYNC_TREE_NODE_FROM_HASH);
|
||||
}
|
||||
@ -1063,7 +985,7 @@ btr_search_guess_on_hash(
|
||||
|
||||
ut_ad(buf_block_get_state(block) == BUF_BLOCK_REMOVE_HASH);
|
||||
|
||||
if (!has_search_latch) {
|
||||
if (!ahi_latch) {
|
||||
|
||||
btr_leaf_page_release(block, latch_mode, mtr);
|
||||
}
|
||||
@ -1085,11 +1007,9 @@ btr_search_guess_on_hash(
|
||||
record to determine if our guess for the cursor position is
|
||||
right. */
|
||||
if (index_id != btr_page_get_index_id(block->frame)
|
||||
|| !btr_search_check_guess(cursor,
|
||||
has_search_latch,
|
||||
tuple, mode)) {
|
||||
|| !btr_search_check_guess(cursor, !!ahi_latch, tuple, mode)) {
|
||||
|
||||
if (!has_search_latch) {
|
||||
if (!ahi_latch) {
|
||||
btr_leaf_page_release(block, latch_mode, mtr);
|
||||
}
|
||||
|
||||
@ -1110,7 +1030,7 @@ btr_search_guess_on_hash(
|
||||
info->last_hash_succ = FALSE;
|
||||
|
||||
/* Currently, does not work if the following fails: */
|
||||
ut_ad(!has_search_latch);
|
||||
ut_ad(!ahi_latch);
|
||||
|
||||
btr_leaf_page_release(block, latch_mode, mtr);
|
||||
|
||||
@ -1143,7 +1063,7 @@ btr_search_guess_on_hash(
|
||||
#ifdef UNIV_SEARCH_PERF_STAT
|
||||
btr_search_n_succ++;
|
||||
#endif
|
||||
if (!has_search_latch && buf_page_peek_if_too_old(&block->page)) {
|
||||
if (!ahi_latch && buf_page_peek_if_too_old(&block->page)) {
|
||||
|
||||
buf_page_make_young(&block->page);
|
||||
}
|
||||
@ -1191,6 +1111,8 @@ retry:
|
||||
/* This debug check uses a dirty read that could theoretically cause
|
||||
false positives while buf_pool_clear_hash_index() is executing. */
|
||||
assert_block_ahi_valid(block);
|
||||
ut_ad(!btr_search_own_any(RW_LOCK_S));
|
||||
ut_ad(!btr_search_own_any(RW_LOCK_X));
|
||||
|
||||
if (index == NULL) {
|
||||
return;
|
||||
@ -1214,9 +1136,6 @@ retry:
|
||||
% btr_ahi_parts;
|
||||
latch = btr_search_latches[ahi_slot];
|
||||
|
||||
ut_ad(!btr_search_own_any(RW_LOCK_S));
|
||||
ut_ad(!btr_search_own_any(RW_LOCK_X));
|
||||
|
||||
rw_lock_s_lock(latch);
|
||||
assert_block_ahi_valid(block);
|
||||
|
||||
@ -1419,6 +1338,7 @@ If index is non-NULL, this function checks if n_fields and n_bytes are
|
||||
sensible, and does not build a hash index if not.
|
||||
@param[in,out] index index for which to build.
|
||||
@param[in,out] block index page, s-/x- latched.
|
||||
@param[in,out] ahi_latch the adaptive search latch
|
||||
@param[in] n_fields hash this many full fields
|
||||
@param[in] n_bytes hash this many bytes of the next field
|
||||
@param[in] left_side hash for searches from left side */
|
||||
@ -1427,12 +1347,11 @@ void
|
||||
btr_search_build_page_hash_index(
|
||||
dict_index_t* index,
|
||||
buf_block_t* block,
|
||||
rw_lock_t* ahi_latch,
|
||||
ulint n_fields,
|
||||
ulint n_bytes,
|
||||
ibool left_side)
|
||||
{
|
||||
hash_table_t* table;
|
||||
page_t* page;
|
||||
const rec_t* rec;
|
||||
const rec_t* next_rec;
|
||||
ulint fold;
|
||||
@ -1454,6 +1373,7 @@ btr_search_build_page_hash_index(
|
||||
}
|
||||
|
||||
rec_offs_init(offsets_);
|
||||
ut_ad(ahi_latch == btr_get_search_latch(index));
|
||||
ut_ad(index);
|
||||
ut_ad(block->page.id.space() == index->space);
|
||||
ut_a(!dict_index_is_ibuf(index));
|
||||
@ -1463,20 +1383,17 @@ btr_search_build_page_hash_index(
|
||||
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_S)
|
||||
|| rw_lock_own(&(block->lock), RW_LOCK_X));
|
||||
|
||||
btr_search_s_lock(index);
|
||||
rw_lock_s_lock(ahi_latch);
|
||||
|
||||
table = btr_get_search_table(index);
|
||||
page = buf_block_get_frame(block);
|
||||
const bool rebuild = block->index
|
||||
&& (block->curr_n_fields != n_fields
|
||||
|| block->curr_n_bytes != n_bytes
|
||||
|| block->curr_left_side != left_side);
|
||||
|
||||
if (block->index && ((block->curr_n_fields != n_fields)
|
||||
|| (block->curr_n_bytes != n_bytes)
|
||||
|| (block->curr_left_side != left_side))) {
|
||||
|
||||
btr_search_s_unlock(index);
|
||||
rw_lock_s_unlock(ahi_latch);
|
||||
|
||||
if (rebuild) {
|
||||
btr_search_drop_page_hash_index(block);
|
||||
} else {
|
||||
btr_search_s_unlock(index);
|
||||
}
|
||||
|
||||
/* Check that the values for hash index build are sensible */
|
||||
@ -1491,6 +1408,7 @@ btr_search_build_page_hash_index(
|
||||
return;
|
||||
}
|
||||
|
||||
page_t* page = buf_block_get_frame(block);
|
||||
n_recs = page_get_n_recs(page);
|
||||
|
||||
if (n_recs == 0) {
|
||||
@ -1573,7 +1491,8 @@ btr_search_build_page_hash_index(
|
||||
|
||||
btr_search_check_free_space_in_heap(index);
|
||||
|
||||
btr_search_x_lock(index);
|
||||
hash_table_t* table = btr_get_search_table(index);
|
||||
rw_lock_x_lock(ahi_latch);
|
||||
|
||||
if (!btr_search_enabled) {
|
||||
goto exit_func;
|
||||
@ -1611,7 +1530,7 @@ btr_search_build_page_hash_index(
|
||||
MONITOR_INC_VALUE(MONITOR_ADAPTIVE_HASH_ROW_ADDED, n_cached);
|
||||
exit_func:
|
||||
assert_block_ahi_valid(block);
|
||||
btr_search_x_unlock(index);
|
||||
rw_lock_x_unlock(ahi_latch);
|
||||
|
||||
ut_free(folds);
|
||||
ut_free(recs);
|
||||
@ -1620,6 +1539,60 @@ exit_func:
|
||||
}
|
||||
}
|
||||
|
||||
/** Updates the search info.
|
||||
@param[in,out] info search info
|
||||
@param[in,out] cursor cursor which was just positioned */
|
||||
void
|
||||
btr_search_info_update_slow(btr_search_t* info, btr_cur_t* cursor)
|
||||
{
|
||||
rw_lock_t* ahi_latch = btr_get_search_latch(cursor->index);
|
||||
|
||||
ut_ad(!rw_lock_own(ahi_latch, RW_LOCK_S));
|
||||
ut_ad(!rw_lock_own(ahi_latch, RW_LOCK_X));
|
||||
|
||||
buf_block_t* block = btr_cur_get_block(cursor);
|
||||
|
||||
/* NOTE that the following two function calls do NOT protect
|
||||
info or block->n_fields etc. with any semaphore, to save CPU time!
|
||||
We cannot assume the fields are consistent when we return from
|
||||
those functions! */
|
||||
|
||||
btr_search_info_update_hash(info, cursor);
|
||||
|
||||
bool build_index = btr_search_update_block_hash_info(
|
||||
info, block, cursor);
|
||||
|
||||
if (build_index || (cursor->flag == BTR_CUR_HASH_FAIL)) {
|
||||
|
||||
btr_search_check_free_space_in_heap(cursor->index);
|
||||
}
|
||||
|
||||
if (cursor->flag == BTR_CUR_HASH_FAIL) {
|
||||
/* Update the hash node reference, if appropriate */
|
||||
|
||||
#ifdef UNIV_SEARCH_PERF_STAT
|
||||
btr_search_n_hash_fail++;
|
||||
#endif /* UNIV_SEARCH_PERF_STAT */
|
||||
|
||||
rw_lock_x_lock(ahi_latch);
|
||||
|
||||
btr_search_update_hash_ref(info, block, cursor);
|
||||
|
||||
rw_lock_x_unlock(ahi_latch);
|
||||
}
|
||||
|
||||
if (build_index) {
|
||||
/* Note that since we did not protect block->n_fields etc.
|
||||
with any semaphore, the values can be inconsistent. We have
|
||||
to check inside the function call that they make sense. */
|
||||
btr_search_build_page_hash_index(cursor->index, block,
|
||||
ahi_latch,
|
||||
block->n_fields,
|
||||
block->n_bytes,
|
||||
block->left_side);
|
||||
}
|
||||
}
|
||||
|
||||
/** Move or delete hash entries for moved records, usually in a page split.
|
||||
If new_block is already hashed, then any hash index for block is dropped.
|
||||
If new_block is not hashed, and block is hashed, then a new hash index is
|
||||
@ -1638,19 +1611,27 @@ btr_search_move_or_delete_hash_entries(
|
||||
return;
|
||||
}
|
||||
|
||||
dict_index_t* index = block->index;
|
||||
if (!index) {
|
||||
index = new_block->index;
|
||||
} else {
|
||||
ut_ad(!new_block->index || index == new_block->index);
|
||||
}
|
||||
assert_block_ahi_valid(block);
|
||||
assert_block_ahi_valid(new_block);
|
||||
|
||||
rw_lock_t* ahi_latch = index ? btr_get_search_latch(index) : NULL;
|
||||
|
||||
if (new_block->index) {
|
||||
btr_search_drop_page_hash_index(block);
|
||||
return;
|
||||
}
|
||||
|
||||
dict_index_t* index = block->index;
|
||||
if (!index) {
|
||||
return;
|
||||
}
|
||||
btr_search_s_lock(index);
|
||||
|
||||
rw_lock_s_lock(ahi_latch);
|
||||
|
||||
if (block->index) {
|
||||
ulint n_fields = block->curr_n_fields;
|
||||
@ -1661,19 +1642,20 @@ btr_search_move_or_delete_hash_entries(
|
||||
new_block->n_bytes = block->curr_n_bytes;
|
||||
new_block->left_side = left_side;
|
||||
|
||||
btr_search_s_unlock(index);
|
||||
rw_lock_s_unlock(ahi_latch);
|
||||
|
||||
ut_a(n_fields > 0 || n_bytes > 0);
|
||||
|
||||
btr_search_build_page_hash_index(
|
||||
index, new_block, n_fields, n_bytes, left_side);
|
||||
index, new_block, ahi_latch,
|
||||
n_fields, n_bytes, left_side);
|
||||
ut_ad(n_fields == block->curr_n_fields);
|
||||
ut_ad(n_bytes == block->curr_n_bytes);
|
||||
ut_ad(left_side == block->curr_left_side);
|
||||
return;
|
||||
}
|
||||
|
||||
btr_search_s_unlock(index);
|
||||
rw_lock_s_unlock(ahi_latch);
|
||||
}
|
||||
|
||||
/** Updates the page hash index when a single record is deleted from a page.
|
||||
@ -1728,7 +1710,9 @@ btr_search_update_hash_on_delete(btr_cur_t* cursor)
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
|
||||
btr_search_x_lock(index);
|
||||
rw_lock_t* ahi_latch = btr_get_search_latch(index);
|
||||
|
||||
rw_lock_x_lock(ahi_latch);
|
||||
assert_block_ahi_valid(block);
|
||||
|
||||
if (block->index) {
|
||||
@ -1744,21 +1728,25 @@ btr_search_update_hash_on_delete(btr_cur_t* cursor)
|
||||
assert_block_ahi_valid(block);
|
||||
}
|
||||
|
||||
btr_search_x_unlock(index);
|
||||
rw_lock_x_unlock(ahi_latch);
|
||||
}
|
||||
|
||||
/** Updates the page hash index when a single record is inserted on a page.
|
||||
@param[in] cursor cursor which was positioned to the place to insert
|
||||
using btr_cur_search_, and the new record has been
|
||||
inserted next to the cursor. */
|
||||
inserted next to the cursor.
|
||||
@param[in] ahi_latch the adaptive hash index latch */
|
||||
void
|
||||
btr_search_update_hash_node_on_insert(btr_cur_t* cursor)
|
||||
btr_search_update_hash_node_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch)
|
||||
{
|
||||
hash_table_t* table;
|
||||
buf_block_t* block;
|
||||
dict_index_t* index;
|
||||
rec_t* rec;
|
||||
|
||||
ut_ad(ahi_latch == btr_get_search_latch(cursor->index));
|
||||
ut_ad(!btr_search_own_any(RW_LOCK_S));
|
||||
ut_ad(!btr_search_own_any(RW_LOCK_X));
|
||||
#ifdef MYSQL_INDEX_DISABLE_AHI
|
||||
if (cursor->index->disable_ahi) return;
|
||||
#endif
|
||||
@ -1781,8 +1769,7 @@ btr_search_update_hash_node_on_insert(btr_cur_t* cursor)
|
||||
|
||||
ut_a(cursor->index == index);
|
||||
ut_a(!dict_index_is_ibuf(index));
|
||||
|
||||
btr_search_x_lock(index);
|
||||
rw_lock_x_lock(ahi_latch);
|
||||
|
||||
if (!block->index) {
|
||||
|
||||
@ -1806,11 +1793,11 @@ btr_search_update_hash_node_on_insert(btr_cur_t* cursor)
|
||||
|
||||
func_exit:
|
||||
assert_block_ahi_valid(block);
|
||||
btr_search_x_unlock(index);
|
||||
rw_lock_x_unlock(ahi_latch);
|
||||
} else {
|
||||
btr_search_x_unlock(index);
|
||||
rw_lock_x_unlock(ahi_latch);
|
||||
|
||||
btr_search_update_hash_on_insert(cursor);
|
||||
btr_search_update_hash_on_insert(cursor, ahi_latch);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1818,9 +1805,10 @@ func_exit:
|
||||
@param[in,out] cursor cursor which was positioned to the
|
||||
place to insert using btr_cur_search_...,
|
||||
and the new record has been inserted next
|
||||
to the cursor */
|
||||
to the cursor
|
||||
@param[in] ahi_latch the adaptive hash index latch */
|
||||
void
|
||||
btr_search_update_hash_on_insert(btr_cur_t* cursor)
|
||||
btr_search_update_hash_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch)
|
||||
{
|
||||
hash_table_t* table;
|
||||
buf_block_t* block;
|
||||
@ -1834,13 +1822,16 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor)
|
||||
ulint n_fields;
|
||||
ulint n_bytes;
|
||||
ibool left_side;
|
||||
ibool locked = FALSE;
|
||||
bool locked = false;
|
||||
mem_heap_t* heap = NULL;
|
||||
ulint offsets_[REC_OFFS_NORMAL_SIZE];
|
||||
ulint* offsets = offsets_;
|
||||
rec_offs_init(offsets_);
|
||||
|
||||
ut_ad(ahi_latch == btr_get_search_latch(cursor->index));
|
||||
ut_ad(page_is_leaf(btr_cur_get_page(cursor)));
|
||||
ut_ad(!btr_search_own_any(RW_LOCK_S));
|
||||
ut_ad(!btr_search_own_any(RW_LOCK_X));
|
||||
#ifdef MYSQL_INDEX_DISABLE_AHI
|
||||
if (cursor->index->disable_ahi) return;
|
||||
#endif
|
||||
@ -1899,10 +1890,8 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor)
|
||||
fold = rec_fold(rec, offsets, n_fields, n_bytes, index->id);
|
||||
} else {
|
||||
if (left_side) {
|
||||
|
||||
btr_search_x_lock(index);
|
||||
|
||||
locked = TRUE;
|
||||
locked = true;
|
||||
rw_lock_x_lock(ahi_latch);
|
||||
|
||||
if (!btr_search_enabled) {
|
||||
goto function_exit;
|
||||
@ -1917,10 +1906,8 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor)
|
||||
if (fold != ins_fold) {
|
||||
|
||||
if (!locked) {
|
||||
|
||||
btr_search_x_lock(index);
|
||||
|
||||
locked = TRUE;
|
||||
locked = true;
|
||||
rw_lock_x_lock(ahi_latch);
|
||||
|
||||
if (!btr_search_enabled) {
|
||||
goto function_exit;
|
||||
@ -1938,11 +1925,9 @@ check_next_rec:
|
||||
if (page_rec_is_supremum(next_rec)) {
|
||||
|
||||
if (!left_side) {
|
||||
|
||||
if (!locked) {
|
||||
btr_search_x_lock(index);
|
||||
|
||||
locked = TRUE;
|
||||
locked = true;
|
||||
rw_lock_x_lock(ahi_latch);
|
||||
|
||||
if (!btr_search_enabled) {
|
||||
goto function_exit;
|
||||
@ -1958,10 +1943,8 @@ check_next_rec:
|
||||
if (ins_fold != next_fold) {
|
||||
|
||||
if (!locked) {
|
||||
|
||||
btr_search_x_lock(index);
|
||||
|
||||
locked = TRUE;
|
||||
locked = true;
|
||||
rw_lock_x_lock(ahi_latch);
|
||||
|
||||
if (!btr_search_enabled) {
|
||||
goto function_exit;
|
||||
@ -1980,8 +1963,9 @@ function_exit:
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
if (locked) {
|
||||
btr_search_x_unlock(index);
|
||||
rw_lock_x_unlock(ahi_latch);
|
||||
}
|
||||
ut_ad(!rw_lock_own(ahi_latch, RW_LOCK_X));
|
||||
}
|
||||
|
||||
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, MariaDB Corporation.
|
||||
Copyright (c) 2017, 2018, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
@ -177,8 +177,7 @@ Note that if mode is PAGE_CUR_LE, which is used in inserts, then
|
||||
cursor->up_match and cursor->low_match both will have sensible values.
|
||||
If mode is PAGE_CUR_GE, then up_match will a have a sensible value. */
|
||||
dberr_t
|
||||
btr_cur_search_to_nth_level(
|
||||
/*========================*/
|
||||
btr_cur_search_to_nth_level_func(
|
||||
dict_index_t* index, /*!< in: index */
|
||||
ulint level, /*!< in: the tree level of search */
|
||||
const dtuple_t* tuple, /*!< in: data tuple; NOTE: n_fields_cmp in
|
||||
@ -197,23 +196,29 @@ btr_cur_search_to_nth_level(
|
||||
cursor->left_block is used to store a pointer
|
||||
to the left neighbor page, in the cases
|
||||
BTR_SEARCH_PREV and BTR_MODIFY_PREV;
|
||||
NOTE that if has_search_latch
|
||||
is != 0, we maybe do not have a latch set
|
||||
on the cursor page, we assume
|
||||
the caller uses his search latch
|
||||
to protect the record! */
|
||||
NOTE that if ahi_latch, we might not have a
|
||||
cursor page latch, we assume that ahi_latch
|
||||
protects the record! */
|
||||
btr_cur_t* cursor, /*!< in/out: tree cursor; the cursor page is
|
||||
s- or x-latched, but see also above! */
|
||||
ulint has_search_latch,
|
||||
/*!< in: latch mode the caller
|
||||
currently has on search system:
|
||||
RW_S_LATCH, or 0 */
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
rw_lock_t* ahi_latch,
|
||||
/*!< in: currently held btr_search_latch
|
||||
(in RW_S_LATCH mode), or NULL */
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
const char* file, /*!< in: file name */
|
||||
unsigned line, /*!< in: line where called */
|
||||
mtr_t* mtr, /*!< in/out: mini-transaction */
|
||||
ib_uint64_t autoinc = 0);
|
||||
/*!< in: PAGE_ROOT_AUTO_INC to be written
|
||||
(0 if none) */
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
# define btr_cur_search_to_nth_level(i,l,t,m,lm,c,a,fi,li,mtr) \
|
||||
btr_cur_search_to_nth_level_func(i,l,t,m,lm,c,a,fi,li,mtr)
|
||||
#else /* BTR_CUR_HASH_ADAPT */
|
||||
# define btr_cur_search_to_nth_level(i,l,t,m,lm,c,a,fi,li,mtr) \
|
||||
btr_cur_search_to_nth_level_func(i,l,t,m,lm,c,fi,li,mtr)
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
/*****************************************************************//**
|
||||
Opens a cursor at either end of an index.
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, MariaDB Corporation.
|
||||
Copyright (c) 2017, 2018, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
@ -136,20 +136,25 @@ btr_pcur_open_with_no_init_func(
|
||||
may end up on the previous page of the
|
||||
record! */
|
||||
ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ...;
|
||||
NOTE that if has_search_latch != 0 then
|
||||
we maybe do not acquire a latch on the cursor
|
||||
page, but assume that the caller uses his
|
||||
btr search latch to protect the record! */
|
||||
NOTE that if ahi_latch then we might not
|
||||
acquire a cursor page latch, but assume
|
||||
that the ahi_latch protects the record! */
|
||||
btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
|
||||
ulint has_search_latch,
|
||||
/*!< in: latch mode the caller
|
||||
currently has on search system:
|
||||
RW_S_LATCH, or 0 */
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
rw_lock_t* ahi_latch,
|
||||
/*!< in: adaptive hash index latch held
|
||||
by the caller, or NULL if none */
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
const char* file, /*!< in: file name */
|
||||
unsigned line, /*!< in: line where called */
|
||||
mtr_t* mtr); /*!< in: mtr */
|
||||
#define btr_pcur_open_with_no_init(ix,t,md,l,cur,has,m) \
|
||||
btr_pcur_open_with_no_init_func(ix,t,md,l,cur,has,__FILE__,__LINE__,m)
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
# define btr_pcur_open_with_no_init(ix,t,md,l,cur,ahi,m) \
|
||||
btr_pcur_open_with_no_init_func(ix,t,md,l,cur,ahi,__FILE__,__LINE__,m)
|
||||
#else /* BTR_CUR_HASH_ADAPT */
|
||||
# define btr_pcur_open_with_no_init(ix,t,md,l,cur,ahi,m) \
|
||||
btr_pcur_open_with_no_init_func(ix,t,md,l,cur,__FILE__,__LINE__,m)
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
/*****************************************************************//**
|
||||
Opens a persistent cursor at either end of an index. */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2015, 2017, MariaDB Corporation.
|
||||
Copyright (c) 2015, 2018, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
@ -454,9 +454,12 @@ btr_pcur_open_low(
|
||||
|
||||
ut_ad(!dict_index_is_spatial(index));
|
||||
|
||||
err = btr_cur_search_to_nth_level(
|
||||
index, level, tuple, mode, latch_mode,
|
||||
btr_cursor, 0, file, line, mtr, autoinc);
|
||||
err = btr_cur_search_to_nth_level_func(
|
||||
index, level, tuple, mode, latch_mode, btr_cursor,
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
NULL,
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
file, line, mtr, autoinc);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
ib::warn() << " Error code: " << err
|
||||
@ -491,15 +494,15 @@ btr_pcur_open_with_no_init_func(
|
||||
may end up on the previous page of the
|
||||
record! */
|
||||
ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ...;
|
||||
NOTE that if has_search_latch != 0 then
|
||||
we maybe do not acquire a latch on the cursor
|
||||
page, but assume that the caller uses his
|
||||
btr search latch to protect the record! */
|
||||
NOTE that if ahi_latch then we might not
|
||||
acquire a cursor page latch, but assume
|
||||
that the ahi_latch protects the record! */
|
||||
btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
|
||||
ulint has_search_latch,
|
||||
/*!< in: latch mode the caller
|
||||
currently has on search system:
|
||||
RW_S_LATCH, or 0 */
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
rw_lock_t* ahi_latch,
|
||||
/*!< in: adaptive hash index latch held
|
||||
by the caller, or NULL if none */
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
const char* file, /*!< in: file name */
|
||||
unsigned line, /*!< in: line where called */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
@ -514,9 +517,12 @@ btr_pcur_open_with_no_init_func(
|
||||
|
||||
btr_cursor = btr_pcur_get_btr_cur(cursor);
|
||||
|
||||
err = btr_cur_search_to_nth_level(
|
||||
err = btr_cur_search_to_nth_level_func(
|
||||
index, 0, tuple, mode, latch_mode, btr_cursor,
|
||||
has_search_latch, file, line, mtr);
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
ahi_latch,
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
file, line, mtr);
|
||||
|
||||
cursor->pos_state = BTR_PCUR_IS_POSITIONED;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, MariaDB Corporation.
|
||||
Copyright (c) 2017, 2018, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
@ -91,12 +91,11 @@ both have sensible values.
|
||||
we assume the caller uses his search latch
|
||||
to protect the record!
|
||||
@param[out] cursor tree cursor
|
||||
@param[in] has_search_latch
|
||||
latch mode the caller currently has on
|
||||
search system: RW_S/X_LATCH or 0
|
||||
@param[in] ahi_latch the adaptive hash index latch being held,
|
||||
or NULL
|
||||
@param[in] mtr mini transaction
|
||||
@return TRUE if succeeded */
|
||||
ibool
|
||||
@return whether the search succeeded */
|
||||
bool
|
||||
btr_search_guess_on_hash(
|
||||
dict_index_t* index,
|
||||
btr_search_t* info,
|
||||
@ -104,7 +103,7 @@ btr_search_guess_on_hash(
|
||||
ulint mode,
|
||||
ulint latch_mode,
|
||||
btr_cur_t* cursor,
|
||||
ulint has_search_latch,
|
||||
rw_lock_t* ahi_latch,
|
||||
mtr_t* mtr);
|
||||
|
||||
/** Move or delete hash entries for moved records, usually in a page split.
|
||||
@ -140,17 +139,19 @@ btr_search_drop_page_hash_when_freed(
|
||||
/** Updates the page hash index when a single record is inserted on a page.
|
||||
@param[in] cursor cursor which was positioned to the place to insert
|
||||
using btr_cur_search_, and the new record has been
|
||||
inserted next to the cursor. */
|
||||
inserted next to the cursor.
|
||||
@param[in] ahi_latch the adaptive hash index latch */
|
||||
void
|
||||
btr_search_update_hash_node_on_insert(btr_cur_t* cursor);
|
||||
btr_search_update_hash_node_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch);
|
||||
|
||||
/** Updates the page hash index when a single record is inserted on a page.
|
||||
@param[in] cursor cursor which was positioned to the
|
||||
@param[in,out] cursor cursor which was positioned to the
|
||||
place to insert using btr_cur_search_...,
|
||||
and the new record has been inserted next
|
||||
to the cursor */
|
||||
to the cursor
|
||||
@param[in] ahi_latch the adaptive hash index latch */
|
||||
void
|
||||
btr_search_update_hash_on_insert(btr_cur_t* cursor);
|
||||
btr_search_update_hash_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch);
|
||||
|
||||
/** Updates the page hash index when a single record is deleted from a page.
|
||||
@param[in] cursor cursor which was positioned on the record to delete
|
||||
@ -163,18 +164,6 @@ btr_search_update_hash_on_delete(btr_cur_t* cursor);
|
||||
bool
|
||||
btr_search_validate();
|
||||
|
||||
/** X-Lock the search latch (corresponding to given index)
|
||||
@param[in] index index handler */
|
||||
UNIV_INLINE
|
||||
void
|
||||
btr_search_x_lock(const dict_index_t* index);
|
||||
|
||||
/** X-Unlock the search latch (corresponding to given index)
|
||||
@param[in] index index handler */
|
||||
UNIV_INLINE
|
||||
void
|
||||
btr_search_x_unlock(const dict_index_t* index);
|
||||
|
||||
/** Lock all search latches in exclusive mode. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
@ -185,18 +174,6 @@ UNIV_INLINE
|
||||
void
|
||||
btr_search_x_unlock_all();
|
||||
|
||||
/** S-Lock the search latch (corresponding to given index)
|
||||
@param[in] index index handler */
|
||||
UNIV_INLINE
|
||||
void
|
||||
btr_search_s_lock(const dict_index_t* index);
|
||||
|
||||
/** S-Unlock the search latch (corresponding to given index)
|
||||
@param[in] index index handler */
|
||||
UNIV_INLINE
|
||||
void
|
||||
btr_search_s_unlock(const dict_index_t* index);
|
||||
|
||||
/** Lock all search latches in shared mode. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
@ -243,15 +220,11 @@ btr_get_search_table(const dict_index_t* index);
|
||||
#else /* BTR_CUR_HASH_ADAPT */
|
||||
# define btr_search_sys_create(size)
|
||||
# define btr_search_drop_page_hash_index(block)
|
||||
# define btr_search_s_lock(index)
|
||||
# define btr_search_s_unlock(index)
|
||||
# define btr_search_s_lock_all(index)
|
||||
# define btr_search_s_unlock_all(index)
|
||||
# define btr_search_x_lock(index)
|
||||
# define btr_search_x_unlock(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)
|
||||
# define btr_search_update_hash_on_insert(cursor, ahi_latch)
|
||||
# define btr_search_update_hash_on_delete(cursor)
|
||||
# define btr_search_sys_resize(hash_size)
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2018, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
@ -45,13 +46,11 @@ btr_search_info_create(mem_heap_t* heap)
|
||||
}
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
/*********************************************************************//**
|
||||
Updates the search info. */
|
||||
/** Updates the search info.
|
||||
@param[in,out] info search info
|
||||
@param[in,out] cursor cursor which was just positioned */
|
||||
void
|
||||
btr_search_info_update_slow(
|
||||
/*========================*/
|
||||
btr_search_t* info, /*!< in/out: search info */
|
||||
btr_cur_t* cursor);/*!< in: cursor which was just positioned */
|
||||
btr_search_info_update_slow(btr_search_t* info, btr_cur_t* cursor);
|
||||
|
||||
/*********************************************************************//**
|
||||
Updates the search info. */
|
||||
@ -87,24 +86,6 @@ btr_search_info_update(
|
||||
btr_search_info_update_slow(info, cursor);
|
||||
}
|
||||
|
||||
/** X-Lock the search latch (corresponding to given index)
|
||||
@param[in] index index handler */
|
||||
UNIV_INLINE
|
||||
void
|
||||
btr_search_x_lock(const dict_index_t* index)
|
||||
{
|
||||
rw_lock_x_lock(btr_get_search_latch(index));
|
||||
}
|
||||
|
||||
/** X-Unlock the search latch (corresponding to given index)
|
||||
@param[in] index index handler */
|
||||
UNIV_INLINE
|
||||
void
|
||||
btr_search_x_unlock(const dict_index_t* index)
|
||||
{
|
||||
rw_lock_x_unlock(btr_get_search_latch(index));
|
||||
}
|
||||
|
||||
/** Lock all search latches in exclusive mode. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
@ -125,24 +106,6 @@ btr_search_x_unlock_all()
|
||||
}
|
||||
}
|
||||
|
||||
/** S-Lock the search latch (corresponding to given index)
|
||||
@param[in] index index handler */
|
||||
UNIV_INLINE
|
||||
void
|
||||
btr_search_s_lock(const dict_index_t* index)
|
||||
{
|
||||
rw_lock_s_lock(btr_get_search_latch(index));
|
||||
}
|
||||
|
||||
/** S-Unlock the search latch (corresponding to given index)
|
||||
@param[in] index index handler */
|
||||
UNIV_INLINE
|
||||
void
|
||||
btr_search_s_unlock(const dict_index_t* index)
|
||||
{
|
||||
rw_lock_s_unlock(btr_get_search_latch(index));
|
||||
}
|
||||
|
||||
/** Lock all search latches in shared mode. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
|
@ -1272,24 +1272,19 @@ static
|
||||
void
|
||||
row_sel_open_pcur(
|
||||
/*==============*/
|
||||
plan_t* plan, /*!< in: table plan */
|
||||
ibool search_latch_locked,
|
||||
/*!< in: TRUE if the thread currently
|
||||
has the search latch locked in
|
||||
s-mode */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
plan_t* plan, /*!< in: table plan */
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
rw_lock_t* ahi_latch,
|
||||
/*!< in: the adaptive hash index latch */
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
mtr_t* mtr) /*!< in/out: mini-transaction */
|
||||
{
|
||||
dict_index_t* index;
|
||||
func_node_t* cond;
|
||||
que_node_t* exp;
|
||||
ulint n_fields;
|
||||
ulint has_search_latch = 0; /* RW_S_LATCH or 0 */
|
||||
ulint i;
|
||||
|
||||
if (search_latch_locked) {
|
||||
has_search_latch = RW_S_LATCH;
|
||||
}
|
||||
|
||||
index = plan->index;
|
||||
|
||||
/* Calculate the value of the search tuple: the exact match columns
|
||||
@ -1325,7 +1320,7 @@ row_sel_open_pcur(
|
||||
|
||||
btr_pcur_open_with_no_init(index, plan->tuple, plan->mode,
|
||||
BTR_SEARCH_LEAF, &plan->pcur,
|
||||
has_search_latch, mtr);
|
||||
ahi_latch, mtr);
|
||||
} else {
|
||||
/* Open the cursor to the start or the end of the index
|
||||
(FALSE: no init) */
|
||||
@ -1473,7 +1468,7 @@ row_sel_try_search_shortcut(
|
||||
rw_lock_t* ahi_latch = btr_get_search_latch(index);
|
||||
rw_lock_s_lock(ahi_latch);
|
||||
|
||||
row_sel_open_pcur(plan, TRUE, mtr);
|
||||
row_sel_open_pcur(plan, ahi_latch, mtr);
|
||||
|
||||
const rec_t* rec = btr_pcur_get_rec(&(plan->pcur));
|
||||
|
||||
@ -1659,8 +1654,11 @@ table_loop:
|
||||
if (!plan->pcur_is_open) {
|
||||
/* Evaluate the expressions to build the search tuple and
|
||||
open the cursor */
|
||||
|
||||
row_sel_open_pcur(plan, FALSE, &mtr);
|
||||
row_sel_open_pcur(plan,
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
NULL,
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
&mtr);
|
||||
|
||||
cursor_just_opened = TRUE;
|
||||
|
||||
@ -3841,7 +3839,7 @@ row_sel_try_search_shortcut_for_mysql(
|
||||
rw_lock_t* ahi_latch = btr_get_search_latch(index);
|
||||
rw_lock_s_lock(ahi_latch);
|
||||
btr_pcur_open_with_no_init(index, search_tuple, PAGE_CUR_GE,
|
||||
BTR_SEARCH_LEAF, pcur, RW_S_LATCH, mtr);
|
||||
BTR_SEARCH_LEAF, pcur, ahi_latch, mtr);
|
||||
rec = btr_pcur_get_rec(pcur);
|
||||
|
||||
if (!page_rec_is_user_rec(rec) || rec_is_default_row(rec, index)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user