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

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
Loading
Loading
Loading
Loading
+13 −11
Original line number Diff line number Diff line
@@ -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);

@@ -2488,7 +2489,8 @@ btr_validate_level(
					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) {

+3 −3
Original line number Diff line number Diff line
@@ -2347,7 +2347,7 @@ btr_cur_pessimistic_delete(
			node_ptr = dict_tree_build_node_ptr(
					tree, page_rec_get_next(rec),
					buf_frame_get_page_no(page),
						heap);
       					heap, btr_page_get_level(page, mtr));

			btr_insert_on_non_leaf_level(tree,
					btr_page_get_level(page, mtr) + 1,
+9 −0
Original line number Diff line number Diff line
@@ -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));
+11 −2
Original line number Diff line number Diff line
@@ -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);
	}
+3 −1
Original line number Diff line number Diff line
@@ -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. */