MySQL-InnoDB 刷脏页的控制策略

以下内容来自mysql45讲第12讲-为什么我的mysql会抖一下

正确地告诉 InnoDB 所在主机的 IO 能力,这样 InnoDB 才能知道需要全力刷脏页的时候,可以刷多快。
innodb_io_capacity 这个参数它会告诉 InnoDB 你的磁盘能力。这个值建议设置成磁盘的 IOPS。
磁盘的 IOPS 可以通过 fio 这个工具来测试

fio -filename=/tmp/iops.txt -direct=1 -iodepth 1 -thread -rw=randrw -ioengine=psync -bs=16k -size=500M -numjobs=10 -runtime=10 -group_reporting -name=mytest

#参数说明:
-filename=/tmp/iops.txt  --测试文件或者磁盘名称,文件不存在会自动创建。
-direct=1  --测试过程绕过机器自带的缓冲区,使测试结果更真实。
-iodepth  --IO队列深度,主要根据设备的并行度来调整。
-thread
-rw=randrw  --随机读写,可选randwrite|randread|read|write|randrw
-ioengine=psync  --IO引擎使用psync,也可以选择libaio
-bs=16k  --单次IO块大小为16KB
-size=500M  --测试文件大小为 5GB。
-numjobs=10  --测试线程为10个
-runtime=10  --测试时间为10秒,也可以持续时间长点比如1000秒
-group_reporting  --设置显示结果,指定group_porting将汇总每个进程的信息。

其实,因为没能正确地设置 innodb_io_capacity 参数,而导致的性能问题也比比皆是。之前,就曾有其他公司的开发负责人找我看一个库的性能问题,说 MySQL 的写入速度很慢,TPS 很低,但是数据库主机的 IO 压力并不大。经过一番排查,发现罪魁祸首就是这个参数的设置出了问题。

他的主机磁盘用的是 SSD,但是 innodb_io_capacity 的值设置的是 300。于是,InnoDB 认为这个系统的能力就这么差,所以刷脏页刷得特别慢,甚至比脏页生成的速度还慢,这样就造成了脏页累积,影响了查询和更新性能

刷脏时机:

  1. InnoDB 的 redo log 写满了。这时候系统会停止所有更新操作,把 checkpoint 往前推进,redo log 留出空间可以继续写。
  2. 系统内存不足。当需要新的内存页,而内存不够用的时候,就要淘汰一些数据页,空出内存给别的数据页使用。如果淘汰的是“脏页”,就要先将脏页写到磁盘。
  3. MySQL 认为系统“空闲”的时候。
  4. MySQL 正常关闭的情况。这时候,MySQL 会把内存的脏页都 flush 到磁盘上,这样下次 MySQL 启动的时候,就可以直接从磁盘上读数据,启动速度会很快。

控制刷脏策略考虑因素:

  1. 脏页比例:
    参数innodb_max_dirty_pages_pct是控制脏页比例上限,默认值是75%, 表示当Buffer Pool中的脏数据页达到整体缓存的75%时,触发刷新的动作。
    脏页比例是通过Innodb_buffer_pool_pages_dirty/Innodb_buffer_pool_pages_total得到的

  2. redo log 写盘速度:
    一个内存配置为 128GB、innodb_io_capacity 设置为 20000 的大规格实例,正常会建议你将 redo log 设置成 4 个 1GB 的文件。

posted @   Enzo_Ocean  阅读(121)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示