⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 btr0cur.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 5 页
字号:
/******************************************************The index tree cursorAll changes that row operations make to a B-tree or the recordsthere must go through this module! Undo log records are written hereof every modify or insert of a clustered index record.			NOTE!!!To make sure we do not run out of disk space during a pessimisticinsert or update, we have to reserve 2 x the height of the index treemany pages in the tablespace before we start the operation, becauseif leaf splitting has been started, it is difficult to undo, exceptby crashing the database and doing a roll-forward.(c) 1994-2001 Innobase OyCreated 10/16/1994 Heikki Tuuri*******************************************************/#include "btr0cur.h"#ifdef UNIV_NONINL#include "btr0cur.ic"#endif#include "page0page.h"#include "rem0rec.h"#include "rem0cmp.h"#include "btr0btr.h"#include "btr0sea.h"#include "row0upd.h"#include "trx0rec.h"#include "que0que.h"#include "row0row.h"#include "srv0srv.h"#include "ibuf0ibuf.h"#include "lock0lock.h"#ifdef UNIV_DEBUG/* If the following is set to TRUE, this module prints a lot oftrace information of individual record operations */ibool	btr_cur_print_record_ops = FALSE;#endif /* UNIV_DEBUG */ulint	btr_cur_n_non_sea	= 0;ulint	btr_cur_n_sea		= 0;ulint	btr_cur_n_non_sea_old	= 0;ulint	btr_cur_n_sea_old	= 0;/* In the optimistic insert, if the insert does not fit, but this much spacecan be released by page reorganize, then it is reorganized */#define BTR_CUR_PAGE_REORGANIZE_LIMIT	(UNIV_PAGE_SIZE / 32)/* When estimating number of different kay values in an index samplethis many index pages */#define BTR_KEY_VAL_ESTIMATE_N_PAGES	8/* The structure of a BLOB part header *//*--------------------------------------*/#define BTR_BLOB_HDR_PART_LEN		0	/* BLOB part len on this						page */#define BTR_BLOB_HDR_NEXT_PAGE_NO	4	/* next BLOB part page no,						FIL_NULL if none *//*--------------------------------------*/#define BTR_BLOB_HDR_SIZE		8/***********************************************************************Marks all extern fields in a record as owned by the record. This functionshould be called if the delete mark of a record is removed: a not deletemarked record always owns all its extern fields. */staticvoidbtr_cur_unmark_extern_fields(/*=========================*/	rec_t*		rec,	/* in: record in a clustered index */	mtr_t*		mtr,	/* in: mtr */	const ulint*	offsets);/* in: array returned by rec_get_offsets() *//***********************************************************************Adds path information to the cursor for the current page, for whichthe binary search has been performed. */staticvoidbtr_cur_add_path_info(/*==================*/	btr_cur_t*	cursor,		/* in: cursor positioned on a page */	ulint		height,		/* in: height of the page in tree;					0 means leaf node */	ulint		root_height);	/* in: root node height in tree *//***************************************************************Frees the externally stored fields for a record, if the field is mentionedin the update vector. */staticvoidbtr_rec_free_updated_extern_fields(/*===============================*/	dict_index_t*	index,	/* in: index of rec; the index tree MUST be				X-latched */	rec_t*		rec,	/* in: record */	const ulint*	offsets,/* in: rec_get_offsets(rec, index) */	upd_t*		update,	/* in: update vector */	ibool		do_not_free_inherited,/* in: TRUE if called in a				rollback and we do not want to free				inherited fields */	mtr_t*		mtr);	/* in: mini-transaction handle which contains				an X-latch to record page and to the tree *//***************************************************************Gets the externally stored size of a record, in units of a database page. */staticulintbtr_rec_get_externally_stored_len(/*==============================*/				/* out: externally stored part,				in units of a database page */	rec_t*		rec,	/* in: record */	const ulint*	offsets);/* in: array returned by rec_get_offsets() *//*==================== B-TREE SEARCH =========================*/	/************************************************************************Latches the leaf page or pages requested. */staticvoidbtr_cur_latch_leaves(/*=================*/	page_t*		page,		/* in: leaf page where the search					converged */	ulint		space,		/* in: space id */	ulint		page_no,	/* in: page number of the leaf */	ulint		latch_mode,	/* in: BTR_SEARCH_LEAF, ... */	btr_cur_t*	cursor, 	/* in: cursor */	mtr_t*		mtr)		/* in: mtr */{	ulint	left_page_no;	ulint	right_page_no;	page_t*	get_page;		ut_ad(page && mtr);	if (latch_mode == BTR_SEARCH_LEAF) {			get_page = btr_page_get(space, page_no, RW_S_LATCH, mtr);		ut_a(page_is_comp(get_page) == page_is_comp(page));		buf_block_align(get_page)->check_index_page_at_flush = TRUE;	} else if (latch_mode == BTR_MODIFY_LEAF) {		get_page = btr_page_get(space, page_no, RW_X_LATCH, mtr);		ut_a(page_is_comp(get_page) == page_is_comp(page));		buf_block_align(get_page)->check_index_page_at_flush = TRUE;	} else if (latch_mode == BTR_MODIFY_TREE) {		/* x-latch also brothers from left to right */		left_page_no = btr_page_get_prev(page, mtr);		if (left_page_no != FIL_NULL) {			get_page = btr_page_get(space, left_page_no,							RW_X_LATCH, mtr);			ut_a(page_is_comp(get_page) == page_is_comp(page));			buf_block_align(get_page)->check_index_page_at_flush =									TRUE;		}						get_page = btr_page_get(space, page_no, RW_X_LATCH, mtr);		ut_a(page_is_comp(get_page) == page_is_comp(page));		buf_block_align(get_page)->check_index_page_at_flush = TRUE;		right_page_no = btr_page_get_next(page, mtr);		if (right_page_no != FIL_NULL) {			get_page = btr_page_get(space, right_page_no,							RW_X_LATCH, mtr);			buf_block_align(get_page)->check_index_page_at_flush =									TRUE;		}	} else if (latch_mode == BTR_SEARCH_PREV) {		/* s-latch also left brother */		left_page_no = btr_page_get_prev(page, mtr);		if (left_page_no != FIL_NULL) {			cursor->left_page = btr_page_get(space, left_page_no,							RW_S_LATCH, mtr);			ut_a(page_is_comp(cursor->left_page) ==					page_is_comp(page));			buf_block_align(			cursor->left_page)->check_index_page_at_flush = TRUE;		}		get_page = btr_page_get(space, page_no, RW_S_LATCH, mtr);		ut_a(page_is_comp(get_page) == page_is_comp(page));		buf_block_align(get_page)->check_index_page_at_flush = TRUE;	} else if (latch_mode == BTR_MODIFY_PREV) {		/* x-latch also left brother */		left_page_no = btr_page_get_prev(page, mtr);		if (left_page_no != FIL_NULL) {			cursor->left_page = btr_page_get(space, left_page_no,							RW_X_LATCH, mtr);			ut_a(page_is_comp(cursor->left_page) ==					page_is_comp(page));			buf_block_align(			cursor->left_page)->check_index_page_at_flush = TRUE;		}		get_page = btr_page_get(space, page_no, RW_X_LATCH, mtr);		ut_a(page_is_comp(get_page) == page_is_comp(page));		buf_block_align(get_page)->check_index_page_at_flush = TRUE;	} else {		ut_error;	}}/************************************************************************Searches an index tree and positions a tree cursor on a given level.NOTE: n_fields_cmp in tuple must be set so that it cannot be comparedto node pointer page number fields on the upper levels of the tree!Note that if mode is PAGE_CUR_LE, which is used in inserts, thencursor->up_match and cursor->low_match both will have sensible values.If mode is PAGE_CUR_GE, then up_match will a have a sensible value. */voidbtr_cur_search_to_nth_level(/*========================*/	dict_index_t*	index,	/* in: index */	ulint		level,	/* in: the tree level of search */	dtuple_t*	tuple,	/* in: data tuple; NOTE: n_fields_cmp in				tuple must be set so that it cannot get				compared to the node ptr page number field! */	ulint		mode,	/* in: PAGE_CUR_L, ...;				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;				cursor->left_page is used to store a pointer				to the left neighbor page, in the cases				BTR_SEARCH_PREV and BTR_MODIFY_PREV;				NOTE that if has_search_latch				is != 0, we maybe do not have a latch set				on the cursor page, we assume				the caller uses his search latch				to protect the record! */	btr_cur_t*	cursor, /* in/out: tree cursor; the cursor page is				s- or x-latched, but see also above! */	ulint		has_search_latch,/* in: info on the latch mode the				caller currently has on btr_search_latch:				RW_S_LATCH, or 0 */	mtr_t*		mtr)	/* in: mtr */{	dict_tree_t*	tree;	page_cur_t*	page_cursor;	page_t*		page;	page_t*		guess;	rec_t*		node_ptr;	ulint		page_no;	ulint		space;	ulint		up_match;	ulint		up_bytes;	ulint		low_match;	ulint 		low_bytes;	ulint		height;	ulint		savepoint;	ulint		rw_latch;	ulint		page_mode;	ulint		insert_planned;	ulint		buf_mode;	ulint		estimate;	ulint		ignore_sec_unique;	ulint		root_height = 0; /* remove warning */#ifdef BTR_CUR_ADAPT	btr_search_t*	info;#endif	mem_heap_t*	heap		= NULL;	ulint		offsets_[REC_OFFS_NORMAL_SIZE];	ulint*		offsets		= offsets_;	*offsets_ = (sizeof offsets_) / sizeof *offsets_;	/* Currently, PAGE_CUR_LE is the only search mode used for searches	ending to upper levels */	ut_ad(level == 0 || mode == PAGE_CUR_LE);	ut_ad(dict_tree_check_search_tuple(index->tree, tuple));	ut_ad(!(index->type & DICT_IBUF) || ibuf_inside());	ut_ad(dtuple_check_typed(tuple));#ifdef UNIV_DEBUG	cursor->up_match = ULINT_UNDEFINED;	cursor->low_match = ULINT_UNDEFINED;#endif		insert_planned = latch_mode & BTR_INSERT;	estimate = latch_mode & BTR_ESTIMATE;	ignore_sec_unique = latch_mode & BTR_IGNORE_SEC_UNIQUE;	latch_mode = latch_mode & ~(BTR_INSERT | BTR_ESTIMATE					| BTR_IGNORE_SEC_UNIQUE);	ut_ad(!insert_planned || (mode == PAGE_CUR_LE));		cursor->flag = BTR_CUR_BINARY;	cursor->index = index;#ifndef BTR_CUR_ADAPT	guess = NULL;#else	info = btr_search_get_info(index);	guess = info->root_guess;#ifdef BTR_CUR_HASH_ADAPT#ifdef UNIV_SEARCH_PERF_STAT	info->n_searches++;#endif		if (btr_search_latch.writer == RW_LOCK_NOT_LOCKED		&& latch_mode <= BTR_MODIFY_LEAF && info->last_hash_succ		&& !estimate#ifdef PAGE_CUR_LE_OR_EXTENDS		&& mode != PAGE_CUR_LE_OR_EXTENDS#endif /* PAGE_CUR_LE_OR_EXTENDS */		&& srv_use_adaptive_hash_indexes	        && btr_search_guess_on_hash(index, info, tuple, mode,						latch_mode, cursor,						has_search_latch, mtr)) {		/* Search using the hash index succeeded */		ut_ad(cursor->up_match != ULINT_UNDEFINED					|| mode != PAGE_CUR_GE);		ut_ad(cursor->up_match != ULINT_UNDEFINED					|| mode != PAGE_CUR_LE);		ut_ad(cursor->low_match != ULINT_UNDEFINED					|| mode != PAGE_CUR_LE);		btr_cur_n_sea++;	        return;	}#endif#endif	btr_cur_n_non_sea++;	/* If the hash search did not succeed, do binary search down the	tree */	if (has_search_latch) {		/* Release possible search latch to obey latching order */		rw_lock_s_unlock(&btr_search_latch);	}	/* Store the position of the tree latch we push to mtr so that we	know how to release it when we have latched leaf node(s) */	savepoint = mtr_set_savepoint(mtr);	tree = index->tree;		if (latch_mode == BTR_MODIFY_TREE) {		mtr_x_lock(dict_tree_get_lock(tree), mtr);	} else if (latch_mode == BTR_CONT_MODIFY_TREE) {		/* Do nothing */		ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree),							MTR_MEMO_X_LOCK));	} else {		mtr_s_lock(dict_tree_get_lock(tree), mtr);	}		page_cursor = btr_cur_get_page_cur(cursor);	space = dict_tree_get_space(tree);	page_no = dict_tree_get_page(tree);	up_match = 0;	up_bytes = 0;	low_match = 0;	low_bytes = 0;	height = ULINT_UNDEFINED;	rw_latch = RW_NO_LATCH;	buf_mode = BUF_GET;	/* We use these modified search modes on non-leaf levels of the	B-tree. These let us end up in the right B-tree leaf. In that leaf	we use the original search mode. */	switch (mode) {	case PAGE_CUR_GE:		page_mode = PAGE_CUR_L;		break;	case PAGE_CUR_G:		page_mode = PAGE_CUR_LE;		break;	default:#ifdef PAGE_CUR_LE_OR_EXTENDS		ut_ad(mode == PAGE_CUR_L || mode == PAGE_CUR_LE			|| mode == PAGE_CUR_LE_OR_EXTENDS);#else /* PAGE_CUR_LE_OR_EXTENDS */		ut_ad(mode == PAGE_CUR_L || mode == PAGE_CUR_LE);#endif /* PAGE_CUR_LE_OR_EXTENDS */		page_mode = mode;		break;	}	/* Loop and search until we arrive at the desired level */	for (;;) {		if ((height == 0) && (latch_mode <= BTR_MODIFY_LEAF)) {			rw_latch = latch_mode;			if (insert_planned && ibuf_should_try(index,							ignore_sec_unique)) {								/* Try insert to the insert buffer if the				page is not in the buffer pool */				buf_mode = BUF_GET_IF_IN_POOL;			}		}retry_page_get:				page = buf_page_get_gen(space, page_no, rw_latch, guess,					buf_mode,					__FILE__, __LINE__,					mtr);		if (page == NULL) {			/* This must be a search to perform an insert;			try insert to the insert buffer */			ut_ad(buf_mode == BUF_GET_IF_IN_POOL);			ut_ad(insert_planned);			ut_ad(cursor->thr);			if (ibuf_should_try(index, ignore_sec_unique) &&				ibuf_insert(tuple, index, space, page_no,							cursor->thr)) {				/* Insertion to the insert buffer succeeded */				cursor->flag = BTR_CUR_INSERT_TO_IBUF;				if (UNIV_LIKELY_NULL(heap)) {					mem_heap_free(heap);				}				return;			}			/* Insert to the insert buffer did not succeed:			retry page get */			buf_mode = BUF_GET;			goto retry_page_get;		}		buf_block_align(page)->check_index_page_at_flush = TRUE;			#ifdef UNIV_SYNC_DEBUG							if (rw_latch != RW_NO_LATCH) {			buf_page_dbg_add_level(page, SYNC_TREE_NODE);		}#endif		ut_ad(0 == ut_dulint_cmp(tree->id,					btr_page_get_index_id(page)));		if (height == ULINT_UNDEFINED) {			/* We are in the root node */			height = btr_page_get_level(page, mtr);			root_height = height;			cursor->tree_height = root_height + 1;#ifdef BTR_CUR_ADAPT			if (page != guess) {				info->root_guess = page;			}	#endif		}			if (height == 0) {			if (rw_latch == RW_NO_LATCH) {				btr_cur_latch_leaves(page, space,						page_no, latch_mode, cursor,						mtr);			}			if ((latch_mode != BTR_MODIFY_TREE)			    && (latch_mode != BTR_CONT_MODIFY_TREE)) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -