运维事故复盘必须精确到秒级时间线、根因落至可验证配置或命令、还原完整shell上下文、区分临时绕过与永久修复操作。

事故时间线必须精确到秒级
运维事故复盘的第一硬性要求是时间线对齐,不能只写“上午10点左右服务中断”,而要从监控告警触发、日志第一条异常记录、用户反馈时间、操作执行命令时间戳等多源数据交叉比对,统一到系统 UTC 时间。常见错误是直接复制 date 命令输出却忽略时区差异,或用 tail -f /var/log/messages 人工估算时间——这会导致关键操作顺序误判。建议在复盘前先导出所有相关主机的 journalctl --since "2024-06-15 02:15:00" --until "2024-06-15 02:18:30" 日志,并用 awk '{print ,,,}' 提取带毫秒精度的时间字段(如 systemd-journald 默认支持)。
根因必须落到可验证的具体配置或命令上
“网络不稳定”“磁盘性能下降”这类模糊归因没有复盘价值。真正有效的根因描述应能被他人在测试环境一键复现。例如:
- 错误写法:MySQL 连接超时
- 正确写法:my.cnf 中 wait_timeout=30 导致应用连接池复用空闲连接时被 MySQL 主动断开,且应用未配置 testOnBorrow=true
- 验证方式:mysql -h $HOST -e "show variables like 'wait_timeout';" + 抓包确认 FIN 包由 mysqld 主动发出
常见陷阱是把现象当原因,比如看到 Connection refused 就认为是端口没开,实际可能是 systemctl stop firewalld 后又执行了 iptables-restore 覆盖规则,导致 iptables -L -n | grep :3306 显示 DROP。
变更操作需还原完整 shell 上下文
不能只写“升级了 Nginx”,必须明确:
- 执行用户(sudo -u deploy 还是 root?)
- 当前工作目录(pwd 输出,影响相对路径配置加载)
- 环境变量(env | grep -E "(PATH|LD_LIBRARY_PATH)",尤其影响动态链接库查找)
- 实际执行命令(不是“用了 ansible”,而是 ansible-playbook deploy.yml --limit web01 -e "nginx_version=1.24.0")
一个典型反例:某次故障源于 curl https://api.example.com 在 cron 中失败,但交互式执行正常——复盘发现 cron 默认 PATH=/usr/bin:/bin,而 curl 实际在 /usr/local/bin/curl,且未指定绝对路径。
恢复动作要区分“临时绕过”和“永久修复”
复盘文档里必须用不同标记区分两类操作:
- 临时绕过:echo 1 > /proc/sys/net/ipv4/ip_forward(解决燃眉之急,但未修改 /etc/sysctl.conf)
- 永久修复:sysctl -w net.ipv4.ip_forward=1 && echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
最容易被忽略的是“绕过动作”的副作用:比如为快速恢复数据库,执行了 kill -9 $(pgrep -f "postgres.*port=5433"),但没检查是否误杀了同主机上的备份进程(其命令行也含 postgres 和端口号),导致后续备份失败。这类连锁影响必须在复盘中显式列出。










