过去有一段时间,线上的游戏数据库不定时出现慢查询,通过慢查询日志排查,都是些简单的通过主键update语句,并且数据库表都是简单的结构,单纯看sql语句没能发现有什么异常,看CPU和内存也没什么异常,因为使云数据库,很多宿主机上系统参数的性能都无法查询到,后面和他们的相关人员沟通查询到是io出现瓶颈导致的,经过复查数据库发现Innodb_io_capacity=20000,但是系统是HDD,很大概率这里会出现问题,后面云数据库提供商给免费升级到ssd后就没出过问题。
Innodb_io_capacity定义的是innodb刷脏页的能力,定义高于系统本身的能力,自然会容易出问题,这个值该怎么设置保证innodb可以正常发挥呢?可以参考fio命令测试出的系统io能力进行定义。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_io_capacity相关的刷脏页机制
innodb有WAL(Write-AheadLogging)机制,在处理更新语句时候,只做了写日志这一磁盘操作,这个日志叫做redo log,在特定时间再把内存中的数据库写入磁盘flush。当内存数据页跟磁盘数据页内容不一致的时候,我们称这个内存页为“脏页”。内存数据写入到磁盘后,内存和磁盘上的数据页的内容就一致了,称为“干净页”。而偶尔出现的慢查询,可能就是在刷脏页(flush)。
那么,什么情况会引发数据库的 flush 过程呢?
- redo log满了
- 内存不够用了,要先将脏页写到磁盘
- mysql认为系统空闲的时候
- mysql正常关闭前