Commit 086fe412 authored by heikki@donna.mysql.fi's avatar heikki@donna.mysql.fi

btr0cur.c, btr0btr.c, dict0dict.h, dict0dict.c:

  Fix a bug in insert buffer B-tree upper levels; probably caused the crash by B.Fitzpatrick
buf0flu.c:
  Fix a bug in previous change
  A small optimization for LRU flushes to avoid losing hot pages from the buffer pool
parent 3ed8188b
......@@ -21,7 +21,7 @@ Created 6/2/1994 Heikki Tuuri
#include "lock0lock.h"
#include "ibuf0ibuf.h"
/**
/*
Node pointers
-------------
Leaf pages of a B-tree contain the index records stored in the
......@@ -550,14 +550,15 @@ btr_page_get_father_for_rec(
ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree),
MTR_MEMO_X_LOCK));
ut_ad(user_rec != page_get_supremum_rec(page));
ut_ad(user_rec != page_get_infimum_rec(page));
ut_a(user_rec != page_get_supremum_rec(page));
ut_a(user_rec != page_get_infimum_rec(page));
ut_ad(dict_tree_get_page(tree) != buf_frame_get_page_no(page));
heap = mem_heap_create(100);
tuple = dict_tree_build_node_ptr(tree, user_rec, 0, heap);
tuple = dict_tree_build_node_ptr(tree, user_rec, 0, heap,
btr_page_get_level(page, mtr));
/* In the following, we choose just any index from the tree as the
first parameter for btr_cur_search_to_nth_level. */
......@@ -569,7 +570,7 @@ btr_page_get_father_for_rec(
node_ptr = btr_cur_get_rec(&cursor);
ut_ad(btr_node_ptr_get_child_page_no(node_ptr) ==
ut_a(btr_node_ptr_get_child_page_no(node_ptr) ==
buf_frame_get_page_no(page));
mem_heap_free(heap);
......@@ -949,8 +950,8 @@ btr_root_raise_and_insert(
/* Build the node pointer (= node key and page address) for the
child */
node_ptr = dict_tree_build_node_ptr(tree, rec, new_page_no, heap);
node_ptr = dict_tree_build_node_ptr(tree, rec, new_page_no, heap,
level);
/* Reorganize the root to get free space */
btr_page_reorganize(root, mtr);
......@@ -1365,7 +1366,7 @@ btr_attach_half_pages(
half */
node_ptr_upper = dict_tree_build_node_ptr(tree, split_rec,
upper_page_no, heap);
upper_page_no, heap, level);
/* Insert it next to the pointer to the lower half. Note that this
may generate recursion leading to a split on the higher level. */
......@@ -2230,7 +2231,7 @@ btr_check_node_ptr(
node_ptr_tuple = dict_tree_build_node_ptr(
tree,
page_rec_get_next(page_get_infimum_rec(page)),
0, heap);
0, heap, btr_page_get_level(page, mtr));
ut_a(cmp_dtuple_rec(node_ptr_tuple, node_ptr) == 0);
......@@ -2485,10 +2486,11 @@ loop:
heap = mem_heap_create(256);
node_ptr_tuple = dict_tree_build_node_ptr(
tree,
tree,
page_rec_get_next(
page_get_infimum_rec(page)),
0, heap);
0, heap,
btr_page_get_level(page, &mtr));
if (cmp_dtuple_rec(node_ptr_tuple, node_ptr) != 0) {
......
......@@ -2345,9 +2345,9 @@ btr_cur_pessimistic_delete(
heap = mem_heap_create(256);
node_ptr = dict_tree_build_node_ptr(
tree, page_rec_get_next(rec),
buf_frame_get_page_no(page),
heap);
tree, page_rec_get_next(rec),
buf_frame_get_page_no(page),
heap, btr_page_get_level(page, mtr));
btr_insert_on_non_leaf_level(tree,
btr_page_get_level(page, mtr) + 1,
......
......@@ -556,6 +556,15 @@ buf_flush_try_neighbors(
block = buf_page_hash_get(space, i);
if (block && flush_type == BUF_FLUSH_LRU && i != offset
&& !block->old) {
/* We avoid flushing 'non-old' blocks in an LRU flush,
because the flushed blocks are soon freed */
continue;
}
if (block && buf_flush_ready_for_flush(block, flush_type)) {
mutex_exit(&(buf_pool->mutex));
......
......@@ -2411,7 +2411,9 @@ dict_tree_build_node_ptr(
dict_tree_t* tree, /* in: index tree */
rec_t* rec, /* in: record for which to build node pointer */
ulint page_no,/* in: page number to put in node pointer */
mem_heap_t* heap) /* in: memory heap where pointer created */
mem_heap_t* heap, /* in: memory heap where pointer created */
ibool level) /* in: level of rec in tree: 0 means leaf
level */
{
dtuple_t* tuple;
dict_index_t* ind;
......@@ -2423,9 +2425,16 @@ dict_tree_build_node_ptr(
if (tree->type & DICT_UNIVERSAL) {
/* In a universal index tree, we take the whole record as
the node pointer */
the node pointer if the reord is on the leaf level,
on non-leaf levels we remove the last field, which
contains the page number of the child page */
n_unique = rec_get_n_fields(rec);
if (level > 0) {
ut_a(n_unique > 1);
n_unique--;
}
} else {
n_unique = dict_index_get_n_unique_in_tree(ind);
}
......
......@@ -622,7 +622,9 @@ dict_tree_build_node_ptr(
dict_tree_t* tree, /* in: index tree */
rec_t* rec, /* in: record for which to build node pointer */
ulint page_no,/* in: page number to put in node pointer */
mem_heap_t* heap); /* in: memory heap where pointer created */
mem_heap_t* heap, /* in: memory heap where pointer created */
ibool level); /* in: level of rec in tree: 0 means leaf
level */
/**************************************************************************
Copies an initial segment of a physical record, long enough to specify an
index entry uniquely. */
......
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