当内存数据页跟磁盘数据页内容不一致的时候,我们称这个内存页为“脏页”。内存数据写入到磁盘后,内存和磁盘上的数据页的内容就一致了,称为“干净页”。
InnoDB用缓冲池(buffer pool)管理内存,缓冲池中的内存页有三种状态:
第一种是,还没有使用的;
第二种是,使用了并且是干净页;
第三种是,使用了并且是脏页。
InnoDB的策略是尽量使用内存,因此对于一个长时间运行的库来说,未被使用的页面很少。而当要读入的数据页没有再内存的时候,就必须到缓冲池中申请一个数据页。这时候只能把最久不使用的数据页从内存中淘汰掉;如果要淘汰的是一个干净页,就直接释放出来复用;但如果是脏页,就必须将脏页先刷到磁盘,变成干净页后才能复用。
所以,刷脏页虽然是常态,但是出现以下两种情况,都是会明显影响性能的:
1、一个查询要淘汰的脏页个数太多,会导致查询的响应时间明显变长;
2、日志写满,更新全部堵住,写性能跌为0,这种情况对敏感业务来说,是不能接受的。
所以,InnoDB需要有控制脏页比例的机制,来尽量避免上面的这两种情况。
InnoDB刷脏页的控制策略
首先,需要正确的告知InnoDB所在的主机的IO能力,这样InnoDB才能知道需要权力刷脏页的时候,可以刷多快。
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_flush_neighbors:mysql有一个机制,可能导致查询慢:再准备刷一个脏页的时候,如果这个数据页旁边的数据页刚好是脏页,就会把这个“邻居”页带着一起刷掉;而且这个把“邻居”拖下水的逻辑还可以继续蔓延,也就是对于每个邻居数据页,如果跟它相邻的数据页页是脏页的话,也会被放到一起刷。
innodb_flush_neighbors=1时,就有上述的机制,值为0时表示不找邻居,自己刷自己的。
网友评论