事件摘要#
这是一个经过脱敏的演练型复盘:凌晨磁盘使用率从 71% 上升到 100%,Nginx 无法写日志,PostgreSQL 临时文件创建失败,最终表现为文章页间歇性 500。恢复目标是先阻止继续写满,再释放可确认的数据,最后恢复服务。
时间线#
| 时间 | 现象与动作 | 结果 |
|---|---|---|
| 02:13 | 首个 5xx 告警 | 确认用户受影响 |
| 02:17 | df -h 显示根分区 100% | 排除 inode 问题 |
| 02:22 | 定位 38 GB 容器 JSON 日志 | 找到主要增量 |
| 02:30 | 暂停异常任务并轮转日志 | 写入恢复 |
| 02:41 | 数据库、首页、登录验证通过 | 结束应急阶段 |
证据收集#
bash
date -Is
df -hT
df -ih
du -xhd1 /var /www 2>/dev/null | sort -h
find /var/lib/docker/containers -name '*-json.log' -printf '%s %p
' | sort -nr | head
journalctl --since '02:00' --until '03:00' -p warning
根因链#
- 一个下游连接错误进入无退避重试。
- 应用每次重试打印完整堆栈。
- 容器未配置
max-size与max-file。 - 磁盘告警阈值只设为 95%,且没有增长速率告警。
- 根分区同时承载数据库与容器日志,故障域没有隔离。
修复与验证#
- 停止异常重试任务
- 配置容器日志轮转
- 增加 70%/85% 分级告警和 6 小时增长预测
- 将数据库数据卷迁移到独立磁盘
- 编写只读磁盘排查 Runbook
bash
docker compose up -d --force-recreate app
curl -fsS https://blog.example.com/api/health
docker exec postgres pg_isready -U blog -d gkblog
复盘结论#
直接原因是日志无上限,系统性原因是没有容量预算和增长率监控。行动项必须有负责人、截止时间和验证证据;“加强监控”不是可验收的修复。
讨论区 56
分享你的经验、补充或不同观点。支持 Markdown 基础语法。