flush的时机
当更新一条SQL的时候,其实是先写undo日志,然后更新数据,二阶段写入redo 和 bin log。对于更新数据,其实是只修改了changer buffer中的数据,比如将name = qxlxi, 但是磁盘数据页没有和内存页数据保持一致。
内存页和磁盘数据页内容不一致时为脏页,内存数据写入磁盘后,内存和磁盘上数据页一致时为干净页。
那么有几种时机会进行flush。
1.redo log写满
当redo log写满后,就会开始将数据写入磁盘中。如图所示,会先将cp到cp’的数据刷新到磁盘中,然后继续写redo log。
2.系统内存不足
当系统内存不足时,会淘汰一批数据页,如果淘汰的是脏页,那么先将脏页写入到磁盘中。
3.MySQL空闲
mysql空闲的时候,就会处理脏页数据的同步
4.mysql正常关闭
mysql正常关闭,将内存的脏页flush到磁盘上。下次启动直接从磁盘上读取数据,启动数据快。
好了,来分析下,对于mysql空闲和关闭进行flush其实是正常,redo log写满场景其实需要避免,出现这种情况,其实所有更新必须堵住,更新数为0。
第二种内存不够用,其实InnoDB用缓冲池管理内存,缓冲池中的内存有三种状态。
- 没有使用、使用了是干净页、使用了是脏页。
当读入的数据页没有在内存的时候,就会申请从缓冲池中申请一块数据页,根据LRU算法将内存页淘汰,如果是干净页可以直接复用,如果时脏页,需要先将脏页刷到磁盘,然后变成干净页才能使用。
所以总结下:
1.一个查询如果淘汰的脏页个数太多,就会导致查询的响应时间变长,(涉及flush刷盘)
2.日志写满,更新全部堵住,写性能跌为0。
InnoDB需要控制脏页比例的机制,来避免上面的两种情况。
InnoDB 刷脏页的控制策略
sql innodb_io_capacity
告诉InnoDB所在主机的IO能力,InnoDB才知道需要权利刷脏页的时候,可以刷多块,通过这个参数决定,通常设置成磁盘的 IOPS。
决定InnoDB刷盘速度的两个因素,一个是脏页比例,另外就是redo log写盘速度。
sql innodb_io_capacity
不要接近75%
当一个查询请求执行的时候,需要flush一个脏页,而这个脏页flush的时候,旁边的也是脏页,那么就会跟着刷新。bashinnodb_flush_neighbors
可以决定是否启用连坐机制。1是,0否。如果时机械硬盘建议设置为0,SSD则可以采用1,8.0目前采用0.
小结
WAL机制,其实就是为了避免随机写入,而采用追加日志的方式,先写入redo log。然后异步刷盘的操作。提升数据库的性能,但是也引入了脏页的问题,脏页flush会占用资源从而影响更新和查询语句的响应时间。所以掌握flush的刷新时机,已经相关的策略配置是非常重要的。