关于mysql:第35问InnoDB-刷脏页慢会影响我的业务么

问题:

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

试验

先宽油建个数据库:

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

咱们起一个 gdb,(别胆怯,本试验没有什么太深的调试技巧。)

咱们输出以下命令:

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

最初一行 attach,咱们让 gdb 管控咱们的 MySQL 实例。

通过一堆看不懂的输入,gdb 曾经管控了 MySQL 实例,能够输出命令了。

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

而后咱们在 thread 13 上打一个断点(咱们为什么晓得要在 pc_sleep_if_needed 处打断点呢?留待晚点解释):

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

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

咱们将 1 号线程放开:

而后将 gdb 放在一边,当初开始给 MySQL 上压力,还是用咱们罕用的办法:

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

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

数据页总共有 7745 页,而脏页总共有 6586 页,看上去还能够开释一些非脏页进去。

察看 redo log 的状态:

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

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

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

那么为什么咱们不能持续进行业务呢?

咱们将 innodb metrics 关上:

察看相干的 metrics:

能够看到 innodb 定义的两条水位线:redo log 尚未 checkpoint 的日志大小(modified age)的水位线,一条异步水位线,一条同步水位线(这两条水位线是 innodb 主动算进去的,不要问为什么正当)

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

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

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

江湖上始终有一个传说,解决 SQL 的线程会在紧急的情况下帮忙刷脏页。

本试验中咱们只停下了一个线程,大家也就能够验证这个传说不非常靠谱,所有的刷脏页都是通过专门的线程进行,解决 SQL 的线程只能提出刷脏页的需要,而不能间接入手。

扩大常识

一、

举荐浏览 percona 的文章:

https://www.percona.com/blog/…

此文剖析了 innodb 刷脏页的三个起因:脏页比例高、闲暇页数低、adaptive flush(通过计算 redo log 的应用度进行不同水平的刷脏页策略),并给予了充沛的探讨。

在本试验中,咱们触发了 adaptive flush 的水位线,业务因而受到了影响。

二、

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

当大家碰到 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 的技术内容,你们还有什么想晓得的吗?连忙留言通知小编吧!

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理