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

📄 btr0cur.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 5 页
字号:
				/* Release the tree s-latch */				mtr_release_s_latch_at_savepoint(						mtr, savepoint,						dict_tree_get_lock(tree));			}			page_mode = mode;		}		page_cur_search_with_match(page, index, tuple, page_mode,					&up_match, &up_bytes,					&low_match, &low_bytes, page_cursor);		if (estimate) {			btr_cur_add_path_info(cursor, height, root_height);		}			/* If this is the desired level, leave the loop */		ut_ad(height		== btr_page_get_level(page_cur_get_page(page_cursor), mtr));		if (level == height) {			if (level > 0) {				/* x-latch the page */				page = btr_page_get(space,						page_no, RW_X_LATCH, mtr);				ut_a((ibool)!!page_is_comp(page)						== index->table->comp);			}			break;		}		ut_ad(height > 0);		height--;		guess = NULL;		node_ptr = page_cur_get_rec(page_cursor);		offsets = rec_get_offsets(node_ptr, cursor->index, offsets,						ULINT_UNDEFINED, &heap);		/* Go to the child node */		page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets);	}	if (UNIV_LIKELY_NULL(heap)) {		mem_heap_free(heap);	}	if (level == 0) {		cursor->low_match = low_match;		cursor->low_bytes = low_bytes;		cursor->up_match = up_match;		cursor->up_bytes = up_bytes;#ifdef BTR_CUR_ADAPT				if (srv_use_adaptive_hash_indexes) {			btr_search_info_update(index, cursor);		}#endif		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);	}	if (has_search_latch) {				rw_lock_s_lock(&btr_search_latch);	}}/*********************************************************************Opens a cursor at either end of an index. */voidbtr_cur_open_at_index_side(/*=======================*/	ibool		from_left,	/* in: TRUE if open to the low end,					FALSE if to the high end */	dict_index_t*	index,		/* in: index */	ulint		latch_mode,	/* in: latch mode */	btr_cur_t*	cursor,		/* in: cursor */	mtr_t*		mtr)		/* in: mtr */{	page_cur_t*	page_cursor;	dict_tree_t*	tree;	page_t*		page;	ulint		page_no;	ulint		space;	ulint		height;	ulint		root_height = 0; /* remove warning */	rec_t*		node_ptr;	ulint		estimate;	ulint           savepoint;	mem_heap_t*	heap		= NULL;	ulint		offsets_[REC_OFFS_NORMAL_SIZE];	ulint*		offsets		= offsets_;	*offsets_ = (sizeof offsets_) / sizeof *offsets_;	estimate = latch_mode & BTR_ESTIMATE;	latch_mode = latch_mode & ~BTR_ESTIMATE;		tree = index->tree;		/* Store the position of the tree latch we push to mtr so that we	know how to release it when we have latched the leaf node */	savepoint = mtr_set_savepoint(mtr);	if (latch_mode == BTR_MODIFY_TREE) {		mtr_x_lock(dict_tree_get_lock(tree), mtr);	} else {		mtr_s_lock(dict_tree_get_lock(tree), mtr);	}		page_cursor = btr_cur_get_page_cur(cursor);	cursor->index = index;	space = dict_tree_get_space(tree);	page_no = dict_tree_get_page(tree);	height = ULINT_UNDEFINED;	for (;;) {		page = buf_page_get_gen(space, page_no, RW_NO_LATCH, NULL,					BUF_GET,					__FILE__, __LINE__,					mtr);		ut_ad(0 == ut_dulint_cmp(tree->id,						btr_page_get_index_id(page)));		buf_block_align(page)->check_index_page_at_flush = TRUE;		if (height == ULINT_UNDEFINED) {			/* We are in the root node */			height = btr_page_get_level(page, mtr);			root_height = height;		}		if (height == 0) {			btr_cur_latch_leaves(page, space, page_no,						latch_mode, cursor, mtr);			/* In versions <= 3.23.52 we had forgotten to			release the tree latch here. If in an index scan			we had to scan far to find a record visible to the			current transaction, that could starve others			waiting for the tree latch. */ 			if ((latch_mode != BTR_MODIFY_TREE)			    && (latch_mode != BTR_CONT_MODIFY_TREE)) {				/* Release the tree s-latch */				mtr_release_s_latch_at_savepoint(						mtr, savepoint,						dict_tree_get_lock(tree));			}		}				if (from_left) {			page_cur_set_before_first(page, page_cursor);		} else {			page_cur_set_after_last(page, page_cursor);		}		if (height == 0) {		        if (estimate) {			        btr_cur_add_path_info(cursor, height,						      root_height);		        }			break;		}		ut_ad(height > 0);		if (from_left) {			page_cur_move_to_next(page_cursor);		} else {			page_cur_move_to_prev(page_cursor);		}		if (estimate) {			btr_cur_add_path_info(cursor, height, root_height);		}		height--;		node_ptr = page_cur_get_rec(page_cursor);		offsets = rec_get_offsets(node_ptr, cursor->index, offsets,						ULINT_UNDEFINED, &heap);		/* Go to the child node */		page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets);	}	if (UNIV_LIKELY_NULL(heap)) {		mem_heap_free(heap);	}}	/**************************************************************************Positions a cursor at a randomly chosen position within a B-tree. */voidbtr_cur_open_at_rnd_pos(/*====================*/	dict_index_t*	index,		/* in: index */	ulint		latch_mode,	/* in: BTR_SEARCH_LEAF, ... */	btr_cur_t*	cursor,		/* in/out: B-tree cursor */	mtr_t*		mtr)		/* in: mtr */{	page_cur_t*	page_cursor;	dict_tree_t*	tree;	page_t*		page;	ulint		page_no;	ulint		space;	ulint		height;	rec_t*		node_ptr;	mem_heap_t*	heap		= NULL;	ulint		offsets_[REC_OFFS_NORMAL_SIZE];	ulint*		offsets		= offsets_;	*offsets_ = (sizeof offsets_) / sizeof *offsets_;	tree = index->tree;		if (latch_mode == BTR_MODIFY_TREE) {		mtr_x_lock(dict_tree_get_lock(tree), mtr);	} else {		mtr_s_lock(dict_tree_get_lock(tree), mtr);	}		page_cursor = btr_cur_get_page_cur(cursor);	cursor->index = index;	space = dict_tree_get_space(tree);	page_no = dict_tree_get_page(tree);	height = ULINT_UNDEFINED;		for (;;) {		page = buf_page_get_gen(space, page_no, RW_NO_LATCH, NULL,					BUF_GET,					__FILE__, __LINE__,					mtr);		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);		}		if (height == 0) {			btr_cur_latch_leaves(page, space, page_no,						latch_mode, cursor, mtr);		}		page_cur_open_on_rnd_user_rec(page, page_cursor);			if (height == 0) {			break;		}		ut_ad(height > 0);		height--;		node_ptr = page_cur_get_rec(page_cursor);		offsets = rec_get_offsets(node_ptr, cursor->index, offsets,						ULINT_UNDEFINED, &heap);		/* Go to the child node */		page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets);	}	if (UNIV_LIKELY_NULL(heap)) {		mem_heap_free(heap);	}}	/*==================== B-TREE INSERT =========================*//*****************************************************************Inserts a record if there is enough space, or if enough space canbe freed by reorganizing. Differs from _optimistic_insert becauseno heuristics is applied to whether it pays to use CPU time forreorganizing the page or not. */staticrec_t*btr_cur_insert_if_possible(/*=======================*/				/* out: pointer to inserted record if succeed,				else NULL */	btr_cur_t*	cursor,	/* in: cursor on page after which to insert;				cursor stays valid */	dtuple_t*	tuple,	/* in: tuple to insert; the size info need not				have been stored to tuple */	ibool*		reorg,	/* out: TRUE if reorganization occurred */	mtr_t*		mtr)	/* in: mtr */{	page_cur_t*	page_cursor;	page_t*		page;	rec_t*		rec;	ut_ad(dtuple_check_typed(tuple));		*reorg = FALSE;	page = btr_cur_get_page(cursor);	ut_ad(mtr_memo_contains(mtr, buf_block_align(page),							MTR_MEMO_PAGE_X_FIX));	page_cursor = btr_cur_get_page_cur(cursor);		/* Now, try the insert */	rec = page_cur_tuple_insert(page_cursor, tuple, cursor->index, mtr);	if (!rec) {		/* If record did not fit, reorganize */		btr_page_reorganize(page, cursor->index, mtr);		*reorg = TRUE;		page_cur_search(page, cursor->index, tuple,						PAGE_CUR_LE, page_cursor);		rec = page_cur_tuple_insert(page_cursor, tuple,						cursor->index, mtr);	}	return(rec);}/*****************************************************************For an insert, checks the locks and does the undo logging if desired. */UNIV_INLINEulintbtr_cur_ins_lock_and_undo(/*======================*/				/* out: DB_SUCCESS, DB_WAIT_LOCK,				DB_FAIL, or error number */	ulint		flags,	/* in: undo logging and locking flags: if				not zero, the parameters index and thr				should be specified */	btr_cur_t*	cursor,	/* in: cursor on page after which to insert */	dtuple_t*	entry,	/* in: entry to insert */	que_thr_t*	thr,	/* in: query thread or NULL */	ibool*		inherit)/* out: TRUE if the inserted new record maybe				should inherit LOCK_GAP type locks from the				successor record */{	dict_index_t*	index;	ulint		err;	rec_t*		rec;	dulint		roll_ptr;	/* Check if we have to wait for a lock: enqueue an explicit lock	request if yes */	rec = btr_cur_get_rec(cursor);	index = cursor->index;		err = lock_rec_insert_check_and_lock(flags, rec, index, thr, inherit);		if (err != DB_SUCCESS) {		return(err);	}	if ((index->type & DICT_CLUSTERED) && !(index->type & DICT_IBUF)) {		err = trx_undo_report_row_operation(flags, TRX_UNDO_INSERT_OP,					thr, index, entry, NULL, 0, NULL,					&roll_ptr);		if (err != DB_SUCCESS) {			return(err);		}		/* Now we can fill in the roll ptr field in entry */		if (!(flags & BTR_KEEP_SYS_FLAG)) {			row_upd_index_entry_sys_field(entry, index,						DATA_ROLL_PTR, roll_ptr);		}	}	return(DB_SUCCESS);}#ifdef UNIV_DEBUG/*****************************************************************Report information about a transaction. */staticvoidbtr_cur_trx_report(/*===============*/	trx_t*			trx,	/* in: transaction */	const dict_index_t*	index,	/* in: index */	const char*		op)	/* in: operation */{	fprintf(stderr, "Trx with id %lu %lu going to ",		ut_dulint_get_high(trx->id),		ut_dulint_get_low(trx->id));	fputs(op, stderr);	dict_index_name_print(stderr, trx, index);	putc('\n', stderr);}#endif /* UNIV_DEBUG *//*****************************************************************Tries to perform an insert to a page in an index tree, next to cursor.It is assumed that mtr holds an x-latch on the page. The operation doesnot succeed if there is too little space on the page. If there is justone record on the page, the insert will always succeed; this is toprevent trying to split a page with just one record. */ulintbtr_cur_optimistic_insert(/*======================*/				/* out: DB_SUCCESS, DB_WAIT_LOCK,				DB_FAIL, or error number */	ulint		flags,	/* in: undo logging and locking flags: if not				zero, the parameters index and thr should be				specified */	btr_cur_t*	cursor,	/* in: cursor on page after which to insert;				cursor stays valid */	dtuple_t*	entry,	/* in: entry to insert */	rec_t**		rec,	/* out: pointer to inserted record if				succeed */	big_rec_t**	big_rec,/* out: big rec vector whose fields have to				be stored externally by the caller, or				NULL */	que_thr_t*	thr,	/* in: query thread or NULL */	mtr_t*		mtr)	/* in: mtr */{	big_rec_t*	big_rec_vec	= NULL;	dict_index_t*	index;	page_cur_t*	page_cursor;	page_t*		page;	ulint		max_size;	rec_t*		dummy_rec;	ulint		level;	ibool		reorg;	ibool		inherit;	ulint		rec_size;	ulint		type;	ulint		err;		*big_rec = NULL;	page = btr_cur_get_page(cursor);	index = cursor->index;	if (!dtuple_check_typed_no_assert(entry)) {		fputs("InnoDB: Error in a tuple to insert into ", stderr);		dict_index_name_print(stderr, thr_get_trx(thr), index);	}#ifdef UNIV_DEBUG	if (btr_cur_print_record_ops && thr) {		btr_cur_trx_report(thr_get_trx(thr), index, "insert into ");		dtuple_print(stderr, entry);	}#endif /* UNIV_DEBUG */	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);	level = btr_page_get_level(page, mtr);calculate_sizes_again:	/* Calculate the record size when entry is converted to a record */	rec_size = rec_get_converted_size(index, entry);	if (rec_size >=

⌨️ 快捷键说明

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