为什么OS已经有了页面置换机制,MySQL中的Buffer Pool还需要再实现一遍?

问题引入

舍友最近在找实习,简历上有CMU15-445经典数据库项目。在面试时被问到:

  1. 操作系统已经有页面置换算法,为什么Buffer Pool中还需要自己实现呢?

  2. 操作系统中的页面置换,对自己实现的页面置换有什么影响?

个人理解

MySQL在默认配置下,读取一行数据,要先打开磁盘中对应的数据页,这时因为局部性,会直接复制一份磁盘文件的整页数据到Page Cache中。

然后,这一页还会被读到用户空间的Buffer Pool中;Buffer Pool中数据的修改,对Page Cache没有影响。

当Buffer Pool淘汰了数据页,会把脏页的内容刷进Page Cache。之后fsync()才会把Page Cache的内容刷到磁盘中。

这里Page Cache和Buffer Pool的内容有重叠,浪费内存了。所以MySQL提供了O_DIRECT方式,可以绕过Page Cache,节省内存。

回到最初的问题,数据库文件太大,Buffer Pool只按需缓存其中一部分内容到内存。而Buffer Pool是用户内存空间的一部分,又受到OS页面置换的管理。

Buffer Pool的置换算法管理的是哪些磁盘页被调入虚拟内存;OS的置换算法管理的是Buffer Pool的虚拟内存中,哪些部分使用实际物理内存,剩余部分被swap到磁盘中。

OS的置换只是超出了实际物理内存空间才会进行,平时对Buffer Pool应当没有影响。所以Buffer Pool的大小应该合理设置,如果太大,超出的部分会经常被OS给置换,影响效率;而太小,就达不到缓存的效果了,因为要不停自我置换。

Buffer Pool不进行置换可以吗?不太好,因为Buffer Pool中会使用哈希表,保存数据页号到Buffer Pool中地址的映射,如果不置换,这个哈希表越来越大,查起来就很慢了。

不用Buffer Pool,用mmap直接把数据文件全都装进来可以吗?反正虚拟内存空间很大嘛,需要的时候OS会帮我们自动置换。不太好,OS的置换阈值不受我们控制,不灵活。

那么用mmap+手动方式进行置换呢?我去查了下为什么没人这么干,搜到一篇回答,可以看参考资料中的最后一篇,大意说的也是mmap不够灵活,Buffer Pool可以看作是mmap的重新实现。

总结

  1. MySQL自己实现的Buffer Pool比较灵活,阈值大小可控,并且可以随着版本更新去迭代优化。

  2. 当物理内存不足时,可能会对Buffer Pool中的页面进行置换,对效率造成影响,所以Buffer Pool的大小要合理设置。

参考资料

mysql刷盘机制详解_liuzhilong_62的博客-CSDN博客
揭开 Buffer Pool 的面纱 | 小林coding
细看InnoDB数据落盘 图解 MYSQL 专家hatemysql - zengkefu - 博客园
关于Linux中的mmap和page cache的问题? - 知乎
Why is mmap considered bad while designing a database system? - Quora

posted @ 2023-03-22 22:04  zaqny  阅读(205)  评论(0编辑  收藏  举报