AOF 只追加、从不修改,文件会越长越大。AOF Rewrite 就是把「重放后得到当前数据集所需的最少命令」重新写一遍,替换掉旧的。Redis 7 之后 AOF 的文件结构也变了(不再是单个 appendonly.aof)。这篇直接看 appendonlydir 里的文件、manifest 的变化和日志,把一次重写从头到尾走一遍。
89 appendonly.aof.1.base.rdb
0 appendonly.aof.1.incr.aof
102 appendonly.aof.manifest
manifest:
file appendonly.aof.1.base.rdb seq 1 type b
file appendonly.aof.1.incr.aof seq 1 type i startoffset 0启动一个新的 appendonly 实例:appendonlydir 里有 base(appendonly.aof.1.base.rdb)、incr(appendonly.aof.1.incr.aof)和 appendonly.aof.manifest。manifest 列出当前有效的文件、序号和类型(b = base,i = incr)。
重写前:
89 appendonly.aof.1.base.rdb
10688913 appendonly.aof.1.incr.aof
102 appendonly.aof.manifest
manifest:
file appendonly.aof.1.base.rdb seq 1 type b
file appendonly.aof.1.incr.aof seq 1 type i startoffset 0
> BGREWRITEAOF
"Background append only file rewriting started"
重写耗时(INFO aof_rewrite_in_progress 从 1 变 0):约 0.15 s;aof_last_rewrite_time_sec = 0;aof_last_bgrewrite_status = ok
重写后:
1439002 appendonly.aof.2.base.rdb
0 appendonly.aof.2.incr.aof
107 appendonly.aof.manifest
manifest:
file appendonly.aof.2.base.rdb seq 2 type b
file appendonly.aof.2.incr.aof seq 2 type i startoffset 350000写入 30 万次 INCR counter 和 5 万个 SET 之后,incr 文件有 10.7 MB。BGREWRITEAOF 完成(约 0.15 s)后,文件变成 appendonly.aof.2.base.rdb(1.44 MB)加一个空的新 incr;manifest 指向新的一对,旧文件被删除。30 万次 INCR 折叠成一条 counter = 300000。manifest 里的 startoffset 350000 我没有追究它的精确定义(与写入的命令数 350000 相同)。
appendonly.aof.2.base.rdb: 前 9 字节 = b'REDIS0015' 是 RDB 格式(aof-use-rdb-preamble 默认 yes)。DBSIZE = 50001 counter = 300000
新 base 的文件头是 REDIS0015——RDB。默认 aof-use-rdb-preamble yes,重写产出的 base 是 RDB 快照,之后的增量才是命令文本。混合持久化的详细对比见第 61 篇。
Creating AOF base file appendonly.aof.1.base.rdb on server start Creating AOF incr file appendonly.aof.1.incr.aof on server start Creating AOF incr file appendonly.aof.2.incr.aof on background rewrite Background append only file rewriting started by pid 33732 Successfully created the temporary AOF base file temp-rewriteaof-bg-33732.aof Fork CoW for AOF rewrite: current 0 MB, peak 0 MB, average 0 MB Background AOF rewrite terminated with success Successfully renamed the temporary AOF base file temp-rewriteaof-bg-33732.aof into appendonly.aof.2.base.rdb Background AOF rewrite finished successfully
关键顺序:先 Creating AOF incr file … on background rewrite(新写入从这一刻起进新 incr),再 Background append only file rewriting started by pid …(fork),子进程写 temp-rewriteaof-bg-….aof,成功后 rename 为新的 base,最后 Background AOF rewrite finished successfully。重写期间的写入不需要在内存里缓冲、再补写——它们直接进新的 incr 文件(见第 60 篇)。
> CONFIG SET auto-aof-rewrite-percentage 100 "OK" 日志: Starting automatic rewriting of AOF on 192% growth 触发时写入了 36000 个 key;aof_base_size = 1439002,aof_current_size = 4379938(触发条件:current ≥ base×2 且 ≥ 1 MB)
自动重写关掉之后,把 auto-aof-rewrite-percentage 设回 100(auto-aof-rewrite-min-size 设 1 MB)并继续写入,日志出现 Starting automatic rewriting of AOF on 192% growth:当时 aof_base_size = 1439002、aof_current_size = 4379938。触发点是 AOF 相对 base 的增长(百分比)超过阈值且大小超过 min-size;实际触发时的 192% 大于 100%,因为我的写入是每批 2000 个 key,检查有间隔,没有精确停在 100%。