绑定完请刷新页面
取消
刷新

分享好友

×
取消 复制
磁盘&CPU调节(1)—Buffer Pool(五十四)
2023-02-06 09:31:45

上篇文章说mysql5.6之后新增了系统变量optimizer_tance可以看到他的优化过程。

缓存的重要性

前面我们说过innoDB表示吧数据存在表空间,不管是用于存储表的系统数据,还是存储用户数据的索引(聚簇索引 和 二级索引),表空间实际是在磁盘上的。但我们不可能每次查询数据都从磁盘上查询,那样以磁盘的龟速,怎么能配的上快速的cpu呢。所以我们在磁盘访问数据的时候,会把整个页的数据全部都放入缓存中,即使只是访问一条,也是会把整个页都放入缓存,而且查询完之后,也不会立即释放缓存,而是缓存起来,可以省去磁盘I/O的开销。

InnoDB的Buffer Pool

什么是buffer pool,mysql服务器在启动的时候,会向操作系统申请一片连续的内存,这个名字就是buffer pool(缓冲池)。他是多大呢,默认是128m,小是5M,你也可以设置,当设置小于5m的时候,默认就是5M。

Innodb_buffer_pool_size=268435456

这个值是字节,也就是我指定为256M。

Buffer pool内部组成

Buffer pool里的页和磁盘上的页大小都是16kb。为了管理缓存区这些缓存页,mysql为每个缓存页创建了一些控制信息,这些控制信息包括表空间编号,页号,缓存页在buffer pool中地址、链表节点信息、一些锁信息以及LSN信息(锁和LSN信息后面再讲),当然还有一些控制信息。

每个缓存也对应的控制信息大小是相同的,我们吧每个页对应的控制信息占用的内存块称为【控制块】,控制块和缓存块是一一对应的,控制块放在buffer pool前面,缓存块放在buffer pool后面,但是中间还有个碎片区,每个控制块对应一个缓存页,那剩余空间不够分的时候怎么办呢,这就是碎片区。(需要注意的是控制块大概占缓存页大小的百分之5,而我们设置的innoDB_buffer_pool_size不包含这个内存,所以设置的内存大小实际总的要多百分之5)


Free链表管理

我们在启动mysql的时候,就会完成buffer pool的初始化过程,先想系统申请内存空间,在把他们划分成不同的控制块和缓存页。此时这些缓存页都是空闲的,后面只有随着程序的运行,数据不断从磁盘刷新到缓存页才有数据。那么从磁盘上刷到缓存页的数据放在哪个位子呢。哪些缓存页是空闲可用的呢?

这时候控制块作用就来了,我们吧空闲缓存页的控制块统一放在free 链表,所以刚开始初始化的时候,所有缓存页都在free 链表。

Free 链表有一个基节点,里面有个start和end节点,还有总的count,控制块里还有双向链表连接起来。

有了这个free链表就方便了,如果从磁盘刷新数据到buffer pool只要取个空闲页缓存页,然后把页号,表空间id,等信息填写上去,后从free 链表移除。


缓存页的hash处理

我们知道了数据存储在缓存页,但如何访问呢,总不能一点点遍历,这时候就用到了hash表,吧空间id+页号为key,value就是缓存页,通过key找到对应的value缓存页。

所以刷新数据的时候,先通过key判断是否已经有存在的缓存页,有就直接使用,没有就从free链表申请一个新的缓存页。

Flush链表管理

加入我们修改了缓存页,这时候缓存页和磁盘上的数据就不一致了,这时候就是脏数据,这时候我们就需要吧缓存页的数据同步到磁盘上,但我们不能每次都I/O访问磁盘,这样会效率很低,会在统一的时间段同步。

但如果同步又不能吧256G的缓存页全部同步到磁盘,这样也会影响效率,于是在修改后的链表会存入和free链表一样的结构,方便查找和同步,就叫flush链表。



文章来源:知乎平台  原文地址:https://zhuanlan.zhihu.com/p/416419232

分享好友

分享这个小栈给你的朋友们,一起进步吧。

MySQL干货资料
创建时间:2020-05-06 14:18:32
每天都有干货输出哦
展开
订阅须知

• 所有用户可根据关注领域订阅专区或所有专区

• 付费订阅:虚拟交易,一经交易不退款;若特殊情况,可3日内客服咨询

• 专区发布评论属默认订阅所评论专区(除付费小栈外)

技术专家

查看更多
  • 飘絮絮絮丶
    专家
戳我,来吐槽~