mysql笔记系列(十)sql执行突然变慢的原因

14.sql执行突然变慢的原因,有时候,一条语句执行很快,有时候又执行很慢。

mysql在执行更新操作的时候,写磁盘的时候,是写的redolog和内存,写完就返回更新成功, 此时数据文件并没有被更新。
内存数据和磁盘数据就不一致,这时候内存页也叫脏页,内存数据写入到磁盘之后,这个时候内存数据页就叫干净页,
这个过程叫flush 。

执行的很快的时候就是写内存和日志,执行的很慢的时候就是在flush。
flush的场景
1.当redolog的空间用完了,mysql就会停止所有的更新操作,把checkpoiont指针向前推进,留出来空间。
但是这个指针推进的前提是,将这段区间内对应的内存脏页都flush到磁盘数据里面。

2.当内存不够的时候,需要淘汰掉一部分不用的内存数据,然后加载新的数据,这时候如果淘汰的是脏页,那么需要将脏页写到磁盘中,再淘汰。
这样可以确保,如果内存中有数据,那么数据中就是最新的,如果内存中没有,那么磁盘中的数据就是最新的。

3.空闲的时候,系统自己慢慢把脏页flush到磁盘中。

4.mysql关闭的时候,也会将此时内存中的脏页都flush到磁盘中。

其中3 和4 对性能无影响。
1是致命的,一旦redolog用完了,就会将更新全部停掉,等待flush完成。应当尽量避免,
2是常态,淘汰数据是将最久没使用的数据页淘汰掉,但是如果一个查询要淘汰太多的脏页,会使得查询时间变长,因为每一个脏页淘汰之前都要将数据flush到磁盘上。

避免1和2影响性能的关键在于,控制flush的速度,如果太慢了,就会导致redolog不够或者内存脏页太多,太快了又会导致频繁写磁盘。
innoDB参照脏页比例和redolog的写盘速度,两个因素控制刷盘的速度。

innoDB还有一个策略,就是在flush一个脏页时,发现这个数据页旁边的也是脏页,也会将旁边的这个脏页也flush掉,而且这个机制是会“传染”的,也就是这个脏页的旁边也是脏页,那也会一起被flush。 这个策略在机械硬盘的时代有很大提升,减少了随机IO次数,但是现在都是固态硬盘,也就没那么大的必要。因此,在 MySQL 8.0 中,innodb_flush_neighbors 参数的默认值已经是 0 了。

注意:如果redolog设置的很小,那么体现出来的就是磁盘压力很小,但是数据库性能出现间歇性下跌。

你可能感兴趣的:(mysql)