diff options
author | Vlad Lesin <vlad_lesin@mail.ru> | 2022-06-06 14:31:19 +0300 |
---|---|---|
committer | Vlad Lesin <vlad_lesin@mail.ru> | 2022-07-25 15:13:49 +0300 |
commit | 222e800e24c34603af7240fbffbb26223acf7e02 (patch) | |
tree | 7e5a649fcaff90d92efa0443d57e5eb909f7b0fb /storage/innobase/include/page0cur.h | |
parent | 6156a2be3029af8eace41c067739fce0f3193fca (diff) | |
download | mariadb-git-222e800e24c34603af7240fbffbb26223acf7e02.tar.gz |
MDEV-21136 InnoDB's records_in_range estimates can be way off
Get rid of BTR_ESTIMATE and btr_cur_t::path_arr.
Before the fix btr_estimate_n_rows_in_range_low() used two
btr_cur_search_to_nth_level() calls to create two arrays of tree path,
the array per border. And then it tried to estimate the number of rows
diving level-by-level with the array elements. As the path pages are
unlatched during the arrays iterating, the tree could be modified, the
estimation function called itself until the number of attempts exceed.
After the fix the estimation happens during search process. Roughly, the
algorithm is the following. Dive in the left page, then if there are pages
between left and right ones, read a few pages to the right, if the right
page is reached, fetch it and count the exact number of rows, otherwise
count the estimated number of rows, and fetch the right page.
The latching order corresponds to WL#6326 rules, i.e.:
(2.1) [same as (1.1)]: Page latches must be acquired in descending order
of tree level.
(2.2) When acquiring a node pointer page latch at level L, we must hold
the left sibling page latch (at level L) or some ancestor latch
(at level>L).
When we dive to the level down, the parent page is unlatched only after
the the current level page is latched. When we estimate the number of rows
on some level, we latch the left border, then fetch the next page, and
then fetch the next page unlatching the previous page after the current
page is latched until the right border is reached. I.e. the left sibling
is always latched when we acquire page latch on the same level. When we
reach the right border, the current page is unlatched, and then the right
border is latched. Following to (2.2) rule, we can do this because the
right border's parent is latched.
Diffstat (limited to 'storage/innobase/include/page0cur.h')
-rw-r--r-- | storage/innobase/include/page0cur.h | 9 |
1 files changed, 3 insertions, 6 deletions
diff --git a/storage/innobase/include/page0cur.h b/storage/innobase/include/page0cur.h index e715df19741..11677513dd8 100644 --- a/storage/innobase/include/page0cur.h +++ b/storage/innobase/include/page0cur.h @@ -54,14 +54,11 @@ page_zip_des_t* page_cur_get_page_zip( /*==================*/ page_cur_t* cur); /*!< in: page cursor */ -/*********************************************************//** -Gets the record where the cursor is positioned. +/* Gets the record where the cursor is positioned. +@param cur page cursor @return record */ UNIV_INLINE -rec_t* -page_cur_get_rec( -/*=============*/ - page_cur_t* cur); /*!< in: page cursor */ +rec_t *page_cur_get_rec(const page_cur_t *cur); #else /* UNIV_DEBUG */ # define page_cur_get_page(cur) page_align((cur)->rec) # define page_cur_get_block(cur) (cur)->block |