事故评审清单

事故评审(Postmortem / Incident Review)是在事故发生后,系统性回顾事故过程、分析根因、总结教训、制定改进措施的过程。目标不是追责,而是防止同类事故再次发生。

要点

  • 事故评审在事故解决后 1 周内完成(趁记忆新鲜)
  • 目标不是追责,而是防止同类事故再次发生
  • 重点:完整时间线、5 Why 根因分析、具体改进措施
  • 改进措施要有负责人和截止时间

1. 适用时机

  • 生产环境发生事故(服务不可用、数据丢失、安全事件)
  • 接近事故(near-miss):差一点就出事故的情况
  • 重大性能退化(用户明显感知)
  • 数据不一致或错误(影响业务)

事故评审应该在事故解决后 1 周内完成(趁记忆新鲜)。

2. 评审前准备

  • 事故时间线:从发现到解决的完整时间线
  • 影响范围:影响了哪些用户、哪些功能、多长时间
  • 相关日志和监控数据:事故发生时的系统状态
  • 相关人员:参与者、目击者、受影响方
  • 初步根因分析:直接原因是什么?

3. 核心检查项

3.1 事故描述

  • 事故标题清晰(时间 + 影响 + 简述)
  • 事故等级明确(P0/P1/P2/P3 或严重程度)
  • 事故持续时间(从发生到解决)
  • 影响范围(用户数、订单数、金额损失)
  • 事故作者(谁写的这份报告,何时完成)

3.2 时间线

  • 事故发生时间(什么时候开始出问题)
  • 发现时间(什么时候发现出问题)
  • 响应时间(什么时候开始处理)
  • 诊断时间(什么时候定位到根因)
  • 解决时间(什么时候恢复正常)
  • 每个关键节点的行动记录

时间线示例

## 事故时间线
 
| 时间 | 事件 | 负责人 |
|------|------|--------|
| 14:00 | 发布新版本 v2.3.0 | 运维 |
| 14:05 | 用户开始反馈订单页面报错 | 客服 |
| 14:10 | 监控告警:订单 API 错误率 > 5% | 系统 |
| 14:12 | on-call 工程师收到告警,开始排查 | 张三 |
| 14:15 | 确认是数据库查询超时 | 张三 |
| 14:20 | 发现新版本缺少索引 | 张三 |
| 14:25 | 决定回滚到 v2.2.9 | 张三、李四 |
| 14:30 | 回滚完成,服务恢复正常 | 运维 |
| 14:35 | 确认所有指标恢复正常 | 张三 |
 
**持续时间**:25 分钟(14:10 - 14:35)
**检测时间**:10 分钟(14:00 发布,14:10 发现)
**响应时间**:2 分钟(14:10 告警,14:12 开始处理)

3.3 影响评估

  • 用户影响(多少用户受影响、影响程度)
  • 业务影响(订单、收入、声誉)
  • 数据影响(数据丢失、数据错误)
  • 合规影响(是否需要报告监管机构)

影响评估示例

## 影响评估
 
### 用户影响
- 受影响用户:约 5000 人(过去 1 小时活跃用户)
- 影响程度:无法创建订单,但能浏览商品
- 用户反馈:收到约 200 条客服投诉
 
### 业务影响
- 订单损失:约 1000 单(按正常转化率估算)
- 收入损失:约 ¥50,000(按平均客单价 ¥50 估算)
- 声誉影响:社交媒体出现负面评论
 
### 数据影响
- 数据丢失:无
- 数据错误:无(订单创建失败,没有脏数据)
 
### 合规影响
- 无需报告监管机构(无数据泄露)

3.4 根因分析

  • 直接原因(什么代码/配置/操作触发了问题)
  • 根本原因(为什么会有这个代码/配置/操作)
  • 5 Why 分析(连问 5 个为什么,找到根本原因)
  • contributing factors(加剧问题的其他因素)

5 Why 分析示例

## 根因分析
 
### 直接原因
新版本 v2.3.0 的订单查询接口缺少数据库索引,导致全表扫描,查询超时。
 
### 5 Why 分析
1. **为什么订单查询超时?**
   因为数据库查询耗时超过 5 秒。
 
2. **为什么查询耗时超过 5 秒?**
   因为缺少索引,进行了全表扫描。
 
3. **为什么缺少索引?**
   因为新版本的查询条件变了,但没添加对应索引。
 
4. **为什么没添加对应索引?**
   因为代码评审时没检查数据库查询性能。
 
5. **为什么代码评审没检查数据库查询性能?**
   因为团队没有数据库查询性能的检查清单。
 
### 根本原因
团队缺少数据库查询性能的检查流程,导致代码评审时没有发现索引缺失。
 
### 加剧因素
- 测试环境数据量小(只有 1000 条),没有暴露性能问题
- 生产环境数据量大(100 万条),问题被放大
- 没有压测环节,无法在上线前发现性能问题

3.5 检测与响应

  • 事故是怎么发现的?(监控告警?用户反馈?)
  • 如果是用户反馈,说明监控有盲区
  • 响应速度如何?(从发现到响应花了多久?)
  • 响应过程是否有序?(有明确的 on-call 流程吗?)
  • 沟通是否顺畅?(相关人员都及时通知了吗?)

3.6 解决过程

  • 采取了什么措施解决问题?
  • 为什么选择这个措施?考虑过其他方案吗?
  • 解决过程中有没有走弯路?
  • 解决后如何验证问题真的解决了?

3.7 改进措施

  • 短期措施(立即执行的修复)
  • 中期措施(防止同类问题再次发生)
  • 长期措施(系统架构改进、流程优化)
  • 每项措施有负责人和截止时间
  • 措施可验证(怎么判断措施有效?)

改进措施示例

## 改进措施
 
| 类型 | 措施 | 负责人 | 截止时间 | 验证方式 |
|------|------|--------|----------|----------|
| 短期 | 添加缺失的数据库索引 | 张三 | 2026-06-22 | 查询延迟 < 100ms |
| 中期 | 建立数据库查询性能检查清单 | 李四 | 2026-06-30 | 清单文档化 |
| 中期 | 代码评审时强制检查数据库查询 | 王五 | 2026-06-30 | PR 模板更新 |
| 长期 | 测试环境数据量对齐生产环境 | 赵六 | 2026-07-15 | 数据量 > 100 万 |
| 长期 | 建立压测流程,上线前必须压测 | 张三 | 2026-07-30 | 压测报告模板 |
 
### 短期措施(已完成)
- 2026-06-22 10:00 添加索引
- 2026-06-22 10:30 验证查询延迟 < 100ms
- 2026-06-22 11:00 重新发布 v2.3.1
 
### 中期措施(进行中)
- 2026-06-25 完成数据库查询性能检查清单
- 2026-06-28 更新 PR 模板
- 2026-06-30 团队培训
 
### 长期措施(待开始)
- 2026-07-01 开始测试环境数据同步
- 2026-07-15 完成数据同步
- 2026-07-30 建立压测流程

3.8 经验教训

  • 这次事故教会了我们什么?
  • 哪些做法是对的?值得保留
  • 哪些做法是错的?需要避免
  • 有没有类似的隐患需要排查?

经验教训示例

## 经验教训
 
### 做得好的
1. **监控告警有效**:14:10 自动检测到错误率上升,及时告警
2. **on-call 响应迅速**:14:12 开始处理,2 分钟内响应
3. **回滚决策果断**:14:25 决定回滚,没有犹豫
4. **沟通及时**:14:15 通知客服团队,准备应对用户投诉
 
### 需要改进的
1. **检测不够快**:14:00 发布,14:10 才发现,中间 10 分钟是用户先反馈
2. **测试环境数据量不足**:测试环境只有 1000 条数据,没有暴露性能问题
3. **缺少压测环节**:上线前没有做压测,无法发现性能瓶颈
4. **代码评审不充分**:评审时没有检查数据库查询性能
 
### 类似隐患
- 其他新接口是否也有类似问题?需要排查
- 其他查询条件变化的接口是否都添加了索引?

4. 评审会流程

一个典型的事故评审会流程(1-2 小时):

  1. 开场(5 分钟):明确会议目的——学习,不是追责
  2. 回顾时间线(15 分钟):事故作者讲述事故过程
  3. 提问与澄清(20 分钟):参与者补充细节
  4. 根因讨论(30 分钟):一起分析根本原因
  5. 改进措施(20 分钟):制定具体改进计划
  6. 总结(10 分钟):确认行动项和负责人

5. 评审会上容易漏的点

  1. 检测盲区:问「这个事故是监控发现的还是用户反馈的?」如果是用户反馈,说明监控需要改进
  2. 响应效率:问「从发现到响应花了多久?为什么这么久?」
  3. 沟通问题:问「相关人员都及时通知了吗?沟通顺畅吗?」
  4. 类似隐患:问「其他模块有没有类似的问题?需要排查吗?」
  5. 措施跟踪:问「改进措施谁来跟踪?怎么判断完成了?」

6. 通过标准

  • 事故时间线完整、准确
  • 根因分析深入(不是「人为失误」就结束)
  • 改进措施具体、可执行、有负责人
  • 经验教训记录清楚
  • 相关人员都参与并认可

7. 反模式

以下是事故评审的反模式:

  • 追责文化:找出「肇事者」惩罚,而不是改进系统
  • 浅尝辄止:根因分析停在「人为失误」,不问为什么
  • 只说不做:列了一堆改进措施,没人跟踪
  • 事后诸葛亮:「我早就说会出问题」——没用,要往前看
  • 不分享:事故报告写完就锁在抽屉里,团队学不到教训

8. 事故报告模板

# [日期] [事故标题]
 
## 事故信息
- 等级:P0/P1/P2/P3
- 持续时间:X 小时 Y 分钟
- 影响范围:...
- 事故作者:...
 
## 时间线
- HH:MM 事故发生
- HH:MM 事故发现
- HH:MM 开始响应
- HH:MM 定位根因
- HH:MM 问题解决
- HH:MM 确认恢复
 
## 影响
- 用户影响:...
- 业务影响:...
- 数据影响:...
 
## 根因分析
### 直接原因
...
 
### 根本原因(5 Why)
1. 为什么 X?因为 Y
2. 为什么 Y?因为 Z
...
 
### 加剧因素
...
 
## 检测与响应
### 如何发现
...
 
### 响应过程
...
 
## 改进措施
| 措施 | 负责人 | 截止时间 | 状态 |
|---|---|---|---|
| ... | ... | ... | 待办 |
 
## 经验教训
### 做得好的
...
 
### 需要改进的
...

9. 维护建议

事故评审清单需要随团队实践更新:

  • 出现新的事故类型时,补充对应检查项
  • 改进措施跟踪机制优化时,调整相关流程
  • 团队规模扩大时,强化沟通和知识分享要求
  • 每半年复审一次,删除过时的检查项