昨天有个用户在群里找到我们,他说:

应用已经稳定运行一年多,最近在做投放,访问时频繁出现“数据库连接失败”。
服务器负载不高,以前也从没出现过。
每次重启宝塔或服务器又能恢复,但过一阵又会复现。

这种问题,比“直接宕机”更麻烦。因为它不是持续异常,而是“偶发失效”。排查从这里开始。

第一步:第一反应——怀疑 OOM

类似“数据库连接失败但是重启恢复”的场景,其实碰到过很多次,我的第一直觉是:会不会是内存被打满,被系统杀了?

而且用户反馈的是在流量投放的时候会出现,想着会不会是突发访问较大导致的。

于是直接让用户去执行:

dmesg -T | grep -i -E 'killed process|oom'

按照以往的经验,如果发生过 OOM,应该能直接看到类似:

Killed process xxxx (mysqld)

的输出,但是用户截图反馈什么都没出现,所以这个时候按照经验已经在设想既然 dmesg 查不到 OOM ≈ 不是 OOM,于是我们把这个先放到了一边

图片

第二步:查看 MySQL 当前状态

继续确认数据库服务状态:

systemctl status mysql

其实这里本来是想着从进程守护的日志中找点什么错误信息的,但很遗憾,结果正常:

图片

程序层面报数据库连接错误,但 MySQL 服务看起来是正常的。这就开始变得诡异。(当时忽略了用户已经重启过服务器的事情)

第三步:查看 MySQL 错误日志

继续去翻 MySQL 的错误日志:

tail -n 200 /www/server/data/*.err

本来想着预期会看到什么关键的异常报错,但MySQL error log 里基本都是启动/恢复类 Note 和 Warning,比如说诸如此类 “ready for connections”“Starting crash recovery”“Crash recovery finished”。

没有看到 mysqld 自己崩溃、段错误、InnoDB fatal error 之类的关键报错。没有明显异常。

到这里为止:

  • 内核层面没看到 OOM

  • 服务状态正常

  • 数据库日志正常

排查进入僵局。

第四步:重新审视问题特征

阶段性的复盘一下,回头去看看用户描述:不是持续挂掉,是间歇性失效,重启后恢复,一段时间后又复现

这意味着问题可能发生在某个瞬间。而我们刚才看的都是“当前状态”。于是我们决定翻历史系统日志。

第五步:直接查系统 messages

这次我执行了:

egrep -i "Out of memory|oom-killer|Killed process|mysqld" /var/log/messages* | tail -n 200

图片

这一步,终于出现了关键记录:

php-fpm invoked oom-killerKilled process xxxx (mysqld)

到这里,方向彻底明确。数据库不是自己崩溃。是被系统 OOM Killer 杀掉的。

为什么一开始 dmesg 没查到?

回头看第一步:

dmesg -T | grep -i -E 'killed process|oom'

之所以没有输出,是因为:

  • 机器中间已经发生过重启

  • dmesg 只保留当前内核缓冲区

  • 之前的 OOM 记录已经不存在

也就是说:OOM 发生过,但是在我排查的时候,dmesg 已经看不到了如果只查 dmesg,很容易直接排除 OOM。这也是这次排查最大的弯路。

END

很多“数据库连接错误”的问题,并不是数据库本身出问题。如果:MySQL 日志干净、服务状态看起来正常、问题具有“间歇性”、重启可以恢复

一定要往系统层面翻历史日志。有时候数据库没有崩,只是被系统“牺牲”。这次排查不复杂,复杂的是我们走过的弯路。

其实面板数据库界面里有一个进程守护功能,原理大概是通过计划任务定时检测数据库是否在运行,没有就启动,在一定程度上能缓解数据库挂了导致业务出现问题的影响,有需要的也可以开一下:

图片

图片

官网论坛上有良哥写的 MySQL 简单调优,感兴趣的小伙伴也可以阅读下:

图片

附:OOM 是什么?为什么“挂的总是数据库”?

OOM(Out Of Memory)指的是:系统内存耗尽

当 Linux 发现内存不够用、系统可能整体失去响应时,会触发内核的保护机制(OOM Killer),强制结束一个或多个进程来“保住系统还能活着”。

这也是为什么你会看到一种很迷惑的现象:应用端报:数据库连接失败、MySQL 自己日志却很干净、重启后又能恢复

因为很多时候,MySQL 不是“自己崩溃”,而是被系统在某个瞬间“强制结束”了。(这也是我们这次排查里:dmesg 查不到 ≠ 没发生过 的根源之一。),最后附两张示意图吧:

图片

图片

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐