携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情
一、什么是MySQL刷脏页
InnoDB 在处理更新语句的时候,只做了写日志这一个磁盘操作。这个日志叫作 redo log(重做日志),在更新内存写完 redo log 后,就返回给客户端,本次更新成功。
内存里的数据写入磁盘的过程,术语就是 flush。
当内存数据页跟磁盘数据页内容不一致的时候,我们称这个内存页为“脏页”。内存数据写入到磁盘后,内存和磁盘上的数据页的内容就一致了,称为“干净页” 。
二、为什么会有脏页
当内存中与磁盘中的数据不一致时,内存中的数据页就称为脏页。mysql因为WAL机制,在更新时,首先会更新内存,再写redo log。一般情况下是在空闲时,将redo log刷新到磁盘中。
三、什么时候会触发数据库flush(刷脏页)
1,redo log写满,系统会停止一切更新操作,把 checkpoint 往前推进,redo log 留出空间可以继续写;
2,mysql认为空闲的时候,主动去刷新;
3,系统内存不足。当需要新的内存页,而内存不够用的时候,就要淘汰一些数据页,空出内存给别的数据页使用。如果淘汰的是“脏页”,就要先将脏页写到磁盘。
4,MySQL正常关闭的情况。这时候,MySQL会把内存的脏页都flush到磁盘上,这样下次MySQL启动的时候,就可以直接从磁盘上读数据,启动速度会很快。
四、控制刷脏页的策略:
1,正确设置innodb_io_capacity参数,它会告诉InnoDB你的磁盘能力。合理地设置innodb_io_capacity的值,并且平时要多关注脏页比例,不要让它经常接近75%。
2,indodb刷脏页会涉及“连坐”操作,即如果刷新某个脏页,判断连续的数据页是否也是脏页,一直循环,这样无疑会提高io效率,会减少很多随机io,而刷脏页的过程由于会占用资源,可能会让你的更新和查询语句的响应时间长一些。
参数innodb_flush_neighbors 为1 代表开启连坐机制,0为关闭。
在MySQL 8.0中,innodb_flush_neighbors参数的默认值已经是0了。