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,
|
immediately after the cursor. Thus, the cursor may end up on a user record,
|
||||||
or on a page infimum record. */
|
or on a page infimum record. */
|
||||||
dberr_t
|
dberr_t
|
||||||
btr_cur_search_to_nth_level(
|
btr_cur_search_to_nth_level_func(
|
||||||
/*========================*/
|
|
||||||
dict_index_t* index, /*!< in: index */
|
dict_index_t* index, /*!< in: index */
|
||||||
ulint level, /*!< in: the tree level of search */
|
ulint level, /*!< in: the tree level of search */
|
||||||
const dtuple_t* tuple, /*!< in: data tuple; NOTE: n_fields_cmp in
|
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
|
cursor->left_block is used to store a pointer
|
||||||
to the left neighbor page, in the cases
|
to the left neighbor page, in the cases
|
||||||
BTR_SEARCH_PREV and BTR_MODIFY_PREV;
|
BTR_SEARCH_PREV and BTR_MODIFY_PREV;
|
||||||
NOTE that if has_search_latch
|
NOTE that if ahi_latch, we might not have a
|
||||||
is != 0, we maybe do not have a latch set
|
cursor page latch, we assume that ahi_latch
|
||||||
on the cursor page, we assume
|
protects the record! */
|
||||||
the caller uses his search latch
|
|
||||||
to protect the record! */
|
|
||||||
btr_cur_t* cursor, /*!< in/out: tree cursor; the cursor page is
|
btr_cur_t* cursor, /*!< in/out: tree cursor; the cursor page is
|
||||||
s- or x-latched, but see also above! */
|
s- or x-latched, but see also above! */
|
||||||
ulint has_search_latch,
|
#ifdef BTR_CUR_HASH_ADAPT
|
||||||
/*!< in: info on the latch mode the
|
rw_lock_t* ahi_latch,
|
||||||
caller currently has on search system:
|
/*!< in: currently held btr_search_latch
|
||||||
RW_S_LATCH, or 0 */
|
(in RW_S_LATCH mode), or NULL */
|
||||||
|
#endif /* BTR_CUR_HASH_ADAPT */
|
||||||
const char* file, /*!< in: file name */
|
const char* file, /*!< in: file name */
|
||||||
unsigned line, /*!< in: line where called */
|
unsigned line, /*!< in: line where called */
|
||||||
mtr_t* mtr, /*!< in: mtr */
|
mtr_t* mtr, /*!< in: mtr */
|
||||||
@ -1123,7 +1121,7 @@ btr_cur_search_to_nth_level(
|
|||||||
&& mode != PAGE_CUR_LE_OR_EXTENDS
|
&& mode != PAGE_CUR_LE_OR_EXTENDS
|
||||||
# endif /* PAGE_CUR_LE_OR_EXTENDS */
|
# endif /* PAGE_CUR_LE_OR_EXTENDS */
|
||||||
&& !dict_index_is_spatial(index)
|
&& !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()
|
btr_search_enabled below, and btr_search_guess_on_hash()
|
||||||
will have to check it again. */
|
will have to check it again. */
|
||||||
&& btr_search_enabled
|
&& btr_search_enabled
|
||||||
@ -1131,7 +1129,7 @@ btr_cur_search_to_nth_level(
|
|||||||
&& !(tuple->info_bits & REC_INFO_MIN_REC_FLAG)
|
&& !(tuple->info_bits & REC_INFO_MIN_REC_FLAG)
|
||||||
&& btr_search_guess_on_hash(index, info, tuple, mode,
|
&& btr_search_guess_on_hash(index, info, tuple, mode,
|
||||||
latch_mode, cursor,
|
latch_mode, cursor,
|
||||||
has_search_latch, mtr)) {
|
ahi_latch, mtr)) {
|
||||||
|
|
||||||
/* Search using the hash index succeeded */
|
/* 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
|
/* If the hash search did not succeed, do binary search down the
|
||||||
tree */
|
tree */
|
||||||
|
|
||||||
if (has_search_latch) {
|
#ifdef BTR_CUR_HASH_ADAPT
|
||||||
|
if (ahi_latch) {
|
||||||
/* Release possible search latch to obey latching order */
|
/* 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
|
/* 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) */
|
know how to release it when we have latched leaf node(s) */
|
||||||
@ -2222,15 +2222,17 @@ func_exit:
|
|||||||
ut_free(prev_tree_savepoints);
|
ut_free(prev_tree_savepoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_search_latch) {
|
|
||||||
btr_search_s_lock(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mbr_adj) {
|
if (mbr_adj) {
|
||||||
/* remember that we will need to adjust parent MBR */
|
/* remember that we will need to adjust parent MBR */
|
||||||
cursor->rtr_info->mbr_adj = true;
|
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);
|
DBUG_RETURN(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3300,10 +3302,14 @@ fail_err:
|
|||||||
ut_ad(entry->info_bits == REC_INFO_DEFAULT_ROW);
|
ut_ad(entry->info_bits == REC_INFO_DEFAULT_ROW);
|
||||||
ut_ad(index->is_instant());
|
ut_ad(index->is_instant());
|
||||||
ut_ad(flags == BTR_NO_LOCKING_FLAG);
|
ut_ad(flags == BTR_NO_LOCKING_FLAG);
|
||||||
} else if (!reorg && cursor->flag == BTR_CUR_HASH) {
|
|
||||||
btr_search_update_hash_node_on_insert(cursor);
|
|
||||||
} else {
|
} 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 */
|
#endif /* BTR_CUR_HASH_ADAPT */
|
||||||
|
|
||||||
@ -3509,7 +3515,8 @@ btr_cur_pessimistic_insert(
|
|||||||
ut_ad((flags & ~BTR_KEEP_IBUF_BITMAP)
|
ut_ad((flags & ~BTR_KEEP_IBUF_BITMAP)
|
||||||
== BTR_NO_LOCKING_FLAG);
|
== BTR_NO_LOCKING_FLAG);
|
||||||
} else {
|
} 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 */
|
#endif /* BTR_CUR_HASH_ADAPT */
|
||||||
if (inherit && !(flags & BTR_NO_LOCKING_FLAG)) {
|
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,
|
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 */
|
/* Restore the old search mode */
|
||||||
cursor->search_mode = old_mode;
|
cursor->search_mode = old_mode;
|
||||||
|
@ -48,7 +48,7 @@ Search system is protected by array of latches. */
|
|||||||
char btr_search_enabled = true;
|
char btr_search_enabled = true;
|
||||||
|
|
||||||
/** Number of adaptive hash index partition. */
|
/** Number of adaptive hash index partition. */
|
||||||
ulong btr_ahi_parts = 8;
|
ulong btr_ahi_parts;
|
||||||
|
|
||||||
#ifdef UNIV_SEARCH_PERF_STAT
|
#ifdef UNIV_SEARCH_PERF_STAT
|
||||||
/** Number of successful adaptive hash index lookups */
|
/** 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));
|
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
|
/** This function should be called before reserving any btr search mutex, if
|
||||||
the intended operation might add nodes to the search system hash table.
|
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
|
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) {
|
if (heap->free_block == NULL) {
|
||||||
buf_block_t* block = buf_block_alloc(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
|
if (btr_search_enabled
|
||||||
&& heap->free_block == NULL) {
|
&& heap->free_block == NULL) {
|
||||||
@ -234,7 +218,7 @@ btr_search_check_free_space_in_heap(dict_index_t* index)
|
|||||||
buf_block_free(block);
|
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(info);
|
||||||
|
|
||||||
ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_S));
|
rw_lock_t* ahi_latch = btr_get_search_latch(index);
|
||||||
ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_X));
|
rw_lock_s_lock(ahi_latch);
|
||||||
|
|
||||||
btr_search_s_lock(index);
|
|
||||||
ret = info->ref_count;
|
ret = info->ref_count;
|
||||||
btr_search_s_unlock(index);
|
rw_lock_s_unlock(ahi_latch);
|
||||||
|
|
||||||
return(ret);
|
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
|
/** 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
|
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.
|
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
|
we assume the caller uses his search latch
|
||||||
to protect the record!
|
to protect the record!
|
||||||
@param[out] cursor tree cursor
|
@param[out] cursor tree cursor
|
||||||
@param[in] has_search_latch
|
@param[in] ahi_latch the adaptive hash index latch being held,
|
||||||
latch mode the caller currently has on
|
or NULL
|
||||||
search system: RW_S/X_LATCH or 0
|
|
||||||
@param[in] mtr mini transaction
|
@param[in] mtr mini transaction
|
||||||
@return TRUE if succeeded */
|
@return whether the search succeeded */
|
||||||
ibool
|
bool
|
||||||
btr_search_guess_on_hash(
|
btr_search_guess_on_hash(
|
||||||
dict_index_t* index,
|
dict_index_t* index,
|
||||||
btr_search_t* info,
|
btr_search_t* info,
|
||||||
@ -960,7 +886,7 @@ btr_search_guess_on_hash(
|
|||||||
ulint mode,
|
ulint mode,
|
||||||
ulint latch_mode,
|
ulint latch_mode,
|
||||||
btr_cur_t* cursor,
|
btr_cur_t* cursor,
|
||||||
ulint has_search_latch,
|
rw_lock_t* ahi_latch,
|
||||||
mtr_t* mtr)
|
mtr_t* mtr)
|
||||||
{
|
{
|
||||||
const rec_t* rec;
|
const rec_t* rec;
|
||||||
@ -970,6 +896,8 @@ btr_search_guess_on_hash(
|
|||||||
btr_cur_t cursor2;
|
btr_cur_t cursor2;
|
||||||
btr_pcur_t pcur;
|
btr_pcur_t pcur;
|
||||||
#endif
|
#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) {
|
if (!btr_search_enabled) {
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
@ -977,6 +905,7 @@ btr_search_guess_on_hash(
|
|||||||
|
|
||||||
ut_ad(index && info && tuple && cursor && mtr);
|
ut_ad(index && info && tuple && cursor && mtr);
|
||||||
ut_ad(!dict_index_is_ibuf(index));
|
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)
|
ut_ad((latch_mode == BTR_SEARCH_LEAF)
|
||||||
|| (latch_mode == BTR_MODIFY_LEAF));
|
|| (latch_mode == BTR_MODIFY_LEAF));
|
||||||
|
|
||||||
@ -1009,27 +938,27 @@ btr_search_guess_on_hash(
|
|||||||
cursor->fold = fold;
|
cursor->fold = fold;
|
||||||
cursor->flag = BTR_CUR_HASH;
|
cursor->flag = BTR_CUR_HASH;
|
||||||
|
|
||||||
if (!has_search_latch) {
|
rw_lock_t* use_latch = ahi_latch ? NULL : btr_get_search_latch(index);
|
||||||
btr_search_s_lock(index);
|
|
||||||
|
if (use_latch) {
|
||||||
|
rw_lock_s_lock(use_latch);
|
||||||
|
|
||||||
if (!btr_search_enabled) {
|
if (!btr_search_enabled) {
|
||||||
btr_search_s_unlock(index);
|
goto fail;
|
||||||
|
|
||||||
btr_search_failure(info, cursor);
|
|
||||||
|
|
||||||
return(FALSE);
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
ut_ad(btr_search_enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
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_S));
|
||||||
|
|
||||||
rec = (rec_t*) ha_search_and_get_data(
|
rec = (rec_t*) ha_search_and_get_data(
|
||||||
btr_get_search_table(index), fold);
|
btr_get_search_table(index), fold);
|
||||||
|
|
||||||
if (rec == NULL) {
|
if (rec == NULL) {
|
||||||
|
if (use_latch) {
|
||||||
if (!has_search_latch) {
|
fail:
|
||||||
btr_search_s_unlock(index);
|
rw_lock_s_unlock(use_latch);
|
||||||
}
|
}
|
||||||
|
|
||||||
btr_search_failure(info, cursor);
|
btr_search_failure(info, cursor);
|
||||||
@ -1039,22 +968,15 @@ btr_search_guess_on_hash(
|
|||||||
|
|
||||||
buf_block_t* block = buf_block_from_ahi(rec);
|
buf_block_t* block = buf_block_from_ahi(rec);
|
||||||
|
|
||||||
if (!has_search_latch) {
|
if (use_latch) {
|
||||||
|
|
||||||
if (!buf_page_get_known_nowait(
|
if (!buf_page_get_known_nowait(
|
||||||
latch_mode, block, BUF_MAKE_YOUNG,
|
latch_mode, block, BUF_MAKE_YOUNG,
|
||||||
__FILE__, __LINE__, mtr)) {
|
__FILE__, __LINE__, mtr)) {
|
||||||
|
goto fail;
|
||||||
if (!has_search_latch) {
|
|
||||||
btr_search_s_unlock(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
btr_search_failure(info, cursor);
|
|
||||||
|
|
||||||
return(FALSE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
btr_search_s_unlock(index);
|
rw_lock_s_unlock(use_latch);
|
||||||
|
|
||||||
buf_block_dbg_add_level(block, SYNC_TREE_NODE_FROM_HASH);
|
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);
|
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);
|
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
|
record to determine if our guess for the cursor position is
|
||||||
right. */
|
right. */
|
||||||
if (index_id != btr_page_get_index_id(block->frame)
|
if (index_id != btr_page_get_index_id(block->frame)
|
||||||
|| !btr_search_check_guess(cursor,
|
|| !btr_search_check_guess(cursor, !!ahi_latch, tuple, mode)) {
|
||||||
has_search_latch,
|
|
||||||
tuple, mode)) {
|
|
||||||
|
|
||||||
if (!has_search_latch) {
|
if (!ahi_latch) {
|
||||||
btr_leaf_page_release(block, latch_mode, mtr);
|
btr_leaf_page_release(block, latch_mode, mtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1110,7 +1030,7 @@ btr_search_guess_on_hash(
|
|||||||
info->last_hash_succ = FALSE;
|
info->last_hash_succ = FALSE;
|
||||||
|
|
||||||
/* Currently, does not work if the following fails: */
|
/* 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);
|
btr_leaf_page_release(block, latch_mode, mtr);
|
||||||
|
|
||||||
@ -1143,7 +1063,7 @@ btr_search_guess_on_hash(
|
|||||||
#ifdef UNIV_SEARCH_PERF_STAT
|
#ifdef UNIV_SEARCH_PERF_STAT
|
||||||
btr_search_n_succ++;
|
btr_search_n_succ++;
|
||||||
#endif
|
#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);
|
buf_page_make_young(&block->page);
|
||||||
}
|
}
|
||||||
@ -1191,6 +1111,8 @@ retry:
|
|||||||
/* This debug check uses a dirty read that could theoretically cause
|
/* This debug check uses a dirty read that could theoretically cause
|
||||||
false positives while buf_pool_clear_hash_index() is executing. */
|
false positives while buf_pool_clear_hash_index() is executing. */
|
||||||
assert_block_ahi_valid(block);
|
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) {
|
if (index == NULL) {
|
||||||
return;
|
return;
|
||||||
@ -1214,9 +1136,6 @@ retry:
|
|||||||
% btr_ahi_parts;
|
% btr_ahi_parts;
|
||||||
latch = btr_search_latches[ahi_slot];
|
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);
|
rw_lock_s_lock(latch);
|
||||||
assert_block_ahi_valid(block);
|
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.
|
sensible, and does not build a hash index if not.
|
||||||
@param[in,out] index index for which to build.
|
@param[in,out] index index for which to build.
|
||||||
@param[in,out] block index page, s-/x- latched.
|
@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_fields hash this many full fields
|
||||||
@param[in] n_bytes hash this many bytes of the next field
|
@param[in] n_bytes hash this many bytes of the next field
|
||||||
@param[in] left_side hash for searches from left side */
|
@param[in] left_side hash for searches from left side */
|
||||||
@ -1427,12 +1347,11 @@ void
|
|||||||
btr_search_build_page_hash_index(
|
btr_search_build_page_hash_index(
|
||||||
dict_index_t* index,
|
dict_index_t* index,
|
||||||
buf_block_t* block,
|
buf_block_t* block,
|
||||||
|
rw_lock_t* ahi_latch,
|
||||||
ulint n_fields,
|
ulint n_fields,
|
||||||
ulint n_bytes,
|
ulint n_bytes,
|
||||||
ibool left_side)
|
ibool left_side)
|
||||||
{
|
{
|
||||||
hash_table_t* table;
|
|
||||||
page_t* page;
|
|
||||||
const rec_t* rec;
|
const rec_t* rec;
|
||||||
const rec_t* next_rec;
|
const rec_t* next_rec;
|
||||||
ulint fold;
|
ulint fold;
|
||||||
@ -1454,6 +1373,7 @@ btr_search_build_page_hash_index(
|
|||||||
}
|
}
|
||||||
|
|
||||||
rec_offs_init(offsets_);
|
rec_offs_init(offsets_);
|
||||||
|
ut_ad(ahi_latch == btr_get_search_latch(index));
|
||||||
ut_ad(index);
|
ut_ad(index);
|
||||||
ut_ad(block->page.id.space() == index->space);
|
ut_ad(block->page.id.space() == index->space);
|
||||||
ut_a(!dict_index_is_ibuf(index));
|
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)
|
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_S)
|
||||||
|| rw_lock_own(&(block->lock), RW_LOCK_X));
|
|| 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);
|
const bool rebuild = block->index
|
||||||
page = buf_block_get_frame(block);
|
&& (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)
|
rw_lock_s_unlock(ahi_latch);
|
||||||
|| (block->curr_n_bytes != n_bytes)
|
|
||||||
|| (block->curr_left_side != left_side))) {
|
|
||||||
|
|
||||||
btr_search_s_unlock(index);
|
|
||||||
|
|
||||||
|
if (rebuild) {
|
||||||
btr_search_drop_page_hash_index(block);
|
btr_search_drop_page_hash_index(block);
|
||||||
} else {
|
|
||||||
btr_search_s_unlock(index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check that the values for hash index build are sensible */
|
/* Check that the values for hash index build are sensible */
|
||||||
@ -1491,6 +1408,7 @@ btr_search_build_page_hash_index(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
page_t* page = buf_block_get_frame(block);
|
||||||
n_recs = page_get_n_recs(page);
|
n_recs = page_get_n_recs(page);
|
||||||
|
|
||||||
if (n_recs == 0) {
|
if (n_recs == 0) {
|
||||||
@ -1573,7 +1491,8 @@ btr_search_build_page_hash_index(
|
|||||||
|
|
||||||
btr_search_check_free_space_in_heap(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) {
|
if (!btr_search_enabled) {
|
||||||
goto exit_func;
|
goto exit_func;
|
||||||
@ -1611,7 +1530,7 @@ btr_search_build_page_hash_index(
|
|||||||
MONITOR_INC_VALUE(MONITOR_ADAPTIVE_HASH_ROW_ADDED, n_cached);
|
MONITOR_INC_VALUE(MONITOR_ADAPTIVE_HASH_ROW_ADDED, n_cached);
|
||||||
exit_func:
|
exit_func:
|
||||||
assert_block_ahi_valid(block);
|
assert_block_ahi_valid(block);
|
||||||
btr_search_x_unlock(index);
|
rw_lock_x_unlock(ahi_latch);
|
||||||
|
|
||||||
ut_free(folds);
|
ut_free(folds);
|
||||||
ut_free(recs);
|
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.
|
/** 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 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
|
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;
|
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(block);
|
||||||
assert_block_ahi_valid(new_block);
|
assert_block_ahi_valid(new_block);
|
||||||
|
|
||||||
|
rw_lock_t* ahi_latch = index ? btr_get_search_latch(index) : NULL;
|
||||||
|
|
||||||
if (new_block->index) {
|
if (new_block->index) {
|
||||||
btr_search_drop_page_hash_index(block);
|
btr_search_drop_page_hash_index(block);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dict_index_t* index = block->index;
|
|
||||||
if (!index) {
|
if (!index) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
btr_search_s_lock(index);
|
|
||||||
|
rw_lock_s_lock(ahi_latch);
|
||||||
|
|
||||||
if (block->index) {
|
if (block->index) {
|
||||||
ulint n_fields = block->curr_n_fields;
|
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->n_bytes = block->curr_n_bytes;
|
||||||
new_block->left_side = left_side;
|
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);
|
ut_a(n_fields > 0 || n_bytes > 0);
|
||||||
|
|
||||||
btr_search_build_page_hash_index(
|
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_fields == block->curr_n_fields);
|
||||||
ut_ad(n_bytes == block->curr_n_bytes);
|
ut_ad(n_bytes == block->curr_n_bytes);
|
||||||
ut_ad(left_side == block->curr_left_side);
|
ut_ad(left_side == block->curr_left_side);
|
||||||
return;
|
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.
|
/** 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);
|
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);
|
assert_block_ahi_valid(block);
|
||||||
|
|
||||||
if (block->index) {
|
if (block->index) {
|
||||||
@ -1744,21 +1728,25 @@ btr_search_update_hash_on_delete(btr_cur_t* cursor)
|
|||||||
assert_block_ahi_valid(block);
|
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.
|
/** 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
|
@param[in] cursor cursor which was positioned to the place to insert
|
||||||
using btr_cur_search_, and the new record has been
|
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
|
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;
|
hash_table_t* table;
|
||||||
buf_block_t* block;
|
buf_block_t* block;
|
||||||
dict_index_t* index;
|
dict_index_t* index;
|
||||||
rec_t* rec;
|
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
|
#ifdef MYSQL_INDEX_DISABLE_AHI
|
||||||
if (cursor->index->disable_ahi) return;
|
if (cursor->index->disable_ahi) return;
|
||||||
#endif
|
#endif
|
||||||
@ -1781,8 +1769,7 @@ btr_search_update_hash_node_on_insert(btr_cur_t* cursor)
|
|||||||
|
|
||||||
ut_a(cursor->index == index);
|
ut_a(cursor->index == index);
|
||||||
ut_a(!dict_index_is_ibuf(index));
|
ut_a(!dict_index_is_ibuf(index));
|
||||||
|
rw_lock_x_lock(ahi_latch);
|
||||||
btr_search_x_lock(index);
|
|
||||||
|
|
||||||
if (!block->index) {
|
if (!block->index) {
|
||||||
|
|
||||||
@ -1806,11 +1793,11 @@ btr_search_update_hash_node_on_insert(btr_cur_t* cursor)
|
|||||||
|
|
||||||
func_exit:
|
func_exit:
|
||||||
assert_block_ahi_valid(block);
|
assert_block_ahi_valid(block);
|
||||||
btr_search_x_unlock(index);
|
rw_lock_x_unlock(ahi_latch);
|
||||||
} else {
|
} 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
|
@param[in,out] cursor cursor which was positioned to the
|
||||||
place to insert using btr_cur_search_...,
|
place to insert using btr_cur_search_...,
|
||||||
and the new record has been inserted next
|
and the new record has been inserted next
|
||||||
to the cursor */
|
to the cursor
|
||||||
|
@param[in] ahi_latch the adaptive hash index latch */
|
||||||
void
|
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;
|
hash_table_t* table;
|
||||||
buf_block_t* block;
|
buf_block_t* block;
|
||||||
@ -1834,13 +1822,16 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor)
|
|||||||
ulint n_fields;
|
ulint n_fields;
|
||||||
ulint n_bytes;
|
ulint n_bytes;
|
||||||
ibool left_side;
|
ibool left_side;
|
||||||
ibool locked = FALSE;
|
bool locked = false;
|
||||||
mem_heap_t* heap = NULL;
|
mem_heap_t* heap = NULL;
|
||||||
ulint offsets_[REC_OFFS_NORMAL_SIZE];
|
ulint offsets_[REC_OFFS_NORMAL_SIZE];
|
||||||
ulint* offsets = offsets_;
|
ulint* offsets = offsets_;
|
||||||
rec_offs_init(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(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
|
#ifdef MYSQL_INDEX_DISABLE_AHI
|
||||||
if (cursor->index->disable_ahi) return;
|
if (cursor->index->disable_ahi) return;
|
||||||
#endif
|
#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);
|
fold = rec_fold(rec, offsets, n_fields, n_bytes, index->id);
|
||||||
} else {
|
} else {
|
||||||
if (left_side) {
|
if (left_side) {
|
||||||
|
locked = true;
|
||||||
btr_search_x_lock(index);
|
rw_lock_x_lock(ahi_latch);
|
||||||
|
|
||||||
locked = TRUE;
|
|
||||||
|
|
||||||
if (!btr_search_enabled) {
|
if (!btr_search_enabled) {
|
||||||
goto function_exit;
|
goto function_exit;
|
||||||
@ -1917,10 +1906,8 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor)
|
|||||||
if (fold != ins_fold) {
|
if (fold != ins_fold) {
|
||||||
|
|
||||||
if (!locked) {
|
if (!locked) {
|
||||||
|
locked = true;
|
||||||
btr_search_x_lock(index);
|
rw_lock_x_lock(ahi_latch);
|
||||||
|
|
||||||
locked = TRUE;
|
|
||||||
|
|
||||||
if (!btr_search_enabled) {
|
if (!btr_search_enabled) {
|
||||||
goto function_exit;
|
goto function_exit;
|
||||||
@ -1938,11 +1925,9 @@ check_next_rec:
|
|||||||
if (page_rec_is_supremum(next_rec)) {
|
if (page_rec_is_supremum(next_rec)) {
|
||||||
|
|
||||||
if (!left_side) {
|
if (!left_side) {
|
||||||
|
|
||||||
if (!locked) {
|
if (!locked) {
|
||||||
btr_search_x_lock(index);
|
locked = true;
|
||||||
|
rw_lock_x_lock(ahi_latch);
|
||||||
locked = TRUE;
|
|
||||||
|
|
||||||
if (!btr_search_enabled) {
|
if (!btr_search_enabled) {
|
||||||
goto function_exit;
|
goto function_exit;
|
||||||
@ -1958,10 +1943,8 @@ check_next_rec:
|
|||||||
if (ins_fold != next_fold) {
|
if (ins_fold != next_fold) {
|
||||||
|
|
||||||
if (!locked) {
|
if (!locked) {
|
||||||
|
locked = true;
|
||||||
btr_search_x_lock(index);
|
rw_lock_x_lock(ahi_latch);
|
||||||
|
|
||||||
locked = TRUE;
|
|
||||||
|
|
||||||
if (!btr_search_enabled) {
|
if (!btr_search_enabled) {
|
||||||
goto function_exit;
|
goto function_exit;
|
||||||
@ -1980,8 +1963,9 @@ function_exit:
|
|||||||
mem_heap_free(heap);
|
mem_heap_free(heap);
|
||||||
}
|
}
|
||||||
if (locked) {
|
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
|
#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) 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
|
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
|
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.
|
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. */
|
If mode is PAGE_CUR_GE, then up_match will a have a sensible value. */
|
||||||
dberr_t
|
dberr_t
|
||||||
btr_cur_search_to_nth_level(
|
btr_cur_search_to_nth_level_func(
|
||||||
/*========================*/
|
|
||||||
dict_index_t* index, /*!< in: index */
|
dict_index_t* index, /*!< in: index */
|
||||||
ulint level, /*!< in: the tree level of search */
|
ulint level, /*!< in: the tree level of search */
|
||||||
const dtuple_t* tuple, /*!< in: data tuple; NOTE: n_fields_cmp in
|
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
|
cursor->left_block is used to store a pointer
|
||||||
to the left neighbor page, in the cases
|
to the left neighbor page, in the cases
|
||||||
BTR_SEARCH_PREV and BTR_MODIFY_PREV;
|
BTR_SEARCH_PREV and BTR_MODIFY_PREV;
|
||||||
NOTE that if has_search_latch
|
NOTE that if ahi_latch, we might not have a
|
||||||
is != 0, we maybe do not have a latch set
|
cursor page latch, we assume that ahi_latch
|
||||||
on the cursor page, we assume
|
protects the record! */
|
||||||
the caller uses his search latch
|
|
||||||
to protect the record! */
|
|
||||||
btr_cur_t* cursor, /*!< in/out: tree cursor; the cursor page is
|
btr_cur_t* cursor, /*!< in/out: tree cursor; the cursor page is
|
||||||
s- or x-latched, but see also above! */
|
s- or x-latched, but see also above! */
|
||||||
ulint has_search_latch,
|
#ifdef BTR_CUR_HASH_ADAPT
|
||||||
/*!< in: latch mode the caller
|
rw_lock_t* ahi_latch,
|
||||||
currently has on search system:
|
/*!< in: currently held btr_search_latch
|
||||||
RW_S_LATCH, or 0 */
|
(in RW_S_LATCH mode), or NULL */
|
||||||
|
#endif /* BTR_CUR_HASH_ADAPT */
|
||||||
const char* file, /*!< in: file name */
|
const char* file, /*!< in: file name */
|
||||||
unsigned line, /*!< in: line where called */
|
unsigned line, /*!< in: line where called */
|
||||||
mtr_t* mtr, /*!< in/out: mini-transaction */
|
mtr_t* mtr, /*!< in/out: mini-transaction */
|
||||||
ib_uint64_t autoinc = 0);
|
ib_uint64_t autoinc = 0);
|
||||||
/*!< in: PAGE_ROOT_AUTO_INC to be written
|
/*!< in: PAGE_ROOT_AUTO_INC to be written
|
||||||
(0 if none) */
|
(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.
|
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) 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
|
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
|
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
|
may end up on the previous page of the
|
||||||
record! */
|
record! */
|
||||||
ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ...;
|
ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ...;
|
||||||
NOTE that if has_search_latch != 0 then
|
NOTE that if ahi_latch then we might not
|
||||||
we maybe do not acquire a latch on the cursor
|
acquire a cursor page latch, but assume
|
||||||
page, but assume that the caller uses his
|
that the ahi_latch protects the record! */
|
||||||
btr search latch to protect the record! */
|
|
||||||
btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
|
btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
|
||||||
ulint has_search_latch,
|
#ifdef BTR_CUR_HASH_ADAPT
|
||||||
/*!< in: latch mode the caller
|
rw_lock_t* ahi_latch,
|
||||||
currently has on search system:
|
/*!< in: adaptive hash index latch held
|
||||||
RW_S_LATCH, or 0 */
|
by the caller, or NULL if none */
|
||||||
|
#endif /* BTR_CUR_HASH_ADAPT */
|
||||||
const char* file, /*!< in: file name */
|
const char* file, /*!< in: file name */
|
||||||
unsigned line, /*!< in: line where called */
|
unsigned line, /*!< in: line where called */
|
||||||
mtr_t* mtr); /*!< in: mtr */
|
mtr_t* mtr); /*!< in: mtr */
|
||||||
#define btr_pcur_open_with_no_init(ix,t,md,l,cur,has,m) \
|
#ifdef BTR_CUR_HASH_ADAPT
|
||||||
btr_pcur_open_with_no_init_func(ix,t,md,l,cur,has,__FILE__,__LINE__,m)
|
# 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. */
|
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) 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
|
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
|
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));
|
ut_ad(!dict_index_is_spatial(index));
|
||||||
|
|
||||||
err = btr_cur_search_to_nth_level(
|
err = btr_cur_search_to_nth_level_func(
|
||||||
index, level, tuple, mode, latch_mode,
|
index, level, tuple, mode, latch_mode, btr_cursor,
|
||||||
btr_cursor, 0, file, line, mtr, autoinc);
|
#ifdef BTR_CUR_HASH_ADAPT
|
||||||
|
NULL,
|
||||||
|
#endif /* BTR_CUR_HASH_ADAPT */
|
||||||
|
file, line, mtr, autoinc);
|
||||||
|
|
||||||
if (err != DB_SUCCESS) {
|
if (err != DB_SUCCESS) {
|
||||||
ib::warn() << " Error code: " << err
|
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
|
may end up on the previous page of the
|
||||||
record! */
|
record! */
|
||||||
ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ...;
|
ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ...;
|
||||||
NOTE that if has_search_latch != 0 then
|
NOTE that if ahi_latch then we might not
|
||||||
we maybe do not acquire a latch on the cursor
|
acquire a cursor page latch, but assume
|
||||||
page, but assume that the caller uses his
|
that the ahi_latch protects the record! */
|
||||||
btr search latch to protect the record! */
|
|
||||||
btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
|
btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
|
||||||
ulint has_search_latch,
|
#ifdef BTR_CUR_HASH_ADAPT
|
||||||
/*!< in: latch mode the caller
|
rw_lock_t* ahi_latch,
|
||||||
currently has on search system:
|
/*!< in: adaptive hash index latch held
|
||||||
RW_S_LATCH, or 0 */
|
by the caller, or NULL if none */
|
||||||
|
#endif /* BTR_CUR_HASH_ADAPT */
|
||||||
const char* file, /*!< in: file name */
|
const char* file, /*!< in: file name */
|
||||||
unsigned line, /*!< in: line where called */
|
unsigned line, /*!< in: line where called */
|
||||||
mtr_t* mtr) /*!< in: mtr */
|
mtr_t* mtr) /*!< in: mtr */
|
||||||
@ -514,9 +517,12 @@ btr_pcur_open_with_no_init_func(
|
|||||||
|
|
||||||
btr_cursor = btr_pcur_get_btr_cur(cursor);
|
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,
|
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;
|
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) 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
|
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
|
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
|
we assume the caller uses his search latch
|
||||||
to protect the record!
|
to protect the record!
|
||||||
@param[out] cursor tree cursor
|
@param[out] cursor tree cursor
|
||||||
@param[in] has_search_latch
|
@param[in] ahi_latch the adaptive hash index latch being held,
|
||||||
latch mode the caller currently has on
|
or NULL
|
||||||
search system: RW_S/X_LATCH or 0
|
|
||||||
@param[in] mtr mini transaction
|
@param[in] mtr mini transaction
|
||||||
@return TRUE if succeeded */
|
@return whether the search succeeded */
|
||||||
ibool
|
bool
|
||||||
btr_search_guess_on_hash(
|
btr_search_guess_on_hash(
|
||||||
dict_index_t* index,
|
dict_index_t* index,
|
||||||
btr_search_t* info,
|
btr_search_t* info,
|
||||||
@ -104,7 +103,7 @@ btr_search_guess_on_hash(
|
|||||||
ulint mode,
|
ulint mode,
|
||||||
ulint latch_mode,
|
ulint latch_mode,
|
||||||
btr_cur_t* cursor,
|
btr_cur_t* cursor,
|
||||||
ulint has_search_latch,
|
rw_lock_t* ahi_latch,
|
||||||
mtr_t* mtr);
|
mtr_t* mtr);
|
||||||
|
|
||||||
/** Move or delete hash entries for moved records, usually in a page split.
|
/** 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.
|
/** 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
|
@param[in] cursor cursor which was positioned to the place to insert
|
||||||
using btr_cur_search_, and the new record has been
|
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
|
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.
|
/** 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_...,
|
place to insert using btr_cur_search_...,
|
||||||
and the new record has been inserted next
|
and the new record has been inserted next
|
||||||
to the cursor */
|
to the cursor
|
||||||
|
@param[in] ahi_latch the adaptive hash index latch */
|
||||||
void
|
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.
|
/** 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
|
@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
|
bool
|
||||||
btr_search_validate();
|
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. */
|
/** Lock all search latches in exclusive mode. */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
void
|
void
|
||||||
@ -185,18 +174,6 @@ UNIV_INLINE
|
|||||||
void
|
void
|
||||||
btr_search_x_unlock_all();
|
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. */
|
/** Lock all search latches in shared mode. */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
void
|
void
|
||||||
@ -243,15 +220,11 @@ btr_get_search_table(const dict_index_t* index);
|
|||||||
#else /* BTR_CUR_HASH_ADAPT */
|
#else /* BTR_CUR_HASH_ADAPT */
|
||||||
# define btr_search_sys_create(size)
|
# define btr_search_sys_create(size)
|
||||||
# define btr_search_drop_page_hash_index(block)
|
# 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_lock_all(index)
|
||||||
# define btr_search_s_unlock_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_info_update(index, cursor)
|
||||||
# define btr_search_move_or_delete_hash_entries(new_block, block)
|
# 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_update_hash_on_delete(cursor)
|
||||||
# define btr_search_sys_resize(hash_size)
|
# define btr_search_sys_resize(hash_size)
|
||||||
#endif /* BTR_CUR_HASH_ADAPT */
|
#endif /* BTR_CUR_HASH_ADAPT */
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
|
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
|
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
|
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
|
#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
|
void
|
||||||
btr_search_info_update_slow(
|
btr_search_info_update_slow(btr_search_t* info, btr_cur_t* cursor);
|
||||||
/*========================*/
|
|
||||||
btr_search_t* info, /*!< in/out: search info */
|
|
||||||
btr_cur_t* cursor);/*!< in: cursor which was just positioned */
|
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
Updates the search info. */
|
Updates the search info. */
|
||||||
@ -87,24 +86,6 @@ btr_search_info_update(
|
|||||||
btr_search_info_update_slow(info, cursor);
|
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. */
|
/** Lock all search latches in exclusive mode. */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
void
|
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. */
|
/** Lock all search latches in shared mode. */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
void
|
void
|
||||||
|
@ -1272,24 +1272,19 @@ static
|
|||||||
void
|
void
|
||||||
row_sel_open_pcur(
|
row_sel_open_pcur(
|
||||||
/*==============*/
|
/*==============*/
|
||||||
plan_t* plan, /*!< in: table plan */
|
plan_t* plan, /*!< in: table plan */
|
||||||
ibool search_latch_locked,
|
#ifdef BTR_CUR_HASH_ADAPT
|
||||||
/*!< in: TRUE if the thread currently
|
rw_lock_t* ahi_latch,
|
||||||
has the search latch locked in
|
/*!< in: the adaptive hash index latch */
|
||||||
s-mode */
|
#endif /* BTR_CUR_HASH_ADAPT */
|
||||||
mtr_t* mtr) /*!< in: mtr */
|
mtr_t* mtr) /*!< in/out: mini-transaction */
|
||||||
{
|
{
|
||||||
dict_index_t* index;
|
dict_index_t* index;
|
||||||
func_node_t* cond;
|
func_node_t* cond;
|
||||||
que_node_t* exp;
|
que_node_t* exp;
|
||||||
ulint n_fields;
|
ulint n_fields;
|
||||||
ulint has_search_latch = 0; /* RW_S_LATCH or 0 */
|
|
||||||
ulint i;
|
ulint i;
|
||||||
|
|
||||||
if (search_latch_locked) {
|
|
||||||
has_search_latch = RW_S_LATCH;
|
|
||||||
}
|
|
||||||
|
|
||||||
index = plan->index;
|
index = plan->index;
|
||||||
|
|
||||||
/* Calculate the value of the search tuple: the exact match columns
|
/* 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_pcur_open_with_no_init(index, plan->tuple, plan->mode,
|
||||||
BTR_SEARCH_LEAF, &plan->pcur,
|
BTR_SEARCH_LEAF, &plan->pcur,
|
||||||
has_search_latch, mtr);
|
ahi_latch, mtr);
|
||||||
} else {
|
} else {
|
||||||
/* Open the cursor to the start or the end of the index
|
/* Open the cursor to the start or the end of the index
|
||||||
(FALSE: no init) */
|
(FALSE: no init) */
|
||||||
@ -1473,7 +1468,7 @@ row_sel_try_search_shortcut(
|
|||||||
rw_lock_t* ahi_latch = btr_get_search_latch(index);
|
rw_lock_t* ahi_latch = btr_get_search_latch(index);
|
||||||
rw_lock_s_lock(ahi_latch);
|
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));
|
const rec_t* rec = btr_pcur_get_rec(&(plan->pcur));
|
||||||
|
|
||||||
@ -1659,8 +1654,11 @@ table_loop:
|
|||||||
if (!plan->pcur_is_open) {
|
if (!plan->pcur_is_open) {
|
||||||
/* Evaluate the expressions to build the search tuple and
|
/* Evaluate the expressions to build the search tuple and
|
||||||
open the cursor */
|
open the cursor */
|
||||||
|
row_sel_open_pcur(plan,
|
||||||
row_sel_open_pcur(plan, FALSE, &mtr);
|
#ifdef BTR_CUR_HASH_ADAPT
|
||||||
|
NULL,
|
||||||
|
#endif /* BTR_CUR_HASH_ADAPT */
|
||||||
|
&mtr);
|
||||||
|
|
||||||
cursor_just_opened = TRUE;
|
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_t* ahi_latch = btr_get_search_latch(index);
|
||||||
rw_lock_s_lock(ahi_latch);
|
rw_lock_s_lock(ahi_latch);
|
||||||
btr_pcur_open_with_no_init(index, search_tuple, PAGE_CUR_GE,
|
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);
|
rec = btr_pcur_get_rec(pcur);
|
||||||
|
|
||||||
if (!page_rec_is_user_rec(rec) || rec_is_default_row(rec, index)) {
|
if (!page_rec_is_user_rec(rec) || rec_is_default_row(rec, index)) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user