服务重启时 Redis AOF 损坏阻止启动
日期:2026-10-15 Owner:docker-compose.yml(redis 服务及持久卷) 关联决策:用户沙盒环境与默认模板
影响
开发环境执行已授权的默认模板切换与服务重启时,Redis 无法加载原 AOF,应用服务恢复被延迟约 13 分钟。停机前确认没有非终态 Run、活动沙盒命令或待处理后台作业。原持久化文件完整备份并保留;恢复后的 16 个数据库与本次正常停机 RDB 的键数及键值指纹一致,未观察到该快照的数据丢失。损坏形成时间及此前影响范围未知。
事实时间线
时间使用 Asia/Shanghai,来源为 Redis 日志、容器启动时间、持久化校验器与隔离恢复记录。
- 17:57:45:Redis 收到正常停机请求,执行 AOF fsync,并成功保存最终 RDB。
- 17:57:46 起:Redis 启动读取增量 AOF,报告
Bad file format并退出,容器重启策略重复启动失败。 - 恢复前:停止重试并完整备份持久卷。
redis-check-aof确认增量 AOF 中段损坏,截断会丢弃约 2 MB 后续记录;redis-check-rdb确认上述停机快照 CRC 正确。 - 隔离验证:相同 Redis 镜像在无网络、无发布端口的容器中仅加载快照,通过原生
CONFIG SET appendonly yes重建 AOF。校验新 AOF 后重新启动隔离实例,16 个数据库的键数与键值指纹一致,共 37 个存活键。 - 18:09:25:保留原 AOF 目录后替换为验证通过的副本,原 Redis 容器成功加载。应用启动前逐库回读与隔离副本一致,AOF 写入状态正常。
- 18:10:34 起:原 API、worker、前端容器启动;9 个常驻服务处于 running,8 个配置 healthcheck 的服务均 healthy,API ready 与前端响应通过,默认模板的 3 个真实集成场景通过。
因果链
Compose 的 Redis 使用 --appendonly yes,启动时读取 AOF。原增量文件包含非法 RESP 数据;只读解析在首处错误发现连续零字节,后续还有另一处帧错误。Redis 拒绝加载该文件,重启策略持续重复同一失败;应用需要 Redis 就绪,因此恢复被阻断。损坏字节如何写入尚未确定,不能把正常停机、模板切换或重启策略作为损坏根因。
安全网为何漏过
现有 Redis healthcheck 执行 PING,只能证明当前进程可响应,不能证明下一次启动可重放完整 AOF。此前进程内数据可用,文件格式问题直到重启加载时才暴露。
修正与验证
恢复只替换数据副本,没有修改 Redis 配置或添加自动修复。原始损坏目录及完整备份保留,未对原文件运行 redis-check-aof --fix,未清空持久卷。正常停机 RDB 是本次恢复依据;没有该快照时,不能推定截断后仍能保留完整状态。
直接 oracle 为 redis-check-rdb CRC、redis-check-aof 格式验证,以及隔离加载前后和在线恢复后的逐库指纹。指纹按键名排序,聚合键名及 Redis DUMP 的二进制值;不输出键名或内容。负向案例为原 AOF 副本的只读校验和原启动拒绝,正确原因均为文件格式损坏。默认模板真实回归的准确命令及结果见关联决策。
防复发措施
运行时已有的 AOF 格式校验会拒绝加载损坏文件;恢复验收以完整快照、原生重建、再次加载及逐库一致性为发布条件。此条件已在本次维护执行,尚未形成自动 workflow。尚无针对损坏根因的修复或新增 guard,本事故保持根因未闭合状态。
未解决风险
损坏形成机制、磁盘与宿主历史故障、此前是否存在未持久化写入尚未查明。隔离重放与当前业务回归不能证明未来不会再次损坏;没有完整停机快照时的恢复策略未验证。