Redis恢复被删掉了的key值

本文只是小实验,不供线上使用参考

本文假定的情况是,某同学不小心手残,把redis中的一个key删掉了,想恢复被删掉的key的数据。对于mysql等数据库等,有完整的数据库日志,回滚或者看日志就可以考虑恢复,但redis没有。

实验开始:
第一步:准备redis环境

  1. 清空redis数据,清除已有的rdb和aof持久化文件

     rm appendonly.aof
     rm dump.rdb 
    

默认的aof和rdb持久化文件分别为appendonly.aof和dump.rdb,清除这两个文件

  1. 开启aof和rdb持久化策略

     appendonly yes
     appendfilename "appendonly.aof"
    
     // rdb默认开启,可以配置调整参数
     save 900 1
     save 300 10
     save 60 10000
    
  2. 重启redis-server

第二步:测试

  • 连接redis后,通过save命令产生redis rdb备份文件,通过config set appendonly yes会产生aof文件;**

这是通过winhex打开查看的rdb文件:
Redis恢复被删掉了的key值_第1张图片
nodepad打开查看的aof文件:
Redis恢复被删掉了的key值_第2张图片

可以看到aof文件内容为空,rdb文件是二进制格式,查看后里面是redis rdb文件基础格式信息,没有数据。

  • 填充数据

往redis中填充数据,为方便查看,分别从a1填充到a10, 在通过save和config命令更新aof文件和rdb文件,如下:

127.0.0.1:6379> set a1 a
OK
127.0.0.1:6379> set a2 a
OK
127.0.0.1:6379> set a3 a
OK
127.0.0.1:6379> set a4 a
OK
127.0.0.1:6379> set a5 a
OK
127.0.0.1:6379> set a6 a
OK
127.0.0.1:6379> set a7 a
OK
127.0.0.1:6379> set a8 a
OK
127.0.0.1:6379> set a9 a
OK
127.0.0.1:6379> set a10 a
127.0.0.1:6379> 
127.0.0.1:6379> save
OK
127.0.0.1:6379> config set appendonly yes
  • 查看aof和rdb文件情况
    理论上aof文件作为redis内存镜像应该会有内容更新,aof文件也一样。

rdb文件内容:
Redis恢复被删掉了的key值_第3张图片

aof文件内容(太长了,只显示部分):

*2
$6
SELECT
$1
0
*3
$3
set
$2
a1
$1
a

从以上文件可以看出rdb文件存放的是大概是直接的key和value值,aof文件存放的操作日志,包含命令,key值和value值

  • 设置一个key值,然后删掉

    127.0.0.1:6379> config set appendonly yes
     OK
     127.0.0.1:6379> set b bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
     OK
     127.0.0.1:6379> 
     127.0.0.1:6379> 
     127.0.0.1:6379> del b
     (integer) 1
     127.0.0.1:6379> save
     OK
     127.0.0.1:6379> config set appendonly yes
    

rdb文件内容如下,可以看出rdb文件中内容是没有变化的:
Redis恢复被删掉了的key值_第4张图片
aof文件中增加了下面下面一段操作日志,包括set b和del b两条命令:
Redis恢复被删掉了的key值_第5张图片

  • 关闭redis,备份aof文件,删掉aof中最后四行,并重启

以下为最后四行的解析:

*2   // 代表del b总共分为两部分
$3  // $3代表接下来是个字符串,长度为3
del // 字符串del,长度为3
$1  //   $1代表接下来是个字符串,长度为1
b    // 字符串b,长度为1
  • *重启redis后,通过keys 查看所有的key

有b这个key:

127.0.0.1:6379> keys *
 1) "a1"
 2) "a5"
 3) "a8"
 4) "a7"
 5) "a4"
 6) "a3"
 7) "a10"
 8) "a6"
 9) "b"
10) "a9"
11) "a2"
127.0.0.1:6379> 
  • 删掉dump.db,重启redis
    还是有b这个关键字了;

    127.0.0.1:6379> keys *
      1) "a4"
      2) "a3"
      3) "a10"
      4) "b"
      5) "a8"
      6) "a6"
      7) "a5"
      8) "a1"
      9) "a2"
     10) "a9"
     11) "a7"
    

这样被删的key b被恢复了,但这里有个问题,无论rdb文件存在与否,b都被恢复了,从redis启动日志看出,这里恢复数据是优先从aof文件中恢复的(DB loaded from append only file: 0.000 seconds)。

17235:M 18 Sep 18:35:31.340 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
17235:M 18 Sep 18:35:31.341 # Server started, Redis version 3.0.7
17235:M 18 Sep 18:35:31.341 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
17235:M 18 Sep 18:35:31.341 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
17235:M 18 Sep 18:35:31.341 * DB loaded from append only file: 0.000 seconds
17235:M 18 Sep 18:35:31.341 * The server is now ready to accept connections on port 6379

这里有关redis恢复机制,即在开启aof并且存在文件的情况下,优先从aof文件中恢复

  1. 如果只配置 AOF ,重启时加载 AOF 文件恢复数据;
  2. 如果同时配置了 RDB 和 AOF ,启动是只加载 AOF 文件恢复数据;
  3. 如果只配置 RDB,启动是将加载 dump 文件恢复数据。

结论:
如果要恢复删除的key,前提是需要开启aof持久化策略;在开启aof持久化策略的情况下,删不删除rdb文件没有关系。

小心操作为上,特别是线上redis

你可能感兴趣的:(Redis)