“抖”:sql执行变慢了,随机出现,持续时间短。
刷脏页的原因:
innodb在更新数据的时候,更新内存,写redo log,(并没有将内存数据页同步到磁盘上)。
这里引出两个概念:
- 脏页 内存页与磁盘页数据不一致的内存页
- 干净页 内存页与磁盘页数据一致的内存页
flush脏页就是将内存页的数据更新到磁盘
刷脏页的触发时机:
- redo log 写满了。flush脏页。
- 内存不足,淘汰数据页,淘汰的数据页是脏页,就会flush。
(flush脏页写磁盘保证了数据页的两个状态1.数据页在内存中,内存中的数据一定是正确的2.内存中没有数据,磁盘上的一定是正确的,读入内存后返回。) - mysql认为系统空闲的时候刷脏页。
- mysql正常关闭的时候。
(innodb在更新数据的,会更新内存,我们请求数据的时候,先尝试从内存读,内存不存在就从磁盘读入内存再返回,请求完数据后,内存中一定会有数据,可以加速下一次请求数据)
情况1时暂停更新,写性能跌为零,为redo log腾出一些空间而刷脏页。
情况2时内存不足,mysql 使用 buffer pool分配内存,内存页分为脏页,干净页,未使用页。innodb的策略是尽量使用内存,所以未使用页的情况会变的很少。当内存不足的情况下,会去bufferpool申请数据页,这里会用缓存淘汰算法进行页面的淘汰一般用lru,淘汰的页面是干净页直接返回,淘汰脏页必须刷脏页。
刷脏页对应的控制策略:
1.innodb_io_capacity 设置为系统的IOPS,如果这个值设置小了,那么可能会出现刷脏页的速度小于脏页产生的速度,造成脏页累计,从而影响查询与更新的性能。
刷脏页速度的参考点:1.内存中的脏页比例,2.redo log的写盘速度
innodb_max_dirty_pages_pct脏页比例上限(默认75%)
脏页比例的计算是innodb_buffer_pool_dirty/innodb_buffer_pool_pages_total(尽量不要让当前脏页比接近75%)
innodb如何选择刷脏页的速度。首先通过当前脏页比例算出一个值M,之后根据redo log的写盘速度计算出一个值N,R=max(N,M),引擎按照R%的速度刷脏页。
innodb_flush_neighbors这个参数会控制在刷脏页时是否会将相邻的脏页也一起刷掉,而且这个动作是会蔓延的,如果是机械硬盘建议设置成0,如果是ssd的话就可以直接设置成1了。