MySQL 单点详解(09)

MySQL 单点详解(09):缓冲池缓的是什么,脏页又是怎么刷回去的

面试官:buffer pool 是干什么的?加了它查询为什么就快了?

面试官:脏页什么时候刷回磁盘?刷不过来会怎么样?

缓冲池缓的不是查询结果,是数据页。

结果会失效,页不会。它只是把磁盘上的东西搬近了一点。

一、缓冲池缓的是什么

第二期说过,InnoDB 按页读写,一页 16KB。

读一行,也要把整页搬进内存。

缓冲池就是内存里腾出的一大块地方,专门放这些页。

表① 这块地方都放什么

区域 放什么
数据页 表和索引的叶子、非叶子
undo 页 回滚要用的旧版本
变更缓冲 还没合并进页的索引改动
自适应哈希 热点等值查询的快捷入口

主体是数据页。一次查询要的那一页在池子里,就不用碰磁盘;不在,才去读。

磁盘读一页是微秒级往上,内存读一页是纳秒级。差的是三个数量级,不是百分之几十。

所以缓冲池命中率一掉,慢查询就成片出现。这也是它比任何 SQL 改写都更影响性能的原因。

二、LRU 为什么改成了两段

内存装不下所有页,就得淘汰。常规做法是最近最少使用先走。

但直接用这个规则会出事:一次全表扫描,几十万页涌进来,把热数据全冲走了。

InnoDB 的改法是分两段。

表② 冷热分区

区 占比 放什么
热区 八分之五 反复访问、真正在用的页
冷区 八分之三 新读进来的页,先在这里待着

新页一律先进冷区,不动热区。

而且在冷区待不满一秒的页,被访问也不许升到热区。

这一秒就是关键:全表扫描扫过的页,通常只读一次,一秒内就被淘汰,进不了热区。

真正反复用的页,隔一会儿又会被读到,那时才升上去。

同一套规则,靠一个时间门槛把"扫一遍"和"反复用"分开了。

三、脏页什么时候刷

内存里的页被改过、还没写回磁盘,这个页就叫脏页。

它不能一直脏着,也不能随时就刷。

表③ 四个刷盘时机

时机 为什么这时候刷
日志快写满一圈 不刷就没法推进,事务会被卡住
内存不够要淘汰 腾位置前得先把脏的写回去
系统空闲 趁没人用,提前分摊掉
正常关闭 收尾,把该落盘的都落了

前两个是被动,后两个是主动。

主动刷的意义在于错峰:闲的时候多刷一点,忙的时候就不用停下来等磁盘。

四、刷不过来会怎样

如果产生脏页的速度超过刷盘速度,脏页越积越多,最后触到上限。

这时候用户线程得自己下场刷脏页,语句就卡住了。

表现很有特点:SQL 平时几十毫秒,突然变成几秒;磁盘 IO 打满;过一阵自己又好了。

这叫刷脏抖动。它跟慢查询长得像,但原因完全不同,加索引没用。

常见的两个诱因:一是突然的大批量写入,二是缓冲池给小了,热数据本来就装不下。

还有一种是长事务,它让 undo 一直不释放,间接把池子占住。

五、面试官会往下问的三层

第一层:变更缓冲是干什么的?

写普通索引时,那一页可能不在内存里。为了改一个字段去磁盘读一整页,很亏。

所以先把改动记在变更缓冲里,等这一页因为别的原因被读进来时,再一起合并。

它省的是随机读,代价是这块内存不能给数据页用。

第二层:缓冲池是不是越大越好?

大部分情况是,一般给到物理内存的一半到七成。

但太大也有代价:机器重启后要花很久预热,这段时间性能很差;而且刷脏时一次要处理的量也更大。

第三层:怎么知道命中率高不高?

看状态里的命中次数和读取次数,两者一比就是命中率。

生产上更实用的判断是看磁盘读的量:业务量没涨,读却在涨,基本就是池子不够或者被大查询冲了。

收尾

这期压成一句:缓冲池把页搬进内存,两段 LRU 挡住全表扫描的冲击,脏页靠错峰刷盘,刷不动就会抖动。

相关推荐
瀚高PG实验室1 小时前
瀚高数据库运行日志(错误日志)查看与分析方法
数据库·postgresql·瀚高数据库
snow@li1 小时前
PostgreSQL:PostgreSQL(PG)全景深度梳理
数据库·postgresql
java_nnnn1 小时前
Spring IoC & DI 从入门到理解:控制反转、依赖注入与 Bean 管理详解
数据库·sql·spring
吹什么轩1 小时前
constexpr 完全指南:从 const 的两种含义,到编译期计算的四次演进
java·前端·javascript
她的男孩1 小时前
租户 A 的验证码,却用了租户 B 的 AccessKey:Forge Admin 修跨租户短信串发
java·spring boot·saas
LabVIEW开发2 小时前
LabVIEW 局部变量与数据流:这道 CLAD 题为什么答案是 Undefined
java·开发语言·labview
文丑颜不良啊2 小时前
LeetCode1721~1740题目解析
java·leetcode
wangbing11252 小时前
监控网页项目常用英文缩写
java
麻瓜code2 小时前
双写一致性:为什么是“删缓存“,而不是“改缓存“
java·缓存·mybatis