BGREWRITEAOF命令用于异步触发AOF文件重写,仅提交任务到后台队列并返回“started”,不保证立即完成;重写由fork子进程执行,不影响主线程,失败时旧AOF文件保持不变。

直接执行 BGREWRITEAOF 就能触发重写,但返回成功不等于立刻完成
执行 redis-cli BGREWRITEAOF 后,Redis 返回 Background append only file rewriting started,仅表示任务已提交到后台队列,并非文件已生成。重写由 fork 出的子进程异步执行,主进程照常处理请求。若此时有 RDB 快照正在生成(rdb_bgsave_in_progress 为 1),重写会被延迟,直到 RDB 完成——这时 INFO persistence 中的 aof_rewrite_scheduled 会显示为 1。
BGREWRITEAOF 失败的常见原因和对应检查项
命令返回 ERR Background append only file rewriting already in progress:说明已有重写在跑,Redis 不支持并发 AOF 重写,需等 aof_rewrite_in_progress 变为 0 再试。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 检查磁盘空间是否充足——重写期间需临时写入新 AOF 文件,若磁盘满,子进程会失败并静默退出,旧 AOF 保留不变
- 确认 AOF 功能已启用:
CONFIG GET appendonly必须返回yes;否则命令直接报错 - 查看
INFO persistence中的aof_enabled和aof_rewrite_in_progress字段,排除配置未生效或状态干扰
客户端代码里调用 bgrewriteaof() 的注意事项
以 Jedis 为例,jedis.bgrewriteaof() 是阻塞式调用,但只阻塞到命令发出去、收到响应为止,不等待重写结束。返回值是字符串响应,不是布尔值,别用 if (jedis.bgrewriteaof()) 这类写法。
- 必须捕获
JedisDataException,比如遇到ERR响应时会抛出异常,而非返回错误字符串 - 生产环境建议加超时控制:设置
Jedis构造时的 connection timeout 和 so timeout,避免因网络卡顿导致线程挂住 - 不要在重写高频触发的场景里轮询调用——例如监控到
aof_current_size略超阈值就立刻发命令,可能撞上正在运行的重写而失败
重写完成后旧 AOF 文件没变小?那是正常现象
AOF 重写生成的是全新文件(如 appendonly.aof.1234567890),重写成功后 Redis 会原子性地 rename 覆盖原 appendonly.aof。但这个过程分两步:rename + fsync。如果重写刚完成就立即 ls -lh,可能看到大小未变——因为内核缓存还没刷盘,或 rename 尚未完成。真正释放磁盘空间要等 rename 成功且旧文件所有句柄关闭。
- 最稳妥的验证方式是看
INFO persistence中的aof_current_rewrite_time_sec是否为正数,以及aof_last_bgrewrite_status是否为ok - 别依赖
du或ls的瞬时输出判断结果;用stat appendonly.aof对比修改时间更可靠 - 如果重写后文件反而变大,大概率是业务写入速率远高于重写速度,导致重写过程中大量新命令追加进缓冲区,最终被合并进新文件

















