7 buffer pool的组织结构

本文详细解析了InnoDB的Buffer Pool组织结构,包括buf_page_get_gen函数的作用、表空间文件中页的分布以及buf_page_t结构。讨论了extent描述符、不同类型的页列表以及file segment的结构,阐述了在数据存储和管理中的关键角色。
摘要由CSDN通过智能技术生成

一、buf_page_get_gen

它的作用是将文件数据读入缓存。

前面在“6 InnoDB相关的数据结构”一节中,已经提到了buf_pool_t的初始化;并在事务初始化时,宏buf_page_get会调用buf_page_get_gen。我们知道buf_pool中会缓存多种页:索引页、数据页、undo页等,buf_page_get_gen视为了进入database page。现把它的主要代码展示如下:

本次执行以buf_page_get_gen (space=0, zip_size=0, offset=5, rw_latch=2, guess=0x0, mode=10,  file=..., line=120, mtr=0xbfffdfd8)为例。(参考上一篇)

buf_block_t*
buf_page_get_gen(
/*=============*/
	ulint		space,	/*!< in: space id */
	ulint		zip_size,/*!< in: compressed page size in bytes or 0 for uncompressed pages */
	ulint		offset,	/*!< in: page number */
	ulint		rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
	buf_block_t*	guess,	/*!< in: guessed block or NULL */
	ulint		mode,	/*!< in: BUF_GET, BUF_GET_IF_IN_POOL,
				BUF_PEEK_IF_IN_POOL, BUF_GET_NO_LATCH, or
				BUF_GET_IF_IN_POOL_OR_WATCH */
	const char*	file,	/*!< in: file name */
	ulint		line,	/*!< in: line where called */
	mtr_t*		mtr)	/*!< in: mini-transaction */ //不可分割的事务,原子性
{
	buf_block_t*	block;
	ulint		fold;
	unsigned	access_time;
	ulint		fix_type;
	ibool		must_read;
	ulint		retries = 0;
	buf_pool_t*	buf_pool = buf_pool_get(space, offset);

	buf_pool->stat.n_page_gets++;
	fold = buf_page_address_fold(space, offset); //Calculates a folded value of a file page address to use in the page hash table.
loop:
	block = guess;
	buf_pool_mutex_enter(buf_pool);

	if (block) {
		/* If the guess is a compressed page descriptor that
		has been allocated by buf_page_alloc_descriptor(),
		it may have been freed by buf_relocate(). */

		if (!buf_block_is_uncompressed(buf_pool, block)
		    || offset != block->page.offset
		    || space != block->page.space
		    || buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE) {

			block = guess = NULL;
		} else {
			ut_ad(!block->page.in_zip_hash);
			ut_ad(block->page.in_page_hash);
		}
	}

	if (block == NULL) {
		block = (buf_block_t*) buf_page_hash_get_low(
			buf_pool, space, offset, fold); //Returns the control block of a file page
	}

	if (block && buf_pool_watch_is_sentinel(buf_pool, &block->page)) {
		block = NULL;
	}

	if (block == NULL) {
		/* Page not in buf_pool: needs to be read from file */

		if (mode == BUF_GET_IF_IN_POOL_OR_WATCH) {
			block = (buf_block_t*) buf_pool_watch_set(
				space, offset, fold);

			if (UNIV_LIKELY_NULL(block)) {

				goto got_block;
			}
		}

		buf_pool_mutex_exit(buf_pool);

		if (mode == BUF_GET_IF_IN_POOL
		    || mode == BUF_PEEK_IF_IN_POOL
		    || mode == BUF_GET_IF_IN_POOL_OR_WATCH) {

			return(NULL);
		}

		if (buf_read_page(space, zip_size, offset)) {  //异步从文件读入数据到buf_pool
			buf_read_ahead_random(space, zip_size, offset, ibuf_inside(mtr));//随机预读相关

			retries = 0;
		} else if (retries < BUF_PAGE_READ_MAX_RETRIES) {
			++retries;
		} else {
			//打印错误
		}
		goto loop; //回到loop,这次异步线程已经将数据取来,所以所要找的block就不为空了。
	}

got_block:
	ut_ad(page_zip_get_size(&block->page.zip) == zip_size);

	must_read = buf_block_get_io_fix(block) == BUF_IO_READ; //本例执行中must_read=0

	if (must_read && (mode == BUF_GET_IF_IN_POOL
			  || mode == BUF_PEEK_IF_IN_POOL)) {

		/* The page is being read to buffer pool,
		but we cannot wait around for the read to
		complete. */
null_exit:
		buf_pool_mutex_exit(buf_pool);

		return(NULL);
	}

	switch (buf_block_get_state(block)) {
		buf_page_t*	bpage;
		ibool		success;

	case BUF_BLOCK_FILE_PAGE: //本例是这种情况,表示该block存的是一个文件页
		break;
	.... //其他case情况
	}

	ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);

	mutex_enter(&block->mutex);

	buf_block_buf_fix_inc(block, file, line); //block->page.buf_fix_count++;

	buf_pool_mutex_exit(buf_pool);

	/* Check if this is the firs
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值