Commit 38a4648a authored by monty@work.mysql.com's avatar monty@work.mysql.com
Browse files

merge

parents 24b9e879 1d7747aa
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -2347,6 +2347,8 @@ btr_validate_level(
	
	mtr_start(&mtr);

	mtr_x_lock(dict_tree_get_lock(tree), &mtr);
	
	page = btr_root_get(tree, &mtr);

	space = buf_frame_get_space_id(page);
+92 −38
Original line number Diff line number Diff line
@@ -256,7 +256,8 @@ btr_cur_search_to_nth_level(
#ifdef UNIV_SEARCH_PERF_STAT
	info->n_searches++;
#endif	
	if (latch_mode <= BTR_MODIFY_LEAF && info->last_hash_succ
	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,
						latch_mode, cursor,
@@ -344,9 +345,7 @@ btr_cur_search_to_nth_level(
retry_page_get:		
		page = buf_page_get_gen(space, page_no, rw_latch, guess,
					buf_mode,
#ifdef UNIV_SYNC_DEBUG
					IB__FILE__, __LINE__,
#endif
					mtr);

		if (page == NULL) {
@@ -515,9 +514,7 @@ btr_cur_open_at_index_side(
	for (;;) {
		page = buf_page_get_gen(space, page_no, RW_NO_LATCH, NULL,
					BUF_GET,
#ifdef UNIV_SYNC_DEBUG
					IB__FILE__, __LINE__,
#endif
					mtr);
		ut_ad(0 == ut_dulint_cmp(tree->id,
						btr_page_get_index_id(page)));
@@ -604,9 +601,7 @@ btr_cur_open_at_rnd_pos(
	for (;;) {
		page = buf_page_get_gen(space, page_no, RW_NO_LATCH, NULL,
					BUF_GET,
#ifdef UNIV_SYNC_DEBUG
					IB__FILE__, __LINE__,
#endif
					mtr);
		ut_ad(0 == ut_dulint_cmp(tree->id,
						btr_page_get_index_id(page)));
@@ -1222,6 +1217,57 @@ btr_cur_parse_update_in_place(
	return(ptr);
}

/*****************************************************************
Updates a secondary index record when the update causes no size
changes in its fields. The only case when this function is currently
called is that in a char field characters change to others which
are identified in the collation order. */

ulint
btr_cur_update_sec_rec_in_place(
/*============================*/
				/* out: DB_SUCCESS or error number */
	btr_cur_t*	cursor,	/* in: cursor on the record to update;
				cursor stays valid and positioned on the
				same record */
	upd_t*		update,	/* in: update vector */
	que_thr_t*	thr,	/* in: query thread */
	mtr_t*		mtr)	/* in: mtr */
{
	dict_index_t*	index 		= cursor->index;
	dict_index_t*	clust_index;
	ulint		err;
	rec_t*		rec;
	dulint		roll_ptr	= ut_dulint_zero;
	trx_t*		trx		= thr_get_trx(thr);

	/* Only secondary index records are updated using this function */
	ut_ad(0 == (index->type & DICT_CLUSTERED));

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

	if (err != DB_SUCCESS) {

		return(err);
	}

	/* Remove possible hash index pointer to this record */
	btr_search_update_hash_on_delete(cursor);

	row_upd_rec_in_place(rec, update);

	clust_index = dict_table_get_first_index(index->table);

	/* Note that roll_ptr is really just a dummy value since
	a secondary index record does not contain any sys columns */

	btr_cur_update_in_place_log(BTR_KEEP_SYS_FLAG, rec, clust_index,
						update, trx, roll_ptr, mtr);
	return(DB_SUCCESS);
}

/*****************************************************************
Updates a record when the update causes no size changes in its fields. */

@@ -1248,7 +1294,7 @@ btr_cur_update_in_place(
	ibool		was_delete_marked;

	/* Only clustered index records are updated using this function */
	ut_ad((cursor->index)->type & DICT_CLUSTERED);
	ut_ad(cursor->index->type & DICT_CLUSTERED);

	rec = btr_cur_get_rec(cursor);
	index = cursor->index;
@@ -2477,27 +2523,33 @@ btr_estimate_n_rows_in_range(
}

/***********************************************************************
Estimates the number of different key values in a given index. */
Estimates the number of different key values in a given index, for
each n-column prefix of the index where n <= dict_index_get_n_unique(index).
The estimates are stored in the array index->stat_n_diff_key_vals. */

ulint
void
btr_estimate_number_of_different_key_vals(
/*======================================*/
				/* out: estimated number of key values */
	dict_index_t*	index)	/* in: index */
{
	btr_cur_t	cursor;
	page_t*		page;
	rec_t*		rec;
	ulint		total_n_recs		= 0;
	ulint		n_diff_in_page;
	ulint		n_diff			= 0;
	ulint		n_cols;
	ulint		matched_fields;
	ulint		matched_bytes;
	ulint*		n_diff;
	ulint		not_empty_flag	= 0;
	ulint		i;
	ulint		j;
	mtr_t		mtr;

	if (index->type & DICT_UNIQUE) {
		return(index->table->stat_n_rows);
	n_cols = dict_index_get_n_unique(index);

	n_diff = mem_alloc((n_cols + 1) * sizeof(ib_longlong));

	for (j = 0; j <= n_cols; j++) {
		n_diff[j] = 0;
	}

	/* We sample some pages in the index to get an estimate */
@@ -2507,17 +2559,19 @@ btr_estimate_number_of_different_key_vals(

		btr_cur_open_at_rnd_pos(index, BTR_SEARCH_LEAF, &cursor, &mtr);
		
		/* Count the number of different key values minus one on this
		index page: we subtract one because otherwise our algorithm
		would give a wrong estimate for an index where there is
		just one key value */
		/* Count the number of different key values minus one
		for each prefix of the key on this index page: we subtract
		one because otherwise our algorithm would give a wrong
		estimate for an index where there is just one key value */

		page = btr_cur_get_page(&cursor);

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

		n_diff_in_page = 0;
		if (rec != page_get_supremum_rec(page)) {
			not_empty_flag = 1;
		}
		
		while (rec != page_get_supremum_rec(page)
		       && page_rec_get_next(rec)
@@ -2528,30 +2582,30 @@ btr_estimate_number_of_different_key_vals(
			cmp_rec_rec_with_match(rec, page_rec_get_next(rec),
						index, &matched_fields,
						&matched_bytes);
			if (matched_fields <
				dict_index_get_n_ordering_defined_by_user(
								index)) {
				n_diff_in_page++;

			for (j = matched_fields + 1; j <= n_cols; j++) {
				n_diff[j]++;
			}
					
			rec = page_rec_get_next(rec);
		}
		
		n_diff += n_diff_in_page;
		
		total_n_recs += page_get_n_recs(page);
		
		mtr_commit(&mtr);
	}

	if (n_diff == 0) {
		/* We play safe and assume that there are just two different
		key values in the index */
	/* If we saw k borders between different key values on
	BTR_KEY_VAL_ESTIMATE_N_PAGES leaf pages, we can estimate how many
	there will be in index->stat_n_leaf_pages */
	
		return(2);
	for (j = 0; j <= n_cols; j++) {
		index->stat_n_diff_key_vals[j] =
				(n_diff[j] * index->stat_n_leaf_pages
				 + BTR_KEY_VAL_ESTIMATE_N_PAGES - 1
				 + not_empty_flag)
		                	/ BTR_KEY_VAL_ESTIMATE_N_PAGES;
	}
	
	return(index->table->stat_n_rows / (total_n_recs / n_diff));
	mem_free(n_diff);
}

/*================== EXTERNAL STORAGE OF BIG FIELDS ===================*/
+52 −18
Original line number Diff line number Diff line
@@ -62,8 +62,10 @@ btr_pcur_free_for_mysql(
/******************************************************************
The position of the cursor is stored by taking an initial segment of the
record the cursor is positioned on, before, or after, and copying it to the
cursor data structure. NOTE that the page where the cursor is positioned
must not be empty! */
cursor data structure, or just setting a flag if the cursor id before the
first in an EMPTY tree, or after the last in an EMPTY tree. NOTE that the
page where the cursor is positioned must not be empty if the index tree is
not totally empty! */

void
btr_pcur_store_position(
@@ -93,9 +95,21 @@ btr_pcur_store_position(
	ut_a(cursor->latch_mode != BTR_NO_LATCHES);

	if (page_get_n_recs(page) == 0) {
		/* It must be an empty index tree */

		/* Cannot store position! */
		btr_pcur_close(cursor);
		ut_a(btr_page_get_next(page, mtr) == FIL_NULL
		     && 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;
		}

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

		return;
	} 
@@ -140,13 +154,15 @@ btr_pcur_copy_stored_position(

	ut_memcpy((byte*)pcur_receive, (byte*)pcur_donate, sizeof(btr_pcur_t));

	if (pcur_donate->old_rec_buf) {

		pcur_receive->old_rec_buf = mem_alloc(pcur_donate->buf_size);
	
		ut_memcpy(pcur_receive->old_rec_buf, pcur_donate->old_rec_buf,
						pcur_donate->buf_size);
		pcur_receive->old_rec = pcur_receive->old_rec_buf
			+ (pcur_donate->old_rec - pcur_donate->old_rec_buf);
	
	}	
}

/******************************************************************
@@ -158,7 +174,9 @@ to the last record LESS OR EQUAL to the stored record;
the last record LESS than the user record which was the successor of the page
infimum;
(3) cursor was positioned on the page supremum: restores to the first record
GREATER than the user record which was the predecessor of the supremum. */
GREATER than the user record which was the predecessor of the supremum.
(4) cursor was positioned before the first or after the last in an empty tree:
restores to before first or after the last in the tree. */

ibool
btr_pcur_restore_position(
@@ -177,17 +195,33 @@ 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));
	ut_a(cursor->pos_state == BTR_PCUR_WAS_POSITIONED
			|| cursor->pos_state == BTR_PCUR_IS_POSITIONED);
	ut_a(cursor->old_stored == BTR_PCUR_OLD_STORED);

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

	    	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_pcur_get_btr_cur(cursor)->index, latch_mode,
					btr_pcur_get_btr_cur(cursor), mtr);
		return(FALSE);
	}
	
	ut_a(cursor->old_rec);

	page = btr_cur_get_page(btr_pcur_get_btr_cur(cursor));

	if ((latch_mode == BTR_SEARCH_LEAF)
					|| (latch_mode == BTR_MODIFY_LEAF)) {
	if (latch_mode == BTR_SEARCH_LEAF || latch_mode == BTR_MODIFY_LEAF) {
		/* Try optimistic restoration */
	    
		if (buf_page_optimistic_get(latch_mode, page,
@@ -242,16 +276,15 @@ btr_pcur_restore_position(
	/* Restore the old search mode */
	cursor->search_mode = old_mode;

	if ((cursor->rel_pos == BTR_PCUR_ON)
	if (cursor->rel_pos == BTR_PCUR_ON
	    && btr_pcur_is_on_user_rec(cursor, mtr)
		&& (0 == cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor)))) {
	    && 0 == cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor))) {

	        /* We have to store the NEW value for the modify clock, since
	        the cursor can now be on a different page! */

	        cursor->modify_clock = buf_frame_get_modify_clock(
				    buf_frame_align(
						    btr_pcur_get_rec(cursor)));
				    buf_frame_align(btr_pcur_get_rec(cursor)));
		mem_heap_free(heap);

		return(TRUE);
@@ -366,6 +399,7 @@ btr_pcur_move_backward_from_page(

		latch_mode2 = BTR_MODIFY_PREV;
	} else {
		latch_mode2 = 0; /* To eliminate compiler warning */
		ut_error;
	}

+0 −2
Original line number Diff line number Diff line
@@ -680,9 +680,7 @@ btr_search_guess_on_hash(

		success = buf_page_get_known_nowait(latch_mode, page,
						BUF_MAKE_YOUNG,
#ifdef UNIV_SYNC_DEBUG
						IB__FILE__, __LINE__,
#endif
						mtr);

		rw_lock_s_unlock(&btr_search_latch);
+151 −50
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@ Created 11/5/1995 Heikki Tuuri
#include "ibuf0ibuf.h"
#include "dict0dict.h"
#include "log0recv.h"
#include "trx0undo.h"
#include "srv0srv.h"

/*
		IMPLEMENTATION OF THE BUFFER POOL
@@ -240,6 +242,11 @@ buf_page_is_corrupted(

	checksum = buf_calc_page_checksum(read_buf);

	/* Note that InnoDB initializes empty pages to zero, and
	early versions of InnoDB did not store page checksum to
	the 4 most significant bytes of the page lsn field at the
	end of a page: */
	
	if ((mach_read_from_4(read_buf + FIL_PAGE_LSN + 4)
		    		!= mach_read_from_4(read_buf + UNIV_PAGE_SIZE
					- FIL_PAGE_END_LSN + 4))
@@ -256,6 +263,71 @@ buf_page_is_corrupted(
	return(FALSE);
}

/************************************************************************
Prints a page to stderr. */

void
buf_page_print(
/*===========*/
	byte*	read_buf)	/* in: a database page */
{
	dict_index_t*	index;
	ulint		checksum;
	char*		buf;
	
	buf = mem_alloc(4 * UNIV_PAGE_SIZE);

	ut_sprintf_buf(buf, read_buf, UNIV_PAGE_SIZE);

	fprintf(stderr,
	"InnoDB: Page dump in ascii and hex (%lu bytes):\n%s",
					UNIV_PAGE_SIZE, buf);
	fprintf(stderr, "InnoDB: End of page dump\n");

	mem_free(buf);

	checksum = buf_calc_page_checksum(read_buf);

	fprintf(stderr, "InnoDB: Page checksum %lu stored checksum %lu\n",
			checksum, mach_read_from_4(read_buf
                                        + UNIV_PAGE_SIZE
					- FIL_PAGE_END_LSN)); 
	fprintf(stderr,
	"InnoDB: Page lsn %lu %lu, low 4 bytes of lsn at page end %lu\n",
		mach_read_from_4(read_buf + FIL_PAGE_LSN),
		mach_read_from_4(read_buf + FIL_PAGE_LSN + 4),
		mach_read_from_4(read_buf + UNIV_PAGE_SIZE
					- FIL_PAGE_END_LSN + 4));
	if (mach_read_from_2(read_buf + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE)
	    == TRX_UNDO_INSERT) {
	    	fprintf(stderr,
			"InnoDB: Page may be an insert undo log page\n");
	} else if (mach_read_from_2(read_buf + TRX_UNDO_PAGE_HDR
						+ TRX_UNDO_PAGE_TYPE)
	    	== TRX_UNDO_UPDATE) {
	    	fprintf(stderr,
			"InnoDB: Page may be an update undo log page\n");
	}

	if (fil_page_get_type(read_buf) == FIL_PAGE_INDEX) {
	    	fprintf(stderr,
			"InnoDB: Page may be an index page ");

		fprintf(stderr,
			"where index id is %lu %lu\n",
			ut_dulint_get_high(btr_page_get_index_id(read_buf)),
			ut_dulint_get_low(btr_page_get_index_id(read_buf)));

		index = dict_index_find_on_id_low(
					btr_page_get_index_id(read_buf));
		if (index) {
			fprintf(stderr, "InnoDB: and table %s index %s\n",
						index->table_name,
						index->name);
		}
	}
}

/************************************************************************
Initializes a buffer control block when the buf_pool is created. */
static
@@ -334,6 +406,8 @@ buf_pool_create(
	frame = ut_align(buf_pool->frame_mem, UNIV_PAGE_SIZE);
	buf_pool->frame_zero = frame;

	buf_pool->high_end = frame + UNIV_PAGE_SIZE * curr_size;

	/* Init block structs and assign frames for them */
	for (i = 0; i < max_size; i++) {

@@ -345,6 +419,9 @@ buf_pool_create(
	buf_pool->page_hash = hash_create(2 * max_size);

	buf_pool->n_pend_reads = 0;

	buf_pool->last_printout_time = time(NULL);

	buf_pool->n_pages_read = 0;
	buf_pool->n_pages_written = 0;
	buf_pool->n_pages_created = 0;
@@ -352,6 +429,8 @@ buf_pool_create(
	buf_pool->n_page_gets = 0;
	buf_pool->n_page_gets_old = 0;
	buf_pool->n_pages_read_old = 0;
	buf_pool->n_pages_written_old = 0;
	buf_pool->n_pages_created_old = 0;
	
	/* 2. Initialize flushing fields
	   ---------------------------- */
@@ -379,6 +458,10 @@ buf_pool_create(
	for (i = 0; i < curr_size; i++) {

		block = buf_pool_get_nth_block(buf_pool, i);

		/* Wipe contents of page to eliminate a Purify warning */
		memset(block->frame, '\0', UNIV_PAGE_SIZE);

		UT_LIST_ADD_FIRST(free, buf_pool->free, block);
	}

@@ -650,10 +733,8 @@ buf_page_get_gen(
	buf_frame_t*	guess,	/* in: guessed frame or NULL */
	ulint		mode,	/* in: BUF_GET, BUF_GET_IF_IN_POOL,
				BUF_GET_NO_LATCH, BUF_GET_NOWAIT */
#ifdef UNIV_SYNC_DEBUG
	char*		file,	/* in: file name */
	ulint		line,	/* in: line where called */
#endif
	mtr_t*		mtr)	/* in: mini-transaction */
{
	buf_block_t*	block;
@@ -759,19 +840,13 @@ buf_page_get_gen(

	if (mode == BUF_GET_NOWAIT) {
		if (rw_latch == RW_S_LATCH) {
			success = rw_lock_s_lock_func_nowait(&(block->lock)
					#ifdef UNIV_SYNC_DEBUG
					,file, line
					#endif
			   		);
			success = rw_lock_s_lock_func_nowait(&(block->lock),
								file, line);
			fix_type = MTR_MEMO_PAGE_S_FIX;
		} else {
			ut_ad(rw_latch == RW_X_LATCH);
			success = rw_lock_x_lock_func_nowait(&(block->lock)
					#ifdef UNIV_SYNC_DEBUG
					,file, line
					#endif
			   		);
			success = rw_lock_x_lock_func_nowait(&(block->lock),
					file, line);
			fix_type = MTR_MEMO_PAGE_X_FIX;
		}

@@ -796,18 +871,12 @@ buf_page_get_gen(
		fix_type = MTR_MEMO_BUF_FIX;
	} else if (rw_latch == RW_S_LATCH) {

		rw_lock_s_lock_func(&(block->lock)
					#ifdef UNIV_SYNC_DEBUG
					,0, file, line
					#endif
			   		);
		rw_lock_s_lock_func(&(block->lock), 0, file, line);

		fix_type = MTR_MEMO_PAGE_S_FIX;
	} else {
		rw_lock_x_lock_func(&(block->lock), 0
					#ifdef UNIV_SYNC_DEBUG
					, file, line
					#endif
			   		);
		rw_lock_x_lock_func(&(block->lock), 0, file, line);

		fix_type = MTR_MEMO_PAGE_X_FIX;
	}

@@ -838,10 +907,8 @@ buf_page_optimistic_get_func(
	buf_frame_t*	guess,	/* in: guessed frame */
	dulint		modify_clock,/* in: modify clock value if mode is
				..._GUESS_ON_CLOCK */
#ifdef UNIV_SYNC_DEBUG
	char*		file,	/* in: file name */
	ulint		line,	/* in: line where called */
#endif
	mtr_t*		mtr)	/* in: mini-transaction */
{
	buf_block_t*	block;
@@ -883,18 +950,12 @@ buf_page_optimistic_get_func(
	ut_ad(!ibuf_inside() || ibuf_page(block->space, block->offset));

	if (rw_latch == RW_S_LATCH) {
		success = rw_lock_s_lock_func_nowait(&(block->lock)
				#ifdef UNIV_SYNC_DEBUG
				, file, line
				#endif
				);
		success = rw_lock_s_lock_func_nowait(&(block->lock),
								file, line);
		fix_type = MTR_MEMO_PAGE_S_FIX;
	} else {
		success = rw_lock_x_lock_func_nowait(&(block->lock)
				#ifdef UNIV_SYNC_DEBUG
				, file, line
				#endif
				);
		success = rw_lock_x_lock_func_nowait(&(block->lock),
								file, line);
		fix_type = MTR_MEMO_PAGE_X_FIX;
	}

@@ -971,10 +1032,8 @@ buf_page_get_known_nowait(
	ulint		rw_latch,/* in: RW_S_LATCH, RW_X_LATCH */
	buf_frame_t*	guess,	/* in: the known page frame */
	ulint		mode,	/* in: BUF_MAKE_YOUNG or BUF_KEEP_OLD */
#ifdef UNIV_SYNC_DEBUG
	char*		file,	/* in: file name */
	ulint		line,	/* in: line where called */
#endif
	mtr_t*		mtr)	/* in: mini-transaction */
{
	buf_block_t*	block;
@@ -1017,18 +1076,12 @@ buf_page_get_known_nowait(
	ut_ad(!ibuf_inside() || (mode == BUF_KEEP_OLD));

	if (rw_latch == RW_S_LATCH) {
		success = rw_lock_s_lock_func_nowait(&(block->lock)
				#ifdef UNIV_SYNC_DEBUG
				, file, line
				#endif
				);
		success = rw_lock_s_lock_func_nowait(&(block->lock),
								file, line);
		fix_type = MTR_MEMO_PAGE_S_FIX;
	} else {
		success = rw_lock_x_lock_func_nowait(&(block->lock)
				#ifdef UNIV_SYNC_DEBUG
				, file, line
				#endif
				);
		success = rw_lock_x_lock_func_nowait(&(block->lock),
								file, line);
		fix_type = MTR_MEMO_PAGE_X_FIX;
	}
	
@@ -1315,13 +1368,30 @@ buf_page_io_complete(
		   to the 4 upper bytes of the page end lsn field */

		if (buf_page_is_corrupted(block->frame)) {
		  	fprintf(stderr,
			  "InnoDB: Database page corruption or a failed\n"
			  "InnoDB: file read of page %lu.\n", block->offset);
			  
		  	fprintf(stderr,
			  "InnoDB: You may have to recover from a backup.\n");

			buf_page_print(block->frame);

		  	fprintf(stderr,
			  "InnoDB: Database page corruption or a failed\n"
			  "InnoDB: file read of page %lu.\n", block->offset);
		  	fprintf(stderr,
			  "InnoDB: You may have to recover from a backup.\n");
			fprintf(stderr,
			  "InnoDB: It is also possible that your operating\n"
			  "InnoDB: system has corrupted its own file cache\n"
			  "InnoDB: and rebooting your computer removes the\n"
			  "InnoDB: error.\n");
			  
			if (srv_force_recovery < SRV_FORCE_IGNORE_CORRUPT) { 
		  		exit(1);
		  	}
		}

		if (recv_recovery_is_on()) {
			recv_recover_page(TRUE, block->frame, block->space,
@@ -1622,6 +1692,19 @@ buf_print(void)
	ut_a(buf_validate());
}	

/*************************************************************************
Returns the number of pending buf pool ios. */

ulint
buf_get_n_pending_ios(void)
/*=======================*/
{
	return(buf_pool->n_pend_reads
		+ buf_pool->n_flush[BUF_FLUSH_LRU]
		+ buf_pool->n_flush[BUF_FLUSH_LIST]
		+ buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE]);
}

/*************************************************************************
Prints info of the buffer i/o. */

@@ -1629,6 +1712,8 @@ void
buf_print_io(void)
/*==============*/
{
	time_t	current_time;
	double	time_elapsed;
	ulint	size;
	
	ut_ad(buf_pool);
@@ -1637,11 +1722,11 @@ buf_print_io(void)

	mutex_enter(&(buf_pool->mutex));
	
	printf("LRU list length %lu \n", UT_LIST_GET_LEN(buf_pool->LRU));
	printf("Free list length  %lu \n", UT_LIST_GET_LEN(buf_pool->free));
	printf("LRU list length   %lu \n", UT_LIST_GET_LEN(buf_pool->LRU));
	printf("Flush list length %lu \n",
				UT_LIST_GET_LEN(buf_pool->flush_list));
	printf("Buffer pool size in pages %lu\n", size);
	printf("Buffer pool size  %lu\n", size);

	printf("Pending reads %lu \n", buf_pool->n_pend_reads);

@@ -1650,9 +1735,21 @@ buf_print_io(void)
		buf_pool->n_flush[BUF_FLUSH_LIST],
		buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE]);

	current_time = time(NULL);
	time_elapsed = difftime(current_time, buf_pool->last_printout_time);

	buf_pool->last_printout_time = current_time;

	printf("Pages read %lu, created %lu, written %lu\n",
			buf_pool->n_pages_read, buf_pool->n_pages_created,
						buf_pool->n_pages_written);
	printf("%.2f reads/s, %.2f creates/s, %.2f writes/s\n",
		(buf_pool->n_pages_read - buf_pool->n_pages_read_old)
		/ time_elapsed,
		(buf_pool->n_pages_created - buf_pool->n_pages_created_old)
		/ time_elapsed,
		(buf_pool->n_pages_written - buf_pool->n_pages_written_old)
		/ time_elapsed);

	if (buf_pool->n_page_gets > buf_pool->n_page_gets_old) {
		printf("Buffer pool hit rate %lu / 1000\n",
@@ -1660,10 +1757,14 @@ buf_print_io(void)
		- ((1000 *
		    (buf_pool->n_pages_read - buf_pool->n_pages_read_old))
		/ (buf_pool->n_page_gets - buf_pool->n_page_gets_old)));
	} else {
		printf("No buffer pool activity since the last printout\n");
	}

	buf_pool->n_page_gets_old = buf_pool->n_page_gets;
	buf_pool->n_pages_read_old = buf_pool->n_pages_read;
	buf_pool->n_pages_created_old = buf_pool->n_pages_created;
	buf_pool->n_pages_written_old = buf_pool->n_pages_written;

	mutex_exit(&(buf_pool->mutex));
}
Loading