19_MySQL 告警与自动化运维 ------ 告警分级收敛 / Webhook / 定时巡检 / 脚本库
系列定位 :《MySQL 数据库全栈运维实战系列》第 19 篇,与《Oracle 数据库全栈运维实战系列(VMware 版)》同构对标(Oracle 19 告警自动化)。适用版本 :MySQL 8.0(5.7 差异随文标注)。官方文档:Alertmanager 官方文档、Prometheus 告警、MySQL 8.0 Reference Manual。
一、告警与自动化体系全景

图 1

图 2
| 环节 | 组件 | 作用 |
|---|---|---|
| 触发 | Prometheus alert rules | 计算告警表达式(第17篇已配) |
| 收敛 | Alertmanager | 分组、抑制、静默、路由 |
| 通知 | Webhook(飞书/钉钉/邮件) | 分级推送 |
| 自动化 | cron 巡检 + 脚本库 | 定时任务、自动处置 |
二、告警分级标准

图 3
| 级别 | 定义 | 示例 | 通知方式 | 响应要求 |
|---|---|---|---|---|
| P0 | 业务已中断 | mysql_up=0、复制线程中断、磁盘满 |
电话/短信 | 立即(5 分钟内) |
| P1 | 即将/可能中断 | 连接数>80%、主从延迟>60s、长事务 | 飞书/钉钉@值班 | 30 分钟内 |
| P2 | 隐患/趋势 | Buffer 命中率下降、慢查询增多、备份临近过期 | 邮件/工单日报 | 当日处理 |
# alert 规则中用 labels.severity 打级别(解释:与第17篇规则衔接)
# severity: P0 / P1 / P2
2.1 类比 Oracle 速查:告警分级收敛对照
Oracle 侧没有 Prometheus 这套,告警主要靠 Alert Log(告警日志)+ EMCC 事件规则/通知方法。MySQL 的 Alertmanager 分级收敛与之同构:
| MySQL(Prometheus + Alertmanager) | Oracle(19c + EMCC) | 说明 |
|---|---|---|
mysql_up == 0 触发 P0 |
EMCC 事件"数据库 Down" | 实例中断最高级别 |
Alertmanager severity: P0/P1/P2 |
EMCC 事件规则的"Critical/Warning" | 分级思路一致 |
group_by 同类合并 |
EMCC 告警聚合同类事件 | 避免同故障刷屏 |
inhibit_rules 抑制衍生 |
EMCC 关联/抑制规则 | 主故障时压制次级告警 |
amtool silence 维护屏蔽 |
EMCC Blackout/维护窗口 | 升级演练不骚扰 |
| webhook → 飞书/钉钉 | EMCC Notification Method(邮件/SNMP) | 通知通道 |
| Alert Log(MySQL error log) | Oracle Alert Log(alert_*.log) | 错误日志是根因追溯入口 |
(类比 Oracle:MySQL 的 error.log 对应 Oracle 的 alert log;Alertmanager 管"实时告警分发",EMCC 管"事件规则+通知方法",二者职责分工几乎一一对应。)
三、Alertmanager 收敛配置(官方:Configuration)
告警不收敛 = 告警风暴(一篇钉钉炸几百条)。Alertmanager 用 分组/抑制/静默 三件套解决。
# /etc/alertmanager/alertmanager.yml
global:
resolve_timeout: 5m
route:
group_by: ['alertname', 'cluster'] # 解释:按告警名+集群分组,同一类告警合并成一条
group_wait: 30s # 解释:组内等 30s 再发,攒批
group_interval: 5m # 解释:同组新告警间隔 5m 发一次
repeat_interval: 4h # 解释:未恢复的告警 4h 重复提醒
receiver: 'default'
routes:
- match:
severity: P0
receiver: 'p0-phone'
group_wait: 0s # 解释:P0 立即发不等待
- match:
severity: P1
receiver: 'p1-dingtalk'
inhibit_rules: # 解释:抑制------实例 down 时不再发它下面的衍生告警
- source_match:
alertname: MySQLDown
target_match:
severity: P1
equal: ['instance']
receivers:
- name: 'default'
webhook_configs:
- url: 'http://127.0.0.1:8060/dingtalk/default'
- name: 'p0-phone'
webhook_configs:
- url: 'http://127.0.0.1:8060/p0'
- name: 'p1-dingtalk'
webhook_configs:
- url: 'http://127.0.0.1:8060/dingtalk/p1'
| 机制 | 说明 | 解决的问题 |
|---|---|---|
| group_by | 同类告警合并 | 一次故障炸出几十条同类 |
| inhibit | 主告警存在时压制衍生告警 | 实例 down 时还报"连不上"等次级告警 |
| silence | 维护期手动屏蔽 | 升级演练期间不骚扰 |
| routes | 按 severity 分发 | P0 打电话、P2 发邮件 |
3.1 静默管理 amtool(维护期屏蔽)
升级演练、计划内维护期间,用
amtool临时屏蔽告警,避免满屏轰炸;维护结束静默自动过期。
# ① 列出当前所有告警(解释:看哪些在 firing / resolved)
amtool alert query
# ② 创建静默:屏蔽所有 MySQLDown 告警 2 小时(解释:--expires 到期自动解除)
amtool silence add alertname=MySQLDown --author="dba" \
--comment="周末升级维护,预计 2h" --expires=2h
# ③ 按实例静默(解释:只屏蔽 192.168.10.51 这台的告警)
amtool silence add instance=192.168.10.51:9104 --author="dba" \
--comment="节点下线演练" --duration=1h
# ④ 查看当前静默(解释:拿到静默 ID)
amtool silence query
# ⑤ 提前撤销静默(解释:维护结束,立即恢复告警)
amtool silence expire <silence_id>
| 操作 | 命令 | 场景 |
|---|---|---|
| 查告警 | amtool alert query |
值班排查 |
| 加静默 | amtool silence add ... --expires=2h |
升级/演练 |
| 查静默 | amtool silence query |
确认谁在屏蔽 |
| 撤静默 | amtool silence expire <id> |
维护结束 |
静默红线 :静默要有明确
comment与author,且必须设过期时间 ;长期不撤的静默等于关闭告警,是运维事故高发点。(类比 Oracle:这一步对应 EMCC 的 Blackout/维护窗口------EM 里给目标设"维护期",期间不发通知;MySQL 用amtool silence达到同样效果。)
3.2 告警收敛矩阵(分级 × 通道 × 时段)
| 级别 | 工作时段(9:00-21:00) | 夜间/周末(21:00-9:00) | 重复间隔 | 收敛策略 |
|---|---|---|---|---|
| P0 | 电话 + 飞书@值班 | 电话 + 短信 | 不等待 group_wait=0 | 单独分组、立即发 |
| P1 | 飞书@值班群 | 飞书群(不@) | 4h | group_by=alertname 合并 |
| P2 | 邮件/工单 | 次日日报汇总 | 24h | 合并进日报,不单独推送 |
# 夜间路由(解释:在 routes 里按时间/标签分流,P1 夜间不@人)
routes:
- match:
severity: P0
receiver: 'p0-phone'
group_wait: 0s
- match:
severity: P1
receiver: 'p1-dingtalk'
- match:
severity: P2
receiver: 'p2-email'
repeat_interval: 24h
四、Webhook 机器人推送(飞书/钉钉)
Alertmanager 本身不会直接发飞书/钉钉,需要一个 webhook 中转(如 prometheus-webhook-dingtalk 或自研)把告警 JSON 转成机器人消息卡片。

图 4
# 启动 webhook 中转(解释:把 Alertmanager 的告警转成钉钉消息)
./prometheus-webhook-dingtalk \
--dingtalk.url="https://oapi.dingtalk.com/robot/send?access_token=xxxx" \
--web.listen-address=":8060"
4.1 webhook 回调脚本示例(自研中转,飞书/钉钉 JSON 模板)
没有现成 webhook 中转时,用一个轻量 HTTP 脚本接住 Alertmanager POST 的 JSON,再转成飞书/钉钉卡片。Alertmanager 推过来的是
{"status":"firing","alerts":[{...}]}结构。
#!/usr/bin/env python3
# webhook_relay.py(解释:Flask 极简中转,接 Alertmanager,转飞书机器人)
from flask import Flask, request
import requests
app = Flask(__name__)
FEISHU_WEBHOOK = "https://open.feishu.cn/open-apis/bot/v2/hook/xxxx"
@app.route("/feishu", methods=["POST"])
def relay():
data = request.get_json(force=True)
for a in data.get("alerts", []):
labels = a.get("labels", {})
# 解释:拼成飞书富文本卡片,含级别、实例、摘要、开始时间
card = {
"msg_type": "text",
"content": {"text": "[%s] %s\n实例:%s\n摘要:%s\n时间:%s" % (
a.get("status"),
labels.get("alertname"),
labels.get("instance"),
a.get("annotations", {}).get("summary"),
a.get("startsAt"))}
}
requests.post(FEISHU_WEBHOOK, json=card)
return "ok"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8060) # 解释:Alertmanager 配置指向此地址
// 飞书/钉钉机器人收到的消息卡片示例(解释:status=firing 为触发,resolved 为恢复)
{
"msg_type": "text",
"content": {
"text": "[firing] MySQLDown\n实例:192.168.10.51:9104\n摘要:MySQL 实例不可用\n时间:2026-10-09T08:00:00Z"
}
}
# Alertmanager receiver 指向自研中转(解释:webhook_configs 直接 POST 到上面的脚本)
receivers:
- name: 'p1-feishu'
webhook_configs:
- url: 'http://127.0.0.1:8060/feishu'
send_resolved: true # 解释:恢复时也发一条 resolved 卡片,形成闭环
安全 :飞书/钉钉机器人 webhook 建议加"自定义关键词"(如必须含
MySQL)与 IP 白名单;中转脚本只监听内网,不对公网暴露。(类比 Oracle:EMCC 的 Notification Method 支持邮件/SNMP/REST Webhook 推事件;MySQL 这里用自研 webhook 中转推飞书/钉钉,是同一类"通知通道"在开源生态的实现。)
# 验证 Alertmanager 已加载配置(解释:热加载)
amtool config show
systemctl reload alertmanager
VMware 注意事项 :Alertmanager 与 webhook 中转发告警,必须保证告警链路与被监控库解耦------不要让 Alertmanager 跑在被监控的 MySQL 虚机上,否则库宕机时 Alertmanager 一起挂、告警发不出去(单点)。生产上 Alertmanager 单独部署一台虚机,且保证它到飞书/钉钉的出网(HTTPS 443)畅通。
五、定时巡检与自动化处置(脚本库)
5.1 定时巡检(衔接第 18 篇)
# crontab(解释:每天 08:00 巡检;评分<75 自动触发告警 webhook)
0 8 * * * /opt/scripts/mysql_inspect.sh -h192.168.10.51 -uexporter -p'Exp@Pass2026' \
> /var/log/mysql_inspect/$(date +\%F).log 2>&1
5.2 脚本库目录规范与 cron 排期
/opt/scripts/
├── inspect/ # 巡检脚本(第18篇)
│ └── mysql_inspect.sh
├── backup/ # 备份脚本(第07篇 xtrabackup)
│ ├── full_backup.sh
│ └── binlog_backup.sh
├── failover/ # 切换脚本(第14篇)
│ ├── promote_replica.sh
│ └── check_replica_lag.sh
├── clean/ # 清理脚本(旧 binlog / 慢日志轮转)
│ └── clean_old_binlog.sh
└── notify/ # 告警通知封装
└── webhook_relay.py
| 任务 | cron 表达式 | 频率 | 说明 |
|---|---|---|---|
| 健康巡检 | 0 8 `` * |
每天 08:00 | 评分 <75 触发 P1 |
| 全量备份 | 0 2 `` 0 |
周日 02:00 | xtrabackup 物理备份 |
| binlog 备份 | /5 `` * |
每 5 分钟 | 持续归档 binlog |
| 磁盘清理 | 0 6 `` * |
每天 06:00 | 磁盘>80% 清旧 binlog |
| 备份恢复演练 | 0 3 1 |
每月 1 号 03:00 | 验证备份可恢复 |
5.3 自动化处置示例:自动清理旧 binlog
#!/bin/bash
# clean_old_binlog.sh(解释:磁盘使用率超 80% 时自动 PURGE 7 天前 binlog)
USAGE=$(df -P /var/lib/mysql | awk 'NR==2{print $5}' | tr -d '%')
if [ "$USAGE" -gt 80 ]; then
mysql -uexporter -p'Exp@Pass2026' -e \
"PURGE BINARY LOGS BEFORE DATE(NOW() - INTERVAL 7 DAY);"
echo "磁盘使用率 ${USAGE}%,已清理 7 天前 binlog"
fi
自动化红线 :自动处置只做低风险、可逆的动作(清旧日志、摘除延迟从库);切主、删数据等高风险动作必须保留人工确认,不能全自动。
六、告警闭环流程

图 5

图 6
Alertmanager 在告警恢复时会自动发一条
resolved通知------值班人看到"恢复"才算闭环,不能只发不恢复。
七、要点速记
- 告警三级:P0 业务中断打电话、P1 隐患发群@值班、P2 日报邮件。
- Alertmanager 三件套:group_by 合并、inhibit 抑制衍生、silence 维护屏蔽。
- 告警链路与被监控库解耦:Alertmanager 独立部署,库挂了告警还能发。
- Webhook 中转:Alertmanager → 8060 中转 → 飞书/钉钉机器人。
- 自动化只做低风险可逆动作:切主/删数据保留人工确认。
- 告警要闭环:触发→处置→恢复(resolved)→复盘→调阈值。
八、踩坑记录(实测汇总)
| # | 坑 | 现象 | 解决 |
|---|---|---|---|
| 1 | 没分组 | 一次故障群里炸几百条 | group_by 同类合并 |
| 2 | 没抑制 | 实例 down 又报一堆衍生 | 配 inhibit_rules |
| 3 | Alertmanager 和库同机 | 库挂告警发不出 | 独立虚机部署告警链路 |
| 4 | 告警只发不恢复 | 值班不知是否已好 | 开 resolve 通知 |
| 5 | P0 也等 group_wait | P0 延迟 30s 才到 | P0 路由 group_wait=0 |
| 6 | 机器人 token 泄露 | 群被刷 | 加关键词/IP 限制 |
| 7 | 自动切主无确认 | 误切造成双主 | 高风险动作人工确认 |
| 8 | webhook 出网不通 | 告警静默失败 | 放行 HTTPS 443 出网 |
| 9 | repeat_interval 太短 | 未恢复告警刷屏 | 4h 合理值 |
| 10 | 维护期没 silence | 升级演练满屏告警 | 提前配 silence |
九、参考资料(官方正式文档)
| 主题 | 官方链接 |
|---|---|
| Alertmanager 配置官方文档 | https://prometheus.io/docs/alerting/latest/configuration/ |
| Prometheus 告警规则 | https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/ |
| amtool(告警管理) | https://prometheus.io/docs/alerting/latest/amtool/ |
| prometheus-webhook-dingtalk | https://github.com/timonwang/prometheus-webhook-dingtalk |
| MySQL 8.0 Reference Manual | https://dev.mysql.com/doc/refman/8.0/en/ |
| PURGE BINARY LOGS | https://dev.mysql.com/doc/refman/8.0/en/purge-binary-logs.html |
本文章属于《MySQL 数据库全栈运维实战系列》监控与巡检篇。欢迎收藏、交流。