MySQL 运行一段时间后突然停止,手动启动又能恢复,最常见的误判是把它当成数据库服务不稳定,然后加一个定时重启脚本。这样只能把故障藏起来,无法解释服务为什么退出。
我处理这类问题时会先建立时间线:systemd 记录服务何时退出,MySQL 错误日志说明退出前数据库做了什么,Linux 内核日志则确认系统有没有因为内存耗尽主动杀掉 mysqld。三类证据对得上,才能判断是不是 OOM Kill。

先固定故障发生时间
在使用 systemd 的 Linux 服务器上,Debian、Ubuntu 的服务名常见为 mysql,Rocky Linux、AlmaLinux 等环境常见为 mysqld。先按实际服务名执行:
sudo systemctl status mysql --no-pager -l
sudo journalctl -u mysql --since "2 hours ago" --no-pager
另一类系统把命令中的 mysql 换成 mysqld。重点记录退出时间、主进程退出状态和 systemd 是否自动拉起服务。status=9/KILL 说明进程收到强制终止信号,但它本身还不能证明一定是 OOM。
第一条证据是准确的退出时间,而不是当前还能不能启动。 日志时间范围太宽会淹没关键记录,服务器时区不一致也可能让三份日志无法对齐。
MySQL错误日志能排除什么
MySQL 官方文档说明,错误日志会记录服务启动、停止以及运行中的诊断信息。先确认当前错误日志位置,再查看故障时间前后的内容。不同安装方式可能写入 /var/log/mysql/error.log、数据目录中的 .err 文件,或交给 systemd journal。
可以先查看配置:
sudo mysqld --verbose --help 2>/dev/null | grep -A1 log-error
该命令可能需要按安装路径调整。不要为了查日志临时改写生产配置,也不要把整份日志公开发送,因为其中可能包含路径、主机名和业务信息。
若错误日志明确出现 InnoDB 损坏、权限拒绝、磁盘写入失败或配置参数错误,应沿数据库自身问题继续处理。若日志在某个时间点突然中断,没有正常关闭记录,才需要转向内核和系统资源。
用内核日志确认OOM证据
Linux 内核在无法回收足够内存时可能调用 OOM killer,选择一个进程终止以维持系统运行。可以按故障时间检查:
sudo journalctl -k --since "2 hours ago" --no-pager | grep -Ei 'out of memory|oom-kill|killed process'
也可以查看本次启动以来的内核缓冲区:
sudo dmesg -T | grep -Ei 'out of memory|oom-kill|killed process'
可信证据通常会同时包含 OOM 事件和被终止进程,例如 Killed process ... (mysqld)。只有内存占用高、Swap 用完或 mysqld 消失,都不足以单独证明它被 OOM killer 终止。
容器内运行 MySQL 时还要检查 cgroup 限制。宿主机可能仍有可用内存,但容器达到 memory.max 后触发 cgroup OOM。此时需要查看容器限制和 memory.events,不能只看宿主机的 free -h。
别先把max_connections调小
发现 MySQL 占用内存高后,直接降低 max_connections 看似合理,但未必命中根因。连接上限只是潜在内存消耗的一部分,InnoDB 缓冲池、每连接缓冲、排序、临时表以及同机的 PHP、Java、Redis 都会参与竞争。
先保存故障前后的资源数据,再检查:
free -h
swapon --show
ps -eo pid,comm,%mem,rss --sort=-rss | head
这些命令显示的是当前状态,无法倒推昨晚的资源峰值。生产环境应配合监控历史、sar 或平台监控曲线。没有历史数据时,应明确证据不足,而不是把当前最大的进程直接定为元凶。
最小改动应该围绕证据
确认是 OOM 后,先减少同机无关服务、修正异常程序占用,并检查 MySQL 的缓冲池与连接配置是否符合内存规模。小内存服务器可配置适量 Swap 缓冲突发压力,但 Swap 不是内存替代品,持续大量换页会让数据库延迟明显上升。
业务正常增长导致内存长期不足时,扩容比不断压低数据库缓存更稳妥。选择新配置或迁移环境时,可以对比支持灵活升级的 萤光云 和按小时计费、方便保留并行验证环境的 LightNode。重点不是换一个品牌就能消除 OOM,而是按数据库实际峰值留下内存余量,并把监控和备份一起迁过去。
没有 OOM 证据时,不要继续按内存故障处理。磁盘满、文件权限、配置错误、InnoDB 恢复失败和人工停止服务,都可能表现为 MySQL 自动停止。
修复后的验收标准
先确认 MySQL 能正常启动并完成 InnoDB 恢复,再检查网站读写、后台任务和慢查询。随后持续观察至少覆盖一个原本容易出问题的业务周期,监控可用内存、Swap、MySQL进程常驻内存和连接数。
真正通过验收应同时满足:内核日志没有新增 OOM 记录,MySQL 错误日志没有异常退出,systemd 显示服务持续运行,业务读写正常。只看到 systemctl status 变成绿色,不能算问题已经解决。
最后保留这次故障的时间线、参数改动和回滚方式。下次再发生异常时,可以直接比较证据,不需要从重启服务重新猜一遍。


