禅道博客

分享专业技术知识,文章内容干货满满

为什么Mysql有时候会不稳定

2022-09-26 10:03:55
代婷婷
原创 151

内存数据页和磁盘数据页内容不一致的时候,这个内存页为“脏页”。内存数据写入到磁盘后,内存和磁盘上的数据页的内容就一致了,称为“干净页”。不论是脏页还是干净页,都在内存中。平时的更新操作就是写内存和日志,mysql突然变慢的那个瞬间可能就是在刷脏页(flush)。


一、什么时候会引发flush过程:

  • InnoDB的redo log写满了。这时系统会停止更新操作,把一部分日志flush到磁盘上。之后就可以继续写入日志。
  • 系统内存不足,当需要更新内存页的时候,内存不够用,需要淘汰一些数据页,如果淘汰的是脏页,就需要先将脏页写到磁盘。
  • mysql认为系统空闲的时候把redo log里面的操作记录到磁盘中,为了提高效率,mysql有空就会刷脏页。
  • Mysql正常关闭的情况下,会把内存的脏页都flush到磁盘上,下次mysql启动的时候就可以直接从磁盘上读数据。


二、这四种场景对性能的影响:

第一种是redo log 写满了,InnoDB要尽量避免这种情况,因为出现这种情况,整个系统就不能再更新了。

第二种是内存不够用了,这种情况是常态,InnoDB用缓冲池管理内存,缓冲池中内存页有三种状态:
  • 没有使用;
  • 使用了是干净页;
  • 使用了是脏页。


InnoDB的策略是尽量使用内存,因此对一个长时间使用的库来说,未被使用的页面很少。当要读入的数据页没有在内存的时候,就需要到缓冲池种申请一个数据页,这时候是把最久不用的数据页从内存中淘汰掉:如果淘汰的是一个干净页,就直接释放出来复用,如果是脏页,就需要先将脏页刷到磁盘,变成干净页才能复用。如果出现以下两种情况会明显影响性能:

  • 一个查询需要淘汰的脏页个数太多。
  • 日志写满,写性能跌为0。

第三种是mysql空闲时候的操作,这是系统没什么压力;

第四种是数据库关闭的时候,也不需要关注性能问题。


三、InnoDB刷脏页的控制策略:

1.设置innodb_io_capacity参数,是告诉InnoDB你的磁盘能力。 InnoDB 的刷盘速度就是要参考这两个因素:一个是脏页比例,一个是 redo log 写盘速度。合理地设置 innodb_io_capacity 的值,并且平时要多关注脏页比例,不要让它经常接近 75%。

2.一个查询请求需要在执行过程中先 flush 掉一个脏页时,这个查询就可能要比平时慢了。而 MySQL 中的一个机制,可能让你的查询会更慢:在准备刷一个脏页的时候,如果这个数据页旁边的数据页刚好是脏页,就会把这个“邻居”也带着一起刷掉;而且这个把“邻居”拖下水的逻辑还可以继续蔓延,也就是对于每个邻居数据页,如果跟它相邻的数据页也还是脏页的话,也会被放到一起刷。在 InnoDB 中,innodb_flush_neighbors 参数就是用来控制这个行为的,值为 1 的时候会有上述的“连坐”机制,值为 0 时表示不找邻居,自己刷自己的。


发表评论
评论通过审核后显示。