首先引入两个概念
脏页:当内存数据页和磁盘数据页不一致时,内存页叫脏页。
干净页:一致则为干净页。
平时一些执行很快的更新操作,其实就是在写内存和日志。出现抖动(突然某个简单的sql执行的很慢)可能就是在执行flush刷脏页(更新磁盘中的旧数据)。
刷脏页的四种情况
1、redo log写满了,此时会暂停所有更新操作,推进cp(checkpoint点),重新腾出空间。
2、内存满了。会淘汰一些数据页,若淘汰的是脏页,需要先flush掉脏页。
3、当mysql服务空闲时,会自动进行脏页的flush。
4、关闭mysql时,会对旧数据进行更新。
第三四种情况属于空闲情况,一般不会对性能产生影响。所以主要探讨前两种情况。
针对第一种情况,会暂停所有的更新操作,这种情况是需要尽量避免的。针对第二种情况,某个查询如果发现内存中找不到,并且内存满了,便会淘汰一些内存页,如果内存页是脏页,还需要淘汰之前进行flush。如果一个查询需要淘汰的脏页比较多,也会影响查询性能。
针对以上两种情况,innodb有对应的脏页控制策略来避免上述情况。
这就要用到 innodb_io_capacity 这个参数了,它会告诉 InnoDB 你的磁盘能力,也就是全力刷盘的能力。这个值建议设置成磁盘的IOPS,IOPS的测试命令为:
fio -filename=$filename -direct=1 -iodepth 1 -thread -rw=randrw -ioengine=psync -bs=16k -size=500M -numjobs=10 -runtime=10 -group_reporting -name=mytest
但是肯定不可能mysql一直在全力刷磁盘吧,总需要提供读写等服务吧。所以我们需要设置一个合理的百分比,让引擎分配合理的资源用来刷盘。
那怎么计算这个比例呢 ?默认是参照两个参数
1、innodb_max_dirty_pages_pc(脏页比例上限),innodb会根据
当前的脏页比例计算出一个值假设为F1,再根据当前日志序号计算出另一个值F2,两个值的较大值就是这个比例。