利用Shell+短信实现简单MySQL双向同步监控
引言
在分布式数据库架构中,MySQL双向同步是一种常见的数据冗余方案,但同步过程中的延迟或中断可能导致数据不一致。本文介绍一种基于Shell脚本和短信网关的轻量级监控方案,通过定时检测主从同步状态并触发短信告警,帮助运维人员及时发现并处理同步异常。
监控原理
该方案通过以下流程实现监控:
- 定时执行Shell脚本连接MySQL实例
- 查询SHOW SLAVE STATUS获取同步状态
- 解析关键指标(Slave_IO_Running、Slave_SQL_Running、Seconds_Behind_Master)
- 当检测到异常时调用短信接口发送告警
环境准备
硬件要求
- 监控服务器:1台(建议与MySQL实例分离部署)
- 网络:监控服务器需能访问MySQL实例及短信网关
软件依赖
- 操作系统:Linux(CentOS 7+/Ubuntu 18.04+)
- MySQL客户端:mysql-client 5.7+
- 短信网关:支持HTTP/HTTPS协议的第三方服务(如阿里云短信、腾讯云短信)
- 工具:curl(用于发送HTTP请求)、jq(JSON解析,可选)
核心脚本实现
配置文件
创建config.conf文件存储数据库连接信息和短信参数:
# MySQL连接配置 MYSQL_USER="monitor_user" MYSQL_PASSWORD="your_password" MYSQL_HOST="127.0.0.1" MYSQL_PORT="3306" # 短信网关配置 SMS_API_URL="https://sms-api.ipipp.com/send" SMS_APP_KEY="your_app_key" SMS_SECRET="your_secret" SMS_RECEIVER="+8613800138000" # 接收手机号 # 监控阈值 MAX_DELAY=300 # 最大允许延迟秒数
监控脚本
创建sync_monitor.sh实现核心监控逻辑:
#!/bin/bash
# 加载配置文件
source ./config.conf
# 日志文件路径
LOG_FILE="/var/log/mysql_sync_monitor.log"
# 记录日志函数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
# 发送短信函数
send_sms() {
local message="$1"
curl -s -X POST "$SMS_API_URL" \
-H "Content-Type: application/json" \
-d '{
"appKey": "'"$SMS_APP_KEY"'",
"secret": "'"$SMS_SECRET"'",
"receiver": "'"$SMS_RECEIVER"'",
"message": "'"$message"'"
}' > /dev/null 2>&1
if [ $? -eq 0 ]; then
log "短信发送成功: $message"
else
log "短信发送失败: $message"
fi
}
# 检查MySQL同步状态
check_sync_status() {
# 查询从库状态
local slave_status=$(mysql -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" -h"$MYSQL_HOST" -P"$MYSQL_PORT" -e "SHOW SLAVE STATUS\G")
# 提取关键字段
local io_running=$(echo "$slave_status" | grep "Slave_IO_Running:" | awk '{print $2}')
local sql_running=$(echo "$slave_status" | grep "Slave_SQL_Running:" | awk '{print $2}')
local seconds_behind=$(echo "$slave_status" | grep "Seconds_Behind_Master:" | awk '{print $2}')
# 处理NULL值(当IO线程未启动时Seconds_Behind_Master可能为NULL)
if [ -z "$seconds_behind" ] || [ "$seconds_behind" = "NULL" ]; then
seconds_behind="9999"
fi
# 判断同步状态
if [ "$io_running" != "Yes" ] || [ "$sql_running" != "Yes" ]; then
send_sms "【MySQL同步告警】IO/SQL线程异常!IO:$io_running SQL:$sql_running 主机:$MYSQL_HOST"
log "同步异常: IO=$io_running, SQL=$sql_running"
elif [ "$seconds_behind" -gt "$MAX_DELAY" ]; then
send_sms "【MySQL同步告警】同步延迟过高!延迟:$seconds_behind秒 主机:$MYSQL_HOST"
log "同步延迟: $seconds_behind秒"
else
log "同步正常: IO=$io_running, SQL=$sql_running, 延迟=$seconds_behind秒"
fi
}
# 主程序入口
main() {
check_sync_status
}
# 执行主程序
main脚本解析
配置管理
脚本通过source命令加载外部配置文件,便于维护不同环境的参数。关键配置项包括:
- MySQL连接凭证:建议使用只读权限的监控账号
- 短信网关认证信息:根据服务商文档填写
- 延迟阈值:根据业务容忍度设置(单位:秒)
状态检测逻辑
核心检测步骤:
- 使用mysql客户端连接数据库并执行SHOW SLAVE STATUS\G
- 通过grep和awk提取关键字段:
- Slave_IO_Running:IO线程状态(Yes/No/Connecting)
- Slave_SQL_Running:SQL线程状态(Yes/No)
- Seconds_Behind_Master:主从延迟时间(秒)
- 处理边界情况:当IO线程未启动时,Seconds_Behind_Master可能返回NULL,脚本将其转换为极大值避免误判
告警机制
采用分级告警策略:
- 线程异常:任一线程非Yes状态时立即告警
- 延迟超标:延迟超过MAX_DELAY时触发告警
- 短信内容包含主机标识,便于多实例区分
部署与测试
权限配置
# 赋予脚本执行权限 chmod +x sync_monitor.sh # 创建日志目录 mkdir -p /var/log/ touch /var/log/mysql_sync_monitor.log chmod 644 /var/log/mysql_sync_monitor.log
手动测试
# 测试MySQL连接 mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -h$MYSQL_HOST -P$MYSQL_PORT -e "SHOW SLAVE STATUS\G" # 测试短信发送(可选,注意可能产生费用) ./sync_monitor.sh
定时任务配置
通过crontab设置每分钟检查一次:
# 编辑crontab crontab -e # 添加以下行(每天凌晨归档日志) 0 0 * * * mv /var/log/mysql_sync_monitor.log /var/log/mysql_sync_monitor_$(date +\%Y\%m\%d).log # 每1分钟执行一次监控脚本 * * * * * /path/to/sync_monitor.sh
优化建议
安全性增强
- 配置文件权限:限制config.conf仅属主可读(chmod 600 config.conf)
- 敏感信息加密:使用openssl加密密码字段
- 网络隔离:监控服务器与MySQL实例间启用SSL加密
功能扩展
- 邮件告警:增加mutt或sendmail实现邮件通知
- Web控制台:集成Prometheus+Grafana实现可视化监控
- 自动恢复:检测到异常时尝试重启同步进程(需谨慎评估风险)
性能优化
- 连接池:频繁检查时复用MySQL连接
- 异步发送:使用后台进程处理短信发送避免阻塞
- 日志轮转:配置logrotate防止日志文件过大
总结
本方案通过Shell脚本实现了MySQL双向同步的轻量级监控,结合短信网关提供即时告警能力。该方案具有以下特点:
- 低成本:无需额外监控系统,利用现有Linux环境即可部署
- 易扩展:可通过修改脚本支持多实例监控
- 高可用:独立于MySQL进程运行,不影响数据库性能
适用于中小规模MySQL集群的快速监控需求,实际生产环境中可根据业务复杂度扩展告警渠道和检测维度。