Commit 1d7747aa authored by heikki@donna.mysql.fi's avatar heikki@donna.mysql.fi
Browse files

ut0mem.c Merge changes in InnoDB-3.23.43b

ut0ut.c 	Merge changes in InnoDB-3.23.43b
trx0purge.c	Merge changes in InnoDB-3.23.43b
trx0rec.c	Merge changes in InnoDB-3.23.43b
trx0trx.c	Merge changes in InnoDB-3.23.43b
trx0undo.c	Merge changes in InnoDB-3.23.43b
thr0loc.c	Merge changes in InnoDB-3.23.43b
sync0arr.c	Merge changes in InnoDB-3.23.43b
sync0rw.c	Merge changes in InnoDB-3.23.43b
sync0sync.c	Merge changes in InnoDB-3.23.43b
srv0srv.c	Merge changes in InnoDB-3.23.43b
srv0start.c	Merge changes in InnoDB-3.23.43b
row0ins.c	Merge changes in InnoDB-3.23.43b
row0mysql.c	Merge changes in InnoDB-3.23.43b
row0purge.c	Merge changes in InnoDB-3.23.43b
row0sel.c	Merge changes in InnoDB-3.23.43b
row0umod.c	Merge changes in InnoDB-3.23.43b
row0upd.c	Merge changes in InnoDB-3.23.43b
row0vers.c	Merge changes in InnoDB-3.23.43b
rem0cmp.c	Merge changes in InnoDB-3.23.43b
que0que.c	Merge changes in InnoDB-3.23.43b
pars0opt.c	Merge changes in InnoDB-3.23.43b
pars0pars.c	Merge changes in InnoDB-3.23.43b
lexyy.c 	Merge changes in InnoDB-3.23.43b
pars0grm.c	Merge changes in InnoDB-3.23.43b
page0page.c	Merge changes in InnoDB-3.23.43b
os0file.c	Merge changes in InnoDB-3.23.43b
mtr0log.c	Merge changes in InnoDB-3.23.43b
mem0pool.c	Merge changes in InnoDB-3.23.43b
log0log.c	Merge changes in InnoDB-3.23.43b
log0recv.c	Merge changes in InnoDB-3.23.43b
lock0lock.c	Merge changes in InnoDB-3.23.43b
ibuf0ibuf.c	Merge changes in InnoDB-3.23.43b
fil0fil.c	Merge changes in InnoDB-3.23.43b
dict0crea.c	Merge changes in InnoDB-3.23.43b
dict0dict.c	Merge changes in InnoDB-3.23.43b
dict0load.c	Merge changes in InnoDB-3.23.43b
dict0mem.c	Merge changes in InnoDB-3.23.43b
data0data.c	Merge changes in InnoDB-3.23.43b
data0type.c	Merge changes in InnoDB-3.23.43b
buf0buf.c	Merge changes in InnoDB-3.23.43b
buf0lru.c	Merge changes in InnoDB-3.23.43b
btr0btr.c	Merge changes in InnoDB-3.23.43b
btr0cur.c	Merge changes in InnoDB-3.23.43b
btr0pcur.c	Merge changes in InnoDB-3.23.43b
btr0sea.c	Merge changes in InnoDB-3.23.43b
data0type.ic	Merge changes in InnoDB-3.23.43b
dict0dict.ic	Merge changes in InnoDB-3.23.43b
mtr0mtr.ic	Merge changes in InnoDB-3.23.43b
row0upd.ic	Merge changes in InnoDB-3.23.43b
sync0ipm.ic	Merge changes in InnoDB-3.23.43b
sync0rw.ic	Merge changes in InnoDB-3.23.43b
sync0sync.ic	Merge changes in InnoDB-3.23.43b
trx0rseg.ic	Merge changes in InnoDB-3.23.43b
btr0pcur.ic	Merge changes in InnoDB-3.23.43b
buf0buf.ic	Merge changes in InnoDB-3.23.43b
data0data.ic	Merge changes in InnoDB-3.23.43b
row0upd.h	Merge changes in InnoDB-3.23.43b
srv0srv.h	Merge changes in InnoDB-3.23.43b
sync0arr.h	Merge changes in InnoDB-3.23.43b
sync0rw.h	Merge changes in InnoDB-3.23.43b
sync0sync.h	Merge changes in InnoDB-3.23.43b
trx0trx.h	Merge changes in InnoDB-3.23.43b
ut0mem.h	Merge changes in InnoDB-3.23.43b
data0data.h	Merge changes in InnoDB-3.23.43b
data0type.h	Merge changes in InnoDB-3.23.43b
db0err.h	Merge changes in InnoDB-3.23.43b
dict0crea.h	Merge changes in InnoDB-3.23.43b
dict0dict.h	Merge changes in InnoDB-3.23.43b
dict0load.h	Merge changes in InnoDB-3.23.43b
dict0mem.h	Merge changes in InnoDB-3.23.43b
dict0types.h	Merge changes in InnoDB-3.23.43b
fil0fil.h	Merge changes in InnoDB-3.23.43b
ibuf0ibuf.h	Merge changes in InnoDB-3.23.43b
lock0lock.h	Merge changes in InnoDB-3.23.43b
log0log.h	Merge changes in InnoDB-3.23.43b
mtr0mtr.h	Merge changes in InnoDB-3.23.43b
rem0cmp.h	Merge changes in InnoDB-3.23.43b
row0ins.h	Merge changes in InnoDB-3.23.43b
row0mysql.h	Merge changes in InnoDB-3.23.43b
btr0cur.h	Merge changes in InnoDB-3.23.43b
btr0pcur.h	Merge changes in InnoDB-3.23.43b
btr0sea.h	Merge changes in InnoDB-3.23.43b
buf0buf.h	Merge changes in InnoDB-3.23.43b
sql_table.cc	Merge changes in InnoDB-3.23.43b
sql_db.cc	Merge changes in InnoDB-3.23.43b
ha_innobase.cc	Merge changes in InnoDB-3.23.43b
handler.cc	Merge changes in InnoDB-3.23.43b
ha_innobase.h	Merge changes in InnoDB-3.23.43b
handler.h	Merge changes in InnoDB-3.23.43b
parent a88a9842
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -4,3 +4,4 @@ paul@central.snake.net
serg@serg.mysql.com
monty@work.mysql.com
sasha@mysql.sashanet.com
heikki@donna.mysql.fi
+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);
Loading