真正需要告警的是mysql健康状态而非进程存活,关键指标包括threads_connected、threads_running、slow_queries、seconds_behind_master和uptime,可通过show global status等命令轻量获取,推荐用shell脚本配合crontab轮询监控。

MySQL 主动监控哪些关键状态指标
真正需要告警的不是“MySQL 是否在运行”,而是它是否在健康地服务请求。重点关注:Threads_connected(连接数突增/突降)、Threads_running(活跃线程飙高)、Slow_queries(慢查询持续增长)、Seconds_behind_master(主从延迟超阈值)、Uptime(意外重启)。这些值都能通过 SHOW GLOBAL STATUS 或 SHOW SLAVE STATUS 直接获取,无需安装额外插件。
用 shell 脚本 + mysql 命令行做轻量级轮询监控
别一上来就上 Prometheus+Alertmanager——小团队或单实例场景,一个带条件判断的 shell 脚本更可控、更易排查。核心是用 mysql -N -s -e 获取纯数值,避免解析表头干扰:
#!/bin/bash
HOST="127.0.0.1"
PORT="3306"
USER="monitor"
PASS="xxx"
<h1>获取活跃线程数</h1><p>RUNNING=$(mysql -h$HOST -P$PORT -u$USER -p"$PASS" -N -s -e "SHOW GLOBAL STATUS LIKE 'Threads_running';" 2>/dev/null | awk '{print $2}')
if [ "$RUNNING" -gt 50 ]; then
echo "$(date): ALERT: Threads_running=$RUNNING > 50" | logger -t mysql-monitor</p><h1>这里可加 curl 发钉钉/企业微信,或 mail 发邮件</h1><p>fi</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill2334" title="MySQL"><img
src="https://img.php.cn/upload/skill/000/000/081/178900927846657.jpg" alt="MySQL" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill2334" title="MySQL" class="overflowclass">MySQL</a>
<p class="overflowclass">编写正确的MySQL查询,避免字符集、索引和锁方面的常见陷阱。</p>
</div>
<a rel="nofollow" href="/xiazai/skill2334" title="MySQL" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
-
-N去掉列名,-s禁用表格格式,确保输出是Threads_running 42这样的两列,awk '{print $2}'才能稳定取值 - 密码明文写脚本有风险,建议改用
~/.my.cnf配置文件并设chmod 600,然后去掉命令中-p参数 - 不要用
sleep 1在脚本里死循环——交给crontab每 30 秒跑一次(*/1 * * * * /path/to/check.sh配合sleep $((RANDOM%30))可缓解并发冲击)
监控主从延迟时必须处理 NULL 和 IO/SQL 线程异常
Seconds_behind_master 为 NULL 不代表延迟 0,而是复制已中断。只判断数值大小会漏掉最危险的情况:
# 先检查 SQL/IO 线程是否都为 Yes
SLAVE_IO=$(mysql -e "SHOW SLAVE STATUS\G" 2>/dev/null | grep "Slave_IO_Running:" | awk '{print $2}')
SLAVE_SQL=$(mysql -e "SHOW SLAVE STATUS\G" 2>/dev/null | grep "Slave_SQL_Running:" | awk '{print $2}')
if [[ "$SLAVE_IO" != "Yes" || "$SLAVE_SQL" != "Yes" ]]; then
echo "$(date): CRITICAL: Slave thread broken (IO:$SLAVE_IO, SQL:$SLAVE_SQL)" | logger -t mysql-monitor
fi
<h1>再查延迟(注意:字段名实际是 Seconds_Behind_Master,大小写敏感)</h1><p>DELAY=$(mysql -N -s -e "SHOW SLAVE STATUS;" 2>/dev/null | awk '{print $33}') # 第33列是 Seconds_Behind_Master(5.7+)
if [[ "$DELAY" = "NULL" || "$DELAY" -gt 300 ]]; then
echo "$(date): ALERT: Replication delay is $DELAY seconds" | logger -t mysql-monitor
fi</p>
- 不同 MySQL 版本
SHOW SLAVE STATUS输出列数不同(5.6 是第32列,5.7+ 是第33列),用\G格式再 grep 更稳妥,但性能略差;用列索引快,需按版本校验 -
Seconds_behind_master在 GTID 模式下可能长期为NULL,此时应结合Retrieved_Gtid_Set和Executed_Gtid_Set对比判断进度
告警触发后必须附带上下文,否则无法快速定位
只发“Threads_running > 50”没用。同一时间至少补三行关键诊断信息:
echo "$(date): High load detected" echo "→ Threads_running: $RUNNING" echo "→ Processlist top 3: $(mysql -N -s -e "SELECT CONCAT(user,'@',host),time,info FROM information_schema.processlist WHERE TIME > 60 ORDER BY TIME DESC LIMIT 3;" | head -n3)" echo "→ Last 5 slow log entries: $(tail -n5 /var/log/mysql/mysql-slow.log 2>/dev/null | tail -n3)"
- 避免在告警消息里执行耗时操作(如全量
processlist),用LIMIT和WHERE精准过滤 - 如果启用了
slow_query_log,记得确认日志路径——SELECT @@slow_query_log_file;,别硬编码 - 所有外部命令(
tail、logger、curl)必须加2>/dev/null或超时控制,防止监控脚本自身卡死
最常被忽略的是权限和超时:监控用户必须有 PROCESS 权限(查 processlist)、REPLICATION CLIENT(查主从状态),且连接要设 --connect-timeout=5,否则数据库响应慢时脚本会 hang 住整个 crontab。










