rdb文件损坏表现为redis启动失败并报错failed to load rdb file等,常见于硬件故障;热替换会导致文件被覆盖,须停服后替换并校验;从完好从节点提取rdb需确认同步完成、避免复制中文件、校验魔数;无备份时仅当redis进程存活且可响应命令才可用jedis逐键迁移重建。

主从同步时RDB文件损坏的典型现象
Redis启动失败并报错 Failed to load RDB file,或日志中出现 Invalid RDB magic string、Invalid rdb version、Unexpected EOF 等提示,基本可判定RDB文件已损坏。这种情况在硬件故障(如磁盘坏道、突然断电、SSD写失败)后尤为常见,尤其当主节点或从节点的 dump.rdb 文件被截断、校验和不匹配、或头部魔数(REDIS0011)被破坏时。
必须停服务再替换RDB,否则会立即被覆盖
很多人尝试热替换 dump.rdb,结果发现刚放进去,Redis一有写操作,文件立刻变小或重置为空——这是因为Redis在运行时若检测到RDB文件缺失或不合法,会在下次BGSAVE或退出前自动生成一个新(但空或极小的)RDB;更危险的是,如果配置了 save 规则且满足触发条件,它会在后台自动覆盖你刚放进去的文件。
正确做法是:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 先执行
redis-cli shutdown save或systemctl stop redis,确保进程完全退出 - 确认
ps aux | grep redis无残留进程 - 检查目标路径下原
dump.rdb是否已被重命名或移走(避免同名冲突) - 把修复/重建后的RDB文件(如
dump.rdb.recovered)复制为dump.rdb,权限设为与原文件一致(通常是644,属主为redis用户) - 再启动服务:
redis-server /etc/redis/redis.conf
从从节点安全提取可用RDB的实操要点
主节点RDB损坏但从节点完好时,优先从从节点取RDB,比人工重建快得多,也更可靠。但要注意几个关键细节:
- 必须确认主从同步已完成:在从节点执行
redis-cli info replication | grep "master_repl_offset\|slave_repl_offset",两者 offset 值应完全一致 - 不要直接复制正在使用的
dump.rdb:从节点可能正处在BGSAVE过程中,文件处于临时状态。应先在从节点手动触发一次redis-cli BGSAVE,等redis-cli info persistence | grep rdb_bgsave_in_progress返回0后再拷贝 - 拷贝前校验文件完整性:用
file /var/lib/redis/dump.rdb看是否识别为 “Redis DB dump”;用head -c 10 /var/lib/redis/dump.rdb | hexdump -C检查前几个字节是否为52 45 44 49 53(即 “REDIS” ASCII) - 主节点恢复后,需重置复制关系:启动主节点后,执行
redis-cli SLAVEOF no one脱离从角色,再让其他从节点重新SLAVEOF回来
没有备份时用Jedis逐键迁移重建RDB的边界条件
当主从都损坏、又无外部备份时,只能靠“数据还在内存里但RDB不可读”这一前提,用客户端导出再导入生成新RDB。但这个方法有硬性限制:
- 仅适用于 Redis 实例仍能响应命令(即进程活着、端口通),哪怕
INFO或KEYS *慢也得能返回结果 -
KEYS *在大数据集上会阻塞,生产环境务必改用SCAN游标分批处理,示例中sourceJedis.keys("*")仅适合键数 - 类型为
stream、geo、module自定义类型的数据,Jedis 4.x 默认不支持,需升级客户端或改用 redis-cli --pipe - 过期时间(TTL)无法通过
GET/HGETALL等命令直接获取,需额外调用TTL并在目标端用EXPIREAT设置,否则全丢失 - 迁移完务必在目标实例上执行
redis-cli BGSAVE,否则新RDB不会落地
真正棘手的不是怎么重建,而是你怎么确认重建出来的数据跟原来一致——别跳过校验步骤,至少跑一次 redis-cli --bigkeys 和 redis-cli dbsize 对比数量,再抽样 GET 几个高频 key 看值是否对得上。










