【无标题】

InnoDB的buffer pool结构

从MySQL 5.7.5开始,buffer pool以chunk为单位进行管理,多个chunk组成一个instance。通常一个mysql实例会包含1到多个buffer pool的instance。

  • buffer pool的instance数量由innodb_buffer_pool_instances值指定;
  • 每个instance的chunk数量由innodb_buffer_pool_chunk_size值间接确定;
    一个具有两个instance的buffer pool,chunk数量为2的示意图如图1.1所示。
    图 1.1 两实例的buffer pool
    因此一个mysql实例的InnoDB buffer pool自顶向下分为buf_pool,instance,chunk,block四层逻辑。

Innodb buffer pool初始化

既然InnoDB的buffer pool自定向下分为了四层逻辑,初始化自然也是按照这个顺序进行。
在这里插入图片描述

buf_pool_init

设置一些全局变量,根据buf_pool_size总量和instance数量计算单个instance的size,多次调用buf_pool_init_instance创建指定数量的实例,每个instance对象的类型为buf_pool_t

buf_pool_init_instance

每个instance有专属的free-list,flush-list,LRU-list和其他list。根据instance的size和chunk size确定一个instance包含多少个chunk,多次调用buf_chunk_init创建指定数量的chunk,每个chunk对象的类型为buf_chunk_t

buf_chunk_init

到了chunk层,才会给单个chunk的实际的buffer页分配一整块连续的内存空间,这段空间通过buf_chunk_t::mem域引用,另外buf_chunk_t::blocks也引用同样的地址,但是后者类型为buf_block_t *,代表页控制块列表。也就是说,在每个chunk的一整块内存空间中,开头是控制块列表,紧紧跟着控制块列表的才是实际的buffer空间;
根据单个chunk中page页的数量,多次调用buf_block_init初始化所有的控制块,控制块的类型为buf_block_t

计算单个chunk需要的内存总量

chunk初始化中需要负责为实际的所有的控制块和buffer分配连续空间,因此这段内存空间的总量是需要专门计算的。因为输入参数innodb_buffer_pool_chunk_size只是给出了buffer的size,每个chunk还额外包括所有的控制块占用的内存量;

  1. 将输入的size参数向下对齐到页大小UNIV_PAGE_SIZE的倍数得到mem_size
  2. mem_size加上额外的一段同样对齐UNIV_PAGE_SIZE并且可以容纳指定数量的控制块的内存大小;

找到页缓存实际的内存起始偏移

如上所述,这一整块内存一开始是连续的所有的控制块结构,然后跟着是实际的页空间。实际上,由于所有的控制块结构都放在按页大小对齐的一段内存空间中,且页空间也是从页对齐的偏移起始的,因此两者之间是有一段空隙的,而这里找到这个空隙(其实是确定实际的页数量和首页起始地址)的算法很精巧:

frame = (byte*) ut_align(chunk->mem, UNIV_PAGE_SIZE);
chunk->size = chunk->mem_pfx.m_size / UNIV_PAGE_SIZE
		- (frame != chunk->mem);

/* Subtract the space needed for block descriptors. */
{
	ulint	size = chunk->size;

	while (frame < (byte*) (chunk->blocks + size)) {
		frame += UNIV_PAGE_SIZE;
		size--;
	}

	chunk->size = size;
}

frame一开始指向内存空间头部chunk::mem,frame每次向后移动一整页,代表该chunk的页总数减少一页,此时如果frame依然小于chunk::blocks + size,说明当前frame指向的位置依然无法存放下所有的控制块。如果frame已经超过了chunk::blocks + size,说明当前frame指向的位置可以存放下所有的控制块了,循环退出。

buf_block_init

单个控制块类型buf_block_t的初始化就非常简单了,初始化其所有字段域即可。类型的开头是buf_page_t类型的页描述符,描述该页当前的状态,然后frame字段直接指向对应的页内存空间。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值