宝塔面板显示MySQL“运行中”但实际进程已消失,属典型监控盲区;应通过mysqladmin ping验证真实状态,配合systemctl管理服务,并用脚本每2分钟检测重启,同时排查err日志中的InnoDB崩溃或内存不足等根本原因。

MySQL 进程消失但宝塔面板仍显示“运行中”
这是最典型的监控盲区:宝塔只检查 mysqld 进程名是否存在,而实际 MySQL 可能因内存溢出、磁盘满、配置错误(如 max_connections 超限)或 InnoDB 崩溃导致进程僵死或退出,但残留的 pid 文件或宝塔缓存状态未更新,造成“假运行”。此时网站 500、phpMyAdmin 打不开、mysql -u root -p 直接报 Can't connect to local MySQL server through socket。
实操建议:
- 先手动验证真实状态:
systemctl is-active mysqld或ps aux | grep mysqld | grep -v grep,别信面板图标 - 检查关键日志:
/www/server/data/*.err(尤其是最新时间戳的 err 日志),重点关注InnoDB: Database page corruption或Out of memory - 确认宝塔用的是系统服务还是自研守护:宝塔 8.x 默认用
systemctl管理,脚本必须调用systemctl restart mysqld,而非/etc/init.d/mysqld restart(后者在新版 CentOS/RHEL 已失效)
写一个轻量级 Shell 脚本检测并重启
不依赖第三方工具(如 monit)、不装 cronie 额外包,直接用系统自带 curl + mysqladmin + systemctl。核心逻辑是:连得上 socket 且能执行简单 SQL 才算真活。
示例脚本(保存为 /root/mysql_health_check.sh):
#!/bin/bash
# 检查 mysqladmin 是否可用(避免权限问题)
if ! command -v mysqladmin &> /dev/null; then
exit 1
fi
<h1>尝试用本地 socket 连接并执行 ping(比 telnet 3306 更准,绕过防火墙干扰)</h1><p>if mysqladmin --socket=/tmp/mysql.sock --user=root --password="你的root密码" ping &> /dev/null; then
exit 0
else</p><h1>记录故障时间便于排查</h1><pre class='brush:php;toolbar:false;'>echo "[$(date '+%Y-%m-%d %H:%M:%S')] MySQL down, restarting..." >> /var/log/mysql_monitor.log
systemctl restart mysqld
# 等待 3 秒再验证,防止刚启就判失败
sleep 3
if systemctl is-active --quiet mysqld; then
echo "[$(date '+%Y-%m-%d %H:%M:%S')] MySQL restarted successfully." >> /var/log/mysql_monitor.log
else
echo "[$(date '+%Y-%m-%d %H:%M:%S')] MySQL restart failed!" >> /var/log/mysql_monitor.log
fifi
注意点:
-
--socket=/tmp/mysql.sock必须和你的 MySQL 实际 socket 路径一致,查看方式:mysql -u root -p -e "SHOW VARIABLES LIKE 'socket';" - 密码写在命令行有安全风险,生产环境建议改用配置文件:
mysqladmin --defaults-file=/root/.my.cnf ping,其中/root/.my.cnf权限必须是600,内容为:[client] user=root password=你的密码
- 别用
pgrep mysqld判断——MySQL 崩溃后可能残留孤儿进程,mysqladmin ping是唯一可靠手段
用 crontab 每 2 分钟执行一次
宝塔面板的计划任务界面有时会吞掉脚本输出或权限异常,直接走系统 crontab 更稳。
执行:crontab -e,添加一行:
*/2 * * * * /bin/bash /root/mysql_health_check.sh >/dev/null 2>&1
关键说明:
-
*/2表示每两分钟,太频繁(如 30 秒)可能触发 MySQL 启动风暴;太宽松(如 10 分钟)会导致业务中断过长 -
/bin/bash显式指定解释器,避免某些系统默认 sh 不兼容 bash 语法(如$(date ...)) -
>/dev/null 2>&1屏蔽标准输出和错误,否则 cron 会发邮件(若装了 mailx),日志全走脚本里的>>追加到/var/log/mysql_monitor.log - 测试 cron 是否生效:
tail -f /var/log/cron,看是否有执行记录;再手动运行脚本确认日志生成
重启后连接不上?重点检查 socket 和权限
自动重启成功但 PHP 还连不上,90% 是路径或权限问题,和脚本本身无关。
常见卡点:
- MySQL 重启后 socket 文件路径变更:检查
my.cnf中socket配置是否被宝塔覆盖(宝塔修改配置会备份原文件到/www/server/mysql/my.cnf.bak),确保php.ini的mysqli.default_socket或 PDO DSN 中的unix_socket指向同一路径 - SELinux 强制拦截:CentOS 7/8 默认开启,执行
ausearch -m avc -ts recent | grep mysqld查看拒绝日志,临时放行:setsebool -P mysqld_connect_any on - 宝塔面板自身缓存:重启宝塔服务
bt restart,否则面板数据库管理页可能仍显示旧状态
真正难搞的不是脚本写不对,而是 MySQL 崩溃根源没解决——脚本只是止血,/www/server/data/*.err 里反复出现的错误必须人工介入,否则早晚又挂。


















