Commit 128e872f authored by heikki@hundin.mysql.fi's avatar heikki@hundin.mysql.fi
Browse files

Many files:

  Merge 3.23.52
parent 8056af30
Loading
Loading
Loading
Loading
+22 −5
Original line number Diff line number Diff line
@@ -573,6 +573,13 @@ btr_page_get_father_for_rec(
	if (btr_node_ptr_get_child_page_no(node_ptr) !=
                                                buf_frame_get_page_no(page)) {
		fprintf(stderr,
"InnoDB: Dump of the child page:\n");
		buf_page_print(buf_frame_align(page));
		fprintf(stderr,
"InnoDB: Dump of the parent page:\n");
		buf_page_print(buf_frame_align(node_ptr));

      		fprintf(stderr,
"InnoDB: Corruption of an index tree: table %s, index %s,\n"
"InnoDB: father ptr page no %lu, child page no %lu\n",
                    (UT_LIST_GET_FIRST(tree->tree_indexes))->table_name,
@@ -581,6 +588,12 @@ btr_page_get_father_for_rec(
                    buf_frame_get_page_no(page));
     		page_rec_print(page_rec_get_next(page_get_infimum_rec(page)));
     		page_rec_print(node_ptr);

      		fprintf(stderr,
"InnoDB: You should dump + drop + reimport the table to fix the\n"
"InnoDB: corruption. If the crash happens at the database startup, see\n"
"InnoDB: section 6.1 of http://www.innodb.com/ibman.html about forcing\n"
"InnoDB: recovery. Then dump + drop + reimport.\n");
	}

	ut_a(btr_node_ptr_get_child_page_no(node_ptr) ==
@@ -780,12 +793,14 @@ btr_free_root(

/*****************************************************************
Reorganizes an index page. */

static
void
btr_page_reorganize_low(
/*====================*/
	ibool	low,	/* in: TRUE if locks should not be updated, i.e.,
			there cannot exist locks on the page */
	ibool	recovery,/* in: TRUE if called in recovery: locks should not
			be updated, i.e., there cannot exist locks on the
			page, and a hash index should not be dropped: it
			cannot exist */
	page_t*	page,	/* in: page to be reorganized */
	mtr_t*	mtr)	/* in: mtr */
{
@@ -805,7 +820,9 @@ btr_page_reorganize_low(
	/* Copy the old page to temporary space */
	buf_frame_copy(new_page, page);

	if (!recovery) {
		btr_search_drop_page_hash_index(page);
	}

	/* Recreate the page: note that global data on page (possible
	segment headers, next page-field, etc.) is preserved intact */
@@ -820,7 +837,7 @@ btr_page_reorganize_low(
	/* Copy max trx id to recreated page */
	page_set_max_trx_id(page, page_get_max_trx_id(new_page));
	
	if (!low) {
	if (!recovery) {
		/* Update the record lock bitmaps */
		lock_move_reorganize_page(page, new_page);
	}
+72 −13
Original line number Diff line number Diff line
@@ -36,9 +36,14 @@ Created 10/16/1994 Heikki Tuuri
#include "ibuf0ibuf.h"
#include "lock0lock.h"

/* If the following is set to TRUE, this module prints a lot of
trace information of individual record operations */
ibool	btr_cur_print_record_ops = FALSE;

ulint	btr_cur_rnd	= 0;

ulint	btr_cur_n_non_sea	= 0;
ulint	btr_cur_n_sea		= 0;

/* In the optimistic insert, if the insert does not fit, but this much space
can be released by page reorganize, then it is reorganized */
@@ -187,11 +192,7 @@ btr_cur_search_to_nth_level(
				tuple must be set so that it cannot get
				compared to the node ptr page number field! */
	ulint		mode,	/* in: PAGE_CUR_L, ...;
				NOTE that if the search is made using a unique
				prefix of a record, mode should be
				PAGE_CUR_LE, not PAGE_CUR_GE, as the latter
				may end up on the previous page relative to the
				record! Inserts should always be made using
				Inserts should always be made using
				PAGE_CUR_LE to search the position! */
	ulint		latch_mode, /* in: BTR_SEARCH_LEAF, ..., ORed with
				BTR_INSERT and BTR_ESTIMATE;
@@ -268,7 +269,7 @@ btr_cur_search_to_nth_level(
#ifdef UNIV_SEARCH_PERF_STAT
	info->n_searches++;
#endif	
	if (btr_search_latch.writer != RW_LOCK_NOT_LOCKED
	if (btr_search_latch.writer == RW_LOCK_NOT_LOCKED
		&& latch_mode <= BTR_MODIFY_LEAF && info->last_hash_succ
		&& !estimate
	        && btr_search_guess_on_hash(index, info, tuple, mode,
@@ -283,14 +284,14 @@ btr_cur_search_to_nth_level(
					|| mode != PAGE_CUR_LE);
		ut_ad(cursor->low_match != ULINT_UNDEFINED
					|| mode != PAGE_CUR_LE);
		btr_cur_n_sea++;

	        return;
	}
#endif
#endif

#ifdef UNIV_SEARCH_PERF_STAT
	btr_cur_n_non_sea++;
#endif

	/* If the hash search did not succeed, do binary search down the
	tree */

@@ -798,13 +799,26 @@ btr_cur_optimistic_insert(
	ulint		type;
	ulint		err;	

	ut_ad(dtuple_check_typed(entry));

	*big_rec = NULL;

	page = btr_cur_get_page(cursor);
	index = cursor->index;

	if (!dtuple_check_typed_no_assert(entry)) {
		fprintf(stderr,
"InnoDB: Error in a tuple to insert into table %lu index %lu\n",
					index->table_name, index->name);
	}
	
	if (btr_cur_print_record_ops && thr) {
		printf(
	"Trx with id %lu %lu going to insert to table %s index %s\n",
		ut_dulint_get_high(thr_get_trx(thr)->id),
		ut_dulint_get_low(thr_get_trx(thr)->id),
		index->table_name, index->name);
		dtuple_print(entry);
	}
	
	ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
							MTR_MEMO_PAGE_X_FIX));
	max_size = page_get_max_insert_size_after_reorganize(page, 1);
@@ -928,7 +942,7 @@ btr_cur_optimistic_insert(
			buf_frame_get_page_no(page), max_size,
					rec_size + PAGE_DIR_SLOT_SIZE, type);
*/	
	if (!(type & (DICT_CLUSTERED | DICT_UNIQUE))) {
	if (!(type & DICT_CLUSTERED)) {
		/* We have added a record to page: update its free bits */
		ibuf_update_free_bits_if_full(cursor->index, page, max_size,
					rec_size + PAGE_DIR_SLOT_SIZE);
@@ -1258,6 +1272,15 @@ btr_cur_update_sec_rec_in_place(

	rec = btr_cur_get_rec(cursor);
	
	if (btr_cur_print_record_ops && thr) {
		printf(
	"Trx with id %lu %lu going to update table %s index %s\n",
		ut_dulint_get_high(thr_get_trx(thr)->id),
		ut_dulint_get_low(thr_get_trx(thr)->id),
		index->table_name, index->name);
		rec_print(rec);
	}

	err = lock_sec_rec_modify_check_and_lock(0, rec, index, thr);

	if (err != DB_SUCCESS) {
@@ -1312,6 +1335,15 @@ btr_cur_update_in_place(
	index = cursor->index;
	trx = thr_get_trx(thr);
	
	if (btr_cur_print_record_ops && thr) {
		printf(
	"Trx with id %lu %lu going to update table %s index %s\n",
		ut_dulint_get_high(thr_get_trx(thr)->id),
		ut_dulint_get_low(thr_get_trx(thr)->id),
		index->table_name, index->name);
		rec_print(rec);
	}

	/* Do lock checking and undo logging */
	err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info,
							thr, &roll_ptr);
@@ -1398,6 +1430,15 @@ btr_cur_optimistic_update(
	rec = btr_cur_get_rec(cursor);
	index = cursor->index;
	
	if (btr_cur_print_record_ops && thr) {
		printf(
	"Trx with id %lu %lu going to update table %s index %s\n",
		ut_dulint_get_high(thr_get_trx(thr)->id),
		ut_dulint_get_low(thr_get_trx(thr)->id),
		index->table_name, index->name);
		rec_print(rec);
	}

	ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
							MTR_MEMO_PAGE_X_FIX));
	if (!row_upd_changes_field_size(rec, index, update)) {
@@ -1973,6 +2014,15 @@ btr_cur_del_mark_set_clust_rec(
	rec = btr_cur_get_rec(cursor);
	index = cursor->index;
	
	if (btr_cur_print_record_ops && thr) {
		printf(
	"Trx with id %lu %lu going to del mark table %s index %s\n",
		ut_dulint_get_high(thr_get_trx(thr)->id),
		ut_dulint_get_low(thr_get_trx(thr)->id),
		index->table_name, index->name);
		rec_print(rec);
	}

	ut_ad(index->type & DICT_CLUSTERED);
	ut_ad(rec_get_deleted_flag(rec) == FALSE);

@@ -2102,6 +2152,15 @@ btr_cur_del_mark_set_sec_rec(

	rec = btr_cur_get_rec(cursor);

	if (btr_cur_print_record_ops && thr) {
		printf(
	"Trx with id %lu %lu going to del mark table %s index %s\n",
		ut_dulint_get_high(thr_get_trx(thr)->id),
		ut_dulint_get_low(thr_get_trx(thr)->id),
		cursor->index->table_name, cursor->index->name);
		rec_print(rec);
	}

	err = lock_sec_rec_modify_check_and_lock(flags, rec, cursor->index,
									thr);
	if (err != DB_SUCCESS) {
+65 −14
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ Created 2/17/1996 Heikki Tuuri
#include "page0page.h"
#include "page0cur.h"
#include "btr0cur.h"
#include "btr0pcur.h"
#include "btr0btr.h"

ulint	btr_search_n_succ	= 0;
@@ -145,6 +146,8 @@ btr_search_info_create(

	info = mem_heap_alloc(heap, sizeof(btr_search_t));

	info->magic_n = BTR_SEARCH_MAGIC_N;

	info->last_search = NULL;
	info->n_direction = 0;
	info->root_guess = NULL;
@@ -159,6 +162,12 @@ btr_search_info_create(
	info->n_patt_succ = 0;	
	info->n_searches = 0;	

	/* Set some sensible values */
	info->n_fields = 1;
	info->n_bytes = 0;

	info->side = BTR_SEARCH_LEFT_SIDE;

	return(info);
}

@@ -197,7 +206,7 @@ btr_search_info_update_hash(
	/* Test if the search would have succeeded using the recommended
	hash prefix */

	if ((info->n_fields >= n_unique) && (cursor->up_match >= n_unique)) {
	if (info->n_fields >= n_unique && cursor->up_match >= n_unique) {
			
		info->n_hash_potential++;

@@ -207,8 +216,8 @@ btr_search_info_update_hash(
	cmp = ut_pair_cmp(info->n_fields, info->n_bytes,
					cursor->low_match, cursor->low_bytes);

	if (((info->side == BTR_SEARCH_LEFT_SIDE) && (cmp <= 0))
		|| ((info->side == BTR_SEARCH_RIGHT_SIDE) && (cmp > 0))) {
	if ((info->side == BTR_SEARCH_LEFT_SIDE && cmp <= 0)
		|| (info->side == BTR_SEARCH_RIGHT_SIDE && cmp > 0)) {

		goto set_new_recomm;
	}
@@ -216,8 +225,8 @@ btr_search_info_update_hash(
	cmp = ut_pair_cmp(info->n_fields, info->n_bytes,
					cursor->up_match, cursor->up_bytes);

	if (((info->side == BTR_SEARCH_LEFT_SIDE) && (cmp > 0))
		|| ((info->side == BTR_SEARCH_RIGHT_SIDE) && (cmp <= 0))) {
	if ((info->side == BTR_SEARCH_LEFT_SIDE && cmp > 0)
		|| (info->side == BTR_SEARCH_RIGHT_SIDE && cmp <= 0)) {

	    	goto set_new_recomm;
	}
@@ -233,19 +242,18 @@ btr_search_info_update_hash(
	
	info->hash_analysis = 0;
	
	if ((cursor->up_match >= n_unique)
					|| (cursor->low_match >= n_unique)) {
		info->n_fields = n_unique;
		info->n_bytes = 0;

		info->side = BTR_SEARCH_LEFT_SIDE;
	}

	cmp = ut_pair_cmp(cursor->up_match, cursor->up_bytes,
					cursor->low_match, cursor->low_bytes);
	if (cmp == 0) {
		info->n_hash_potential = 0;

		/* For extra safety, we set some sensible values here */

		info->n_fields = 1;
		info->n_bytes = 0;

		info->side = BTR_SEARCH_LEFT_SIDE;

	} else if (cmp > 0) {
		info->n_hash_potential = 1;

@@ -305,6 +313,9 @@ btr_search_update_block_hash_info(

	info->last_hash_succ = FALSE;

	ut_a(block->magic_n == BUF_BLOCK_MAGIC_N);
	ut_a(info->magic_n == BTR_SEARCH_MAGIC_N);

	if ((block->n_hash_helps > 0)
	    && (info->n_hash_potential > 0)
	    && (block->n_fields == info->n_fields)
@@ -622,6 +633,7 @@ btr_search_guess_on_hash(
	dulint		tree_id;
#ifdef notdefined
	btr_cur_t	cursor2;
	btr_pcur_t	pcur;
#endif
	ut_ad(index && info && tuple && cursor && mtr);
	ut_ad((latch_mode == BTR_SEARCH_LEAF)
@@ -754,7 +766,26 @@ btr_search_guess_on_hash(

	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)))) {

		/* If mode is PAGE_CUR_GE, then the binary search
		in the index tree may actually take us to the supremum
		of the previous page */
					
		info->last_hash_succ = FALSE;

		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));
	} else {
		ut_a(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
@@ -835,6 +866,8 @@ btr_search_drop_page_hash_index(
	n_fields = block->curr_n_fields;
	n_bytes = block->curr_n_bytes;

	ut_a(n_fields + n_bytes > 0);

	rw_lock_s_unlock(&btr_search_latch);
	
	n_recs = page_get_n_recs(page);
@@ -851,6 +884,14 @@ btr_search_drop_page_hash_index(
	rec = page_get_infimum_rec(page);
	rec = page_rec_get_next(rec);

	if (rec != sup) {
		ut_a(n_fields <= rec_get_n_fields(rec));

		if (n_bytes > 0) {
			ut_a(n_fields < rec_get_n_fields(rec));
		}
	}

	tree_id = btr_page_get_index_id(page);
	
	prev_fold = 0;
@@ -980,6 +1021,8 @@ btr_search_build_page_hash_index(
		return;
	}

	ut_a(n_fields + n_bytes > 0);

	/* Calculate and cache fold values and corresponding records into
	an array for fast insertion to the hash index */

@@ -995,6 +1038,14 @@ btr_search_build_page_hash_index(
	rec = page_get_infimum_rec(page);
	rec = page_rec_get_next(rec);

	if (rec != sup) {
		ut_a(n_fields <= rec_get_n_fields(rec));

		if (n_bytes > 0) {
			ut_a(n_fields < rec_get_n_fields(rec));
		}
	}

	/* FIXME: in a mixed tree, all records may not have enough ordering
	fields: */
	
+41 −1
Original line number Diff line number Diff line
@@ -1125,13 +1125,51 @@ buf_page_get_known_nowait(
	return(TRUE);
}

/************************************************************************
Inits a page to the buffer buf_pool, for use in ibbackup --restore. */

void
buf_page_init_for_backup_restore(
/*=============================*/
	ulint		space,	/* in: space id */
	ulint		offset,	/* in: offset of the page within space
				in units of a page */
	buf_block_t*	block)	/* in: block to init */
{
	/* Set the state of the block */
	block->magic_n		= BUF_BLOCK_MAGIC_N;

	block->state 		= BUF_BLOCK_FILE_PAGE;
	block->space 		= space;
	block->offset 		= offset;

	block->lock_hash_val	= 0;
	block->lock_mutex	= NULL;
	
	block->freed_page_clock = 0;

	block->newest_modification = ut_dulint_zero;
	block->oldest_modification = ut_dulint_zero;
	
	block->accessed		= FALSE;
	block->buf_fix_count 	= 0;
	block->io_fix		= 0;

	block->n_hash_helps	= 0;
	block->is_hashed	= FALSE;
	block->n_fields         = 1;
	block->n_bytes          = 0;
	block->side             = BTR_SEARCH_LEFT_SIDE;

	block->file_page_was_freed = FALSE;
}

/************************************************************************
Inits a page to the buffer buf_pool. */
static
void
buf_page_init(
/*==========*/
				/* out: pointer to the block */
	ulint		space,	/* in: space id */
	ulint		offset,	/* in: offset of the page within space
				in units of a page */
@@ -1141,6 +1179,8 @@ buf_page_init(
	ut_ad(block->state == BUF_BLOCK_READY_FOR_USE);

	/* Set the state of the block */
	block->magic_n		= BUF_BLOCK_MAGIC_N;

	block->state 		= BUF_BLOCK_FILE_PAGE;
	block->space 		= space;
	block->offset 		= offset;
+29 −0
Original line number Diff line number Diff line
@@ -100,6 +100,11 @@ buf_read_page_low(
	block = buf_page_init_for_read(mode, space, offset);

	if (block != NULL) {
		if (buf_debug_prints) {
			printf("Posting read request for page %lu, sync %lu\n",
				offset, sync);
		}

		fil_io(OS_FILE_READ | wake_later,
			sync, space, offset, 0, UNIV_PAGE_SIZE,
					(void*)block->frame, (void*)block);
@@ -467,6 +472,12 @@ buf_read_ahead_linear(

	count = 0;

	/* Since Windows XP seems to schedule the i/o handler thread
	very eagerly, and consequently it does not wait for the
	full read batch to be posted, we use special heuristics here */

	os_aio_simulated_put_read_threads_to_sleep();
	
	for (i = low; i < high; i++) {
		/* It is only sensible to do read-ahead in the non-sync
		aio mode: hence FALSE as the first parameter */
@@ -556,16 +567,34 @@ buf_read_recv_pages(
				highest page number the last in the array */
	ulint	n_stored)	/* in: number of page numbers in the array */
{
	ulint	count;
	ulint	i;

	for (i = 0; i < n_stored; i++) {

		count = 0;

		os_aio_print_debug = FALSE;

		while (buf_pool->n_pend_reads >= RECV_POOL_N_FREE_BLOCKS / 2) {

			os_aio_simulated_wake_handler_threads();
			os_thread_sleep(500000);

			count++;

			if (count > 100) {
				fprintf(stderr,
"InnoDB: Error: InnoDB has waited for 50 seconds for pending\n"
"InnoDB: reads to the buffer pool to be finished.\n"
"InnoDB: Number of pending reads %lu\n", buf_pool->n_pend_reads);

				os_aio_print_debug = TRUE;
			}
		}

		os_aio_print_debug = FALSE;

		if ((i + 1 == n_stored) && sync) {
			buf_read_page_low(TRUE, BUF_READ_ANY_PAGE, space,
								page_nos[i]);
Loading