MySQL一问一实验

第35问:InnoDB 刷脏页慢,会影响我的业务么?

2021-04-16  本文已影响0人  爱可生开源社区
image

问题:

InnoDB 刷脏页刷得比较慢,我的业务会受到影响么?如何进行试验验证?

实验

先宽油建个数据库:

image

找到这个数据库负责刷脏页的线程号:

image

我们起一个 gdb,(别害怕,本实验没有什么太深的调试技巧。)

image

我们输入以下命令:

image

前三行命令,允许 gdb 只停下一个线程,而不是停下所有线程。

最后一行 attach,我们让 gdb 管控我们的 MySQL 实例。

image

经过一堆看不懂的输出,gdb 已经管控了 MySQL 实例,可以输入命令了。

我们先输入 info thread,拿到 MySQL 的线程表,找到负责刷脏页的线程在 gdb 中对应的 ID,是第 13 号线程:

image

然后我们在 thread 13 上打一个断点(我们为什么知道要在 pc_sleep_if_needed 处打断点呢?留待晚点解释):

image

紧接着就会看到 thread 13 停在了断点上,这根线程目前就停下来,不会再进行刷脏页了。

再来看一下各个线程的状态,有 1 号线程和 13 号线程停了下来:

image

我们将 1 号线程放开:

image

然后将 gdb 放在一边,现在开始给 MySQL 上压力,还是用我们常用的方法:

image

不停执行最后一句,会发现 insert 会卡住,观察一下 innodb status,

image

buffer pool 不再刷脏,无读无写。

数据页总共有 7745 页,而脏页总共有 6586 页,看上去还可以释放一些非脏页出来。

观察 redo log 的状态:

image

redo log 上一次 checkpoint 到当前的位置,一共有(945661967-869887159 =)75774808 字节(75M)。

而我们的 redo log 总大小有将近 100M(50331648*2 = 100663296 字节)。

image

看上去 redo log 的空闲也够用。

那么为什么我们不能继续进行业务呢?

我们将 innodb metrics 打开:

image

观察相关的 metrics:

image

可以看到 innodb 定义的两条水位线:redo log 尚未 checkpoint 的日志大小(modified age)的水位线,一条异步水位线,一条同步水位线(这两条水位线是 innodb 自动算出来的,不要问为什么合理)

当超过异步水位线时,MySQL 开始调动 IO 尽力刷脏页,但业务仍能正常进行;当超过同步水位线时,将阻塞业务等待刷脏页。

我们的场景下,modified age (=75774808) 刚好超过同步水位线,业务均开始阻塞。

至此,我们通过实验,验证了 innodb 刷脏页慢是会阻塞业务的。

江湖上一直有一个传说,处理 SQL 的线程会在紧急的状况下帮助刷脏页。

本实验中我们只停下了一个线程,大家也就可以验证这个传说不十分靠谱,所有的刷脏页都是通过专门的线程进行,处理 SQL 的线程只能提出刷脏页的需求,而不能直接动手。

扩展知识

一、

推荐阅读 percona 的文章:

https://www.percona.com/blog/2020/01/22/innodb-flushing-in-action-for-percona-server-for-mysql/

此文分析了 innodb 刷脏页的三个原因:脏页比例高、空闲页数低、adaptive flush(通过计算 redo log 的使用度进行不同程度的刷脏页策略),并给予了充分的讨论。

在本实验中,我们触发了 adaptive flush 的水位线,业务因此受到了影响。

二、

如果大家把这个卡顿的环境放置 10 分钟以上,就会发现 MySQL 崩溃了,error log 显示报错信息为:

image

当大家碰到 error log 出现 "Semaphore wait has lasted > 600 seconds" 字样时,不能简单判断其是什么原因,本实验是一种可能,还有许多其他可能,需要其他临床现象进行辅助诊断。

优秀的 MySQL DBA 应当远离“算命式运维”的危险思路。

三、

本实验有两处逻辑跳跃:

  1. 我们是怎么确定断点位置是 pc_sleep_if_needed 的?

  2. 我们怎么知道 redo log 存在水位线的?

这两个的答案都一样,就是使用 gdb 观察 MySQL 的堆栈。

可以使用 pstack 或者 gdb,观察 MySQL 在刷脏页线程或者 hang 住时候的堆栈,加以简单分析。

运维建议

建议大家将 InnoDB 刷脏页的三种原因和刷脏程度加入监控系统,可以据此分析业务是否由于这个原因受到影响。


关于 MySQL 的技术内容,你们还有什么想知道的吗?赶紧留言告诉小编吧!

image
上一篇 下一篇

猜你喜欢

热点阅读