Redis  AOF之执行flushdb或flushall之后的后悔药_数据

 

​FLUSHALL ASYNC​​ (Redis 4.0.0 or greater)


Redis is now able to delete keys in the background in a different thread without blocking the server. An ​​ASYNC​​​ option was added to FLUSHALL​ and FLUSHDB in order to let the entire dataset or a single database to be freed asynchronously.

Asynchronous FLUSHALL​ and FLUSHDB commands only delete keys that were present at the time the command was invoked. Keys created during an asynchronous flush will be unaffected.

 

fluashall对AOF文件影响


Redis执行了flush操作后, AOF持久化文件会受到什么影响呢? 如下所示:
·appendonly no: 对AOF持久化没有任何影响, 因为根本就不存在AOF文件。
·appendonly yes: 只不过是在AOF文件中追加了一条记录, 例如下面就是AOF文件中的flush操作记录:

[root@localhost 6379]# cat appendonly.aof 
REDIS0009 redis-ver5.0.8
redis-bits?.time?!used-mem?
.of-preamble?.?o.*2
$6
SELECT
$1
0
*3
$3
SET
$8
firstkey
$10
firstvalue
*3
$3
SET
$9
secondkey
$11
secondvalue
*3
$3
SET
$9
secondkey
$11
secondvalue
*1
$8
flushall

虽然Redis中的数据被清除掉了, 但是AOF文件还保存着flush操作之前完整的数据, 这对恢复数据是很有帮助的。 注意问题如下:

1) 如果发生了AOF重写, Redis遍历所有数据库重新生成AOF文件, 并会覆盖之前的AOF文件。 所以如果AOF重写发生了, 也就意味着之前的数据就丢掉了, 那么利用AOF文件来恢复的办法就失效了。 所以当误操作后, 需要考虑如下两件事。
·调大AOF重写参数auto-aof-rewrite-percentage和auto-aof-rewrite-minsize, 让Redis不能产生AOF自动重写。
·拒绝手动bgrewriteaof。

127.0.0.1:6379> config set auto-aof-rewrite-percentage 100
OK
127.0.0.1:6379> config set auto-aof-rewrite-min-size 500mb
OK

2) 如果要用AOF文件进行数据恢复, 那么必须要将AOF文件中的flushall相关操作去掉, 为了更加安全, 可以在去掉之后使用redis-check-aof这个工具去检验和修复一下AOF文件, 确保AOF文件格式正确, 保证数据恢复正常。

[root@localhost 6379]# /usr/local/redis/bin/redis-check-aof  /usr/local/redis/6379/appendonly.aof 
The AOF appears to start with an RDB preamble.
Checking the RDB preamble to start:
[offset 0] Checking RDB file /usr/local/redis/6379/appendonly.aof
[offset 26] AUX FIELD redis-ver = '5.0.8'
[offset 40] AUX FIELD redis-bits = '64'
[offset 52] AUX FIELD ctime = '1599484648'
[offset 67] AUX FIELD used-mem = '853408'
[offset 83] AUX FIELD aof-preamble = '1'
[offset 85] Selecting DB ID 0
[offset 109] Checksum OK
[offset 109] \o/ RDB looks OK! \o/
[info] 1 keys read
[info] 0 expires
[info] 0 already expired
RDB preamble is OK, proceeding with AOF tail...
AOF analyzed: size=197, ok_up_to=197, diff=0
AOF is valid

 

RDB有什么变化


Redis执行了flushall操作后, RDB持久化文件会受到什么影响呢?
1) 如果没有开启RDB的自动策略, 也就是配置文件中没有类似如下配置:
save 900 1
save 300 10
save 60 10000
那么除非手动执行过save、 bgsave或者发生了主从的全量复制, 否则RDB文件也会保存flush操作之前的数据, 可以作为恢复数据的数据源。 注意问题如下:
·防止手动执行save、 bgsave, 如果此时执行save、 bgsave, 新的RDB文件就不会包含flush操作之前的数据, 被老的RDB文件进行覆盖。
·RDB文件中的数据可能没有AOF实时性高, 也就是说, RDB文件很可能很久以前主从全量复制生成的, 或者之前用save、 bgsave备份的。
2) 如果开启了RDB的自动策略, 由于flush涉及键值数量较多, RDB文件会被清除, 意味着使用RDB恢复基本无望。
综上所述, 如果AOF已经开启了, 那么用AOF来恢复是比较合理的方式, 但是如果AOF关闭了, 那么RDB虽然数据不是很实时, 但是也能恢复部分数据, 完全取决于RDB是什么时候备份的。 当然RDB并不是一无是处, 它的恢复速度要比AOF快很多, 但是总体来说对于flush操作之后不是最好的恢复数据源。

 

从节点有什么变化


Redis从节点同步了主节点的flush命令, 所以从节点的数据也是被清除了, 从节点的RDB和AOF的变化与主节点没有任何区别。
 

 

快速恢复数据


下面使用AOF作为数据源进行恢复演练。
1) 防止AOF重写。 快速修改Redis主从的auto-aof-rewrite-percentage和auto-aof-rewrite-min-size变为一个很大的值, 从而防止了AOF重写的发生,例如:

config set auto-aof-rewrite-percentage 1000
config set auto-aof-rewrite-min-size 100000000000

2) 去掉主从AOF文件中的flush相关内容:

*1
$8
flushall

3) 重启Redis主节点服务器, 恢复数据。
 

具体过程如下


运维的朋友,可能会碰到这样的情况,在redis不小心执行了flushdb或者flushall的操作,此时是不是打算辞职走人了?下面来讲一下,redis执行了flushdb或者flishall之后的“后悔药”操作:

(1)先看一下我们现在redsi中已经有的数据

Redis  AOF之执行flushdb或flushall之后的后悔药_恢复数据_02

(2)此时我们执行了flushall的操作(flushdb的操作也是一样的)

Redis  AOF之执行flushdb或flushall之后的后悔药_数据_03

(3)我们首先执行关闭的不存储操作:shutdown nosave

Redis  AOF之执行flushdb或flushall之后的后悔药_redis_04

(3)杀掉redis的进程:pkill -9 redis

Redis  AOF之执行flushdb或flushall之后的后悔药_恢复数据_05

(4)修改redis的aof文件,删除到最后执行的flushall相关的命令(我的文件是 /var/rdb/appendonly6379.aof 文件)

Redis  AOF之执行flushdb或flushall之后的后悔药_redis_06

 (5)重启redis,(./bin/redis-server ./redis.conf) (./bin/redis-cli)

Redis  AOF之执行flushdb或flushall之后的后悔药_redis_07

如图,我们执行flushall之前的数据,已经恢复回来了,思路其实很简单,手动将aof文件的flushall命令删除,然后重启redis就会自动加载了