Redis AOF 文件损坏修复记录

结论先行 故障由 AOF 尾部 65 bytes 损坏引起。完成原文件备份后,使用同版本 Redis 镜像运行 redis-check-aof --fix,截断损坏尾部,Redis 最终恢复到 loading:0,并成功返回 PONG。

记录还原了一次 Redis 无法正常完成数据加载的处理过程。由于 dump.rdb 只有约 507 KB,而主要数据集中在约 6.3 GB 的 append.aof 中,直接删除 AOF 并不可取;修复的关键是先确认损坏位置,再以最小代价截断异常尾部。

故障概览

Redis 启动后长时间处于数据加载状态,客户端执行 PING 时无法得到正常响应。运行环境如下:

|------------------|------------------------------------|
| Redis 版本 | 5.0.12 |
| 部署方式 | Docker |
| 服务端口 | 17002 |
| AOF 文件 | /home/docker/redis/data/append.aof |
| 文件大小 | 约 6.3 GB |

现场现象

启动后执行 PING:
(error) LOADING Redis is loading the dataset in memory

随后在启动日志中发现明确的 AOF 格式错误:
Bad file format reading the append only file
初步判断 Redis 能读取 AOF,但文件中存在无法解析的内容,需要进一步确认损坏发生在主体还是尾部。

排查与判断

  1. 检查 Redis 持久化状态

info persistence

返回结果中出现 loading:1,说明 Redis 仍在加载数据,尚未进入可服务状态。

  1. 核对启动日志

Reading RDB preamble from AOF file...
Reading the remaining AOF tail...
Bad file format reading the append only file

日志显示 RDB preamble 已读取,错误出现在后续 AOF tail 阶段,因此可以将问题范围收敛到 AOF 尾部增量数据。

  1. 比较持久化文件大小

append.aof ≈ 6.3 GB
dump.rdb ≈ 507 KB

AOF 远大于 RDB,说明主要数据依赖 append.aof。此时如果直接删除 AOF,可能造成大量数据缺失。
排查结论 本次故障属于 AOF 尾部损坏,修复目标是保留前部有效数据,仅移除无法解析的尾部字节。

修复实施

操作前提醒 redis-check-aof --fix 会修改并截断文件。务必先停止 Redis,并为原始 AOF 创建完整备份。

  1. 停止 Redis 容器

docker stop redis5.0.12

  1. 备份原始 AOF 文件

cp /home/docker/redis/data/append.aof \
/home/docker/redis/data/append.aof.bak

  1. 使用同版本工具修复 AOF

docker run --rm -it \
--user root \
-v /home/docker/redis/data:/data \
redis:5.0.12 \
redis-check-aof --fix /data/append.aof

这里使用 redis:5.0.12 镜像,确保检查工具与故障实例的 Redis 版本一致。数据目录以 /data 挂载,修复命令直接作用于 append.aof。

修复结果

|---------|--------------------------------|
| 检查项 | 结果 |
| AOF 总大小 | 6,723,298,839 bytes |
| 有效位置 | ok_up_to = 6,723,298,774 |
| 损坏范围 | 文件尾部 65 bytes |
| 修复结果 | Successfully truncated AOF |

结果解读 有效数据一直持续到 6,723,298,774 字节位置,仅尾部 65 bytes 被截断。相对于整个 AOF 文件,损坏范围很小,主体数据基本完整。

恢复与验证

  1. 重新启动 Redis

docker start redis5.0.12

  1. 观察数据加载状态

info persistence

启动初期仍可能看到 loading:1;等待加载完成后,状态应变为:
loading:0

  1. 验证服务响应

ping
PONG
恢复确认 Redis 已完成数据加载,PING 返回 PONG,服务恢复正常。

原因分析

从日志和修复结果看,本次属于 AOF 尾部损坏。常见诱因包括:

  • Redis 写入 AOF 的过程中异常退出
  • Docker 容器被强制停止
  • 宿主机异常重启
  • 磁盘写入过程被中断

本次只有最后 65 bytes 损坏,说明异常更可能发生在一次尚未完整落盘的尾部写入中;修复工具截断这一小段后,其余数据仍可被正常加载。

后续优化建议

  1. 恢复后重写 AOF

BGREWRITEAOF

重新生成结构干净、体积更合理的 AOF 文件。

  1. 配置自动 AOF 重写

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 1gb

  1. 优化宿主机内存参数

vm.overcommit_memory=1

同时关闭 Transparent Huge Pages(THP):
echo never > /sys/kernel/mm/transparent_hugepage/enabled

  1. 建立定期备份机制

定期备份 RDB 与 AOF 文件,并确保备份可恢复,避免单一持久化文件成为故障恢复的唯一依赖。

经验总结

  • 看到 LOADING 不要只等待:应同步检查启动日志和 info persistence。
  • AOF 是主要数据来源时,不要直接删除;先备份,再判断可修复范围。
  • 使用与实例一致的 Redis 版本运行 redis-check-aof,降低工具差异带来的风险。
  • 修复完成不等于恢复完成:必须等待 loading:0,并用 PING 等方式验证服务。
  • 恢复后及时执行 BGREWRITEAOF,并完善自动重写和备份策略。
相关推荐
程序员清风4 小时前
Java 后端高并发设计:线程池、限流、熔断与降级
java·数据库·oracle
天衍四九-4 小时前
MySQL中如何定位慢查询?如果SQL语句执行很慢,如何分析和优化?
数据库·sql·mysql
尚久龙5 小时前
mysql-5.7.26-winx64的安装步骤
数据库·mysql
医疗信息化王工5 小时前
DataForge:基于 Python 的数据库批量导出 Excel 工具——从架构到部署的全流程实战
数据库·python·excel
实心儿儿5 小时前
MySQL 的安装
数据库·mysql·adb
考虑考虑5 小时前
docker compose环境变量替换
运维·后端·自动化运维
Java陈序员6 小时前
轻量运维面板!一款现代化的服务器控制面板工具!
运维·服务器·python·react.js·github
bosins6 小时前
WSL 迁移指南:如何将 Linux 环境完整复制到另一台电脑
linux·运维·服务器
IT利刃出鞘6 小时前
Docker Compose--安装WordPress--方法/示例
运维·docker·容器
程序员阿鹏7 小时前
为什么MySQL InnoDB选择B+树?
数据结构·数据库·b树·sql·mysql·算法·缓存