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

📄 buf0rea.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 2 页
字号:
NOTE 2: the calling thread may own latches on pages: to avoid deadlocks thisfunction must be written such that it cannot end up waiting for theselatches!NOTE 3: the calling thread must want access to the page given: this rule isset to prevent unintended read-aheads performed by ibuf routines, a situationwhich could result in a deadlock if the OS does not support asynchronous io. */ulintbuf_read_ahead_linear(/*==================*/			/* out: number of page read requests issued */	ulint	space,	/* in: space id */	ulint	offset)	/* in: page number of a page; NOTE: the current thread			must want access to this page (see NOTE 3 above) */{	ib_longlong	tablespace_version;	buf_block_t*	block;	buf_frame_t*	frame;	buf_block_t*	pred_block	= NULL;	ulint		pred_offset;	ulint		succ_offset;	ulint		count;	int		asc_or_desc;	ulint		new_offset;	ulint		fail_count;	ulint		ibuf_mode;	ulint		low, high;	ulint		err;	ulint		i;		if (srv_startup_is_before_trx_rollback_phase) {	        /* No read-ahead to avoid thread deadlocks */	        return(0);	}	if (ibuf_bitmap_page(offset) || trx_sys_hdr_page(space, offset)) {		/* If it is an ibuf bitmap page or trx sys hdr, we do                no read-ahead, as that could break the ibuf page access                order */		return(0);	}	low  = (offset / BUF_READ_AHEAD_LINEAR_AREA)					* BUF_READ_AHEAD_LINEAR_AREA;	high = (offset / BUF_READ_AHEAD_LINEAR_AREA + 1)					* BUF_READ_AHEAD_LINEAR_AREA;	if ((offset != low) && (offset != high - 1)) {		/* This is not a border page of the area: return */		return(0);	}	/* Remember the tablespace version before we ask te tablespace size	below: if DISCARD + IMPORT changes the actual .ibd file meanwhile, we	do not try to read outside the bounds of the tablespace! */	tablespace_version = fil_space_get_version(space);	mutex_enter(&(buf_pool->mutex));	if (high > fil_space_get_size(space)) {		mutex_exit(&(buf_pool->mutex));		/* The area is not whole, return */		return(0);	}	if (buf_pool->n_pend_reads >			buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) {		mutex_exit(&(buf_pool->mutex));		return(0);	}		/* Check that almost all pages in the area have been accessed; if	offset == low, the accesses must be in a descending order, otherwise,	in an ascending order. */	asc_or_desc = 1;	if (offset == low) {		asc_or_desc = -1;	}	fail_count = 0;	for (i = low; i < high; i++) {		block = buf_page_hash_get(space, i);				if ((block == NULL) || !block->accessed) {			/* Not accessed */			fail_count++;		} else if (pred_block && (ut_ulint_cmp(block->LRU_position,				      		    pred_block->LRU_position)			       		  != asc_or_desc)) {			/* Accesses not in the right order */			fail_count++;			pred_block = block;		}	}	if (fail_count > BUF_READ_AHEAD_LINEAR_AREA -			 BUF_READ_AHEAD_LINEAR_THRESHOLD) {		/* Too many failures: return */		mutex_exit(&(buf_pool->mutex));		return(0);	}	/* If we got this far, we know that enough pages in the area have	been accessed in the right order: linear read-ahead can be sensible */	block = buf_page_hash_get(space, offset);	if (block == NULL) {		mutex_exit(&(buf_pool->mutex));		return(0);	}	frame = block->frame;		/* Read the natural predecessor and successor page addresses from	the page; NOTE that because the calling thread may have an x-latch	on the page, we do not acquire an s-latch on the page, this is to	prevent deadlocks. Even if we read values which are nonsense, the	algorithm will work. */ 	pred_offset = fil_page_get_prev(frame);	succ_offset = fil_page_get_next(frame);	mutex_exit(&(buf_pool->mutex));		if ((offset == low) && (succ_offset == offset + 1)) {	    	/* This is ok, we can continue */	    	new_offset = pred_offset;	} else if ((offset == high - 1) && (pred_offset == offset - 1)) {	    	/* This is ok, we can continue */	    	new_offset = succ_offset;	} else {		/* Successor or predecessor not in the right order */		return(0);	}	low  = (new_offset / BUF_READ_AHEAD_LINEAR_AREA)					* BUF_READ_AHEAD_LINEAR_AREA;	high = (new_offset / BUF_READ_AHEAD_LINEAR_AREA + 1)					* BUF_READ_AHEAD_LINEAR_AREA;	if ((new_offset != low) && (new_offset != high - 1)) {		/* This is not a border page of the area: return */		return(0);	}	if (high > fil_space_get_size(space)) {		/* The area is not whole, return */		return(0);	}	/* If we got this far, read-ahead can be sensible: do it */	if (ibuf_inside()) {		ibuf_mode = BUF_READ_IBUF_PAGES_ONLY;	} else {		ibuf_mode = BUF_READ_ANY_PAGE;	}	count = 0;	/* Since Windows XP seems to schedule the i/o handler thread	very eagerly, and consequently it does not wait for the	full read batch to be posted, we use special heuristics here */	os_aio_simulated_put_read_threads_to_sleep();		for (i = low; i < high; i++) {		/* It is only sensible to do read-ahead in the non-sync		aio mode: hence FALSE as the first parameter */		if (!ibuf_bitmap_page(i)) {			count += buf_read_page_low(&err, FALSE, ibuf_mode					| OS_AIO_SIMULATED_WAKE_LATER,					space, 	tablespace_version, i);			if (err == DB_TABLESPACE_DELETED) {				ut_print_timestamp(stderr);				fprintf(stderr,"  InnoDB: Warning: in linear readahead trying to access tablespace\n""InnoDB: %lu page no. %lu,\n""InnoDB: but the tablespace does not exist or is just being dropped.\n",				 (ulong) space, (ulong) i);			}		}	}	/* In simulated aio we wake the aio handler threads only after	queuing all aio requests, in native aio the following call does	nothing: */		os_aio_simulated_wake_handler_threads();	/* Flush pages from the end of the LRU list if necessary */	buf_flush_free_margin();#ifdef UNIV_DEBUG	if (buf_debug_prints && (count > 0)) {		fprintf(stderr,		"LINEAR read-ahead space %lu offset %lu pages %lu\n",		(ulong) space, (ulong) offset, (ulong) count);	}#endif /* UNIV_DEBUG */        ++srv_read_ahead_seq;	return(count);}/************************************************************************Issues read requests for pages which the ibuf module wants to read in, inorder to contract the insert buffer tree. Technically, this function is likea read-ahead function. */voidbuf_read_ibuf_merge_pages(/*======================*/	ibool	sync,		/* in: TRUE if the caller wants this function				to wait for the highest address page to get				read in, before this function returns */	ulint*	space_ids,	/* in: array of space ids */	ib_longlong* space_versions,/* in: the spaces must have this version				number (timestamp), otherwise we discard the				read; we use this to cancel reads if				DISCARD + IMPORT may have changed the				tablespace size */	ulint*	page_nos,	/* in: array of page numbers to read, with the				highest page number the last in the array */	ulint	n_stored)	/* in: number of page numbers in the array */{	ulint	err;	ulint	i;	ut_ad(!ibuf_inside());#ifdef UNIV_IBUF_DEBUG	ut_a(n_stored < UNIV_PAGE_SIZE);#endif		while (buf_pool->n_pend_reads >			buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) {		os_thread_sleep(500000);	}		for (i = 0; i < n_stored; i++) {		if ((i + 1 == n_stored) && sync) {			buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE,				space_ids[i], space_versions[i], page_nos[i]);		} else {			buf_read_page_low(&err, FALSE, BUF_READ_ANY_PAGE,				space_ids[i], space_versions[i], page_nos[i]);		}		if (err == DB_TABLESPACE_DELETED) {			/* We have deleted or are deleting the single-table			tablespace: remove the entries for that page */			ibuf_merge_or_delete_for_page(NULL, space_ids[i],							page_nos[i], FALSE);		}	}		os_aio_simulated_wake_handler_threads();	/* Flush pages from the end of the LRU list if necessary */	buf_flush_free_margin();#ifdef UNIV_DEBUG	if (buf_debug_prints) {		fprintf(stderr,			"Ibuf merge read-ahead space %lu pages %lu\n",				(ulong) space_ids[0], (ulong) n_stored);	}#endif /* UNIV_DEBUG */}/************************************************************************Issues read requests for pages which recovery wants to read in. */voidbuf_read_recv_pages(/*================*/	ibool	sync,		/* in: TRUE if the caller wants this function				to wait for the highest address page to get				read in, before this function returns */	ulint	space,		/* in: space id */	ulint*	page_nos,	/* in: array of page numbers to read, with the				highest page number the last in the array */	ulint	n_stored)	/* in: number of page numbers in the array */{	ib_longlong	tablespace_version;	ulint		count;	ulint		err;	ulint		i;	tablespace_version = fil_space_get_version(space);	for (i = 0; i < n_stored; i++) {		count = 0;		os_aio_print_debug = FALSE;		while (buf_pool->n_pend_reads >= recv_n_pool_free_frames / 2) {			os_aio_simulated_wake_handler_threads();			os_thread_sleep(500000);			count++;			if (count > 100) {				fprintf(stderr,"InnoDB: Error: InnoDB has waited for 50 seconds for pending\n""InnoDB: reads to the buffer pool to be finished.\n""InnoDB: Number of pending reads %lu, pending pread calls %lu\n",				(ulong) buf_pool->n_pend_reads,				(ulong)os_file_n_pending_preads);				os_aio_print_debug = TRUE;			}		}		os_aio_print_debug = FALSE;		if ((i + 1 == n_stored) && sync) {			buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,					tablespace_version, page_nos[i]);		} else {			buf_read_page_low(&err, FALSE, BUF_READ_ANY_PAGE					| OS_AIO_SIMULATED_WAKE_LATER,				       space, tablespace_version, page_nos[i]);		}	}		os_aio_simulated_wake_handler_threads();	/* Flush pages from the end of the LRU list if necessary */	buf_flush_free_margin();#ifdef UNIV_DEBUG	if (buf_debug_prints) {		fprintf(stderr,			"Recovery applies read-ahead pages %lu\n", (ulong) n_stored);	}#endif /* UNIV_DEBUG */}

⌨️ 快捷键说明

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