目录标题
- appendonly.aof 和 dump.rdb
- 一、你现在看到的现象说明了什么?
- 二、appendonly yes / no 本质区别(一句话版)
- 三、appendonly no(RDB)详细解释
- 1️⃣ 工作方式
- 2️⃣ 你这里的 dump.rdb
- 3️⃣ RDB 的优缺点
- 四、appendonly yes(AOF)详细解释
- 1️⃣ 工作方式
- 2️⃣ AOF 刷盘策略(非常关键)
- 五、为什么你有 appendonly.aof 但大小是 0?
- 🔥 常见原因(按概率)
- ✅ 1️⃣ 曾经开启过 AOF,又关闭了(**最常见**)
- ✅ 2️⃣ 刚开启 AOF,但没有任何写操作
- ❌ 3️⃣ AOF 被 rewrite / truncate 失败(少见)
- 六、Redis 启动时:RDB 和 AOF 谁优先?
- 所以你现在:
- 七、配置切换时 Redis 的真实行为(很多人搞错)
- 从 `appendonly no → yes`
- 从 `appendonly yes → no`
- 八、如何确认当前 Redis 真正在用哪个?
- 1️⃣ 配置层面
- 2️⃣ 运行状态(最准)
- 九、生产环境怎么选?(运维建议)
- 🔥 强烈建议(通用)
- 十、一句话总结(帮你记忆)
- 模拟flushdb测试
- 一、先给结论(帮你快速建立直觉)
- 二、你刚刚做了什么?发生了什么?
- 1️⃣ 执行的命令
- 2️⃣ 文件变化
- 三、appendonly.aof:逐行“复盘历史”
- ① SELECT 0
- ② SET a 1
- ③ FLUSHDB
- 🧠 如果 Redis 重启会发生什么?
- AOF 重放过程:
- 四、dump.rdb:只关心“最终状态”
- 这说明什么?
- 五、为什么 dump.rdb 还变大了?
- 即使 DB 是空的,RDB 也不是 0 字节
- 六、AOF 和 RDB 的核心差异(用你这个实验总结)
- 七、一个关键细节:为什么 AOF 这么“干净”?
- 八、生产级“必懂点”(结合你之前的 IO / iowait 关注点)
- 1️⃣ FLUSHDB 是 **重写屏障**
- 2️⃣ AOF rewrite 本质
- 九、一句话终极总结
- 一句话先给结论(先建立正确直觉)
- 一、FLUSHDB 到底“flush”了什么?
- 二、为什么 FLUSHDB 这么快?
- 对比一下:
- 三、那内存是“立刻释放”吗?(非常重要)
- 实际发生的是:
- 四、FLUSHDB 在 AOF / RDB 中分别怎么体现?
- 1️⃣ AOF:记录的是“命令”
- 2️⃣ RDB:只保存“结果”
- 五、FLUSHDB 是“危险命令”吗?——是的
- 为什么?
- 1️⃣ **不可逆**
- 2️⃣ **AOF 会永久记录**
- 六、FLUSHDB 与 FLUSHALL 的区别(顺手讲清)
- 七、为什么生产环境“慎用 FLUSHDB”?
- 1️⃣ FLUSHDB 可能触发 AOF rewrite
- 2️⃣ 主线程阻塞风险(老版本尤甚)
- 八、如果只是“清数据”,有没有更安全的方式?
- ✅ 推荐做法(生产)
- 方式 1:换 DB / 换前缀(最佳)
- 方式 2:异步删除(Redis 4.0+)
- ❌ 不推荐
- 九、结合你实验的一句话总结
- 一、先给结论(核心原因)
- 二、你现在的 AOF 实际长什么样?
- 三、为什么你的 sed 没生效?
- ❌ 1️⃣ 大小写不匹配
- 四、如果你真的要“改到它”,正确方式是什么?
- ✅ 方法 1:大小写对齐(但 ⚠️ 非常危险)
- ✅ 方法 2:连 `$7` 一起改(仅用于实验)
- 五、但我要明确告诉你一件“红线级”的事
- 六、那为什么 Redis 允许我们 `more appendonly.aof`?
- 七、如果你的目的不是“玩 sed”,而是想验证什么?
- 1️⃣ 验证:AOF 真的是“命令日志”?
- 2️⃣ 验证:改 AOF 能不能阻止 FLUSHDB 生效?
- 八、给你一个“正确的实验建议”(安全 + 可控)
- 九、一句话总结(非常重要)
appendonly.aof 和 dump.rdb
一、你现在看到的现象说明了什么?
/data# ls -l-rw-r--r--1root root0Dec1815:45 appendonly.aof -rw-r--r--1root root175Dec1815: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--1root root175Dec1815:46 dump.rdb说明:
- Redis至少执行过一次 RDB 快照
- 数据量非常小(175 字节)
- Redis 当前运行逻辑:
内存 ←→ dump.rdb
3️⃣ RDB 的优缺点
优点
- 文件小
- 恢复快
- 对性能影响小
缺点
- 可能丢数据
- 崩溃时:
❌ 丢失最后一次快照后的写入
四、appendonly yes(AOF)详细解释
1️⃣ 工作方式
每条写命令都写进
appendonly.aof例如:
SET a 1 INCR a LPUSH q xRedis 重启:
👉重放 AOF 命令恢复数据
2️⃣ AOF 刷盘策略(非常关键)
appendfsync always # 最安全,最慢 appendfsync everysec # 默认,推荐 appendfsync no # 最快,最不安全五、为什么你有 appendonly.aof 但大小是 0?
-rw-r--r--1root root0Dec1815:45 appendonly.aof🔥 常见原因(按概率)
✅ 1️⃣ 曾经开启过 AOF,又关闭了(最常见)
过程可能是:
appendonly yesRedis 创建了
appendonly.aof后来改成:
appendonly noRedis不再写 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 appendonly2️⃣ 运行状态(最准)
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 FLUSHDB2️⃣ 文件变化
-rw-r--r--1root root67appendonly.aof -rw-r--r--1root root188dump.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-clisetb2AOF 会继续追加:
*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)当你执行:
FLUSHDBRedis 做的是:
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 被篡改的后果,推荐这样玩:
cpappendonly.aof appendonly.aof.bakecho'xxxx'>>appendonly.aof redis-server...你会看到 Redis拒绝启动 + 明确报错
九、一句话总结(非常重要)
AOF 是协议日志,不是 shell 脚本
grep可以sed能改,但极易破坏- 大小写不是关键问题
- 协议长度才是生死线
如果你愿意,下一步我可以直接带你看:
- 🔥Redis 启动时是如何逐条解析 AOF 的
- ⚠️redis-check-aof 的修复原理
- 🧠为什么 Redis 不提供“跳过某条 AOF 命令”的官方方式
- 🧪如何安全“回放到某个时间点”