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 "lock0lock.h"
|
||||||
#include "ibuf0ibuf.h"
|
#include "ibuf0ibuf.h"
|
||||||
|
|
||||||
/**
|
/*
|
||||||
Node pointers
|
Node pointers
|
||||||
-------------
|
-------------
|
||||||
Leaf pages of a B-tree contain the index records stored in the
|
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),
|
ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree),
|
||||||
MTR_MEMO_X_LOCK));
|
MTR_MEMO_X_LOCK));
|
||||||
ut_ad(user_rec != page_get_supremum_rec(page));
|
ut_a(user_rec != page_get_supremum_rec(page));
|
||||||
ut_ad(user_rec != page_get_infimum_rec(page));
|
ut_a(user_rec != page_get_infimum_rec(page));
|
||||||
|
|
||||||
ut_ad(dict_tree_get_page(tree) != buf_frame_get_page_no(page));
|
ut_ad(dict_tree_get_page(tree) != buf_frame_get_page_no(page));
|
||||||
|
|
||||||
heap = mem_heap_create(100);
|
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
|
/* In the following, we choose just any index from the tree as the
|
||||||
first parameter for btr_cur_search_to_nth_level. */
|
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);
|
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));
|
buf_frame_get_page_no(page));
|
||||||
mem_heap_free(heap);
|
mem_heap_free(heap);
|
||||||
|
|
||||||
@ -949,8 +950,8 @@ btr_root_raise_and_insert(
|
|||||||
/* Build the node pointer (= node key and page address) for the
|
/* Build the node pointer (= node key and page address) for the
|
||||||
child */
|
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 */
|
/* Reorganize the root to get free space */
|
||||||
btr_page_reorganize(root, mtr);
|
btr_page_reorganize(root, mtr);
|
||||||
|
|
||||||
@ -1365,7 +1366,7 @@ btr_attach_half_pages(
|
|||||||
half */
|
half */
|
||||||
|
|
||||||
node_ptr_upper = dict_tree_build_node_ptr(tree, split_rec,
|
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
|
/* Insert it next to the pointer to the lower half. Note that this
|
||||||
may generate recursion leading to a split on the higher level. */
|
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(
|
node_ptr_tuple = dict_tree_build_node_ptr(
|
||||||
tree,
|
tree,
|
||||||
page_rec_get_next(page_get_infimum_rec(page)),
|
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);
|
ut_a(cmp_dtuple_rec(node_ptr_tuple, node_ptr) == 0);
|
||||||
|
|
||||||
@ -2485,10 +2486,11 @@ loop:
|
|||||||
heap = mem_heap_create(256);
|
heap = mem_heap_create(256);
|
||||||
|
|
||||||
node_ptr_tuple = dict_tree_build_node_ptr(
|
node_ptr_tuple = dict_tree_build_node_ptr(
|
||||||
tree,
|
tree,
|
||||||
page_rec_get_next(
|
page_rec_get_next(
|
||||||
page_get_infimum_rec(page)),
|
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) {
|
if (cmp_dtuple_rec(node_ptr_tuple, node_ptr) != 0) {
|
||||||
|
|
||||||
|
@ -2345,9 +2345,9 @@ btr_cur_pessimistic_delete(
|
|||||||
heap = mem_heap_create(256);
|
heap = mem_heap_create(256);
|
||||||
|
|
||||||
node_ptr = dict_tree_build_node_ptr(
|
node_ptr = dict_tree_build_node_ptr(
|
||||||
tree, page_rec_get_next(rec),
|
tree, page_rec_get_next(rec),
|
||||||
buf_frame_get_page_no(page),
|
buf_frame_get_page_no(page),
|
||||||
heap);
|
heap, btr_page_get_level(page, mtr));
|
||||||
|
|
||||||
btr_insert_on_non_leaf_level(tree,
|
btr_insert_on_non_leaf_level(tree,
|
||||||
btr_page_get_level(page, mtr) + 1,
|
btr_page_get_level(page, mtr) + 1,
|
||||||
|
@ -556,6 +556,15 @@ buf_flush_try_neighbors(
|
|||||||
|
|
||||||
block = buf_page_hash_get(space, i);
|
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)) {
|
if (block && buf_flush_ready_for_flush(block, flush_type)) {
|
||||||
|
|
||||||
mutex_exit(&(buf_pool->mutex));
|
mutex_exit(&(buf_pool->mutex));
|
||||||
|
@ -2411,7 +2411,9 @@ dict_tree_build_node_ptr(
|
|||||||
dict_tree_t* tree, /* in: index tree */
|
dict_tree_t* tree, /* in: index tree */
|
||||||
rec_t* rec, /* in: record for which to build node pointer */
|
rec_t* rec, /* in: record for which to build node pointer */
|
||||||
ulint page_no,/* in: page number to put in 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;
|
dtuple_t* tuple;
|
||||||
dict_index_t* ind;
|
dict_index_t* ind;
|
||||||
@ -2423,9 +2425,16 @@ dict_tree_build_node_ptr(
|
|||||||
|
|
||||||
if (tree->type & DICT_UNIVERSAL) {
|
if (tree->type & DICT_UNIVERSAL) {
|
||||||
/* In a universal index tree, we take the whole record as
|
/* 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);
|
n_unique = rec_get_n_fields(rec);
|
||||||
|
|
||||||
|
if (level > 0) {
|
||||||
|
ut_a(n_unique > 1);
|
||||||
|
n_unique--;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
n_unique = dict_index_get_n_unique_in_tree(ind);
|
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 */
|
dict_tree_t* tree, /* in: index tree */
|
||||||
rec_t* rec, /* in: record for which to build node pointer */
|
rec_t* rec, /* in: record for which to build node pointer */
|
||||||
ulint page_no,/* in: page number to put in 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
|
Copies an initial segment of a physical record, long enough to specify an
|
||||||
index entry uniquely. */
|
index entry uniquely. */
|
||||||
|
Reference in New Issue
Block a user