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

📄 ibuf0ibuf.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 5 页
字号:
	dtuple_set_types_binary(tuple, 1);	return(tuple);}/*************************************************************************Builds a search tuple used to search buffered inserts for an index page.This is for >= 4.1.x format records. */staticdtuple_t*ibuf_new_search_tuple_build(/*========================*/				/* out, own: search tuple */	ulint		space,	/* in: space id */	ulint		page_no,/* in: index page number */	mem_heap_t*	heap)	/* in: heap into which to build */{	dtuple_t*	tuple;	dfield_t*	field;	byte*		buf;		ut_a(trx_sys_multiple_tablespace_format);	tuple = dtuple_create(heap, 3);	/* Store the space id in tuple */	field = dtuple_get_nth_field(tuple, 0);	buf = mem_heap_alloc(heap, 4);	mach_write_to_4(buf, space);	dfield_set_data(field, buf, 4);	/* Store the new format record marker byte */	field = dtuple_get_nth_field(tuple, 1);	buf = mem_heap_alloc(heap, 1);	mach_write_to_1(buf, 0);	dfield_set_data(field, buf, 1);	/* Store the page number in tuple */	field = dtuple_get_nth_field(tuple, 2);	buf = mem_heap_alloc(heap, 4);	mach_write_to_4(buf, page_no);	dfield_set_data(field, buf, 4);	dtuple_set_types_binary(tuple, 3);	return(tuple);}/*************************************************************************Checks if there are enough pages in the free list of the ibuf tree that wedare to start a pessimistic insert to the insert buffer. */UNIV_INLINEiboolibuf_data_enough_free_for_insert(/*=============================*/				/* out: TRUE if enough free pages in list */	ibuf_data_t*	data)	/* in: ibuf data for the space */{#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&ibuf_mutex));#endif /* UNIV_SYNC_DEBUG */	/* We want a big margin of free pages, because a B-tree can sometimes	grow in size also if records are deleted from it, as the node pointers	can change, and we must make sure that we are able to delete the	inserts buffered for pages that we read to the buffer pool, without	any risk of running out of free space in the insert buffer. */	if (data->free_list_len >= data->size / 2 + 3 * data->height) {		return(TRUE);	}	return(FALSE);}/*************************************************************************Checks if there are enough pages in the free list of the ibuf tree that weshould remove them and free to the file space management. */UNIV_INLINEiboolibuf_data_too_much_free(/*====================*/				/* out: TRUE if enough free pages in list */	ibuf_data_t*	data)	/* in: ibuf data for the space */{#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&ibuf_mutex));#endif /* UNIV_SYNC_DEBUG */	if (data->free_list_len >= 3 + data->size / 2 + 3 * data->height) {		return(TRUE);	}	return(FALSE);}/*************************************************************************Allocates a new page from the ibuf file segment and adds it to the freelist. */staticulintibuf_add_free_page(/*===============*/					/* out: DB_SUCCESS, or DB_STRONG_FAIL					if no space left */	ulint		space,		/* in: space id */	ibuf_data_t*	ibuf_data)	/* in: ibuf data for the space */{	mtr_t	mtr;	page_t*	header_page;	ulint	page_no;	page_t*	page;	page_t*	root;	page_t*	bitmap_page;	ut_a(space == 0);	mtr_start(&mtr);	/* Acquire the fsp latch before the ibuf header, obeying the latching	order */	mtr_x_lock(fil_space_get_latch(space), &mtr);		header_page = ibuf_header_page_get(space, &mtr);	/* Allocate a new page: NOTE that if the page has been a part of a	non-clustered index which has subsequently been dropped, then the	page may have buffered inserts in the insert buffer, and these	should be deleted from there. These get deleted when the page	allocation creates the page in buffer. Thus the call below may end	up calling the insert buffer routines and, as we yet have no latches	to insert buffer tree pages, these routines can run without a risk	of a deadlock. This is the reason why we created a special ibuf	header page apart from the ibuf tree. */	page_no = fseg_alloc_free_page(header_page + IBUF_HEADER					+ IBUF_TREE_SEG_HEADER, 0, FSP_UP,									&mtr);	if (page_no == FIL_NULL) {		mtr_commit(&mtr);		return(DB_STRONG_FAIL);	}	page = buf_page_get(space, page_no, RW_X_LATCH, &mtr);#ifdef UNIV_SYNC_DEBUG	buf_page_dbg_add_level(page, SYNC_TREE_NODE_NEW);#endif /* UNIV_SYNC_DEBUG */	ibuf_enter();	mutex_enter(&ibuf_mutex);	root = ibuf_tree_root_get(ibuf_data, space, &mtr);	/* Add the page to the free list and update the ibuf size data */	flst_add_last(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,		      page + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE, &mtr);	fil_page_set_type(page, FIL_PAGE_IBUF_FREE_LIST);	ibuf_data->seg_size++;	ibuf_data->free_list_len++;	/* Set the bit indicating that this page is now an ibuf tree page	(level 2 page) */	bitmap_page = ibuf_bitmap_get_map_page(space, page_no, &mtr);	ibuf_bitmap_page_set_bits(bitmap_page, page_no, IBUF_BITMAP_IBUF,								TRUE, &mtr);	mtr_commit(&mtr);	mutex_exit(&ibuf_mutex);	ibuf_exit();	return(DB_SUCCESS);}/*************************************************************************Removes a page from the free list and frees it to the fsp system. */staticvoidibuf_remove_free_page(/*==================*/	ulint		space,		/* in: space id */	ibuf_data_t*	ibuf_data)	/* in: ibuf data for the space */{	mtr_t	mtr;	mtr_t	mtr2;	page_t*	header_page;	ulint	page_no;	page_t*	page;	page_t*	root;	page_t*	bitmap_page;	ut_a(space == 0);	mtr_start(&mtr);	/* Acquire the fsp latch before the ibuf header, obeying the latching	order */	mtr_x_lock(fil_space_get_latch(space), &mtr);		header_page = ibuf_header_page_get(space, &mtr);	/* Prevent pessimistic inserts to insert buffer trees for a while */	mutex_enter(&ibuf_pessimistic_insert_mutex);	ibuf_enter();	mutex_enter(&ibuf_mutex);	if (!ibuf_data_too_much_free(ibuf_data)) {		mutex_exit(&ibuf_mutex);		ibuf_exit();				mutex_exit(&ibuf_pessimistic_insert_mutex);		mtr_commit(&mtr);		return;	}		mtr_start(&mtr2);		root = ibuf_tree_root_get(ibuf_data, space, &mtr2);	page_no = flst_get_last(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,									&mtr2)		  .page;	/* NOTE that we must release the latch on the ibuf tree root	because in fseg_free_page we access level 1 pages, and the root	is a level 2 page. */		  	mtr_commit(&mtr2);	mutex_exit(&ibuf_mutex);	ibuf_exit();		/* Since pessimistic inserts were prevented, we know that the	page is still in the free list. NOTE that also deletes may take	pages from the free list, but they take them from the start, and	the free list was so long that they cannot have taken the last	page from it. */		fseg_free_page(header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER,							space, page_no, &mtr);#ifdef UNIV_DEBUG_FILE_ACCESSES	buf_page_reset_file_page_was_freed(space, page_no);#endif	ibuf_enter();								mutex_enter(&ibuf_mutex);	root = ibuf_tree_root_get(ibuf_data, space, &mtr);	ut_ad(page_no == flst_get_last(root + PAGE_HEADER					+ PAGE_BTR_IBUF_FREE_LIST, &mtr)		  	 .page);	page = buf_page_get(space, page_no, RW_X_LATCH, &mtr);#ifdef UNIV_SYNC_DEBUG	buf_page_dbg_add_level(page, SYNC_TREE_NODE);#endif /* UNIV_SYNC_DEBUG */	/* Remove the page from the free list and update the ibuf size data */		flst_remove(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,		    page + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE, &mtr);	ibuf_data->seg_size--;	ibuf_data->free_list_len--;		      	mutex_exit(&ibuf_pessimistic_insert_mutex);	/* Set the bit indicating that this page is no more an ibuf tree page	(level 2 page) */	bitmap_page = ibuf_bitmap_get_map_page(space, page_no, &mtr);	ibuf_bitmap_page_set_bits(bitmap_page, page_no, IBUF_BITMAP_IBUF,								FALSE, &mtr);#ifdef UNIV_DEBUG_FILE_ACCESSES	buf_page_set_file_page_was_freed(space, page_no);#endif	mtr_commit(&mtr);	mutex_exit(&ibuf_mutex);	ibuf_exit();}/***************************************************************************Frees excess pages from the ibuf free list. This function is called when an OSthread calls fsp services to allocate a new file segment, or a new page to afile segment, and the thread did not own the fsp latch before this call. */ voidibuf_free_excess_pages(/*===================*/	ulint	space)	/* in: space id */{	ibuf_data_t*	ibuf_data;	ulint		i;	if (space != 0) {	        fprintf(stderr,"InnoDB: Error: calling ibuf_free_excess_pages for space %lu\n", (ulong) space);		return;	}#ifdef UNIV_SYNC_DEBUG	ut_ad(rw_lock_own(fil_space_get_latch(space), RW_LOCK_EX));#endif /* UNIV_SYNC_DEBUG */	ut_ad(rw_lock_get_x_lock_count(fil_space_get_latch(space)) == 1);	ut_ad(!ibuf_inside());		/* NOTE: We require that the thread did not own the latch before,	because then we know that we can obey the correct latching order	for ibuf latches */	ibuf_data = fil_space_get_ibuf_data(space);	if (ibuf_data == NULL) {		/* Not yet initialized */#ifdef UNIV_DEBUG		/*fprintf(stderr,			"Ibuf for space %lu not yet initialized\n", space); */#endif		return;	}	/* Free at most a few pages at a time, so that we do not delay the	requested service too much */	for (i = 0; i < 4; i++) {		mutex_enter(&ibuf_mutex);		if (!ibuf_data_too_much_free(ibuf_data)) {			mutex_exit(&ibuf_mutex);			return;		}		mutex_exit(&ibuf_mutex);		ibuf_remove_free_page(space, ibuf_data);	}}/*************************************************************************Reads page numbers from a leaf in an ibuf tree. */staticulintibuf_get_merge_page_nos(/*====================*/				/* out: a lower limit for the combined volume				of records which will be merged */	ibool		contract,/* in: TRUE if this function is called to				contract the tree, FALSE if this is called				when a single page becomes full and we look				if it pays to read also nearby pages */	rec_t*		rec,	/* in: record from which we read up and down				in the chain of records */	ulint*		space_ids,/* in/out: space id's of the pages */	ib_longlong*	space_versions,/* in/out: tablespace version				timestamps; used to prevent reading in old				pages after DISCARD + IMPORT tablespace */	ulint*		page_nos,/* in/out: buffer for at least				IBUF_MAX_N_PAGES_MERGED many page numbers;				the page numbers are in an ascending order */	ulint*		n_stored)/* out: number of page numbers stored to				page_nos in this function */{	ulint	prev_page_no;	ulint	prev_space_id;	ulint	first_page_no;	ulint	first_space_id;	ulint	rec_page_no;	ulint	rec_space_id;	ulint	sum_volumes;	ulint	volume_for_page;	ulint	rec_volume;	ulint	limit;	ulint	n_pages;	*n_stored = 0;	limit = ut_min(IBUF_MAX_N_PAGES_MERGED, buf_pool->curr_size / 4);	if (page_rec_is_supremum(rec)) {		rec = page_rec_get_prev(rec);	}	if (page_rec_is_infimum(rec)) {		rec = page_rec_get_next(rec);	}	if (page_rec_is_supremum(rec)) {		return(0);	}	first_page_no = ibuf_rec_get_page_no(rec);	first_space_id = ibuf_rec_get_space(rec);	n_pages = 0;	prev_page_no = 0;	prev_space_id = 0;		/* Go backwards from the first rec until we reach the border of the	'merge area', or the page start or the limit of storeable pages is	reached */	while (!page_rec_is_infimum(rec) && UNIV_LIKELY(n_pages < limit)) {		rec_page_no = ibuf_rec_get_page_no(rec);		rec_space_id = ibuf_rec_get_space(rec);		if (rec_space_id != first_space_id		    || rec_page_no / IBUF_MERGE_AREA		       != first_page_no / IBUF_MERGE_AREA) {		    	break;		}				if (rec_page_no != prev_page_no		    || rec_space_id != prev_space_id) {			n_pages++;		}		prev_page_no = rec_page_no;		prev_space_id = rec_space_id;		rec = page_rec_get_prev(rec);	}	rec = page_rec_get_next(rec);	/* At the loop start there is no prev page; we mark this with a pair	of space id, page no (0, 0) for which there can never be entries in	the insert buffer */	prev_page_no = 0;	prev_space_id = 0;	sum_volumes = 0;	volume_for_page = 0;		while (*n_stored < limit) {		if (page_rec_is_supremum(rec)) {			/* When no more records available, mark this with			another 'impossible' pair of space id, page no */			rec_page_no = 1;			rec_space_id = 0;		} else {			rec_page_no = ibuf_rec_get_page_no(rec);			rec_space_id = ibuf_rec_get_space(rec);			ut_ad(rec_page_no > IBUF_TREE_ROOT_PAGE_NO);		}#ifdef UNIV_IBUF_DEBUG		ut_a(*n_stored < IBUF_MAX_N_PAGES_MERGED);#endif		if ((rec_space_id != prev_space_id		     || rec_page_no != prev_page_no)                    && (prev_space_id != 0 || prev_page_no != 0)) {			if ((prev_page_no == first_page_no			     && prev_space_id == first_space_id)			    || contract			    || (volume_for_page >			     ((IBUF_MERGE_THRESHOLD - 1)			      * 4 * UNIV_PAGE_SIZE				    / IBUF_PAGE_SIZE_PER_FREE_SPACE)

⌨️ 快捷键说明

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