Skip to content

Commit 78e695d

Browse files
author
Marcin Babij
committed
Bug #31750840 ADAPTIVE HASH INDEX(AHI) BUILDING CAUSING CONTENTION ON BTR_SEARCH_LATCHES
The latches for searching in AHI were changed to non-blocking - we don't want to wait for a index which the only purpose is to speed up queries. The latches for more update operations in AHI were changed to non-blocking: - we don't have to insert new page to the index, - we don't have to try to update a reference to a failed search, we would do such operations next time we encounter them. RB#27271 Change-Id: I68e4c2ec4b7fa3beebb0cea792f084f735fcd627
1 parent 5352c5b commit 78e695d

File tree

18 files changed

+766
-912
lines changed

18 files changed

+766
-912
lines changed

storage/innobase/btr/btr0sea.cc

Lines changed: 420 additions & 576 deletions
Large diffs are not rendered by default.

storage/innobase/dict/dict0dict.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1295,7 +1295,7 @@ static bool dict_table_can_be_evicted(
12951295
12961296
See also: dict_index_remove_from_cache_low() */
12971297

1298-
if (btr_search_info_get_ref_count(info, index) > 0) {
1298+
if (btr_search_info_get_ref_count(info) > 0) {
12991299
return false;
13001300
}
13011301
}
@@ -2653,7 +2653,7 @@ static void dict_index_remove_from_cache_low(
26532653
zero. See also: dict_table_can_be_evicted() */
26542654

26552655
do {
2656-
ulint ref_count = btr_search_info_get_ref_count(info, index);
2656+
ulint ref_count = btr_search_info_get_ref_count(info);
26572657

26582658
if (ref_count == 0) {
26592659
break;

storage/innobase/gis/gis0sea.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1394,10 +1394,10 @@ static void rtr_copy_buf(matched_rec_t *matches, const buf_block_t *block) {
13941394
/* Skip buf_block_t::lock as it was already initialized by rtr_create_rtr_info
13951395
*/
13961396
ut_ad(rw_lock_validate(&matches->block.lock));
1397-
matches->block.n_hash_helps = block->n_hash_helps;
1398-
matches->block.n_bytes = block->n_bytes;
1399-
matches->block.n_fields = block->n_fields;
1400-
matches->block.left_side = block->left_side;
1397+
matches->block.n_hash_helps.store(block->n_hash_helps.load());
1398+
matches->block.n_bytes.store(block->n_bytes.load());
1399+
matches->block.n_fields.store(block->n_fields.load());
1400+
matches->block.left_side.store(block->left_side.load());
14011401
matches->block.curr_n_fields = block->curr_n_fields;
14021402
matches->block.curr_left_side = block->curr_left_side;
14031403
matches->block.index = block->index;

storage/innobase/ha/ha0ha.cc

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -257,13 +257,8 @@ bool ha_search_and_update_if_found_func(hash_table_t *table, ulint fold,
257257
return false;
258258
}
259259

260-
/** Removes from the chain determined by fold all nodes whose data pointer
261-
points to the page given.
262-
@param[in] table Hash table
263-
@param[in] fold Fold value
264-
@param[in] page Buffer page */
265-
void ha_remove_all_nodes_to_page(hash_table_t *table, ulint fold,
266-
const page_t *page) {
260+
void ha_remove_a_node_to_page(hash_table_t *table, ulint fold,
261+
const page_t *page) {
267262
ha_node_t *node;
268263

269264
ut_ad(table);
@@ -275,30 +270,16 @@ void ha_remove_all_nodes_to_page(hash_table_t *table, ulint fold,
275270

276271
while (node) {
277272
if (page_align(ha_node_get_data(node)) == page) {
278-
/* Remove the hash node */
273+
/* Remove the hash node. It may be a node with a different fold, but we
274+
don't care about it - we delete any entry in this chain for the
275+
specified page. */
279276

280277
ha_delete_hash_node(table, node);
281-
282-
/* Start again from the first node in the chain
283-
because the deletion may compact the heap of
284-
nodes and move other nodes! */
285-
286-
node = ha_chain_get_first(table, fold);
278+
break;
287279
} else {
288280
node = ha_chain_get_next(node);
289281
}
290282
}
291-
#ifdef UNIV_DEBUG
292-
/* Check that all nodes really got deleted */
293-
294-
node = ha_chain_get_first(table, fold);
295-
296-
while (node) {
297-
ut_a(page_align(ha_node_get_data(node)) != page);
298-
299-
node = ha_chain_get_next(node);
300-
}
301-
#endif /* UNIV_DEBUG */
302283
}
303284

304285
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
@@ -381,7 +362,7 @@ builds, see http://bugs.mysql.com/36941 */
381362

382363
n_bufs = UT_LIST_GET_LEN(table->heap->base) - 1;
383364

384-
if (table->heap->free_block) {
365+
if (table->heap->free_block.load()) {
385366
n_bufs++;
386367
}
387368

storage/innobase/include/btr0cur.h

Lines changed: 56 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -641,81 +641,88 @@ constexpr uint32_t BTR_PATH_ARRAY_N_SLOTS = 250;
641641

642642
/** Values for the flag documenting the used search method */
643643
enum btr_cur_method {
644-
BTR_CUR_UNSET = 0, /*!< Flag for initialization only,
645-
not in real use. */
646-
BTR_CUR_HASH = 1, /*!< successful shortcut using
647-
the hash index */
648-
BTR_CUR_HASH_FAIL, /*!< failure using hash, success using
649-
binary search: the misleading hash
650-
reference is stored in the field
651-
hash_node, and might be necessary to
652-
update */
653-
BTR_CUR_BINARY, /*!< success using the binary search */
654-
BTR_CUR_INSERT_TO_IBUF, /*!< performed the intended insert to
655-
the insert buffer */
656-
BTR_CUR_DEL_MARK_IBUF, /*!< performed the intended delete
657-
mark in the insert/delete buffer */
658-
BTR_CUR_DELETE_IBUF, /*!< performed the intended delete in
659-
the insert/delete buffer */
660-
BTR_CUR_DELETE_REF /*!< row_purge_poss_sec() failed */
644+
/** Flag for initialization only, not in real use.*/
645+
BTR_CUR_UNSET = 0,
646+
/** successful shortcut using the hash index */
647+
BTR_CUR_HASH = 1,
648+
/** a search using hash index was not performed. */
649+
BTR_CUR_HASH_NOT_ATTEMPTED,
650+
/** failure using hash, success using binary search. The record pointing by
651+
the cursor may need to be updated in AHI. */
652+
BTR_CUR_HASH_FAIL,
653+
/** success using the binary search */
654+
BTR_CUR_BINARY,
655+
/** performed the intended insert to the insert buffer */
656+
BTR_CUR_INSERT_TO_IBUF,
657+
/** performed the intended delete mark in the insert/delete buffer */
658+
BTR_CUR_DEL_MARK_IBUF,
659+
/** performed the intended delete in the insert/delete buffer */
660+
BTR_CUR_DELETE_IBUF,
661+
/** row_purge_poss_sec() failed */
662+
BTR_CUR_DELETE_REF
661663
};
662664

663665
/** The tree cursor: the definition appears here only for the compiler
664666
to know struct size! */
665667
struct btr_cur_t {
666-
/** index where positioned */
668+
/** Index on which the cursor is positioned. */
667669
dict_index_t *index{nullptr};
668-
/** page cursor */
670+
/** Page cursor. */
669671
page_cur_t page_cur;
670-
/** purge node, for BTR_DELETE */
672+
/** Purge node, for BTR_DELETE */
671673
purge_node_t *purge_node{nullptr};
672674
/** this field is used to store a pointer to the left neighbor page, in the
673-
cases BTR_SEARCH_PREV and BTR_MODIFY_PREV */
675+
cases BTR_SEARCH_PREV and BTR_MODIFY_PREV */
674676
buf_block_t *left_block{nullptr};
675-
/*------------------------------*/
677+
676678
/** this field is only used when btr_cur_search_to_nth_level is called for an
677-
index entry insertion: the calling query thread is passed here to be used
678-
in the insert buffer */
679+
index entry insertion: the calling query thread is passed here to be used in
680+
the insert buffer */
679681
que_thr_t *thr{nullptr};
680-
/*------------------------------*/
682+
681683
/** The following fields are used in
682-
btr_cur_search_to_nth_level to pass information: */
683-
/** @{ */
684-
/** Search method used */
684+
btr_cur_search_to_nth_level to pass information:
685+
@{ */
686+
/** Search method used. */
685687
btr_cur_method flag{BTR_CUR_UNSET};
686688
/** Tree height if the search is done for a pessimistic insert or update
687-
operation */
689+
operation. */
688690
ulint tree_height{0};
689691
/** If the search mode was PAGE_CUR_LE, the number of matched fields to the
690-
first user record to the right of the cursor record after
691-
btr_cur_search_to_nth_level; for the mode PAGE_CUR_GE, the matched fields
692-
to the first user record AT THE CURSOR or to the right of it; NOTE that the
693-
up_match and low_match values may exceed the correct values for comparison
694-
to the adjacent user record if that record is on a different leaf page!
695-
(See the note in row_ins_duplicate_error_in_clust.) */
692+
the first user record to the right of the cursor record after
693+
btr_cur_search_to_nth_level; for the mode PAGE_CUR_GE, the matched fields to
694+
the first user record AT THE CURSOR or to the right of it; NOTE that the
695+
up_match and low_match values may exceed the correct values for comparison to
696+
the adjacent user record if that record is on a different leaf page! See the
697+
note in row_ins_duplicate_error_in_clust. */
696698
ulint up_match{0};
697-
/** number of matched bytes to the right at the time cursor positioned; only
698-
used internally in searches: not defined after the search */
699+
/** Number of matched bytes to the right at the time cursor positioned; only
700+
used internally in searches: not defined after the search. */
699701
ulint up_bytes{0};
700-
/** if search mode was PAGE_CUR_LE, the number of matched fields to the first
701-
user record AT THE CURSOR or to the left of it after
702-
btr_cur_search_to_nth_level; NOT defined for PAGE_CUR_GE or any other
703-
search modes; see also the NOTE in up_match! */
702+
/** If search mode was PAGE_CUR_LE, the number of matched fields to the first
703+
user record AT THE CURSOR or to the left of it after
704+
btr_cur_search_to_nth_level; NOT defined for PAGE_CUR_GE or any other search
705+
modes; see also the NOTE in up_match! */
704706
ulint low_match{0};
705-
/** number of matched bytes to the left at the time cursor positioned; only
706-
used internally in searches: not defined after the search */
707+
/** Number of matched bytes to the left at the time cursor positioned; only
708+
used internally in searches: not defined after the search. */
707709
ulint low_bytes{0};
708-
/** prefix length used in a hash search if hash_node != NULL */
710+
/** Prefix length used in a hash search if flag is any of BTR_CUR_HASH,
711+
BTR_CUR_HASH_FAIL or BTR_CUR_HASH_NOT_ATTEMPTED. */
709712
ulint n_fields{0};
710-
/** hash prefix bytes if hash_node != NULL */
713+
/** Hash prefix bytes if flag is any of BTR_CUR_HASH, BTR_CUR_HASH_FAIL or
714+
BTR_CUR_HASH_NOT_ATTEMPTED. */
711715
ulint n_bytes{0};
712-
/** fold value used in the search if flag is BTR_CUR_HASH */
716+
/** fold value used in the search if flag is any of BTR_CUR_HASH,
717+
BTR_CUR_HASH_FAIL or BTR_CUR_HASH_NOT_ATTEMPTED. */
713718
ulint fold{0};
714719
/** @} */
715-
/** in estimating the number of rows in range, we store in this array
716-
information of the path through the tree */
720+
721+
/** In estimating the number of rows in range, we store in this array
722+
information of the path through the tree. */
717723
btr_path_t *path_arr{nullptr};
718-
/** rtree search info */
724+
725+
/** rtree search info. */
719726
rtr_info_t *rtr_info{nullptr};
720727

721728
/** Ownership of the above rtr_info member. */

0 commit comments

Comments
 (0)