Commit 2fb07495 authored by unknown's avatar unknown
Browse files

Merge hundin.mysql.fi:/home/marko/mysql-5.0

into hundin.mysql.fi:/home/marko/mysql-5.0-current


innobase/dict/dict0dict.c:
  Auto merged
innobase/fil/fil0fil.c:
  Auto merged
innobase/include/lock0lock.h:
  Auto merged
innobase/lock/lock0lock.c:
  Auto merged
innobase/os/os0file.c:
  Auto merged
innobase/row/row0ins.c:
  Auto merged
innobase/row/row0mysql.c:
  Auto merged
innobase/srv/srv0start.c:
  Auto merged
innobase/trx/trx0trx.c:
  Auto merged
sql/ha_innodb.cc:
  Auto merged
sql/ha_innodb.h:
  Auto merged
sql/mysqld.cc:
  Auto merged
parents c2e97308 32360605
Loading
Loading
Loading
Loading
+96 −78
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ Created 6/2/1994 Heikki Tuuri
#include "rem0cmp.h"
#include "lock0lock.h"
#include "ibuf0ibuf.h"
#include "trx0trx.h"

/*
Latching strategy of the InnoDB B-tree
@@ -137,13 +138,13 @@ btr_root_get(
	ulint	space;
	ulint	root_page_no;
	page_t*	root;
	ibool	comp = UT_LIST_GET_FIRST(tree->tree_indexes)->table->comp;
	
	space = dict_tree_get_space(tree);
	root_page_no = dict_tree_get_page(tree);

	root = btr_page_get(space, root_page_no, RW_X_LATCH, mtr);
	ut_a(page_is_comp(root) == comp);
	ut_a(!!page_is_comp(root) ==
			UT_LIST_GET_FIRST(tree->tree_indexes)->table->comp);
	
	return(root);
}
@@ -163,21 +164,19 @@ btr_get_prev_user_rec(
	page_t*	page;
	page_t*	prev_page;
	ulint	prev_page_no;
	rec_t*	prev_rec;
	ulint	space;

	page = buf_frame_align(rec);
	
	if (page_get_infimum_rec(page) != rec) {
	if (!page_rec_is_infimum(rec)) {

		prev_rec = page_rec_get_prev(rec);
		rec_t*	prev_rec = page_rec_get_prev(rec);

		if (page_get_infimum_rec(page) != prev_rec) {
		if (!page_rec_is_infimum(prev_rec)) {

			return(prev_rec);
		}
	}
	
	page = buf_frame_align(rec);
	prev_page_no = btr_page_get_prev(page, mtr);
	space = buf_frame_get_space_id(page);
	
@@ -192,9 +191,7 @@ btr_get_prev_user_rec(
		      				MTR_MEMO_PAGE_X_FIX)));
		ut_a(page_is_comp(prev_page) == page_is_comp(page));

		prev_rec = page_rec_get_prev(page_get_supremum_rec(prev_page));

		return(prev_rec);
		return(page_rec_get_prev(page_get_supremum_rec(prev_page)));
	}

	return(NULL);
@@ -215,21 +212,19 @@ btr_get_next_user_rec(
	page_t*	page;
	page_t*	next_page;
	ulint	next_page_no;
	rec_t*	next_rec;
	ulint	space;

	page = buf_frame_align(rec);
	if (!page_rec_is_supremum(rec)) {

	if (page_get_supremum_rec(page) != rec) {

		next_rec = page_rec_get_next(rec);
		rec_t*	next_rec = page_rec_get_next(rec);

		if (page_get_supremum_rec(page) != next_rec) {
		if (!page_rec_is_supremum(next_rec)) {

			return(next_rec);
		}
	}
	
	page = buf_frame_align(rec);
	next_page_no = btr_page_get_next(page, mtr);
	space = buf_frame_get_space_id(page);
	
@@ -244,9 +239,7 @@ btr_get_next_user_rec(
		      				MTR_MEMO_PAGE_X_FIX)));

		ut_a(page_is_comp(next_page) == page_is_comp(page));
		next_rec = page_rec_get_next(page_get_infimum_rec(next_page));

		return(next_rec);
		return(page_rec_get_next(page_get_infimum_rec(next_page)));
	}

	return(NULL);
@@ -573,8 +566,7 @@ btr_page_get_father_for_rec(

	ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree),
							MTR_MEMO_X_LOCK));
	ut_a(user_rec != page_get_supremum_rec(page));
	ut_a(user_rec != page_get_infimum_rec(page));
	ut_a(page_rec_is_user_rec(user_rec));
	
	ut_ad(dict_tree_get_page(tree) != buf_frame_get_page_no(page));

@@ -598,6 +590,7 @@ btr_page_get_father_for_rec(

	if (btr_node_ptr_get_child_page_no(node_ptr, offsets) !=
                                                buf_frame_get_page_no(page)) {
		rec_t*	print_rec;
		fputs("InnoDB: Dump of the child page:\n", stderr);
		buf_page_print(buf_frame_align(page));
		fputs("InnoDB: Dump of the parent page:\n", stderr);
@@ -612,11 +605,10 @@ btr_page_get_father_for_rec(
			(ulong)
			btr_node_ptr_get_child_page_no(node_ptr, offsets),
			(ulong) buf_frame_get_page_no(page));
		offsets = rec_get_offsets(page_rec_get_next(
				page_get_infimum_rec(page)), index,
		print_rec = page_rec_get_next(page_get_infimum_rec(page));
		offsets = rec_get_offsets(print_rec, index,
				offsets, ULINT_UNDEFINED, &heap);
		page_rec_print(page_rec_get_next(page_get_infimum_rec(page)),
					offsets);
		page_rec_print(print_rec, offsets);
		offsets = rec_get_offsets(node_ptr, index, offsets,
					ULINT_UNDEFINED, &heap);
		page_rec_print(node_ptr, offsets);
@@ -663,7 +655,7 @@ btr_create(
	ulint	type,	/* in: type of the index */
	ulint	space,	/* in: space where created */
	dulint	index_id,/* in: index id */
	ibool	comp,	/* in: TRUE=compact page format */
	ulint	comp,	/* in: nonzero=compact page format */
	mtr_t*	mtr)	/* in: mini-transaction handle */
{
	ulint		page_no;
@@ -854,11 +846,12 @@ btr_page_reorganize_low(

	ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
			      				MTR_MEMO_PAGE_X_FIX));
	ut_ad(!!page_is_comp(page) == index->table->comp);
	data_size1 = page_get_data_size(page);
	max_ins_size1 = page_get_max_insert_size_after_reorganize(page, 1);

	/* Write the log record */
	mlog_open_and_write_index(mtr, page, index, index->table->comp
	mlog_open_and_write_index(mtr, page, index, page_is_comp(page)
			? MLOG_COMP_PAGE_REORGANIZE
			: MLOG_PAGE_REORGANIZE, 0);

@@ -877,7 +870,7 @@ btr_page_reorganize_low(
	/* Recreate the page: note that global data on page (possible
	segment headers, next page-field, etc.) is preserved intact */

	page_create(page, mtr, index->table->comp);
	page_create(page, mtr, page_is_comp(page));
	buf_block_align(page)->check_index_page_at_flush = TRUE;
	
	/* Copy the records from the temporary space to the recreated page;
@@ -1070,7 +1063,7 @@ btr_root_raise_and_insert(
	as there is no lower alphabetical limit to records in the leftmost
	node of a level: */

	btr_set_min_rec_mark(node_ptr_rec, cursor->index->table->comp, mtr);
	btr_set_min_rec_mark(node_ptr_rec, page_is_comp(root), mtr);
		
	/* Free the memory heap */
	mem_heap_free(heap);
@@ -1151,7 +1144,6 @@ btr_page_get_split_rec_to_right(
{
	page_t*	page;
	rec_t*	insert_point;
	rec_t*	supremum;

	page = btr_cur_get_page(cursor);
	insert_point = btr_cur_get_rec(cursor);
@@ -1160,13 +1152,23 @@ btr_page_get_split_rec_to_right(
	the previous insert on the same page, we assume that there is a
	pattern of sequential inserts here. */

	if (page_header_get_ptr(page, PAGE_LAST_INSERT) == insert_point) {
	if (UNIV_LIKELY(page_header_get_ptr(page, PAGE_LAST_INSERT)
				== insert_point)) {

	     	supremum = page_get_supremum_rec(page);
		rec_t*	next_rec;

		next_rec = page_rec_get_next(insert_point);

		if (page_rec_is_supremum(next_rec)) {
split_at_new:
			/* Split at the new record to insert */
	     		*split_rec = NULL;
		} else {
			rec_t*	next_next_rec = page_rec_get_next(next_rec);
			if (page_rec_is_supremum(next_next_rec)) {

		if (page_rec_get_next(insert_point) != supremum
		    && page_rec_get_next(page_rec_get_next(insert_point))
			!= supremum) {
				goto split_at_new;
			}

			/* If there are >= 2 user records up from the insert
			point, split all but 1 off. We want to keep one because
@@ -1175,11 +1177,7 @@ btr_page_get_split_rec_to_right(
			search position just by looking at the records on this
			page. */
		
			*split_rec = page_rec_get_next(
					page_rec_get_next(insert_point));
		} else {
			/* Else split at the new record to insert */
	     		*split_rec = NULL;
			*split_rec = next_next_rec;
		}

		return(TRUE);
@@ -1220,7 +1218,7 @@ btr_page_get_sure_split_rec(
	page = btr_cur_get_page(cursor);
	
	insert_size = rec_get_converted_size(cursor->index, tuple);
	free_space  = page_get_free_space_of_empty(cursor->index->table->comp);
	free_space  = page_get_free_space_of_empty(page_is_comp(page));

	/* free_space is now the free space of a created new page */

@@ -1276,21 +1274,22 @@ btr_page_get_sure_split_rec(
                    	    	supremum record of page */

				if (rec == ins_rec) {
					next_rec = NULL;
					rec = NULL;

					goto func_exit;
				} else if (rec == NULL) {
					next_rec = page_rec_get_next(ins_rec);
				} else {
					next_rec = page_rec_get_next(rec);
				}
				if (next_rec != page_get_supremum_rec(page)) {
					if (heap) {
						mem_heap_free(heap);
					}
					return(next_rec);
				ut_ad(next_rec);
				if (!page_rec_is_supremum(next_rec)) {
					rec = next_rec;
				}
                    	}

			if (heap) {
func_exit:
			if (UNIV_LIKELY_NULL(heap)) {
				mem_heap_free(heap);
			}
			return(rec);
@@ -1329,13 +1328,12 @@ btr_page_insert_fits(

	ut_ad(!split_rec == !offsets);
	ut_ad(!offsets
		|| cursor->index->table->comp == rec_offs_comp(offsets));
		|| !page_is_comp(page) == !rec_offs_comp(offsets));
	ut_ad(!offsets
		|| rec_offs_validate(split_rec, cursor->index, offsets));
	ut_ad(page_is_comp(page) == cursor->index->table->comp);

	insert_size = rec_get_converted_size(cursor->index, tuple);
	free_space  = page_get_free_space_of_empty(cursor->index->table->comp);
	free_space  = page_get_free_space_of_empty(page_is_comp(page));

	/* free_space is now the free space of a created new page */

@@ -1832,14 +1830,15 @@ void
btr_set_min_rec_mark_log(
/*=====================*/
	rec_t*	rec,	/* in: record */
	ibool	comp,	/* TRUE=compact record format */
	ulint	comp,	/* nonzero=compact record format */
	mtr_t*	mtr)	/* in: mtr */
{
	mlog_write_initial_log_record(rec,
		comp ? MLOG_COMP_REC_MIN_MARK : MLOG_REC_MIN_MARK, mtr);

	/* Write rec offset as a 2-byte ulint */
	mlog_catenate_ulint(mtr, rec - buf_frame_align(rec), MLOG_2BYTES);
	mlog_catenate_ulint(mtr, ut_align_offset(rec, UNIV_PAGE_SIZE),
								MLOG_2BYTES);
}

/********************************************************************
@@ -1852,7 +1851,7 @@ btr_parse_set_min_rec_mark(
			/* out: end of log record or NULL */
	byte*	ptr,	/* in: buffer */
	byte*	end_ptr,/* in: buffer end */
	ibool	comp,	/* in: TRUE=compact page format */
	ulint	comp,	/* in: nonzero=compact page format */
	page_t*	page,	/* in: page or NULL */
	mtr_t*	mtr)	/* in: mtr or NULL */
{
@@ -1864,6 +1863,8 @@ btr_parse_set_min_rec_mark(
	}

	if (page) {
		ut_a(!page_is_comp(page) == !comp);

		rec = page + mach_read_from_2(ptr);

		btr_set_min_rec_mark(rec, comp, mtr);
@@ -1879,7 +1880,7 @@ void
btr_set_min_rec_mark(
/*=================*/
	rec_t*	rec,	/* in: record */
	ibool	comp,	/* in: TRUE=compact page format */
	ulint	comp,	/* in: nonzero=compact page format */
	mtr_t*	mtr)	/* in: mtr */
{
	ulint	info_bits;
@@ -2008,11 +2009,12 @@ btr_compress(
	ulint		max_ins_size;
	ulint		max_ins_size_reorg;
	ulint		level;
	ibool		comp	= cursor->index->table->comp;
	ulint		comp;

	page = btr_cur_get_page(cursor);
	tree = btr_cur_get_tree(cursor);
	ut_a(comp == page_is_comp(page));
	comp = page_is_comp(page);
	ut_a(!!comp == cursor->index->table->comp);

	ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree),
							MTR_MEMO_X_LOCK));
@@ -2055,7 +2057,7 @@ btr_compress(
	
	n_recs = page_get_n_recs(page);
	data_size = page_get_data_size(page);
	ut_a(page_is_comp(merge_page) == page_is_comp(page));
	ut_a(page_is_comp(merge_page) == comp);

	max_ins_size_reorg = page_get_max_insert_size_after_reorganize(
							merge_page, n_recs);
@@ -2108,7 +2110,7 @@ btr_compress(
				rec_get_offsets(node_ptr, cursor->index,
				offsets_, ULINT_UNDEFINED, &heap),
				right_page_no, mtr);
		if (heap) {
		if (UNIV_LIKELY_NULL(heap)) {
			mem_heap_free(heap);
		}
		btr_node_ptr_delete(tree, merge_page, mtr);
@@ -2250,10 +2252,9 @@ btr_discard_page(

		node_ptr = page_rec_get_next(page_get_infimum_rec(merge_page));

		ut_ad(node_ptr != page_get_supremum_rec(merge_page));
		ut_ad(page_rec_is_user_rec(node_ptr));

		btr_set_min_rec_mark(node_ptr,
					cursor->index->table->comp, mtr);
		btr_set_min_rec_mark(node_ptr, page_is_comp(merge_page), mtr);
	}	
	
	btr_node_ptr_delete(tree, page, mtr);
@@ -2274,6 +2275,7 @@ btr_discard_page(
	ut_ad(btr_check_node_ptr(tree, merge_page, mtr));
}	

#ifdef UNIV_BTR_PRINT
/*****************************************************************
Prints size info of a B-tree. */

@@ -2401,14 +2403,15 @@ btr_print_tree(
	root = btr_root_get(tree, &mtr);

	btr_print_recursive(tree, root, width, &heap, &offsets, &mtr);
	if (heap) {
	if (UNIV_LIKELY_NULL(heap)) {
		mem_heap_free(heap);
	}

	mtr_commit(&mtr);

	btr_validate_tree(tree);
	btr_validate_tree(tree, NULL);
}
#endif /* UNIV_BTR_PRINT */

/****************************************************************
Checks that the node pointer to a page is appropriate. */
@@ -2497,7 +2500,7 @@ btr_index_rec_validate(

	page = buf_frame_align(rec);

	if (index->type & DICT_UNIVERSAL) {
	if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) {
	        /* The insert buffer index tree can contain records from any
	        other index: we cannot check the number of fields or
	        their length */
@@ -2505,9 +2508,18 @@ btr_index_rec_validate(
	        return(TRUE);
	}

	if (UNIV_UNLIKELY(!!page_is_comp(page) != index->table->comp)) {
		btr_index_rec_validate_report(page, rec, index);
		fprintf(stderr, "InnoDB: compact flag=%lu, should be %lu\n",
			(ulong) !!page_is_comp(page),
			(ulong) index->table->comp);
		return(FALSE);
	}

	n = dict_index_get_n_fields(index);

	if (!index->table->comp && rec_get_n_fields_old(rec) != n) {
	if (!page_is_comp(page)
			&& UNIV_UNLIKELY(rec_get_n_fields_old(rec) != n)) {
		btr_index_rec_validate_report(page, rec, index);
		fprintf(stderr, "InnoDB: has %lu fields, should have %lu\n",
			(ulong) rec_get_n_fields_old(rec), (ulong) n);
@@ -2554,14 +2566,14 @@ btr_index_rec_validate(
				rec_print_new(stderr, rec, offsets);
				putc('\n', stderr);
			}
			if (heap) {
			if (UNIV_LIKELY_NULL(heap)) {
				mem_heap_free(heap);
			}
			return(FALSE);
		}
	}

	if (heap) {
	if (UNIV_LIKELY_NULL(heap)) {
		mem_heap_free(heap);
	}
	return(TRUE);			
@@ -2649,6 +2661,7 @@ btr_validate_level(
/*===============*/
				/* out: TRUE if ok */
	dict_tree_t*	tree,	/* in: index tree */
	trx_t*		trx,	/* in: transaction or NULL */
	ulint		level)	/* in: level number */
{
	ulint		space;
@@ -2696,6 +2709,11 @@ btr_validate_level(
	/* Now we are on the desired level. Loop through the pages on that
	level. */
loop:
	if (trx_is_interrupted(trx)) {
		mtr_commit(&mtr);
		mem_heap_free(heap);
		return(ret);
	}
	mem_heap_empty(heap);
	offsets = offsets2 = NULL;
	mtr_x_lock(dict_tree_get_lock(tree), &mtr);
@@ -2765,7 +2783,7 @@ btr_validate_level(
	if (level > 0 && left_page_no == FIL_NULL) {
		ut_a(REC_INFO_MIN_REC_FLAG & rec_get_info_bits(
			page_rec_get_next(page_get_infimum_rec(page)),
				index->table->comp));
				page_is_comp(page)));
	}

	if (buf_frame_get_page_no(page) != dict_tree_get_page(tree)) {
@@ -2921,7 +2939,7 @@ btr_validate_level(
	mtr_commit(&mtr);

	if (right_page_no != FIL_NULL) {
		ibool	comp = page_is_comp(page);
		ulint	comp = page_is_comp(page);
		mtr_start(&mtr);
	
		page = btr_page_get(space, right_page_no, RW_X_LATCH, &mtr);
@@ -2941,7 +2959,8 @@ ibool
btr_validate_tree(
/*==============*/
				/* out: TRUE if ok */
	dict_tree_t*	tree)	/* in: tree */
	dict_tree_t*	tree,	/* in: tree */
	trx_t*		trx)	/* in: transaction or NULL */
{
	mtr_t	mtr;
	page_t*	root;
@@ -2954,9 +2973,8 @@ btr_validate_tree(
	root = btr_root_get(tree, &mtr);
	n = btr_page_get_level(root, &mtr);

	for (i = 0; i <= n; i++) {
		
		if (!btr_validate_level(tree, n - i)) {
	for (i = 0; i <= n && !trx_is_interrupted(trx); i++) {
		if (!btr_validate_level(tree, trx, n - i)) {

			mtr_commit(&mtr);

+143 −108

File changed.

Preview size limit exceeded, changes collapsed.

+30 −36
Original line number Diff line number Diff line
@@ -78,6 +78,7 @@ btr_pcur_store_position(
	rec_t*		rec;
	dict_tree_t*	tree;
	page_t*		page;
	ulint		offs;
	
	ut_a(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
	ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@@ -87,7 +88,8 @@ btr_pcur_store_position(
	page_cursor = btr_pcur_get_page_cur(cursor);

	rec = page_cur_get_rec(page_cursor);
	page = buf_frame_align(rec);
	page = ut_align_down(rec, UNIV_PAGE_SIZE);
	offs = ut_align_offset(rec, UNIV_PAGE_SIZE);

	ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
							MTR_MEMO_PAGE_S_FIX)
@@ -95,35 +97,33 @@ btr_pcur_store_position(
							MTR_MEMO_PAGE_X_FIX));
	ut_a(cursor->latch_mode != BTR_NO_LATCHES);

	if (page_get_n_recs(page) == 0) {
	if (UNIV_UNLIKELY(page_get_n_recs(page) == 0)) {
		/* It must be an empty index tree; NOTE that in this case
		we do not store the modify_clock, but always do a search
		if we restore the cursor position */

		ut_a(btr_page_get_next(page, mtr) == FIL_NULL
		     && btr_page_get_prev(page, mtr) == FIL_NULL);
		ut_a(btr_page_get_next(page, mtr) == FIL_NULL);
		ut_a(btr_page_get_prev(page, mtr) == FIL_NULL);

		if (rec == page_get_supremum_rec(page)) {

			cursor->rel_pos = BTR_PCUR_AFTER_LAST_IN_TREE;
		cursor->old_stored = BTR_PCUR_OLD_STORED;

			return;
		}
		if (page_rec_is_supremum_low(offs)) {

			cursor->rel_pos = BTR_PCUR_AFTER_LAST_IN_TREE;
		} else {
			cursor->rel_pos = BTR_PCUR_BEFORE_FIRST_IN_TREE;
		cursor->old_stored = BTR_PCUR_OLD_STORED;
		}

		return;
	} 

	if (rec == page_get_supremum_rec(page)) {
	if (page_rec_is_supremum_low(offs)) {

		rec = page_rec_get_prev(rec);

		cursor->rel_pos = BTR_PCUR_AFTER;

	} else if (rec == page_get_infimum_rec(page)) {
	} else if (page_rec_is_infimum_low(offs)) {

		rec = page_rec_get_next(rec);

@@ -139,7 +139,8 @@ btr_pcur_store_position(
						&cursor->buf_size);

	cursor->block_when_stored = buf_block_align(page);	
	cursor->modify_clock = buf_frame_get_modify_clock(page);
	cursor->modify_clock = buf_block_get_modify_clock(
				cursor->block_when_stored);
}

/******************************************************************
@@ -202,33 +203,27 @@ btr_pcur_restore_position(
	dtuple_t*	tuple;
	ulint		mode;
	ulint		old_mode;
	ibool		from_left;
	mem_heap_t*	heap;

	ut_a(cursor->pos_state == BTR_PCUR_WAS_POSITIONED
			|| cursor->pos_state == BTR_PCUR_IS_POSITIONED);
	if (cursor->old_stored != BTR_PCUR_OLD_STORED) {
	if (UNIV_UNLIKELY(cursor->old_stored != BTR_PCUR_OLD_STORED)
	    || UNIV_UNLIKELY(cursor->pos_state != BTR_PCUR_WAS_POSITIONED
			     && cursor->pos_state != BTR_PCUR_IS_POSITIONED)) {
		ut_print_buf(stderr, (const byte*)cursor, sizeof(btr_pcur_t));
		if (cursor->trx_if_known) {
			trx_print(stderr, cursor->trx_if_known);
		}
		
		ut_a(0);
		ut_error;
	}

	if (cursor->rel_pos == BTR_PCUR_AFTER_LAST_IN_TREE
	    || cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE) {
	if (UNIV_UNLIKELY(cursor->rel_pos == BTR_PCUR_AFTER_LAST_IN_TREE
			|| cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE)) {

	    	/* In these cases we do not try an optimistic restoration,
	    	but always do a search */

	    	if (cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE) {
	    		from_left = TRUE;
	    	} else {
	    		from_left = FALSE;
	    	}

		btr_cur_open_at_index_side(from_left,
		btr_cur_open_at_index_side(
			cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE,
			btr_pcur_get_btr_cur(cursor)->index, latch_mode,
					btr_pcur_get_btr_cur(cursor), mtr);

@@ -243,12 +238,13 @@ btr_pcur_restore_position(

	page = btr_cur_get_page(btr_pcur_get_btr_cur(cursor));

	if (latch_mode == BTR_SEARCH_LEAF || latch_mode == BTR_MODIFY_LEAF) {
	if (UNIV_LIKELY(latch_mode == BTR_SEARCH_LEAF)
			|| UNIV_LIKELY(latch_mode == BTR_MODIFY_LEAF)) {
		/* Try optimistic restoration */
	    
		if (buf_page_optimistic_get(latch_mode,
		if (UNIV_LIKELY(buf_page_optimistic_get(latch_mode,
					    cursor->block_when_stored, page,
					    cursor->modify_clock, mtr)) {
					    cursor->modify_clock, mtr))) {
			cursor->pos_state = BTR_PCUR_IS_POSITIONED;
#ifdef UNIV_SYNC_DEBUG
			buf_page_dbg_add_level(page, SYNC_TREE_NODE);
@@ -297,7 +293,7 @@ btr_pcur_restore_position(
	/* Save the old search mode of the cursor */
	old_mode = cursor->search_mode;
	
	if (cursor->rel_pos == BTR_PCUR_ON) {
	if (UNIV_LIKELY(cursor->rel_pos == BTR_PCUR_ON)) {
		mode = PAGE_CUR_LE;
	} else if (cursor->rel_pos == BTR_PCUR_AFTER) {
		mode = PAGE_CUR_G;
@@ -323,12 +319,10 @@ btr_pcur_restore_position(
		the cursor can now be on a different page! But we can retain
		the value of old_rec */

		cursor->modify_clock =
			buf_frame_get_modify_clock(btr_pcur_get_page(cursor));

		cursor->block_when_stored =
			buf_block_align(btr_pcur_get_page(cursor));

		cursor->modify_clock =
			buf_block_get_modify_clock(cursor->block_when_stored);
		cursor->old_stored = BTR_PCUR_OLD_STORED;

		mem_heap_free(heap);
+81 −110
Original line number Diff line number Diff line
@@ -435,7 +435,7 @@ btr_search_update_hash_ref(
				offsets_, ULINT_UNDEFINED, &heap),
				block->curr_n_fields,
				block->curr_n_bytes, tree_id);
		if (heap) {
		if (UNIV_LIKELY_NULL(heap)) {
			mem_heap_free(heap);
		}
#ifdef UNIV_SYNC_DEBUG
@@ -544,10 +544,7 @@ btr_search_check_guess(
				or PAGE_CUR_GE */
	mtr_t*		mtr)	/* in: mtr */
{
	page_t*		page;
	rec_t*		rec;
	rec_t*		prev_rec;
	rec_t*		next_rec;
	ulint		n_unique;
	ulint		match;
	ulint		bytes;
@@ -561,7 +558,6 @@ btr_search_check_guess(
	n_unique = dict_index_get_n_unique_in_tree(cursor->index);
	
	rec = btr_cur_get_rec(cursor);
	page = buf_frame_align(rec);

	ut_ad(page_rec_is_user_rec(rec));

@@ -611,13 +607,16 @@ btr_search_check_guess(
	bytes = 0;

	if ((mode == PAGE_CUR_G) || (mode == PAGE_CUR_GE)) {
		rec_t*	prev_rec;

		ut_ad(rec != page_get_infimum_rec(page));
		ut_ad(!page_rec_is_infimum(rec));
		
		prev_rec = page_rec_get_prev(rec);

		if (prev_rec == page_get_infimum_rec(page)) {
			success = btr_page_get_prev(page, mtr) == FIL_NULL;
		if (page_rec_is_infimum(prev_rec)) {
			success = btr_page_get_prev(
				buf_frame_align(prev_rec), mtr) == FIL_NULL;

			goto exit_func;
		}

@@ -632,14 +631,16 @@ btr_search_check_guess(
		}

		goto exit_func;
	}
	} else {
		rec_t*	next_rec;

	ut_ad(rec != page_get_supremum_rec(page));
		ut_ad(!page_rec_is_supremum(rec));
	
		next_rec = page_rec_get_next(rec);

	if (next_rec == page_get_supremum_rec(page)) {
    		if (btr_page_get_next(page, mtr) == FIL_NULL) {
		if (page_rec_is_supremum(next_rec)) {
			if (btr_page_get_next(
				buf_frame_align(next_rec), mtr) == FIL_NULL) {

				cursor->up_match = 0;
				success = TRUE;
@@ -658,8 +659,9 @@ btr_search_check_guess(
		} else {
			success = cmp != 1;
		}
	}
exit_func:
	if (heap) {
	if (UNIV_LIKELY_NULL(heap)) {
		mem_heap_free(heap);
	}
	return(success);
@@ -694,7 +696,6 @@ btr_search_guess_on_hash(
	buf_block_t*	block;
	rec_t*		rec;
	page_t*		page;
	ibool		success;
	ulint		fold;
	ulint		tuple_n_fields;
	dulint		tree_id;
@@ -710,7 +711,7 @@ btr_search_guess_on_hash(
	/* Note that, for efficiency, the struct info may not be protected by
	any latch here! */

	if (info->n_hash_potential == 0) {
	if (UNIV_UNLIKELY(info->n_hash_potential == 0)) {

		return(FALSE);
	}
@@ -720,12 +721,13 @@ btr_search_guess_on_hash(

	tuple_n_fields = dtuple_get_n_fields(tuple);

	if (tuple_n_fields < cursor->n_fields) {
	if (UNIV_UNLIKELY(tuple_n_fields < cursor->n_fields)) {

		return(FALSE);
	}

	if ((cursor->n_bytes > 0) && (tuple_n_fields <= cursor->n_fields)) {
	if (UNIV_UNLIKELY(tuple_n_fields == cursor->n_fields)
			&& (cursor->n_bytes > 0)) {

	    	return(FALSE);
	}
@@ -740,39 +742,31 @@ btr_search_guess_on_hash(
	cursor->fold = fold;
	cursor->flag = BTR_CUR_HASH;
	
	if (!has_search_latch) {
	if (UNIV_LIKELY(!has_search_latch)) {
		rw_lock_s_lock(&btr_search_latch);
	}

	ut_a(btr_search_latch.writer != RW_LOCK_EX);
	ut_a(btr_search_latch.reader_count > 0);
	ut_ad(btr_search_latch.writer != RW_LOCK_EX);
	ut_ad(btr_search_latch.reader_count > 0);

	rec = ha_search_and_get_data(btr_search_sys->hash_index, fold);

	if (!rec) {
		if (!has_search_latch) {
			rw_lock_s_unlock(&btr_search_latch);
		}
		
		goto failure;
	if (UNIV_UNLIKELY(!rec)) {
		goto failure_unlock;
	}

	page = buf_frame_align(rec);

	if (!has_search_latch) {
	if (UNIV_LIKELY(!has_search_latch)) {

		success = buf_page_get_known_nowait(latch_mode, page,
		if (UNIV_UNLIKELY(!buf_page_get_known_nowait(latch_mode, page,
						BUF_MAKE_YOUNG,
						__FILE__, __LINE__,
						mtr);

		rw_lock_s_unlock(&btr_search_latch);

		if (!success) {

			goto failure;
						mtr))) {
			goto failure_unlock;
		}

		rw_lock_s_unlock(&btr_search_latch);
		can_only_compare_to_cursor_rec = FALSE;

#ifdef UNIV_SYNC_DEBUG
@@ -782,8 +776,8 @@ btr_search_guess_on_hash(

	block = buf_block_align(page);

	if (block->state == BUF_BLOCK_REMOVE_HASH) {
		if (!has_search_latch) {
	if (UNIV_UNLIKELY(block->state == BUF_BLOCK_REMOVE_HASH)) {
		if (UNIV_LIKELY(!has_search_latch)) {
	
			btr_leaf_page_release(page, latch_mode, mtr);
		}
@@ -791,51 +785,33 @@ btr_search_guess_on_hash(
		goto failure;
	}

	ut_a(block->state == BUF_BLOCK_FILE_PAGE);
	ut_a(page_rec_is_user_rec(rec));	
	ut_ad(block->state == BUF_BLOCK_FILE_PAGE);
	ut_ad(page_rec_is_user_rec(rec));

	btr_cur_position(index, rec, cursor);

	/* Check the validity of the guess within the page */

	if (0 != ut_dulint_cmp(tree_id, btr_page_get_index_id(page))) {

		success = FALSE;
/*
		fprintf(stderr, "Tree id %lu, page index id %lu fold %lu\n",
				ut_dulint_get_low(tree_id),
				ut_dulint_get_low(btr_page_get_index_id(page)),
				fold);
*/				
	} else {
	/* If we only have the latch on btr_search_latch, not on the
	page, it only protects the columns of the record the cursor
	is positioned on. We cannot look at the next of the previous
	record to determine if our guess for the cursor position is
	right. */

		success = btr_search_check_guess(cursor,
				               can_only_compare_to_cursor_rec,
					       tuple, mode, mtr);
	}
	
	if (!success) {
		if (!has_search_latch) {
	if (UNIV_EXPECT(ut_dulint_cmp(tree_id, btr_page_get_index_id(page)), 0)
	    || !btr_search_check_guess(cursor, can_only_compare_to_cursor_rec,
					       tuple, mode, mtr)) {
		if (UNIV_LIKELY(!has_search_latch)) {
		          btr_leaf_page_release(page, latch_mode, mtr);
		}

		goto failure;
	}

	if (info->n_hash_potential < BTR_SEARCH_BUILD_LIMIT + 5) {
	if (UNIV_LIKELY(info->n_hash_potential < BTR_SEARCH_BUILD_LIMIT + 5)) {
	
		info->n_hash_potential++;
	}

	if (info->last_hash_succ != TRUE) {
		info->last_hash_succ = TRUE;
	}
	
#ifdef notdefined
	/* These lines of code can be used in a debug version to check
	the correctness of the searched cursor position: */
@@ -843,15 +819,14 @@ btr_search_guess_on_hash(
	info->last_hash_succ = FALSE;

	/* Currently, does not work if the following fails: */
	ut_a(!has_search_latch);
	ut_ad(!has_search_latch);
	
	btr_leaf_page_release(page, latch_mode, mtr);

	btr_cur_search_to_nth_level(index, 0, tuple, mode, latch_mode,
							&cursor2, 0, mtr);
	if (mode == PAGE_CUR_GE
		&& btr_cur_get_rec(&cursor2) == page_get_supremum_rec(
			buf_frame_align(btr_cur_get_rec(&cursor2)))) {
		&& page_rec_is_supremum(btr_cur_get_rec(&cursor2))) {

		/* If mode is PAGE_CUR_GE, then the binary search
		in the index tree may actually take us to the supremum
@@ -861,22 +836,22 @@ btr_search_guess_on_hash(

		btr_pcur_open_on_user_rec(index, tuple, mode, latch_mode,
				&pcur, mtr);
		ut_a(btr_pcur_get_rec(&pcur) == btr_cur_get_rec(cursor));
		ut_ad(btr_pcur_get_rec(&pcur) == btr_cur_get_rec(cursor));
	} else {
		ut_a(btr_cur_get_rec(&cursor2) == btr_cur_get_rec(cursor));
		ut_ad(btr_cur_get_rec(&cursor2) == btr_cur_get_rec(cursor));
	}

	/* NOTE that it is theoretically possible that the above assertions
	fail if the page of the cursor gets removed from the buffer pool
	meanwhile! Thus it might not be a bug. */

	info->last_hash_succ = TRUE;
#endif
	info->last_hash_succ = TRUE;

#ifdef UNIV_SEARCH_PERF_STAT
	btr_search_n_succ++;
#endif
	if (!has_search_latch && buf_block_peek_if_too_old(block)) {
	if (UNIV_LIKELY(!has_search_latch)
			&& buf_block_peek_if_too_old(block)) {

		buf_page_make_young(page);
	}	
@@ -889,6 +864,10 @@ btr_search_guess_on_hash(
	return(TRUE);	

	/*-------------------------------------------*/
failure_unlock:
	if (UNIV_LIKELY(!has_search_latch)) {
		rw_lock_s_unlock(&btr_search_latch);
	}
failure:
	info->n_hash_fail++;

@@ -917,7 +896,6 @@ btr_search_drop_page_hash_index(
	ulint		n_fields;
	ulint		n_bytes;
	rec_t*		rec;
	rec_t*		sup;
	ulint		fold;
	ulint		prev_fold;
	dulint		tree_id;
@@ -968,12 +946,10 @@ btr_search_drop_page_hash_index(

	n_cached = 0;

	sup = page_get_supremum_rec(page);

	rec = page_get_infimum_rec(page);
	rec = page_rec_get_next(rec);

	if (rec != sup) {
	if (!page_rec_is_supremum(rec)) {
		ut_a(n_fields <= rec_get_n_fields(rec, block->index));

		if (n_bytes > 0) {
@@ -988,7 +964,7 @@ btr_search_drop_page_hash_index(
	heap = NULL;
	offsets = NULL;

	while (rec != sup) {
	while (!page_rec_is_supremum(rec)) {
		/* FIXME: in a mixed tree, not all records may have enough
		ordering fields: */
		offsets = rec_get_offsets(rec, block->index,
@@ -1010,7 +986,7 @@ btr_search_drop_page_hash_index(
		prev_fold = fold;
	}

	if (heap) {
	if (UNIV_LIKELY_NULL(heap)) {
		mem_heap_free(heap);
	}

@@ -1090,7 +1066,6 @@ btr_search_build_page_hash_index(
	buf_block_t*	block;
	rec_t*		rec;
	rec_t*		next_rec;
	rec_t*		sup;
	ulint		fold;
	ulint		next_fold;
	dulint		tree_id;
@@ -1158,15 +1133,13 @@ btr_search_build_page_hash_index(

	tree_id = btr_page_get_index_id(page);

	sup = page_get_supremum_rec(page);

	rec = page_get_infimum_rec(page);
	rec = page_rec_get_next(rec);

	offsets = rec_get_offsets(rec, index, offsets,
					n_fields + (n_bytes > 0), &heap);

	if (rec != sup) {
	if (!page_rec_is_supremum(rec)) {
		ut_a(n_fields <= rec_offs_n_fields(offsets));

		if (n_bytes > 0) {
@@ -1188,7 +1161,7 @@ btr_search_build_page_hash_index(
	for (;;) {
		next_rec = page_rec_get_next(rec);

		if (next_rec == sup) {
		if (page_rec_is_supremum(next_rec)) {

			if (side == BTR_SEARCH_RIGHT_SIDE) {
	
@@ -1252,7 +1225,7 @@ btr_search_build_page_hash_index(

	mem_free(folds);
	mem_free(recs);
	if (heap) {
	if (UNIV_LIKELY_NULL(heap)) {
		mem_heap_free(heap);
	}
}
@@ -1370,7 +1343,7 @@ btr_search_update_hash_on_delete(
	fold = rec_fold(rec, rec_get_offsets(rec, cursor->index, offsets_,
				ULINT_UNDEFINED, &heap), block->curr_n_fields,
				block->curr_n_bytes, tree_id);
	if (heap) {
	if (UNIV_LIKELY_NULL(heap)) {
		mem_heap_free(heap);
	}
	rw_lock_x_lock(&btr_search_latch);
@@ -1443,7 +1416,6 @@ btr_search_update_hash_on_insert(
{
	hash_table_t*	table; 
	buf_block_t*	block;
	page_t*		page;
	rec_t*		rec;
	rec_t*		ins_rec;
	rec_t*		next_rec;
@@ -1488,19 +1460,18 @@ btr_search_update_hash_on_insert(
	ins_rec = page_rec_get_next(rec);
	next_rec = page_rec_get_next(ins_rec);

	page = buf_frame_align(rec);
	offsets = rec_get_offsets(ins_rec, cursor->index, offsets,
					ULINT_UNDEFINED, &heap);
	ins_fold = rec_fold(ins_rec, offsets, n_fields, n_bytes, tree_id);

	if (next_rec != page_get_supremum_rec(page)) {
	if (!page_rec_is_supremum(next_rec)) {
		offsets = rec_get_offsets(next_rec, cursor->index, offsets,
					n_fields + (n_bytes > 0), &heap);
		next_fold = rec_fold(next_rec, offsets, n_fields,
							n_bytes, tree_id);
	}

	if (rec != page_get_infimum_rec(page)) {
	if (!page_rec_is_infimum(rec)) {
		offsets = rec_get_offsets(rec, cursor->index, offsets,
					n_fields + (n_bytes > 0), &heap);
		fold = rec_fold(rec, offsets, n_fields, n_bytes, tree_id);
@@ -1534,7 +1505,7 @@ btr_search_update_hash_on_insert(
	}

check_next_rec:
	if (next_rec == page_get_supremum_rec(page)) {
	if (page_rec_is_supremum(next_rec)) {

		if (side == BTR_SEARCH_RIGHT_SIDE) {

@@ -1573,7 +1544,7 @@ btr_search_update_hash_on_insert(
	}	
		
function_exit:
	if (heap) {
	if (UNIV_LIKELY_NULL(heap)) {
		mem_heap_free(heap);
	}
	if (locked) {
@@ -1662,7 +1633,7 @@ btr_search_validate(void)
	}

	rw_lock_x_unlock(&btr_search_latch);
	if (heap) {
	if (UNIV_LIKELY_NULL(heap)) {
		mem_heap_free(heap);
	}

+22 −14

File changed.

Preview size limit exceeded, changes collapsed.

Loading