mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
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 innobase/buf/buf0flu.c: Fix a bug in previous change innobase/dict/dict0dict.c: Fix a bug in insert buffer B-tree upper levels; probably caused the crash by B.Fitzpatrick innobase/include/dict0dict.h: Fix a bug in insert buffer B-tree upper levels; probably caused the crash by B.Fitzpatrick innobase/btr/btr0btr.c: Fix a bug in insert buffer B-tree upper levels; probably caused the crash by B.Fitzpatrick innobase/btr/btr0cur.c: Fix a bug in insert buffer B-tree upper levels; probably caused the crash by B.Fitzpatrick
This commit is contained in:
@ -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. */
|
||||
|
Reference in New Issue
Block a user