目录标题
- appendonly.aof 和 dump.rdb
- 模拟flushdb测试
- 一、先给结论(帮你快速建立直觉)
- 二、你刚刚做了什么?发生了什么?
- 三、appendonly.aof:逐行“复盘历史”
- 四、dump.rdb:只关心“最终状态”
- 五、为什么 dump.rdb 还变大了?
- 六、AOF 和 RDB 的核心差异(用你这个实验总结)
- 七、一个关键细节:为什么 AOF 这么“干净”?
- 八、生产级“必懂点”(结合你之前的 IO / iowait 关注点)
- 九、一句话终极总结
- 一句话先给结论(先建立正确直觉)
- 一、FLUSHDB 到底“flush”了什么?
- 二、为什么 FLUSHDB 这么快?
- 三、那内存是“立刻释放”吗?(非常重要)
- 四、FLUSHDB 在 AOF / RDB 中分别怎么体现?
- 五、FLUSHDB 是“危险命令”吗?——是的
- 六、FLUSHDB 与 FLUSHALL 的区别(顺手讲清)
- 七、为什么生产环境“慎用 FLUSHDB”?
- 八、如果只是“清数据”,有没有更安全的方式?
- 九、结合你实验的一句话总结
appendonly.aof 和 dump.rdb
一、你现在看到的现象说明了什么?
/data # ls -l
-rw-r--r-- 1 root root 0 Dec 18 15:45 appendonly.aof
-rw-r--r-- 1 root root 175 Dec 18 15:46 dump.rdb
👉 结论先给出:
- 当前 Redis 实际在用的是 RDB(appendonly no)
- AOF 功能 未启用或刚被关闭
appendonly.aof是 历史遗留 / 切换时创建但未写入
二、appendonly yes / no 本质区别(一句话版)
| 配置 | 持久化方式 | 核心思路 |
|---|---|---|
appendonly no | RDB | 定期拍快照 |
appendonly yes | AOF | 每条写命令顺序追加 |
三、appendonly no(RDB)详细解释
1️⃣ 工作方式
- Redis 定期 fork 子进程
- 把内存数据 一次性写成 dump.rdb
- 重启时:
👉 直接加载 dump.rdb
2️⃣ 你这里的 dump.rdb
-rw-r--r-- 1 root root 175 Dec 18 15:46 dump.rdb
说明:
- Redis 至少执行过一次 RDB 快照
- 数据量非常小(175 字节)
- Redis 当前运行逻辑:
内存 ←→ dump.rdb
3️⃣ RDB 的优缺点
优点
- 文件小
- 恢复快
- 对性能影响小
缺点
- 可能丢数据
- 崩溃时:
❌ 丢失最后一次快照后的写入
四、appendonly yes(AOF)详细解释
1️⃣ 工作方式
-
每条 写命令 都写进
appendonly.aof -
例如:
SET a 1 INCR a LPUSH q x -
Redis 重启:
👉 重放 AOF 命令恢复数据
2️⃣ AOF 刷盘策略(非常关键)
appendfsync always # 最安全,最慢
appendfsync everysec # 默认,推荐
appendfsync no # 最快,最不安全
五、为什么你有 appendonly.aof 但大小是 0?
-rw-r--r-- 1 root root 0 Dec 18 15:45 appendonly.aof
🔥 常见原因(按概率)
✅ 1️⃣ 曾经开启过 AOF,又关闭了(最常见)
过程可能是:
-
appendonly yes -
Redis 创建了
appendonly.aof -
后来改成:
appendonly no -
Redis 不再写 AOF
-
文件保留但不更新
👉 结果就是:空 AOF + 有效 RDB
✅ 2️⃣ 刚开启 AOF,但没有任何写操作
-
AOF 只记录 写命令
-
如果:
- Redis 启动后没写数据
- 或马上关闭
👉 AOF 文件就是 0 字节
❌ 3️⃣ AOF 被 rewrite / truncate 失败(少见)
一般会伴随:
- 日志报错
- 临时
.aof.tmp文件
你这里不像。
六、Redis 启动时:RDB 和 AOF 谁优先?
重要规则
如果 appendonly yes:
优先使用 AOF
否则:
使用 dump.rdb
所以你现在:
- appendonly.aof = 0
- dump.rdb = 175
说明 Redis 启动时根本没用 AOF
七、配置切换时 Redis 的真实行为(很多人搞错)
从 appendonly no → yes
-
Redis 立即开始写 AOF
-
并且会:
- 把当前内存数据
- 生成一份 AOF(rewrite)
从 appendonly yes → no
- Redis 立刻停止写 AOF
- 不会删除 appendonly.aof
- 文件留在磁盘上(你现在的情况)
八、如何确认当前 Redis 真正在用哪个?
1️⃣ 配置层面
redis-cli CONFIG GET appendonly
2️⃣ 运行状态(最准)
redis-cli INFO persistence
重点看:
aof_enabled:0
rdb_last_save_time:...
九、生产环境怎么选?(运维建议)
🔥 强烈建议(通用)
appendonly yes
appendfsync everysec
并保留 RDB:
save 900 1
save 300 10
save 60 10000
👉 AOF 防数据丢失
👉 RDB 做冷备 / 快速恢复
十、一句话总结(帮你记忆)
你现在这个目录结构 = 典型的 RDB 模式 Redis
dump.rdb→ 真正的数据来源appendonly.aof→ 历史遗留 / 未启用appendonly yes才会让 AOF 真正“活起来”
如果你愿意,我可以帮你:
- 🔍 分析你当前 Redis 是否适合切 AOF
- 🔄 在线开启 AOF 是否安全
- ⚠️ 如何避免 AOF 膨胀 / rewrite 卡顿
- 📊 结合你之前关注的 IO / iowait 场景评估风险
模拟flushdb测试

一、先给结论(帮你快速建立直觉)
你现在这组结果 100% 说明:
✅ AOF 和 RDB 是并行存在、各自独立的
✅ AOF 记录“写命令历史”
✅ RDB 记录“最终内存状态快照”
✅ FLUSHDB 在 AOF 中是一次命令,
但在 RDB 中只体现为“结果为空”
二、你刚刚做了什么?发生了什么?
1️⃣ 执行的命令
SET a 1
FLUSHDB
2️⃣ 文件变化
-rw-r--r-- 1 root root 67 appendonly.aof
-rw-r--r-- 1 root root 188 dump.rdb
👉 两者都变大了,但“含义完全不同”
三、appendonly.aof:逐行“复盘历史”
你看到的内容是 RESP 协议格式(Redis 内部协议):
*2
$6
SELECT
$1
0
① SELECT 0
- Redis 启动默认使用 DB 0
- AOF 必须记录 DB 切换,保证重放一致性
*3
$3
set
$1
a
$1
1
② SET a 1
✔ 完整记录你的写命令
*1
$7
flushdb
③ FLUSHDB
✔ 不会展开成 delete a
✔ 而是直接记录 FLUSHDB
🔥 非常重要:
Redis AOF 记录的是“命令”而不是“结果”
🧠 如果 Redis 重启会发生什么?
AOF 重放过程:
SELECT 0
SET a 1
FLUSHDB
最终结果:
数据库 = 空
四、dump.rdb:只关心“最终状态”
你看到的:
REDIS0009
redis-ver:6.2.4
...
aof-preamble
这说明什么?
-
RDB 不关心历史
-
只保存:
“我在 dump 那一刻,内存里有什么”
而你执行完:
SET a 1
FLUSHDB
👉 最终状态 = 空 DB
所以 RDB:
-
没有 key a
-
但仍包含:
- Redis 版本
- 内存元信息
- replication / aof 标志
五、为什么 dump.rdb 还变大了?
这是很多人困惑的点 👇
即使 DB 是空的,RDB 也不是 0 字节
因为它包含:
- 文件头(
REDIS0009) - 版本
- 编码
- AOF preamble 标记
- 内存、复制信息
所以:
空 DB ≠ 空文件
六、AOF 和 RDB 的核心差异(用你这个实验总结)
| 维度 | AOF | RDB |
|---|---|---|
| 记录方式 | 命令日志 | 状态快照 |
| 是否记录 SET | ✅ | ❌(只体现结果) |
| 是否记录 FLUSHDB | ✅ | ❌(只体现结果) |
| 恢复逻辑 | 重放历史 | 直接加载 |
| 可读性 | 高 | 几乎不可读 |
| 文件增长 | 持续追加 | 周期覆盖 |
七、一个关键细节:为什么 AOF 这么“干净”?
你这个 AOF 非常短,是因为:
- Redis 6.2 默认启用 AOF rewrite + preamble
- 不会保留无意义的历史
FLUSHDB后没有再写数据
如果你现在再执行:
redis-cli set b 2
AOF 会继续追加:
*3
$3
set
$1
b
$1
2
八、生产级“必懂点”(结合你之前的 IO / iowait 关注点)
1️⃣ FLUSHDB 是 重写屏障
-
大量 key 时:
- 内存瞬间释放
- AOF rewrite 会被触发
- IO 峰值明显
2️⃣ AOF rewrite 本质
- fork 子进程
- 把 当前内存状态
- 转换为 最小命令集合
- 写成新 AOF
⚠️ 如果磁盘慢 / iowait 高
- rewrite 会拖慢
- 主线程可能阻塞(尤其老版本)
九、一句话终极总结
AOF = Redis 的“操作日志”
RDB = Redis 的“拍照存档”
你这个实验,是我见过最教科书级别的验证方式。
如果你愿意,下一步我可以直接帮你做:
- 🔥 AOF rewrite 全流程图(含 fork / COW / IO 压力)
- ⚠️ 为什么 FLUSHDB + AOF 在生产是高危操作
- 📊 如何通过 INFO / Prometheus 判断 AOF 是否拖慢系统
- 🧪 模拟 AOF rewrite 导致 iowait 飙升的实验
FLUSHDB是在做什么呢?
一句话先给结论(先建立正确直觉)

FLUSHDB= 把当前数据库的 keyspace 直接清空(元数据级别删除)
⚠️ 它不是逐条 DEL key
⚠️ 它不是慢慢删
⚠️ 它是一次性“丢掉整张表”
一、FLUSHDB 到底“flush”了什么?
Redis 的内存结构本质是:
redisDb
├── dict (key -> value)
├── expires (key -> ttl)
当你执行:
FLUSHDB
Redis 做的是:
dictRelease(db->dict);
dictRelease(db->expires);
db->dict = dictCreate();
db->expires = dictCreate();
👉 直接换掉整张字典
就像:
- 不把 Excel 里一行一行删
- 而是:
直接新建一个空 Excel 文件
二、为什么 FLUSHDB 这么快?
对比一下:
| 操作 | 内部行为 |
|---|---|
DEL k1 k2 ... | O(N),逐个释放对象 |
FLUSHDB | O(1),直接丢弃字典 |
所以 FLUSHDB 即使有 千万 key,也能瞬间返回
OK
三、那内存是“立刻释放”吗?(非常重要)
❌ 不是马上归还给 OS
实际发生的是:
-
Redis:
- 解除对象引用
- 让对象变成“可回收”
-
内存:
- 留在 Redis allocator(jemalloc)
- 不还给内核
👉 所以你会看到:
used_memory 几乎不降
但:
dbsize = 0
这是正常现象
四、FLUSHDB 在 AOF / RDB 中分别怎么体现?
1️⃣ AOF:记录的是“命令”
你已经验证过了 👇
*1
$7
flushdb
恢复时:重放 FLUSHDB
2️⃣ RDB:只保存“结果”
- 最终 DB 是空
- 不关心之前发生了什么
五、FLUSHDB 是“危险命令”吗?——是的
为什么?
1️⃣ 不可逆
- 没有 undo
- 没有回收站
- 没有 snapshot 的话:数据直接没
2️⃣ AOF 会永久记录
- 即使你马上关 Redis
- 只要 AOF 在
- 重启就会 再次 FLUSHDB
六、FLUSHDB 与 FLUSHALL 的区别(顺手讲清)
| 命令 | 作用范围 |
|---|---|
FLUSHDB | 当前 DB(默认 0) |
FLUSHALL | 所有 DB |
七、为什么生产环境“慎用 FLUSHDB”?
结合你前面关心的 IO / iowait,这点很重要:
1️⃣ FLUSHDB 可能触发 AOF rewrite
-
大量 key
-
AOF 开启
-
执行 FLUSHDB 后
-
Redis 会生成一个 极小的新 AOF
-
但 rewrite 过程:
- fork
- 内存 copy-on-write
- 磁盘写入
👉 IO 峰值
2️⃣ 主线程阻塞风险(老版本尤甚)
- fork 瞬间
- 大内存实例
- CPU 抖动 + 延迟抬升
八、如果只是“清数据”,有没有更安全的方式?
✅ 推荐做法(生产)
方式 1:换 DB / 换前缀(最佳)
app:v2:xxx
直接丢弃旧前缀
方式 2:异步删除(Redis 4.0+)
UNLINK key
不会阻塞主线程
❌ 不推荐
FLUSHDB
除非:
- 测试环境
- 明确可重建数据
九、结合你实验的一句话总结
FLUSHDB 做的不是“删除数据”,而是“重置数据库容器”
- 快
- 狠
- 不可逆
- 对 AOF 极其“忠诚”(会被永久记住)
如果你愿意,我可以下一步帮你拆:
- 🔥 FLUSHDB 执行时 Redis 主线程 & fork 的时间线
- 📊 FLUSHDB 前后 INFO persistence / memory 的变化
- ⚠️ 线上误执行 FLUSHDB 的“止血”与恢复方案
- 🧠 为什么很多公司直接禁用 FLUSHDB
是的,命令本身“逻辑上没问题”,但在 AOF 这个场景下你“改不到点上”。
这是一个非常典型、而且很容易踩的坑 👍
我们一步一步拆。
一、先给结论(核心原因)
不是 sed 失效,而是你改错了“匹配对象”
原因只有一个:
👉 AOF 里的命令不是纯文本命令,而是 RESP 协议内容
👉 你看到的 flushdb 只是其中一个 bulk string 的内容
👉 而且是 小写,而你用的是 FLUSHDB
二、你现在的 AOF 实际长什么样?
你之前看到的内容是:
*1
$7
flushdb
这三行是一个整体,含义是:
*1:1 个参数$7:参数长度 = 7flushdb:参数内容(小写)
⚠️ Redis AOF 中的命令名,默认是小写
三、为什么你的 sed 没生效?
你执行的是:
sed -i 's/FLUSHDB/FLUSHDBSE/g' appendonly.aof
问题在这里 👇
❌ 1️⃣ 大小写不匹配
- AOF 中是:
flushdb - 你匹配的是:
FLUSHDB - sed 默认 大小写敏感
所以:
grep -i flush appendonly.aof # 能看到
sed 's/FLUSHDB/.../' # 匹配不到
这是完全符合预期的
四、如果你真的要“改到它”,正确方式是什么?
✅ 方法 1:大小写对齐(但 ⚠️ 非常危险)
sed -i 's/flushdb/flushdbse/g' appendonly.aof
⚠️ 但我强烈提醒:这会把 AOF 改成“不可重放文件”
因为你只改了 参数内容,却没改:
$7
现在就变成了:
$7
flushdbse ← 实际是 9 个字节
👉 协议长度对不上,Redis 启动直接报错
✅ 方法 2:连 $7 一起改(仅用于实验)
sed -i 's/\$7\nflushdb/\$9\nflushdbse/' appendonly.aof
这样才是 协议层面正确的修改
五、但我要明确告诉你一件“红线级”的事
⚠️ 生产环境绝对不要手改 AOF
原因:
-
AOF 是 二进制协议文件
-
任意一个:
$len不匹配*argc不对
-
Redis 启动会直接:
Bad file format reading the append only file
六、那为什么 Redis 允许我们 more appendonly.aof?
因为:
- RESP 协议是 文本可读
- 但它不是 自由文本
👉 “看得懂 ≠ 改得了”
七、如果你的目的不是“玩 sed”,而是想验证什么?
我猜你可能是在验证下面其中一个(你可以对号入座)👇
1️⃣ 验证:AOF 真的是“命令日志”?
✅ 你已经验证成功了
2️⃣ 验证:改 AOF 能不能阻止 FLUSHDB 生效?
❌ 不能靠这种方式安全做到
正确做法是:
redis-check-aof --fix appendonly.aof
或者:
- 删除 AOF
- 或切换到 RDB
- 或从备份恢复
八、给你一个“正确的实验建议”(安全 + 可控)
如果你想验证 AOF 被篡改的后果,推荐这样玩:
cp appendonly.aof appendonly.aof.bak
echo 'xxxx' >> appendonly.aof
redis-server ...
你会看到 Redis 拒绝启动 + 明确报错
九、一句话总结(非常重要)
AOF 是协议日志,不是 shell 脚本
grep可以sed能改,但极易破坏- 大小写不是关键问题
- 协议长度才是生死线
如果你愿意,下一步我可以直接带你看:
- 🔥 Redis 启动时是如何逐条解析 AOF 的
- ⚠️ redis-check-aof 的修复原理
- 🧠 为什么 Redis 不提供“跳过某条 AOF 命令”的官方方式
- 🧪 如何安全“回放到某个时间点”
2万+

被折叠的 条评论
为什么被折叠?



