|
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?用户注册
×
数据库监控告警体系搭建实战:从事后救火到事前发现
一、具体的问题
先说一个大家都不陌生的场景:周报里写"系统稳定运行 30 天",结果周三下午业务方在群里炸锅——下单接口超时,用户流失了一片。DBA 这边一脸茫然:日志看了一圈,监控大盘绿得发光,等用户报障进来已经有 40 分钟了。事后复盘,根因是连接数打满,而监控里根本没有连接数这个指标。
这类团队的问题不是"没有监控",而是监控是"装饰品":指标画了几十张图,告警配了上百条,但真正出事的那一项不在里面,或者在里面但没人看。这篇文章讲的,就是怎么从零搭一套"出事它先叫、没事它闭嘴"的数据库监控告警体系,以 MySQL 为例,思路同样适用于 Oracle 和 PG。
二、核心原理
第一条原则:监控指标要围绕"用户能感知到的故障"选,而不是围绕"DBA 能采集到的数据"选。 用户感知的是慢、是报错、是不可用,所以监控的第一层永远是 RED 三指标——延迟(Latency)、流量(Rate)、错误(Errors),数据库层面对应的是查询响应时间、QPS/TPS、错误连接数。资源类指标(CPU、磁盘、内存、连接数)是第二层,用来解释第一层为什么坏,这叫 USE 方法(资源的使用率、饱和度、错误)。
第二条原则:告警的敌人是狼来了。 一个每天误报二十条的告警体系,用不了一个月就会退化成"红色标注的装饰品",所有人默认它误报。所以告警必须分级:P0 级(主库不可写、磁盘将满)走电话;P1 级(主从延迟超标、连接数逼近上限)走 IM 群;P2 级(慢查询趋势上升)进日报。每条告警必须有明确的 owner 和对应的处置预案,没有预案的告警不发——因为它只会制造恐慌不会缩短恢复时间。
第三条原则:静态阈值天然不适配业务潮汐。 半夜两点 CPU 30% 对晚高峰业务是异常,对报表库是常态。解法有两类:一是给阈值分时段,二是用环比(和上一周期比)替代绝对值。监控告警的本质不是"发现数字大",而是"发现变化"。
三、实例参考(动手步骤)
下面给一套可以照抄的搭建过程,环境为 MySQL 8.0 + Prometheus 生态。
步骤 0:盘点必监控项。 动手之前先把清单定下来,MySQL 侧至少覆盖:连接数(Threads_connected / Max_used_connections)、活跃线程(Threads_running)、慢查询速率、主从延迟(Seconds_Behind_Master)、InnoDB 缓冲池命中率、磁盘剩余空间、备份任务最近一次成功时间。最后一项最容易漏——备份挂了没人知道,出事才发现备份是三个月前的,这种事故我见过不止一次。
步骤 1:部署 exporter。 下载 mysqld_exporter,创建只读监控账号,然后写抓取配置:
- # prometheus.yml 关键段
- scrape_configs:
- - job_name: "mysql"
- static_configs:
- - targets: ["10.0.0.11:9104", "10.0.0.12:9104"]
复制代码- CREATE USER 'exporter'@'10.0.0.5' IDENTIFIED BY '强口令' WITH MAX_USER_CONNECTIONS 3;
- GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'10.0.0.5';
复制代码
WITH MAX_USER_CONNECTIONS 3 这一句别省,防止监控自身把连接打满。
步骤 2:写告警规则。 prometheus 的 rules 文件里,每条规则三要素:表达式、持续时间 for、级别标签。几个核心示例:
- groups:
- - name: mysql.rules
- rules:
- - alert: MySQLConnectionsHigh
- expr: max_over_time(mysql_global_status_threads_connected[5m])
- / mysql_global_variables_max_connections > 0.8
- for: 5m
- labels: {severity: P1}
- annotations: {summary: "连接数超过上限 80%,实例 {{ $labels.instance }}"}
- - alert: MySQLReplicationLag
- expr: mysql_slave_status_seconds_behind_master > 60
- for: 3m
- labels: {severity: P1}
- - alert: MySQLSlowQueriesSpike
- expr: rate(mysql_global_status_slow_queries[10m]) > 0.5
- for: 10m
- labels: {severity: P2}
- - alert: MySQLDown
- expr: mysql_up == 0
- for: 1m
- labels: {severity: P0}
复制代码
for 字段是防抖的关键:瞬时抖动不告警,持续超阈值才告警。没配 for 的告警体系误报率至少翻三倍。
步骤 3:解决潮汐误报。 拿磁盘空间举例,业务高峰期日志写入快,绝对值阈值(如 15%)在高峰日天天误报。改成环比思路:用 predict_linear 预测 4 小时后是否耗尽,比固定阈值聪明得多:
- - alert: DiskWillFill
- expr: predict_linear(node_filesystem_avail_bytes{mountpoint="/data"}[2h], 4*3600) < 0
- for: 10m
- labels: {severity: P0}
复制代码
步骤 4:告警路由分级。 Alertmanager 的 route 配置把 P0 导电话网关、P1 导值班群、P2 导日报邮件:
- route:
- receiver: dba-daily
- routes:
- - match: {severity: P0}
- receiver: dba-phone
- group_wait: 10s
- - match: {severity: P1}
- receiver: dba-oncall-im
- - match: {severity: P2}
- receiver: dba-daily
复制代码
步骤 5:演练验证。 体系搭完不算完,要在测试实例上把每条告警真实触发一遍:把 max_connections 临时调小、故意 stop 掉从库 IO 线程制造延迟、dd 写满一块测试盘。告警链路里任何一个环节(exporter 挂了、webhook 地址错了、值班人手机静音)都会让"配了等于没配",演练是唯一的验证方式。
四、实操检查清单
- [ ] RED 第一层指标齐全:查询延迟 P95/P99、QPS/TPS、错误连接数有大盘且有告警
- [ ] 连接数告警阈值设为 max_connections 的 80%,且历史 Max_used_connections 不超此线
- [ ] 主从延迟告警配了 for 防抖,阈值与业务容忍度对齐(示例 60 秒)
- [ ] 磁盘告警用 predict_linear 预测式,绝对值阈值仅作兜底
- [ ] 备份任务成功状态纳入监控,最近一次成功时间超 24 小时告警
- [ ] 每条告警有 severity 分级,P0/P1/P2 分别路由到电话/IM/日报
- [ ] 每条告警标注 owner 与处置预案链接,无预案的告警删除
- [ ] 所有规则配置 for 持续时间,防止瞬时抖动误报
- [ ] exporter 账号带 MAX_USER_CONNECTIONS 限制,监控自身不构成风险
- [ ] 每条告警规则在测试环境真实触发演练过一次,链路全通
- [ ] 误报率每周复盘一次,连续误报的规则下线或调参
几个容易踩的坑
一是"指标越多越好"的幻觉。大盘塞了 60 张图,出事时没人看第二屏。控制在首屏 8 张以内,其余收进下钻页面。
二是告警直接发大群。P1/P2 告警进业务群,很快会被聊天淹没。告警必须进独立值班渠道,和日常沟通隔离。
三是只监控主库。从库、备份实例、中间件(如 ProxySQL)经常是先坏的那个,exporter 部署清单要覆盖全部实例,包括没人注意的测试库——测试库磁盘打满拖垮共享主机进而影响生产的剧情,真实发生过。
四是告警文案不写上下文。"CPU 高"这种告警让人无从下手,好文案要带实例地址、当前值、阈值和预案链接,收到告警的人 30 秒内知道该干什么。
治理前后对比
| 指标 | 治理前 | 治理后 | | 故障发现方式 | 用户报障(40 分钟后) | 告警先于用户(2 分钟内) | | 日均告警条数 | 误报 23 条,无人响应 | 有效 2~4 条,条条有响应 | | 覆盖实例 | 仅主库 2 台 | 全部 11 台(含从库/备份/测试) | | 备份失败发现 | 出事才发现(已 3 个月未成功) | 超 24 小时即告警 | | P0 平均恢复时间 | 52 分钟 | 11 分钟 | | 告警规则演练 | 从未演练 | 每季度全量触发一遍 |
监控告警体系没有"搭完"一说,它是个持续运营的活:每周看误报率,每季度做演练,每次扩容补 exporter。做到"出事它先叫、收到告警的人知道该干什么",这套体系才算真正上岗。 |
|