Redis:appendonly.aof 和 dump.rdb

目录标题

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 noRDB定期拍快照
appendonly yesAOF每条写命令顺序追加

三、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,又关闭了(最常见

过程可能是:

  1. appendonly yes

  2. Redis 创建了 appendonly.aof

  3. 后来改成:

    appendonly no
    
  4. Redis 不再写 AOF

  5. 文件保留但不更新

👉 结果就是:空 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

  1. Redis 立即开始写 AOF

  2. 并且会:

    • 把当前内存数据
    • 生成一份 AOF(rewrite)

appendonly yes → no

  1. Redis 立刻停止写 AOF
  2. 不会删除 appendonly.aof
  3. 文件留在磁盘上(你现在的情况)

八、如何确认当前 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 记录“最终内存状态快照”
FLUSHDBAOF 中是一次命令
但在 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 的核心差异(用你这个实验总结)

维度AOFRDB
记录方式命令日志状态快照
是否记录 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),逐个释放对象
FLUSHDBO(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:参数长度 = 7
  • flushdb:参数内容(小写

⚠️ 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

原因:

  1. AOF 是 二进制协议文件

  2. 任意一个:

    • $len 不匹配
    • *argc 不对
  3. 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 命令”的官方方式
  • 🧪 如何安全“回放到某个时间点”
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值