一次Redis数据完全丢失的事故

虽然不是我删库,但是还是想跑路

之前可能说过,虽然现在的项目明确最终应该还是要靠MySQL,但是开发期间为了方便,使用Redis做数据落地。

很长一段时间都没有问题,心中隐隐产生了点好像直接使用Redis也没什么问题的感觉。

于是今天就瞬间炸裂了。

早上机房因为一个插线板烧毁,导致断电,不过当时我并不知道具体情况,以为只是普通断网,网好了以后试了试NAS连接没问题,就没有再管了。下午偶然想要更新一下Skynet,结果发现开发服连不上去,仔细一查发现VM宿主机都连不上了,赶紧联系运维去机房看了看,一聊才知道原来是断电了。奇怪的是NAS为什么没问题呢?隐约记得NAS我是设置了断电恢复后自动开机,现在是体会到这个功能的必要性了……下次再出现这种情况,得去把虚拟机宿主服务器也设置一下。

上来以后连上VM看,所有虚拟机都没开,原来VMware ESXi在默认设置下,开机是不会自动启动虚拟机的,查询了一下,把都设置自动启动了。确认虚拟机都启动起来了,也就没再管了。结果过了一会儿,徐哥问游戏服务器的连接问题,我有些纳闷,一看,果然都挂了。这时候正好要去参加一场面试,粗略看了眼好像是Redis问题,systemctl查看果然是Redis没有启动,restart也无效,只好嘱咐徐哥帮忙看一下,准备好材料先去面试。

回来以后问题还没解决,这个问题非常奇怪,系统日志里看Redis只是单纯的启动不了,徐哥查看了Redis日志说是没有权限读取dump.rdb,查看权限竟然是600,所有者和群组都是root。权限设为755后,读取报错,确认应该是文件损毁,改名之后,Redis顺利启动。BGSAVE生成新的dump文件,对比发现,这次生成的文件所有者是正确的Redis,大小也远远超过损毁的文件,看来原来的资料是没救了。损毁的原因猜测应该是断电的时候正好在dump,不过怎么会这么不靠谱呢?仔细去看了一遍Redis有关持久化的文档,以及conf文件,终于搞清楚了,原来是自己的用法不对。

Redis 有两种持久化方案,RDB (Redis DataBase)和 AOF (Append Only File)默认开启的只有RDB,定期全量备份全库,这个从文件名dump也能清楚的看出来,平时非常好用,但是致命的问题就在于……RDB并不保证完整性和一致性。万一在dump的时候断电,那么就是直接的结果……文件损毁。

而AOF就是为了弥补这个缺点而存在的,直接的理解就是记录日志,根据配置可以对每一条记录写一次,或者每秒写一次,在超过指定大小后,还会重写整个文件,防持续追加记录导致文件过大。

找到设置,开启AOF,以后就不怕再断电了。正高兴呢,结果查询了一下,发现Redis竟然数据又消失了……仔细考虑了一下,开启AOF之后,Redis启动时就不再读取RDB,而是根据AOF日志恢复,而现在AOF是空的,那么当然恢复不出任何数据了。这个问题的解决方法也很简单,要么从一开始就开启AOF,要么配置文件中先不开启AOF,而是通过RDB启动起来以后,使用client调用命令手动开启AOF。我这样操作以后发现依然没有数据,这可就奇怪了。再仔细思索一下,心中一凉,完了……又把数据搞丢了。我在上一次发现数据库是空的,然后stop数据库准备不开AOF启动那一次,直接就把空数据库dump了出来,覆盖了有数据的那份……唉……太傻了。

删库有一个好处,我趁机把之前想改的一个key结构给改了,反正都全部重来了,也算苦中作乐吧。好在反正就我们这几个程序策划在里面,给每人发点金币补偿一下吧,哈哈哈。