背景与需求
在 WordPress 或高并发应用场景下,MySQL 服务可能因资源耗尽、连接数过多或内部错误而意外停止。手动恢复耗时且可能造成长时间服务中断。因此,部署一个自动监控和重启 MySQL 的脚本至关重要,可实现无人值守的故障恢复。
基础监控脚本(端口检测)
此脚本通过检测 MySQL 默认的 3306 端口来判断服务状态。若端口未监听,则尝试重启 MySQL 服务,并记录日志。
#!/bin/bash
# 基础版:通过检测3306端口监控MySQL
LOG_FILE="/home/wwwlogs/mysql_messages"
# 检查mysqld进程是否存在
pgrep -x mysqld &> /dev/null
if [ $? -ne 0 ]
then
echo "MySQL stopped at time: $(date)" >> "$LOG_FILE"
/etc/init.d/mysql restart
sleep 15
# 重启后再次检查端口
MYSQLPORT=$(netstat -tln | grep ":3306" | awk '{print $4}' | awk -F: '{print $2}')
if [ "$MYSQLPORT" = "3306" ]
then
echo "MySQL restart successful at time: $(date)" >> "$LOG_FILE"
else
echo "MySQL restart failed at time: $(date)" >> "$LOG_FILE"
# 可配置邮件告警(需安装mailx或sendmail)
# mail -s "[Alert] MySQL restart failed on $(hostname)" admin@example.com < "$LOG_FILE"
fi
else
echo "MySQL server is running at $(date)"
fi
脚本说明与配置
1. 日志路径:请确保 /home/wwwlogs/ 目录存在且有写入权限,或修改为其他目录。
2. 重启命令:根据你的系统初始化系统(如 systemd 或 sysvinit),重启命令可能为 systemctl restart mysql 或 service mysql restart,请按实际情况调整。
3. 端口检测方法:除了 netstat,也可使用以下命令(可能需要安装对应工具):
ss -tln | grep :3306(推荐,更高效)lsof -i:3306nmap localhost -p 3306 | grep open(需安装 nmap)
部署与定时执行
将脚本保存(例如 /usr/local/bin/mysql_monitor.sh),并配置执行权限和定时任务。
# 1. 保存脚本并赋予执行权限
chmod +x /usr/local/bin/mysql_monitor.sh
# 2. 编辑当前用户的crontab
crontab -e
# 3. 添加一行,每5分钟执行一次监控脚本
*/5 * * * * /bin/bash /usr/local/bin/mysql_monitor.sh >/dev/null 2>&1
# 4. 重启crond服务(部分系统为cron)
systemctl restart crond # 或 service cron restart
增强版监控脚本(端口+连接检测)
仅检测端口可能不足,因为 MySQL 可能“假死”(进程在但无法响应查询)。此版本增加了使用数据库账号执行简单查询的检测,更可靠。
#!/bin/bash
# 增强版:端口检测 + 数据库连接测试
MYSQL_USER="root" # 监控用数据库用户(建议创建专用只读用户)
MYSQL_PASS="YourStrongPassword" # 对应用户密码
LOG_FILE="/var/log/mysql_monitor.log"
EMAIL_ADDR="admin@example.com" # 告警邮箱
# 函数:检测MySQL端口是否监听
function check_port {
ss -tln | grep -q ":3306 "
return $?
}
# 函数:测试数据库连接
function check_connection {
timeout 5 mysql -u"$MYSQL_USER" -p"$MYSQL_PASS" -e "SELECT 1;" &> /dev/null
return $?
}
# 函数:重启MySQL服务
function restart_mysql {
echo "[$(date)] Attempting to restart MySQL..." >> "$LOG_FILE"
systemctl restart mysql 2>> "$LOG_FILE"
sleep 10
}
# 函数:发送告警邮件
function send_alert {
local subject="[CRITICAL] MySQL service failure on $(hostname)"
local body="MySQL service failed to restart after multiple attempts. Please check manually."
echo "$body" | mail -s "$subject" "$EMAIL_ADDR"
}
# 主逻辑
if check_port && check_connection; then
echo "[$(date)] MySQL is healthy." >> "$LOG_FILE"
exit 0
else
echo "[$(date)] MySQL check failed. Port or connection test error." >> "$LOG_FILE"
restart_mysql
# 重启后再次检查
if check_port && check_connection; then
echo "[$(date)] MySQL restarted successfully." >> "$LOG_FILE"
else
echo "[$(date)] MySQL restart FAILED." >> "$LOG_FILE"
send_alert
exit 1
fi
fi
增强版脚本重要说明
- 安全性:不要在脚本中硬编码 root 密码。建议创建一个仅用于监控的数据库用户(例如
monitor_user),授予最小的USAGE权限,并将密码存储在受保护的文件中(如~/.my.cnf)。 - 依赖:确保系统已安装
mail命令(或配置其他邮件发送方式)和timeout命令。 - 资源占用:定时任务频率不宜过高(如每分钟),避免对系统造成额外负担。通常 2-5 分钟一次即可。
总结与建议
自动重启脚本是应对 MySQL 意外停止的临时解决方案,而非根本解决之道。若 MySQL 频繁宕机,应深入排查原因:
- 检查错误日志:
/var/log/mysql/error.log或/var/log/mysqld.log。 - 监控系统资源:内存、CPU、磁盘 I/O 和空间是否充足。
- 优化数据库配置:调整
max_connections、innodb_buffer_pool_size等关键参数。 - 考虑高可用方案:对于核心业务,建议部署主从复制或集群,实现真正的服务高可用。
将上述任一脚本部署到你的 LNMP 服务器,并配置好定时任务,即可大幅降低因 MySQL 服务中断导致网站不可用的风险。