【MySQL进阶之路】BufferPool底层设计(下)
欢迎关注公众号(通过文章导读关注:【11来了】),及时收到 AI 前沿项目工具及新技术的推送!
在我后台回复 「资料」 可领取
编程高频电子书
!
在我后台回复「面试」可领取硬核面试笔记
!文章导读地址:点击查看文章导读!
感谢你的关注!
什么时间将缓存页刷入磁盘呢?
在 MySQL 中会有一个后台线程运行定时任务,定时将 LRU 链表的 冷数据区域尾部 的一些缓存页刷入磁盘里去,清空这几个缓存页,将他们加入到 free 链表中(free 链表存放的就是 BufferPool 中的空缓存页的地址)
并且这个后台线程也会在 MySQL 空闲时,将 flush 链表(flush 链表存放的是 BufferPool 中被修改过的缓存页,也称为脏页,脏页都是需要刷回磁盘的)中的缓存页都刷入磁盘中
在 BufferPool 中存储的是什么数据呢?
我们在 MySQL 中看到的数据是一个一个的表,表中有一行一行的数据
那么难道 BufferPool 中存储的是一行一行的数据吗?
肯定不是的,我们可以来思考一下,如果 BufferPool 存储一行一行的数据,那么每次一修改数据时,都需要去磁盘中读取一行数据到 BufferPool 中,而磁盘 IO 是很慢的,一次磁盘 IO 只读取一行数据显然不划算!
所以,在 MySQL 的设计中, BufferPool 存储的其实是 数据页
MySQL 中将很多行的数据放在一个数据页中,当数据在磁盘文件中存储的时候,就是存储的很多数据页:
当数据页进入到 BufferPool 之后,除了数据页之外,每个缓存也还会有对应的描述数据,存储一些数据页的信息,BufferPool 默认大小是 128MB,而数据页大小是 16KB,缓存页大小与数据页大小是相等的,如下:
BufferPool 中缓存页的管理(free、flush链表)
MySQL 在启动的时候,就会在内存区域中初始化 BufferPool,此时 BufferPool 中会直接划分出一个一个的缓存页,初始时所有的缓存也都为空
那么 BufferPool 如何来管理这些缓存页呢,怎么知道哪些缓存页是空的?(free 链表)
BufferPool 通过 free 链表来管理空的缓存页,是一个双向链表,由缓存页的描述数据组成,里边有一个 基础节点 ,可以通过基础节点快速找到开始节点和结束节点,并且基础节点中记录了 free 链表的总节点数:
flush 链表
当缓存页中数据被修改之后,这个缓存页就变为了脏页,这些脏页此时和磁盘中的数据是不一致的,因此称为 脏页
这些脏页就是由 BufferPool 中的 flush 链表来管理的,flush 链表和 free 链表结构一样,都是双向链表