Commit 4a8e3941 authored by osku's avatar osku

btr_lift_page_up(): Set new page levels in all ancestor pages, not just

in the father page.

btr0btr.h: Add a BTR_MAX_LEVELS define.
parent 3d9db439
......@@ -1949,7 +1949,12 @@ btr_lift_page_up(
mtr_t* mtr) /* in: mtr */
{
page_t* father_page;
page_t* iter_page;
page_t* pages[BTR_MAX_LEVELS];
ulint page_level;
ulint root_page_no;
ulint ancestors;
ulint i;
ut_ad(btr_page_get_prev(page, mtr) == FIL_NULL);
ut_ad(btr_page_get_next(page, mtr) == FIL_NULL);
......@@ -1959,6 +1964,30 @@ btr_lift_page_up(
btr_page_get_father_node_ptr(index, page, mtr));
page_level = btr_page_get_level(page, mtr);
root_page_no = dict_index_get_page(index);
ancestors = 1;
pages[0] = father_page;
/* Store all ancestor pages so we can reset their levels later on.
We have to do all the searches on the tree now because later on,
after we've replaced the first level, the tree is in an inconsistent
state and can not be searched. */
iter_page = father_page;
for (;;) {
if (buf_block_get_page_no(buf_block_align(iter_page))
== root_page_no) {
break;
}
ut_a(ancestors < BTR_MAX_LEVELS);
iter_page = buf_frame_align(
btr_page_get_father_node_ptr(index, iter_page, mtr));
pages[ancestors++] = iter_page;
}
btr_search_drop_page_hash_index(page);
......@@ -1970,7 +1999,15 @@ btr_lift_page_up(
index, mtr);
lock_update_copy_and_discard(father_page, page);
btr_page_set_level(father_page, page_level, mtr);
/* Go upward to root page, decreasing levels by one. */
for (i = 0; i < ancestors; i++) {
iter_page = pages[i];
ut_ad(btr_page_get_level(iter_page, mtr) == (page_level + 1));
btr_page_set_level(iter_page, page_level, mtr);
page_level++;
}
/* Free the file page */
btr_page_free(index, page, mtr);
......
......@@ -23,7 +23,17 @@ special big record storage structure */
#define BTR_PAGE_MAX_REC_SIZE (UNIV_PAGE_SIZE / 2 - 200)
/* Latching modes for the search function (in btr0cur.*) */
/* Maximum depth of a B-tree in InnoDB. Note that this isn't a maximum as
such; none of the tree operations avoid producing trees bigger than this. It
is instead a "max depth that other code must work with", useful for e.g.
fixed-size arrays that must store some information about each level in a
tree. In other words: if a B-tree with bigger depth than this is
encountered, it is not acceptable for it to lead to mysterious memory
corruption, but it is acceptable for the program to die with a clear assert
failure. */
#define BTR_MAX_LEVELS 100
/* Latching modes for btr_cur_search_to_nth_level(). */
#define BTR_SEARCH_LEAF RW_S_LATCH
#define BTR_MODIFY_LEAF RW_X_LATCH
#define BTR_NO_LATCHES RW_NO_LATCH
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment