本节摘要:稳定性不是"不出错",而是"出错也能兜住、能恢复、能预测"。本节围绕数据库运维的三件事展开:一是监控指标,用延迟、错误、流量、饱和度这些信号,加上连接数、缓冲池命中、复制延迟等数据库特有指标,判断系统当前是否健康;二是告警,通过分级和阈值设计,让告警既不漏报也不把人淹没;三是备份恢复与容量规划,用 RPO、RTO 两个指标权衡备份策略,用增长预测和例行巡检避免容量撞墙。读完你能搭起一套基本的监控、告警、备份与巡检框架。
阅读完本节,你应当能够:
我们常有一种错觉:系统没报错,就是健康的。可现实里,真正把人打垮的往往不是报错,而是那些安静恶化、直到某一天突然爆掉的过程。一个没加锁的在线变更把支付链路堵了十几分钟;主从复制延迟悄悄爬到几十秒,库存开始超卖;凌晨三点的告警里写着"备份校验失败"。这些都不是 bug,它们更像慢性病——平时不声不响,发作起来要命。
所以稳定性工程的第一件事,是换一个看问题的角度:不预设系统不会崩,而是假设它随时可能出问题,然后想办法让出问题的代价可控。这跟做体检是一个道理。体检不是为了证明自己没病,而是为了在指标偏离正常范围、但还没发展成大病之前把它逮住。数据库的监控、告警、备份、巡检,就是这套体检和应急的手段。
这套手段可以拆成三件事,环环相扣:先看得见(监控指标把系统状态暴露出来),再叫得醒(告警在指标越界时及时提醒),最后兜得住(备份恢复和容量规划保证出了事能退回来、撑得下去)。下面就从"看得见"说起。
监控最忌讳的是"全都盯",最后等于什么都没盯。我们更倾向盯住少数几个能反映本质的数字,其余指标作为下钻时的细节。
业界常说的四个黄金信号——延迟、流量、错误、饱和度——搬到数据库上,各有对应的落地指标。延迟就是查询耗时,重点看 P99 和慢查询数量,而不是平均值。流量是每秒到达的请求数和连接数,反映负载有多重。错误是失败率、连接超时、死锁次数这些"不该发生的事"。饱和度是资源被用到什么程度:连接池还剩多少、缓冲池命中率多少、磁盘队列多长、日志写盘是否积压。
在这四个通用信号之上,数据库还有几个自己特有的、必须单独盯的指标:复制延迟,它直接关系主从之间的数据一致风险;缓冲池命中率,它掉下去往往意味着大量请求开始落盘读;慢查询数量,它是性能退化的先导信号;磁盘容量和增长速率,它是容量规划的地基。
光有指标不够,还得给每个指标定一个"健康区间",否则数据来了也不知道算不算异常。下面这张表给出几个关键指标和对应的观察要点。
| 指标 | 反映什么 | 常见的健康判据方向 |
|---|---|---|
| 查询延迟 P99 | 用户真实体验 | 与基线相比是否漂移,看长尾而非平均 |
| 慢查询数量 | 性能退化的先导信号 | 数量是否在短时间内陡增 |
| 连接数 | 连接池是否即将耗尽 | 是否逼近配置上限、增长是否异常 |
| 缓冲池命中率 | 内存是否还够用 | 是否持续下滑、伴随 IO 上升 |
| 复制延迟 | 主从数据一致性风险 | 是否超过可容忍的秒级阈值 |
| 磁盘容量与增速 | 还能撑多久 | 剩余容量与增长速率的比值 |
💡 关键直觉:指标要成对看,不要孤立看。复制延迟上升本身未必有事,但如果它和慢查询、磁盘 IO 同时恶化,往往意味着真正的故障正在逼近。
盯指标还有一个常被忽略的细节:看什么粒度的数据。原始逐点数据太噪,直接拿来告警会误报;但把聚合窗口拉得太长,又会漏掉短时尖峰。通常的做法是分两层——短窗口(比如一分钟)用于捕捉突变,长窗口(比如一小时)用于看趋势和做容量预测。两层都留,告警和规划各取所需,谁也不耽误谁。
指标越界了,谁来叫醒你?告警。但告警本身是个两难:阈值太松,出事时没人知道;阈值太紧,半夜被海量无效告警淹没,最后人学会了一键静音。告警疲劳的根源,往往不是指标太多,而是告警没有分级、没有上下文。
我们的做法是分级。最低一级是"记录但不打扰",比如轻微的慢查询增长,写入看板供白天复盘。中间一级是"知会",比如复制延迟超过阈值但主库还正常,发一条非紧急消息。最高一级是"立即唤醒",比如主库不可用、数据校验失败,这种必须深夜把人叫起来。
分级之外,阈值也别设成一刀切的固定值。更稳的做法是结合基线:平时这个库的 P99 稳定在 30 毫秒,突然变成 200 毫秒,即便还没到 500 毫秒的硬阈值,也值得告警——因为"偏离基线"本身就是信号。阈值回答"是否越界",基线回答"是否反常",两者要一起用。
还有一点常被忽略:告警要带上下文,而不是只报一个指标名。"复制延迟超阈值"和"复制延迟 38 秒,主库负载正常,最近一次变更是一小时前加索引",后者才让人知道从哪下手。把关键指标、基线值、最近变更一起塞进告警消息,能省掉大量凌晨翻看板的功夫。
⚠️ 常见坑:把告警阈值设置成"永远不会响"或者"永远在响"。前者等于没有告警,后者等于没有耳朵。每一条告警都应该能回答"收到之后我该做什么",答不上来的告警应该删掉。
看得见、叫得醒之后,是兜得住。兜住的核心是备份与恢复,而它本质上是一笔账:你能容忍丢多少数据,你能容忍停多久服务。
这两个容忍度各有一个指标。RPO 是恢复点目标,回答"最多能丢多久的数据"——如果 RPO 是 5 分钟,那备份的粒度必须小于 5 分钟。RTO 是恢复时间目标,回答"最多能停多久"——如果 RTO 是 1 小时,那从故障发生到服务恢复必须在 1 小时内完成。
RPO 和 RTO 定了,备份策略才有依据。全量备份最完整但最重、最慢;增量备份只备份上次之后的变化,轻但恢复时要一层层叠;日志备份(WAL 或 binlog)最细,能精确到某个时间点,代价是恢复时要重放大量日志。现实里通常是三者组合:定期全量打底,中间增量接力,日志补上最后一段的精度。
打个比方,RPO 和 RTO 就像保险里的免赔额和理赔速度。你能接受的免赔额越低、理赔越快,保费就越高——对应到数据库,就是备份越频繁、恢复演练越充分,占用的存储、带宽和人力就越多。所以这笔账没有标准答案,只有"业务能承受的损失"和"团队能付出的成本"之间的平衡。
| 备份方式 | 优点 | 代价 | 典型用途 |
|---|---|---|---|
| 全量备份 | 一份完整、恢复最简单 | 占用大、耗时长 | 周期性打底 |
| 增量备份 | 轻、快 | 恢复需层层叠加、链条易断 | 缩短两次全量之间的窗口 |
| 日志备份 | 可恢复到任意时间点 | 需重放、依赖日志完整 | 补最后一段、做时间点恢复 |
⚠️ 常见坑:只做备份、从不演练恢复。备份的价值在恢复时才兑现,而恢复流程里藏着各种没料到的坑——权限、依赖、版本不一致。没有演练过的备份,等于一份没测试过的逃生通道。
💡 关键直觉:RPO 和 RTO 是业务给的约束,不是 DBA 自己拍的。先把业务能接受的最大数据丢失和最大停机时间问清楚,再倒推备份组合,顺序别反。
最后一件事,是让系统别被"撑爆"。容量规划要回答的是:照现在这个增长速度,磁盘、连接、内存还能撑多久。方法不复杂,难在坚持——持续记录容量曲线,算出增长速率,再留出足够的提前量去扩容或清理。等磁盘用到 95% 再动手,通常已经晚了,因为扩容和搬迁都需要时间。
与容量规划配套的是例行巡检。巡检的价值在于把问题消灭在"亚健康"阶段:定期看一遍慢查询有没有新面孔、复制延迟有没有波动、备份任务有没有按时跑完、校验有没有通过、容量曲线是否偏离预期。这就像定期体检,很多毛病在指标刚偏离时处理,成本远低于等它发展成事故再救火。
一次像样的例行巡检,通常会过一遍这几样:慢查询有没有新面孔、复制延迟和错误率有没有波动、备份任务是否按时跑完且校验通过、磁盘和连接的增长是否偏离预期、最近的变更有没有留下异常。把这些做成固定清单,每周甚至每天过一遍,很多事故就能在萌芽期被掐掉,而不是等告警响了再冲过去。
稳定性的最高境界,说到底不是"反应快",而是"提前量够"。让例行巡检和容量预测替你盯住趋势,比等告警响了再冲过去,省力得多,也可靠得多。
Q:监控告警做得再全,是不是就能高枕无忧了?
不能。监控和告警解决的是"看得见、叫得醒",但最终能不能兜住,取决于备份是否有效、恢复是否演练过、容量是否留了提前量。把告警当终点,是稳定性工程里最常见的一种自我安慰。
到这里,全书的工程实践部分就收尾了。从硬件与内核抽象一路走到基准测试与运维,我们终于把"一个数据库怎么可靠地跑起来"这条线补齐了。真正的功夫不在看懂原理,而在把这些维度、指标和流程用到你自己的系统上去。