基本可判定是rdb版本不兼容,因高版本(如7.0+)生成的redis0011格式rdb被低版本redis加载时,解析器校验头部后静默退出,日志停在“reading rdb file”,dbsize为0且无报错。

Redis启动卡在“Reading RDB file”且dbsize返回0,基本可判定是RDB版本不兼容,不是文件损坏——别删dump.rdb,也别改文件头。
怎么一眼确认是版本不兼容而非损坏
先看文件头和当前Redis版本是否对不上:
- 用
head -c 10 dump.rdb | hexdump -C查前10字节:若输出含52 45 44 49 53 30 30 31 31(即REDIS0011),说明是Redis 7.0+生成的RDB - 运行
redis-server --version:若显示Redis server v=6.2.6或更低,就确定不兼容 - 日志里没有
Bad file format或Invalid magic number,只停在Reading RDB file,且redis-cli dbsize始终为0
为什么不能手动改RDB文件头来“降级”
RDB文件头第10字节硬编码了版本号(如v11),但校验和(CRC64)覆盖整个文件。你改了版本号却没重算CRC,Redis加载时会立刻abort,报Wrong RDB version or checksum error。
更关键的是:Redis 6.x解析器遇到v11的opcode(比如REDIS_RDB_TYPE_MODULE2或新LFU字段)会直接退出,不提供fallback逻辑——这不是格式识别问题,是解析器代码里写了if (rdbver > RDB_VERSION) goto err;。
安全恢复数据的实操路径
目标是把高版本RDB里的数据导出来,再导入低版本实例。不要尝试修复文件本身:
- 在有该RDB文件的机器上,用同版本Redis(如7.0+)临时起一个干净实例:
redis-server --port 6380 --dir /tmp --dbfilename dump.rdb - 连上去确认能读:
redis-cli -p 6380 dbsize应返回非零值;再试redis-cli -p 6380 KEYS *看是否返回键名 - 用
redis-cli -p 6380 --scan --pattern '*' | xargs -L 1000 redis-cli -p 6380 MIGRATE <target-ip> 6379 "" 0 5000</target-ip>,把数据迁到目标低版本实例(注意MIGRATE需目标端开启appendonly no且无密码或配好requirepass) - 若网络不通或跨机房,改用
rdbtools导出:rdb -c json /path/to/dump.rdb > data.json,再用cat data.json | redis-cli --pipe导入目标实例
线上环境最常被忽略的细节
很多人导出后发现部分key丢失,原因往往不是工具问题,而是:
-
rdbtools默认跳过无法解析的模块类型(如RedisJSON、RediSearch的REDIS_RDB_TYPE_MODULE2),需加--filter module参数保留原始二进制字段(但低版本仍无法加载) - 从高版本导出时,
SCAN可能漏掉正在被EXPIRE清理的key,建议先执行SAVE生成新快照再操作 - 如果原RDB来自Redis 8.2.1,注意它新增了
INFO KEYSIZES直方图字段,虽不影响加载,但rdbtools旧版可能报warning,升级到rdbtools>=0.1.18可避免











