基于本文回答

播面 播面

文图音视,全方位拆解八股文
0
评论

线上Redis误执行了FLUSHALL命令,导致数据全部被清空,如何利用AOF文件紧急恢复数据?

知识点图片

这是一项非常紧急的线上救援操作。请立刻停止当前的恐慌,深呼吸,并严格按照以下步骤操作。

⚠️ 最核心的警告:绝对不要在此时重启 Redis!
如果直接重启,Redis 会重新执行 AOF 文件中的命令(包括那条 FLUSHALL),导致数据彻底无法恢复。更糟的是,如果触发了 AOF 自动重写(BGREWRITEAOF),AOF 文件会被重写为一个空文件,届时将彻底回天乏术。

请按照以下步骤进行紧急恢复:

第一步:立刻停止 Redis 服务(防止 AOF 重写)

千万不要使用 redis-cli shutdown(因为它可能会触发保存)。建议直接在服务器上 kill 掉 Redis 进程:

bash
# 找到 Redis 进程 ID
ps -ef | grep redis

# 优雅地 kill 掉进程(不要用 -9,除非 -15 杀不掉)
kill -15 <redis-pid>

第二步:立即备份 AOF 文件(核心救命步骤)

在进行任何修改之前,必须先备份现有的 AOF 文件。这是你最后的数据底线。

  1. 找到 Redis 的数据目录(通常在 redis.conf 中的 dir 配置项下,默认为 /var/lib/redis 或当前目录)。
  2. 备份 AOF 文件:

对于 Redis 7.0 之前的版本(单 AOF 文件):

bash
cp appendonly.aof appendonly.aof.bak

对于 Redis 7.0 及之后的版本(多部分 AOF - Multi-part AOF):
Redis 7.0 之后 AOF 被拆分为一个目录(通常叫 appendonlydir),里面有基础文件(.base.)和增量文件(.incr.)。

bash
cp -r appendonlydir appendonlydir.bak

第三步:编辑 AOF 文件,剔除 FLUSHALL 命令

AOF 文件以 Redis 序列化协议(RESP)纯文本格式记录命令。由于 FLUSHALL 是刚误执行的,它一定在文件的最末尾

操作步骤:

  1. 使用 vimnano 打开 AOF 文件。

    • Redis < 7.0: vim appendonly.aof
    • Redis >= 7.0: 进入 appendonlydir 目录,打开最新的增量文件(例如 vim appendonly.aof.1.incr.aof)。
  2. 在 vim 中按 Shift + G 跳转到文件最后一行。

  3. 你会看到类似如下格式的文本内容(这就是 FLUSHALL 在 AOF 中的样子):

    plaintext
    *1
    $8
    flushall

    (注:如果是 FLUSHDB 则为 $7flushdb;如果是异步清空 FLUSHALL ASYNC,则结构会是 *2 开头包含 async)

  4. 删除这几行! 将关于 FLUSHALL 的这几行(从 *1 开始到 flushall 结束)全部删除。

  5. 保存并退出 (:wq)。

第四步:使用修复后的 AOF 文件启动 Redis

  1. 确保你的 redis.conf 中开启了 AOF(appendonly yes)。
  2. 启动 Redis 服务:
    bash
    # 使用 systemctl 或者直接指定配置启动
    systemctl start redis
    # 或者
    ./redis-server /path/to/redis.conf
  3. 查看 Redis 日志(tail -f /var/log/redis/redis.log),你应该能看到 Redis 正在加载 AOF 文件到内存中:
    * DB loaded from append only file...

第五步:验证数据

使用 redis-cli 连接上去,执行以下命令确认数据是否回来:

bash
redis-cli
127.0.0.1:6379> DBSIZE
127.0.0.1:6379> INFO keyspace

如果能看到 key 的数量恢复正常,恭喜你,抢救成功!


🚨 致命情况说明(什么情况下用此法无法恢复?)

如果你在误执行 FLUSHALL 后,Redis 碰巧执行了 BGREWRITEAOF(AOF 重写机制),旧的 AOF 文件会被一个体现当前内存状态(空库)的新 AOF 文件替换。
如果发生这种情况,AOF 抢救法将失效。 你只能去寻找昨天的 RDB 备份文件,或者云厂商提供的磁盘快照进行恢复。


亡羊补牢:如何防止此类事故再次发生?

事故处理完毕后,强烈建议立即在生产环境落实以下预防措施:

1. 禁用或重命名高危命令(最简单有效)
redis.conf 中加入以下配置,让这些命令失效或改成只有你知道的暗号:

plaintext
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command KEYS ""
# 如果你想改名而不是禁用:
# rename-command FLUSHALL "FLUSHALL_DANGEROUS_999"

2. 启用 ACL 权限控制(Redis 6.0+)
为业务应用分配普通用户权限,只允许执行读写命令,禁止管理员命令。

3. 做好异地备份
编写 Shell 脚本结合 crontab,每天定时把 RDB 和 AOF 文件打包同步到 S3、OSS 或其他备份服务器上。

00:00
00:00