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

📄 btr0btr.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 5 页
字号:
/***************************************************************Parses a redo log record of reorganizing a page. */byte*btr_parse_page_reorganize(/*======================*/				/* out: end of log record or NULL */	byte*		ptr,	/* in: buffer */	byte*		end_ptr __attribute__((unused)),				/* in: buffer end */	dict_index_t*	index,	/* in: record descriptor */	page_t*		page,	/* in: page or NULL */	mtr_t*		mtr)	/* in: mtr or NULL */{	ut_ad(ptr && end_ptr);	/* The record is empty, except for the record initial part */	if (page) {		btr_page_reorganize_low(TRUE, page, index, mtr);	}	return(ptr);}/*****************************************************************Empties an index page. */staticvoidbtr_page_empty(/*===========*/	page_t*	page,	/* in: page to be emptied */	mtr_t*	mtr)	/* in: mtr */{	ut_ad(mtr_memo_contains(mtr, buf_block_align(page),			      				MTR_MEMO_PAGE_X_FIX));	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 */	page_create(page, mtr, page_is_comp(page));	buf_block_align(page)->check_index_page_at_flush = TRUE;}/*****************************************************************Makes tree one level higher by splitting the root, and insertsthe tuple. It is assumed that mtr contains an x-latch on the tree.NOTE that the operation of this function must always succeed,we cannot reverse it: therefore enough free disk space must beguaranteed to be available before this function is called. */rec_t*btr_root_raise_and_insert(/*======================*/				/* out: inserted record */	btr_cur_t*	cursor,	/* in: cursor at which to insert: must be				on the root page; when the function returns,				the cursor is positioned on the predecessor				of the inserted record */	dtuple_t*	tuple,	/* in: tuple to insert */	mtr_t*		mtr)	/* in: mtr */{	dict_tree_t*	tree;	page_t*		root;	page_t*		new_page;	ulint		new_page_no;	rec_t*		rec;	mem_heap_t*	heap;	dtuple_t*	node_ptr;	ulint		level;		rec_t*		node_ptr_rec;	page_cur_t*	page_cursor;		root = btr_cur_get_page(cursor);	tree = btr_cur_get_tree(cursor);	ut_ad(dict_tree_get_page(tree) == buf_frame_get_page_no(root));	ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree),							MTR_MEMO_X_LOCK));	ut_ad(mtr_memo_contains(mtr, buf_block_align(root),			      				MTR_MEMO_PAGE_X_FIX));	btr_search_drop_page_hash_index(root);	/* Allocate a new page to the tree. Root splitting is done by first	moving the root records to the new page, emptying the root, putting	a node pointer to the new page, and then splitting the new page. */		new_page = btr_page_alloc(tree, 0, FSP_NO_DIR,				  btr_page_get_level(root, mtr), mtr);	btr_page_create(new_page, tree, mtr);	level = btr_page_get_level(root, mtr);		/* Set the levels of the new index page and root page */	btr_page_set_level(new_page, level, mtr);	btr_page_set_level(root, level + 1, mtr);		/* Set the next node and previous node fields of new page */	btr_page_set_next(new_page, FIL_NULL, mtr);	btr_page_set_prev(new_page, FIL_NULL, mtr);	/* Move the records from root to the new page */	page_move_rec_list_end(new_page, root, page_get_infimum_rec(root),							cursor->index, mtr);	/* If this is a pessimistic insert which is actually done to	perform a pessimistic update then we have stored the lock	information of the record to be inserted on the infimum of the	root page: we cannot discard the lock structs on the root page */		lock_update_root_raise(new_page, root);	/* Create a memory heap where the node pointer is stored */	heap = mem_heap_create(100);	rec = page_rec_get_next(page_get_infimum_rec(new_page));	new_page_no = buf_frame_get_page_no(new_page);		/* Build the node pointer (= node key and page address) for the	child */	node_ptr = dict_tree_build_node_ptr(tree, rec, new_page_no, heap,					                          level);	/* Reorganize the root to get free space */	btr_page_reorganize(root, cursor->index, mtr);	page_cursor = btr_cur_get_page_cur(cursor);		/* Insert node pointer to the root */	page_cur_set_before_first(root, page_cursor);	node_ptr_rec = page_cur_tuple_insert(page_cursor, node_ptr,						cursor->index, mtr);	ut_ad(node_ptr_rec);	/* The node pointer must be marked as the predefined minimum record,	as there is no lower alphabetical limit to records in the leftmost	node of a level: */	btr_set_min_rec_mark(node_ptr_rec, page_is_comp(root), mtr);			/* Free the memory heap */	mem_heap_free(heap);	/* We play safe and reset the free bits for the new page *//*	fprintf(stderr, "Root raise new page no %lu\n",					buf_frame_get_page_no(new_page)); */	ibuf_reset_free_bits(UT_LIST_GET_FIRST(tree->tree_indexes),								new_page);	/* Reposition the cursor to the child node */	page_cur_search(new_page, cursor->index, tuple,				PAGE_CUR_LE, page_cursor);		/* Split the child and insert tuple */	return(btr_page_split_and_insert(cursor, tuple, mtr));}	/*****************************************************************Decides if the page should be split at the convergence point of insertsconverging to the left. */iboolbtr_page_get_split_rec_to_left(/*===========================*/				/* out: TRUE if split recommended */	btr_cur_t*	cursor,	/* in: cursor at which to insert */	rec_t**		split_rec) /* out: if split recommended,				the first record on upper half page,				or NULL if tuple to be inserted should				be first */{	page_t*	page;	rec_t*	insert_point;	rec_t*	infimum;	page = btr_cur_get_page(cursor);	insert_point = btr_cur_get_rec(cursor);	if (page_header_get_ptr(page, PAGE_LAST_INSERT)	    == page_rec_get_next(insert_point)) {	     	infimum = page_get_infimum_rec(page);				/* If the convergence is in the middle of a page, include also		the record immediately before the new insert to the upper		page. Otherwise, we could repeatedly move from page to page		lots of records smaller than the convergence point. */		if (infimum != insert_point		    && page_rec_get_next(infimum) != insert_point) {			*split_rec = insert_point;		} else {	     		*split_rec = page_rec_get_next(insert_point);	     	}		return(TRUE);	}	return(FALSE);}/*****************************************************************Decides if the page should be split at the convergence point of insertsconverging to the right. */iboolbtr_page_get_split_rec_to_right(/*============================*/				/* out: TRUE if split recommended */	btr_cur_t*	cursor,	/* in: cursor at which to insert */	rec_t**		split_rec) /* out: if split recommended,				the first record on upper half page,				or NULL if tuple to be inserted should				be first */{	page_t*	page;	rec_t*	insert_point;	page = btr_cur_get_page(cursor);	insert_point = btr_cur_get_rec(cursor);	/* We use eager heuristics: if the new insert would be right after	the previous insert on the same page, we assume that there is a	pattern of sequential inserts here. */	if (UNIV_LIKELY(page_header_get_ptr(page, PAGE_LAST_INSERT)				== insert_point)) {		rec_t*	next_rec;		next_rec = page_rec_get_next(insert_point);		if (page_rec_is_supremum(next_rec)) {split_at_new:			/* Split at the new record to insert */	     		*split_rec = NULL;		} else {			rec_t*	next_next_rec = page_rec_get_next(next_rec);			if (page_rec_is_supremum(next_next_rec)) {				goto split_at_new;			}			/* If there are >= 2 user records up from the insert			point, split all but 1 off. We want to keep one because			then sequential inserts can use the adaptive hash			index, as they can do the necessary checks of the right			search position just by looking at the records on this			page. */					*split_rec = next_next_rec;		}		return(TRUE);	}	return(FALSE);}/*****************************************************************Calculates a split record such that the tuple will certainly fit onits half-page when the split is performed. We assume in this functiononly that the cursor page has at least one user record. */staticrec_t*btr_page_get_sure_split_rec(/*========================*/					/* out: split record, or NULL if					tuple will be the first record on					upper half-page */	btr_cur_t*	cursor,		/* in: cursor at which insert					should be made */	dtuple_t*	tuple)		/* in: tuple to insert */	{	page_t*	page;	ulint	insert_size;	ulint	free_space;	ulint	total_data;	ulint	total_n_recs;	ulint	total_space;	ulint	incl_data;	rec_t*	ins_rec;	rec_t*	rec;	rec_t*	next_rec;	ulint	n;	mem_heap_t* heap;	ulint*	offsets;	page = btr_cur_get_page(cursor);		insert_size = rec_get_converted_size(cursor->index, tuple);	free_space  = page_get_free_space_of_empty(page_is_comp(page));	/* free_space is now the free space of a created new page */	total_data   = page_get_data_size(page) + insert_size;	total_n_recs = page_get_n_recs(page) + 1;	ut_ad(total_n_recs >= 2);	total_space  = total_data + page_dir_calc_reserved_space(total_n_recs);	n = 0;	incl_data = 0;	ins_rec = btr_cur_get_rec(cursor);	rec = page_get_infimum_rec(page);	heap = NULL;	offsets = NULL;	/* We start to include records to the left half, and when the	space reserved by them exceeds half of total_space, then if	the included records fit on the left page, they will be put there	if something was left over also for the right page,	otherwise the last included record will be the first on the right	half page */	for (;;) {		/* Decide the next record to include */		if (rec == ins_rec) {			rec = NULL;	/* NULL denotes that tuple is					now included */		} else if (rec == NULL) {			rec = page_rec_get_next(ins_rec);		} else {			rec = page_rec_get_next(rec);		}		if (rec == NULL) {			/* Include tuple */			incl_data += insert_size;		} else {			offsets = rec_get_offsets(rec, cursor->index,					offsets, ULINT_UNDEFINED, &heap);			incl_data += rec_offs_size(offsets);		}		n++;				if (incl_data + page_dir_calc_reserved_space(n)                    >= total_space / 2) {                    	if (incl_data + page_dir_calc_reserved_space(n)                    	    <= free_space) {                    	    	/* The next record will be the first on                    	    	the right half page if it is not the                    	    	supremum record of page */				if (rec == ins_rec) {					rec = NULL;					goto func_exit;				} else if (rec == NULL) {					next_rec = page_rec_get_next(ins_rec);				} else {					next_rec = page_rec_get_next(rec);				}				ut_ad(next_rec);				if (!page_rec_is_supremum(next_rec)) {					rec = next_rec;				}                    	}func_exit:			if (UNIV_LIKELY_NULL(heap)) {				mem_heap_free(heap);			}			return(rec);		}	}}		/*****************************************************************Returns TRUE if the insert fits on the appropriate half-page with thechosen split_rec. */staticiboolbtr_page_insert_fits(/*=================*/					/* out: TRUE if fits */	btr_cur_t*	cursor,		/* in: cursor at which insert					should be made */	rec_t*		split_rec,	/* in: suggestion for first record					on upper half-page, or NULL if					tuple to be inserted should be first */	const ulint*	offsets,	/* in: rec_get_offsets(					split_rec, cursor->index) */	dtuple_t*	tuple,		/* in: tuple to insert */	mem_heap_t*	heap)		/* in: temporary memory heap */{	page_t*	page;	ulint	insert_size;	ulint	free_space;	ulint	total_data;	ulint	total_n_recs;	rec_t*	rec;	rec_t*	end_rec;	ulint*	offs;		page = btr_cur_get_page(cursor);	ut_ad(!split_rec == !offsets);	ut_ad(!offsets		|| !page_is_comp(page) == !rec_offs_comp(offsets));	ut_ad(!offsets		|| rec_offs_validate(split_rec, cursor->index, offsets));	insert_size = rec_get_converted_size(cursor->index, tuple);	free_space  = page_get_free_space_of_empty(page_is_comp(page));	/* free_space is now the free space of a created new page */	total_data   = page_get_data_size(page) + insert_size;	total_n_recs = page_get_n_recs(page) + 1;		/* We determine which records (from rec to end_rec, not including	end_rec) will end up on the other half page from tuple when it is	inserted. */		if (split_rec == NULL) {		rec = page_rec_get_next(page_get_infimum_rec(page));		end_rec = page_rec_get_next(btr_cur_get_rec(cursor));	} else if (cmp_dtuple_rec(tuple, split_rec, offsets) >= 0) {		rec = page_rec_get_next(page_get_infimum_rec(page)); 		end_rec = split_rec;	} else {		rec = split_rec;		end_rec = page_get_supremum_rec(page);	}	if (total_data + page_dir_calc_reserved_space(total_n_recs)	    <= free_space) {		/* Ok, there will be enough available space on the		half page where the tuple is inserted */		return(TRUE);	}	offs = NULL;	while (rec != end_rec) {		/* In this loop we calculate the amount of reserved		space after rec is removed from page. */		offs = rec_get_offsets(rec, cursor->index, offs,						ULINT_UNDEFINED, &heap);		total_data -= rec_offs_size(offs);		total_n_recs--;		if (total_data + page_dir_calc_reserved_space(total_n_recs)                    <= free_space) {

⌨️ 快捷键说明

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