MySQL学习笔记- 刷脏页(flush)对性能的影响
MySQL
有时候会突然变得很慢,但持续时间又特别短,而且很难复现这种情况,这时候很有可能就是 MySQL
在刷脏页,这篇文章来学习一下 MySQL
中刷脏页的过程,可以更好的优化刷脏页对性能的影响。
1.笔记图
2.概念说明
- flush:把内存里的数据写入磁盘的过程
- 脏页:当内存数据页跟磁盘数据页内容不一致的时候,我们称这个内存页为
脏页
- 干净页:内存数据写入到磁盘后,内存和磁盘上的数据页的内容就一致了,称为
干净页
Tips:
MySQL
突然瞬间变慢可能就是在刷脏页(flush)
。
3.引发数据库的 flush 过程场景
- redo log 满了:这时候系统会停止所有更新操作,把
checkpoint
往前推进,redo log
留出空间可以继续写。checkpoint
可不是随便往前修改一下位置就可以的。比如图2
中,把checkpoint
位置从CP
推进到CP’
,就需要将两个点之间的日志(浅绿色部分),对应的所有脏页都flush
到磁盘上。 - 系统内存不足:当需要新的内存页,而内存不够用的时候,就要淘汰一些数据页,空出内存给别的数据页使用。如果淘汰的是“脏页”,就要先将脏页写到磁盘。
- MySQL 认为系统“空闲”的时候:系统会见缝插针地找时间,只要有机会就刷一点“脏页”
- MySQL 正常关闭的情况:这时候,
MySQL
会把内存的脏页都flush
到磁盘上,这样下次MySQL
启动的时候,就可以直接从磁盘上读数据,启动速度会很快。
4.flush 场景性能影响分析
- redo log 满了:出现这种情况的时候,整个系统就不能再接受更新了,所有的更新都必须堵住。
- 系统内存不足:
内存不够用了,要先将脏页写到磁盘
,这种情况其实是常态。InnoDB
用缓冲池(buffer pool)
管理内存,缓冲池中的内存页有三种状态: - 还没有使用的
- 使用了并且是干净页
- 使用了并且是脏页
5.InnoDB 刷脏页的控制策略
- InnoDB 所在主机的 IO 能力
- 相关参数:innodb_io_capacity,这个值建议设置成磁盘的 IOPS
- 磁盘的 IOPS 测试工具:
- 工具名称:
fio
- 测试命令
- 工具名称:
fio -filename=$filename -direct=1 -iodepth 1 -thread -rw=randrw -ioengine=psync -bs=16k -size=500M -numjobs=10 -runtime=10 -group_reporting -name=mytest
- 刷脏页因素
- 脏页比例上限
- 相关参数:
innodb_max_dirty_pages_pct
,默认值是75%
- 计算说明:
InnoDB
每次写入的日志都有一个序号,当前写入的序号跟checkpoint
对应的序号之间的差值,我们假设为N
。InnoDB
会根据这个N
算出一个范围在0
到100
之间的数字,这个计算公式可以记为F2(N)
。F2(N)
算法比较复杂,你只要知道N
越大,算出来的值越大就好了。然后,根据上述算得的F1(M)
和F2(N)
两个值,取其中较大的值记为R
,之后引擎就可以按照innodb_io_capacity
定义的能力乘以R%
来控制刷脏页的速度。
- 相关参数:
- 脏页比例
- 说明:脏页比例是通过
Innodb_buffer_pool_pages_dirty/Innodb_buffer_pool_pages_total
得到的,需要合理地设置innodb_io_capacity
的值,并且平时要多关注脏页比例,不要让它经常接近75%
。 - 命令:
- 说明:脏页比例是通过
select VARIABLE_VALUE into @a from global_status where VARIABLE_NAME = 'Innodb_buffer_pool_pages_dirty';
select VARIABLE_VALUE into @b from global_status where VARIABLE_NAME = 'Innodb_buffer_pool_pages_total';
select @a/@b;
-
是否连带刷相邻脏页:
- 说明:在准备刷一个脏页的时候,如果这个数据页旁边的数据页刚好是脏页,就会把这个“邻居”也带着一起刷掉;而且这个把
邻居
拖下水的逻辑还可以继续蔓延,也就是对于每个邻居数据页,如果跟它相邻的数据页也还是脏页的话,也会被放到一起刷。 - 相关参数:
innodb_flush_neighbors
参数就是用来控制这个行为的,值为1
的时候会有上述的连坐
机制,值为0
时表示不找邻居,自己刷自己的。在MySQL 8.0
中,innodb_flush_neighbors
参数的默认值已经是0
了。
- 说明:在准备刷一个脏页的时候,如果这个数据页旁边的数据页刚好是脏页,就会把这个“邻居”也带着一起刷掉;而且这个把
-
WAL:
- 优点:利用
WAL
技术,数据库将随机写转换成了顺序写,大大提升了数据库的性能。 - 问题:脏页会被后台线程自动
flush
,也会由于数据页淘汰而触发flush
,而刷脏页的过程由于会占用资源,可能会让你的更新和查询语句的响应时间长一些。在文章里,我也给你介绍了控制刷脏页的方法和对应的监控方式。
- 优点:利用
扫码关注