ONLINE DATA LOST

如果你的线上MySQL数据库是由你搭建并维护的,数据库中有比较重要的核心数据,而你突然发现你迷迷糊糊误操作了,执行了 rm -rf /data/ 导致线上MySQL的文件夹目录数据全部丢失, 你会怎么办呢?

If Your Online MySQL Database is Built and Maintained by You, and It Contains Important Core Data, You Have Misunderstood and Executed rm -rf /data/ to Delete the Entire Directory of Your Online MySQL Files, What Will You Do?

这是我在前一段时间,真实经历的一件事,但是所幸,事件的操作者当时以为没有备份,当时真的是太绝望了。在第二天也许是死心了之后又或是总是要面对的,竟然意外的和云服务商找回了对应服务器的前大概2-3天的备份,所幸数据丢失不算很多,一两天的数据还算可以接受。

这事情也过去了大概有半个月,这半个月一直在处理一些其他的事,今天索性就来写个记录。

前情提要

前情提要:作者和我是朋友,也是程序员。他在某一家国企上班。和大家理想中的国企工作不一样,他们那里就只有2个后端开发,Java的代码功能开发也不是很简单,所以是两个后端撑起一个部门,而他们的部门领导对他也并不太好,经常要他打黑工,所以说他的日常就可预期的被一些外人看来莫名其妙的工作所占满,自己的工作总是要拖到很久以后才能干。

事情表象

事情大概是这样子的,7月底的某一天下午4点半,他在微信上问我,数据库被误删除了,要怎么恢复,于是我就比较好奇,顺带抛出了一些问题,数据是否重要,是什么数据库被删除了,从朋友口中我得知,他的数据是线上的MySQL,并且是自己搭建的。刚开始我还比较纳闷,难道国企数据安全这么不规范的吗,在外面随便一个私企都不敢把线上的数据放到MySQL中去,而他们直接把线上的数据放到自己搭建的单节点的MySQL的docker容器中去。属实是buff叠满了。于是我让朋友发我了docker的 inspect信息,看到了服务器磁盘映射挂载的信息,进到了宿主机上的对应目录中去看了一下,果然是空了的。
于是我就真的很奇怪了,如果是之前就有数据的,肯定不可能是空的,那么我就让他给我了他的服务器 history 命令的截图,我还在看的时候,发现了端倪。

表象原因

图片在这里:data_operation.png
注意看在 上方前几行,有一行 rm -rf fi /data/ 这个应该就是误操作的记录。所以这个实际上就是因为我朋友误操作执行了 rm -rf /data/ 才导致数据文件目录被删除掉了,他还告诉我,执行完了,他立马发现不太对劲,然后疯狂按Ctrl + C,但是终结完了以后再进目录,发现mysql的文件目录都已经被删除掉了。

是否备份

数据丢的原因很容易找到,那自然要尝试怎么找回来,但实话说,之前也没遇到过这种情况,于是我们便又开始了找数据的历程。找数据的历程自然起始是要问清楚有无备份,如果有备份的话数据恢复自然就是早晚的事。在遍历了可能的源数据文件 如是否有每日SQL Dump,以及各种备份恢复机制,也就是通过SQL可执行文件/mysql的binlog之类的备份恢复机制/服务器快照策略(这个前面有讲,当时确实认为没有快照)之后,一脸懵逼,全部都没有!!!当时我甚至都认为(不是以为,是真的是感觉要死了)棺材都躺一半了。

恢复尝试

后来问了运维比较好的一位朋友,这种是否能恢复,要取决于磁盘类型和挂载方式,于是又让我朋友通过 cfdisk 和 lsblk 查看文件磁盘的类型,
发现是 LVM逻辑磁盘卷,这个多是虚拟化磁盘类型,也就是把磁盘虚拟化或是融合到一起去,组成一个Pool,再去对上层提供存储和挂载,PVE就是这种磁盘格式。而且在这个过程中,也了解到一些正常的磁盘恢复的手段和方法。最简单的磁盘恢复方式,是实体机安装服务器操作系统 + 机械磁盘。Linux系统是基于inode来实现的文件存储机制,inode包含了每个目录的元数据信息,如果文件被删除时,立马使用inode恢复工具,找到被删除的inode号,也许还可以恢复数据,因为inode是这么一个机制,当你删除,也就是执行 rm -rf /* 时,文件并非是即时立马被删除掉的,很大批量的文件在磁盘上,也并非可以直接全部删除掉,会先在文件系统中标记删除,然后系统在空闲时刻再去回收掉对应的inode,了解到就算是机械盘,
也有个几分钟的时间来让你做对应的操作,如果你恰好反应过来了,又恰好懂得磁盘恢复,又恰好是实体机安装的话,那么可能是可以恢复回来的。否则,变一步,都比登天还难。
如果你的磁盘是SSD的话,SSD是一颗主控去管理N多个堆叠的NAND 芯片,同时SSD的NAND结构是纯粹的电逻辑门控制的,并非是HDD那种磁头读写数据,通过电力改变磁头磁性,来读取出磁盘区块中的比特位是0或1的数据信息的结构,有些SSD磁盘为了加速读写吞吐性能,甚至会在底层增加trim的属性,trim也很好理解,就是当你在删除数据之后,如果有 trim属性的话,那么你的数据区块可能在几秒钟之内就会自动被删除掉。这下子我算是明白了数据中心为什么会宁愿用到HDD也不用很高读取速度的SSD的原因了。因为环境是不一样的,而且存储原理都不一样,HDD更为传统,数据误删除后,还可以通过断电停机等方式,来保存数据,更有甚者,专业数据中心还会使用磁带机来进行数据的冷备。

文件恢复的小知识

现代操作系统的文件格式,磁盘上会有很多超级备份快,类似游戏里的一个一个check point,存储这一区块中的文件元数据信息,如果丢失数据之后,可以尝试从超级备份快找一下。
还有的话,是inode,如果inode没有丢失,且时间足够短的情况下,也是可以恢复回来的。

数据库使用教训

事实证明,数据安全是永无止境的话题。一定要在设计程序之初或是使用某个存储中间件时,就要考虑到数据是怎么恢复和备份的。不要等到真的出了事,再去发现,那样子就晚了。哪怕是使用最错币的方式勤备份,也比不管要强很多倍。
1.使用mysql 的话 要尽量开 binlog备份,同时 binlog的备份目录,建议是不要放在 数据目录中,一定要分开存储。
2.如果自己可以连得上数据库的话,哪怕最垃圾的方式,也就是自己手动每天导出备份一下。
3.如果是有类似宝塔(虽然说安全性差了点,但是好在备份数据是绝对的方便,没有之一)之类的工具的话,那么可以配置一些备份策略,滚动备份,这样子每次至少能保证有n多个历史景象或是全量数据,不至于两眼一抹黑。
4.如果是使用云厂商的数据存储产品,那么肯定1000%是有快照或是备份的,或全量或定期增量,备份策略也要开起来,要考虑到数据的绝对安全性。
5.如果认为我说的1-4 不对,那么请放弃查看本文,我可能就是个菜鸟。

后续

第二天,我朋友可能是联系了云厂商的客服,给了出事的磁盘号,然后云厂商客服帮忙找到了快照,快照是出事之前大约2-3天,损失的数据还算是可以接受,相比于损失全量数据的话,这个代价就算还好。经过这一次事情,我朋友应该知道了备份的重要性吧(或许吧,不过要吐槽的是,朋友的公司的部门,他们那天有同事也在,还说之前从来没有出过这种事,所以其他的也是没有备份的。我就一整个大无语了,这个数据难道还要出过事才能知道的吗,按照这个操作逻辑,但凡出一点事,客户分分钟是要骂娘的事情,你就想嘛,如果你是你公司的产品的客户,直接把你的真实使用的数据丢在一个黑盒子里,也没有备份恢复的机制,你觉得用的放心吗?