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

📄 ibuf0ibuf.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 5 页
字号:
			     / IBUF_MERGE_THRESHOLD)) {			        space_ids[*n_stored] = prev_space_id;				space_versions[*n_stored]						= fil_space_get_version(							prev_space_id);				page_nos[*n_stored] = prev_page_no;				(*n_stored)++;				sum_volumes += volume_for_page;			}			if (rec_space_id != first_space_id			    || rec_page_no / IBUF_MERGE_AREA			       != first_page_no / IBUF_MERGE_AREA) {		    		break;			}			volume_for_page = 0;		}		if (rec_page_no == 1 && rec_space_id == 0) {			/* Supremum record */			break;		}		rec_volume = ibuf_rec_get_volume(rec);		volume_for_page += rec_volume;				prev_page_no = rec_page_no;		prev_space_id = rec_space_id;		rec = page_rec_get_next(rec);	}#ifdef UNIV_IBUF_DEBUG	ut_a(*n_stored <= IBUF_MAX_N_PAGES_MERGED);#endif/*	fprintf(stderr, "Ibuf merge batch %lu pages %lu volume\n", *n_stored,							sum_volumes); */	return(sum_volumes);}/*************************************************************************Contracts insert buffer trees by reading pages to the buffer pool. */staticulintibuf_contract_ext(/*==============*/			/* out: a lower limit for the combined size in bytes			of entries which will be merged from ibuf trees to the			pages read, 0 if ibuf is empty */	ulint*	n_pages,/* out: number of pages to which merged */	ibool	sync)	/* in: TRUE if the caller wants to wait for the			issued read with the highest tablespace address			to complete */{	ulint		rnd_pos;	ibuf_data_t*	data;	btr_pcur_t	pcur;	ulint		space;	ibool		all_trees_empty;	ulint		page_nos[IBUF_MAX_N_PAGES_MERGED];	ulint		space_ids[IBUF_MAX_N_PAGES_MERGED];	ib_longlong	space_versions[IBUF_MAX_N_PAGES_MERGED];	ulint		n_stored;	ulint		sum_sizes;	mtr_t		mtr;	*n_pages = 0;loop:	ut_ad(!ibuf_inside());	mutex_enter(&ibuf_mutex);	ut_ad(ibuf_validate_low());		/* Choose an ibuf tree at random (though there really is only one tree	in the current implementation) */	ibuf_rnd += 865558671;	rnd_pos = ibuf_rnd % ibuf->size;	all_trees_empty = TRUE;	data = UT_LIST_GET_FIRST(ibuf->data_list);	for (;;) {		if (!data->empty) {			all_trees_empty = FALSE;					if (rnd_pos < data->size) {				break;			}					rnd_pos -= data->size;		}					data = UT_LIST_GET_NEXT(data_list, data);		if (data == NULL) {			if (all_trees_empty) {				mutex_exit(&ibuf_mutex);				return(0);			}						data = UT_LIST_GET_FIRST(ibuf->data_list);		}	}	ut_ad(data);	space = data->index->space;	ut_a(space == 0);	/* We currently only have an ibuf tree in				space 0 */	mtr_start(&mtr);	ibuf_enter();		/* Open a cursor to a randomly chosen leaf of the tree, at a random	position within the leaf */	btr_pcur_open_at_rnd_pos(data->index, BTR_SEARCH_LEAF, &pcur, &mtr);	if (0 == page_get_n_recs(btr_pcur_get_page(&pcur))) {		/* This tree is empty */	    	    	data->empty = TRUE;	    	ibuf_exit();	    	mtr_commit(&mtr);	    	btr_pcur_close(&pcur);	    	mutex_exit(&ibuf_mutex);	    	goto loop;	}		mutex_exit(&ibuf_mutex);	sum_sizes = ibuf_get_merge_page_nos(TRUE, btr_pcur_get_rec(&pcur),			space_ids, space_versions, page_nos, &n_stored);#ifdef UNIV_IBUF_DEBUG	/* fprintf(stderr, "Ibuf contract sync %lu pages %lu volume %lu\n",		sync, n_stored, sum_sizes); */#endif	ibuf_exit();	mtr_commit(&mtr);	btr_pcur_close(&pcur);	buf_read_ibuf_merge_pages(sync, space_ids, space_versions, page_nos,								   n_stored);	*n_pages = n_stored;		return(sum_sizes + 1);}/*************************************************************************Contracts insert buffer trees by reading pages to the buffer pool. */ulintibuf_contract(/*==========*/			/* out: a lower limit for the combined size in bytes			of entries which will be merged from ibuf trees to the			pages read, 0 if ibuf is empty */	ibool	sync)	/* in: TRUE if the caller wants to wait for the			issued read with the highest tablespace address			to complete */{	ulint	n_pages;	return(ibuf_contract_ext(&n_pages, sync));}/*************************************************************************Contracts insert buffer trees by reading pages to the buffer pool. */ulintibuf_contract_for_n_pages(/*======================*/			/* out: a lower limit for the combined size in bytes			of entries which will be merged from ibuf trees to the			pages read, 0 if ibuf is empty */	ibool	sync,	/* in: TRUE if the caller wants to wait for the			issued read with the highest tablespace address			to complete */	ulint	n_pages)/* in: try to read at least this many pages to			the buffer pool and merge the ibuf contents to			them */{	ulint	sum_bytes	= 0;	ulint	sum_pages 	= 0;	ulint	n_bytes;	ulint	n_pag2;		while (sum_pages < n_pages) {		n_bytes = ibuf_contract_ext(&n_pag2, sync);				if (n_bytes == 0) {			return(sum_bytes);		}		sum_bytes += n_bytes;		sum_pages += n_pag2;	}	return(sum_bytes);}/*************************************************************************Contract insert buffer trees after insert if they are too big. */UNIV_INLINEvoidibuf_contract_after_insert(/*=======================*/	ulint	entry_size)	/* in: size of a record which was inserted				into an ibuf tree */{	ibool	sync;	ulint	sum_sizes;	ulint	size;	mutex_enter(&ibuf_mutex);	if (ibuf->size < ibuf->max_size + IBUF_CONTRACT_ON_INSERT_NON_SYNC) {		mutex_exit(&ibuf_mutex);		return;	}	sync = FALSE;		if (ibuf->size >= ibuf->max_size + IBUF_CONTRACT_ON_INSERT_SYNC) {		sync = TRUE;	}	mutex_exit(&ibuf_mutex);	/* Contract at least entry_size many bytes */	sum_sizes = 0;	size = 1;	while ((size > 0) && (sum_sizes < entry_size)) {		size = ibuf_contract(sync);		sum_sizes += size;	}}/*************************************************************************Gets an upper limit for the combined size of entries buffered in the insertbuffer for a given page. */ulintibuf_get_volume_buffered(/*=====================*/				/* out: upper limit for the volume of				buffered inserts for the index page, in bytes;				we may also return UNIV_PAGE_SIZE, if the				entries for the index page span on several				pages in the insert buffer */	btr_pcur_t*	pcur,	/* in: pcur positioned at a place in an				insert buffer tree where we would insert an				entry for the index page whose number is				page_no, latch mode has to be BTR_MODIFY_PREV				or BTR_MODIFY_TREE */	ulint		space,	/* in: space id */	ulint		page_no,/* in: page number of an index page */	mtr_t*		mtr)	/* in: mtr */{	ulint	volume;	rec_t*	rec;	page_t*	page;	ulint	prev_page_no;	page_t*	prev_page;	ulint	next_page_no;	page_t*	next_page;		ut_a(trx_sys_multiple_tablespace_format);	ut_ad((pcur->latch_mode == BTR_MODIFY_PREV)				|| (pcur->latch_mode == BTR_MODIFY_TREE));	/* Count the volume of records earlier in the alphabetical order than	pcur */	volume = 0;		rec = btr_pcur_get_rec(pcur);	page = buf_frame_align(rec);	if (page_rec_is_supremum(rec)) {		rec = page_rec_get_prev(rec);	}	for (;;) {		if (page_rec_is_infimum(rec)) {			break;		}				if (page_no != ibuf_rec_get_page_no(rec)		    || space != ibuf_rec_get_space(rec)) {			goto count_later;		}		volume += ibuf_rec_get_volume(rec);		rec = page_rec_get_prev(rec);	}	/* Look at the previous page */		prev_page_no = btr_page_get_prev(page, mtr);	if (prev_page_no == FIL_NULL) {		goto count_later;	}	prev_page = buf_page_get(0, prev_page_no, RW_X_LATCH, mtr);#ifdef UNIV_SYNC_DEBUG	buf_page_dbg_add_level(prev_page, SYNC_TREE_NODE);#endif /* UNIV_SYNC_DEBUG */	rec = page_get_supremum_rec(prev_page);	rec = page_rec_get_prev(rec);		for (;;) {		if (page_rec_is_infimum(rec)) {			/* We cannot go to yet a previous page, because we			do not have the x-latch on it, and cannot acquire one			because of the latching order: we have to give up */					return(UNIV_PAGE_SIZE);		}				if (page_no != ibuf_rec_get_page_no(rec)		    || space != ibuf_rec_get_space(rec)) {			goto count_later;		}		volume += ibuf_rec_get_volume(rec);		rec = page_rec_get_prev(rec);	}		count_later:	rec = btr_pcur_get_rec(pcur);	if (!page_rec_is_supremum(rec)) {		rec = page_rec_get_next(rec);	}	for (;;) {		if (page_rec_is_supremum(rec)) {			break;		}				if (page_no != ibuf_rec_get_page_no(rec)		    || space != ibuf_rec_get_space(rec)) {			return(volume);		}		volume += ibuf_rec_get_volume(rec);		rec = page_rec_get_next(rec);	}	/* Look at the next page */		next_page_no = btr_page_get_next(page, mtr);	if (next_page_no == FIL_NULL) {		return(volume);	}	next_page = buf_page_get(0, next_page_no, RW_X_LATCH, mtr);#ifdef UNIV_SYNC_DEBUG	buf_page_dbg_add_level(next_page, SYNC_TREE_NODE);#endif /* UNIV_SYNC_DEBUG */	rec = page_get_infimum_rec(next_page);	rec = page_rec_get_next(rec);	for (;;) {		if (page_rec_is_supremum(rec)) {			/* We give up */					return(UNIV_PAGE_SIZE);		}				if (page_no != ibuf_rec_get_page_no(rec)		    || space != ibuf_rec_get_space(rec)) {			return(volume);		}		volume += ibuf_rec_get_volume(rec);		rec = page_rec_get_next(rec);	}}/*************************************************************************Reads the biggest tablespace id from the high end of the insert buffertree and updates the counter in fil_system. */voidibuf_update_max_tablespace_id(void)/*===============================*/{	ulint		max_space_id;	rec_t*		rec;	byte*		field;	ulint		len;	ibuf_data_t*	ibuf_data;	dict_index_t*	ibuf_index;	btr_pcur_t	pcur;	mtr_t		mtr;	ibuf_data = fil_space_get_ibuf_data(0);	ibuf_index = ibuf_data->index;	ut_a(!ibuf_index->table->comp);	ibuf_enter();	mtr_start(&mtr);	btr_pcur_open_at_index_side(FALSE, ibuf_index, BTR_SEARCH_LEAF,							&pcur, TRUE, &mtr);	btr_pcur_move_to_prev(&pcur, &mtr);	if (btr_pcur_is_before_first_on_page(&pcur, &mtr)) {		/* The tree is empty */		max_space_id = 0;	} else {		rec = btr_pcur_get_rec(&pcur);		field = rec_get_nth_field_old(rec, 0, &len);		ut_a(len == 4);				max_space_id = mach_read_from_4(field);	}	mtr_commit(&mtr);	ibuf_exit();	/* printf("Maximum space id in insert buffer %lu\n", max_space_id); */	fil_set_max_space_id_if_bigger(max_space_id);}/*************************************************************************Makes an index insert to the insert buffer, instead of directly to the diskpage, if this is possible. */staticulintibuf_insert_low(/*============*/				/* out: DB_SUCCESS, DB_FAIL, DB_STRONG_FAIL */	ulint		mode,	/* in: BTR_MODIFY_PREV or BTR_MODIFY_TREE */	dtuple_t*	entry,	/* in: index entry to insert */	dict_index_t*	index,	/* in: index where to insert; must not be				unique or clustered */	ulint		space,	/* in: space id where to insert */	ulint		page_no,/* in: page number where to insert */	que_thr_t*	thr)	/* in: query thread */{	big_rec_t*	dummy_big_rec;	ulint		entry_size;

⌨️ 快捷键说明

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