主从切换后AOF“失效”是配置继承错误而非文件损坏;新主库加载原从库redis.conf中appendonly no,导致aof_enabled:0、不落盘、重启丢数据,须预设appendonly yes、appendfsync everysec、aof-use-rdb-preamble yes三者联动且禁止运行时SET修改。

主从切换后AOF“失效”不是文件损坏,而是配置继承错误
新主库启动时 aof_enabled:0、CONFIG GET appendonly 返回 no,但业务写入日志正常——这不是 Redis 崩溃或磁盘问题,而是被提升的从库直接加载了自己原本的 redis.conf,其中 appendonly no 未被覆盖。哪怕原主库一直开着 appendonly yes,它升主后也不会写 AOF,连 appendfilename 和 appendfsync 都不生效。
常见后果:INFO persistence 显示 aof_enabled:0;重启后所有切换期间写入全部丢失;容器部署中若挂载统一配置文件,问题更隐蔽。
- Redis 6.2+ 不会自动改写配置文件,
CONFIG REWRITE只保存运行时SET的值,不会覆盖原始appendonly no - 运维手动改完配置但忘记
CONFIG REWRITE或重启,会导致CONFIG GET和磁盘文件不一致 - 哨兵或 Cluster 故障转移时,不触发配置同步,只做角色变更
必须预设三联动AOF配置,缺一不可
仅把 appendonly yes 写进配置不够。主库级 AOF 行为依赖三个参数协同生效,漏掉任意一个都会导致新主库 AOF 文件内容不完整、无法加载,或丢失最近 1 秒数据:
-
appendonly yes:开关必须为yes;从库模板中若为no,升主即失效 -
appendfsync everysec:推荐值;设为no会丢数,always严重拖慢吞吐;注意必须与no-appendfsync-on-rewrite yes配对启用 -
aof-use-rdb-preamble yes:开启后 AOF 前缀为 RDB 格式,加载快;但重写仍需全量解析旧 AOF,不能省略appendfsync安全设置
这三项必须在所有节点(含从库)的初始配置文件中显式声明,且禁止在运行时用 CONFIG SET 动态修改——因为切换后新主不会继承这些运行时 SET 值。
强制全量同步前必须清空脏数据,否则越同步越错
执行 replicaof no one 再 replicaof 不会清空从库现有数据,只是切换复制源。如果原数据已错(比如曾手动 CONFIG SET slave-read-only no 并写入),新同步仍基于错误偏移量或陈旧 RDB 快照,跳过修复。
- 执行前先
INFO replication查看master_replid和master_repl_offset,确认是否和主库一致 - 若从库有写入历史,必须先
FLUSHALL或FLUSHDB清空,否则全量同步后仍混有旧脏数据 - 主库需确保
repl-diskless-sync no(默认),否则从库接收 RDB 断连时可能残留半截文件,后续同步失败
AOF优先恢复逻辑导致“回滚”,但你无法靠RDB fallback
只要 appendonly yes 且 appendonly.aof 文件存在且校验通过,Redis 启动时**完全忽略 dump.rdb**,哪怕后者时间更新。这就是哨兵切换后出现“数据回滚”的根本原因。
典型场景包括:
-
appendfsync no:内核缓冲未刷盘,宕机后 AOF 空或极旧,但 Redis 仍加载它,结果比 RDB 还旧 -
appendfsync everysec:主节点刚好在刷盘前崩溃 + 哨兵切主,新主加载的 AOF 缺这 1 秒之后的所有变更 - AOF 重写中断:bgrewriteaof 生成新 AOF 时失败,留下破损文件;Redis 启动拒绝加载并退回到 RDB —— 但如果 RDB 也过期,就表现为“回滚到更早状态”
真正棘手的是:AOF 文件完整但内容陈旧(比如从节点 AOF 滞后),恢复的就是那个旧状态;而你无法通过配置让 Redis “优先选 RDB”。想强制用 RDB 恢复,只能先 rename 或删除 appendonly.aof,再启动。











