目录
缓冲页
缓冲页的控制块
缓冲页的哈希表
free 链表
flush 链表
LRU 链表
从 innodb buffer pool 看 select 语句的执行过程
多个 innodb buffer pool 实例
innodb_buffer_pool_chunk_size
查看 innodb buffer pool 状态信息
小小的扩展点
问答:
缓冲页
innodb buffer pool 将一块连续的内存划分成了,大小固定的缓冲页。一个缓冲页保存这一个数据页上的所有数据。默认大小为 16KB
innodb_buffer_pool_size 参数控制 innodb buffer pool 的大小,默认值 128MB,可以设置的最小值是 5MB
缓冲页的控制块
一个缓冲页对应一个控制块,每个控制块大小约为 808 字节。 innodb buffer pool 并不包含 控制块占用的内存空间,也就是说 innodb 的
缓冲页的哈希表
使用哈希表保存一个数据页是否在 buffer pool 中,在哈希表中就表示数据页已在 buffer pool 中。哈希表key为 “表空间号 + 数据页号”
free 链表
innodb buffer pool 中的空闲的缓冲页的控制块都在该链表中
flush 链表
innodb buffer pool 中脏页的缓冲页的控制块都在该链表中
LRU 链表
- innodb 中所有的缓冲页的控制块,组成了 LRU 链表
- innodb 将 LRU 链表划分为,young 区域 和 old 区域。young 区域 和 old 区域 的比例是通过 变量 innodb_old_blocks_pct 进行控制,默认值是 37。也就是 young 区域的内存为 0.63*innodb_buffer_pool_size,old 区域的内存为 0.37*innodb_buffer_pool_size
- innodb 有对 链表的 young 区域 进行了划分,如果访问的缓冲页在 young 区域 的后 1/4 部分,则将缓冲页的控制块移动到链表的头部
- innodb_old_blocks_time 默认值是 1000,单位 ms,用户控制缓冲页从 old 区域 移动到 young 区域的时间阈值
从 innodb buffer pool 看 select 语句的执行过程
多个 innodb buffer pool 实例
innodb_buffer_pool_instances 参数控制 buffer pool 实例的大小
每个实例占用空间为 innodb_buffer_size / innodb_buffer_pool_instances
为啥要搞多个实例,可以理解为集群中的多个服务节点,提高系统的处理能力
innodb_buffer_pool_chunk_size
一个 buffer pool 实例是有多个 chunk 组成的,一个 chunk 就代表一片连续的内存空间
innodb_buffer_pool_chunk_size 参数控制 chunk 的大小,默认值是 128MB
查看 innodb buffer pool 状态信息
show engine innodb status
小小的扩展点
冷热数据划分,JVM中的代划分(年轻代,年老代),都是为了提高资源(内存)的利用率
问答:
问:为什么需要对LRU链表划分为 young 区域 和 old 区域
答:假设没有区域划分,业务同学对一个大表进行全表扫描,而这个大表的访问次数是很低频的,那么就会导致 innodb buffer pool 的缓存命中率下降,导致其它的 sql 变慢(访问的数据页不在内存中,会产生磁盘I/O)
问:LRU 链表中为什么对 young 区域 3/4,1/4 的划分
答:降低 LRU 链表节点移动的次数