19_MySQL 告警与自动化运维 —— 告警分级收敛 / Webhook / 定时巡检 / 脚本库

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 通知------值班人看到"恢复"才算闭环,不能只发不恢复。


七、要点速记

  1. 告警三级:P0 业务中断打电话、P1 隐患发群@值班、P2 日报邮件。
  2. Alertmanager 三件套:group_by 合并、inhibit 抑制衍生、silence 维护屏蔽。
  3. 告警链路与被监控库解耦:Alertmanager 独立部署,库挂了告警还能发。
  4. Webhook 中转:Alertmanager → 8060 中转 → 飞书/钉钉机器人。
  5. 自动化只做低风险可逆动作:切主/删数据保留人工确认。
  6. 告警要闭环:触发→处置→恢复(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 数据库全栈运维实战系列》监控与巡检篇。欢迎收藏、交流。

相关推荐
代码不停25 分钟前
Spring Aop
java·数据库·spring
FungLeo29 分钟前
成为全栈·基础补充·Linux 服务器入门
linux·运维·服务器·ssh·部署·成为全栈
keyipatience31 分钟前
MySQL 学习(4)常用数据类型
数据库·mysql
达梦产品与服务33 分钟前
SQLark V4.2 更新 | 新增TiDB、SSL安全连接、数据字典、清空/截断表等40+项功能已上线!
数据库·安全·tidb·ssl
爱和冰阔落42 分钟前
【Linux网络】TCP 服务器怎么写?从 listen、accept 到 read/write,手写完整 Echo Server
linux·运维·服务器·网络
鲁邦通物联网1 小时前
工业装备OEM远程服务架构:边缘计算网关与售后运维系统设计
运维·边缘计算·数据采集·工业数据采集·边缘计算网关·plc数采·厂内数采
码农阿豪1 小时前
SQL Server数据迁移完成后,凌晨的数据库告警该怎么查?
数据库·sqlserver
JosieBook1 小时前
【鸿蒙PC GUI适配】chiaki-ng 移植的工程实践:Qt6/QML 与 ArkUI 的混合窗口架构
华为·架构·harmonyos