MySQL 5.7 进程被系统 OOM Killer 杀掉导致宝塔中频繁显示“已停止”,需查 dmesg 或 /var/log/messages 确认 OOM 记录,调整 innodb_buffer_pool_size 至物理内存的 50%~60%,并部署守护脚本自动拉起。

MySQL 5.7 进程莫名退出,大概率是被系统 OOM Killer 杀掉了
宝塔面板里 MySQL 隔三差五显示“已停止”,点启动又能起来——这不是配置问题,而是 Linux 内核在内存不足时主动干掉了 mysqld 进程。查 /var/log/messages 或用 dmesg -T | grep -i "killed process",如果看到类似 Killed process 12345 (mysqld) 的记录,基本坐实 OOM。
根本原因不是 MySQL 自身崩溃,而是它申请的内存(尤其是 innodb_buffer_pool_size)超出了物理内存余量,触发内核 OOM Killer 机制。
-
innodb_buffer_pool_size建议设为物理内存的 50%~60%,切勿盲目设成 70% 以上 - 检查是否有其他服务(如 PHP-FPM、Redis、Nginx)同时吃内存,合起来超过总内存 90% 就危险
- 用
free -h和ps aux --sort=-%mem | head -10快速定位内存大户
别依赖宝塔自带的“开机自启”,要加进程守护脚本
宝塔的“开机自启”只是注册 systemd service,不解决运行中被杀后自动拉起的问题。必须手动加一个轻量级守护脚本,每 30 秒检测一次 mysqld 是否存活,挂了就重启。
把下面内容保存为 /root/mysql-guard.sh:
#!/bin/bash
while true; do
if ! pgrep -x "mysqld" > /dev/null; then
echo "$(date): mysqld not running, restarting..." >> /var/log/mysql-guard.log
/www/server/mysql/bin/mysqld_safe --defaults-file=/www/server/mysql/etc/my.cnf &
fi
sleep 30
done
- 给执行权限:
chmod +x /root/mysql-guard.sh - 加入开机自启:
echo "/root/mysql-guard.sh > /dev/null 2>&1 &" >> /etc/rc.local(确保/etc/rc.local有执行权限) - 不要用 systemd service 封装这个脚本——简单轮询比复杂 unit 更可靠,也更少引入新故障点
确认 MySQL 启动参数是否绕过了 my.cnf 配置
有些用户改完 /www/server/mysql/etc/my.cnf 发现不生效,是因为宝塔实际调用的是 mysqld_safe,而它可能额外传参覆盖了配置。运行 ps aux | grep mysqld,重点看命令行里有没有 --innodb-buffer-pool-size= 这类硬编码参数。
- 如果有,优先删掉这些显式参数,让
mysqld_safe完全读取my.cnf - 检查
[mysqld]段落下是否误写了[client]或[mysql]段的配置(它们对服务端无效) - 修改后务必用
/www/server/mysql/bin/mysqld --defaults-file=/www/server/mysql/etc/my.cnf --validate-config校验语法
宝塔日志里看不到 OOM 记录?那就直接看内核日志
宝塔面板日志(/www/wwwlogs/mysql.log)通常只记 MySQL 自身错误,OOM 是内核行为,得查系统层日志。最准的方式是:
- 实时监听:
dmesg -w | grep -i "killed process" - 回溯最近一次:
dmesg -T | grep -i "out of memory\|killed process" | tail -5 - 注意时间戳是否和 MySQL 停止时间吻合——这是判断依据,不是猜测
如果确实看到 OOM 记录,别急着调大 innodb_buffer_pool_size,先关掉没用的 PHP 扩展、限制 pm.max_children、甚至考虑加 1~2G swap(仅作缓冲,不替代内存优化)。










