有些不靠谱的同事真的很误事,运维了几年的系统从来没出过误删表数据的事件,3月14日下午突然被同事误删了订单表全量数据,查询表返回0 rows,突然大脑一片空白,心想完了完了,最重要的表数据全部被清理了,虽然有每日凌晨5点的全量备份,但是截止下午的数据怎么找回?从来没碰到过误删事件,也从来没处理过数据恢复。。。

一、先挽救每日备份的数据

找到每日全量备份的数据,把订单表还原到测试库,然后单独把订单表重新备份,针对误删的表进行全量恢复 采用的工具是mydumper,非mysql官方的mydump 心想:好在有每日凌晨5点的全量备份,虽然在自己手里,从开发了每日全量备份脚本并配置定时任务每天执行,从来没派上用场,也希望不会派上用场,但是良好的备份意识还是挽救了90%的数据。 半小时左右,90%的数据恢复,然后把问题上报。

二、没处理过误删也没恢复数据经验,保留现场,上报事故

把90%数据恢复后,赶快写了一封邮件,把事故上报,说明丢失的数据范围、后果,恢复了多少等等,让上级是否请专业的数据恢复,结果上级喊我过去是否可以把剩下的当日备份后的数据找回来,我想了一想,说可以找,只是我没这方面的经验,可能效率和时间上不会很快,这里上级的算盘打得太精了,不愿意请恢复数据的人才来临时救火。。。

三、尝试解析binlog

以自己对mysql的理解,找到当天的binlog,备份下来,查找资料解析binlog,因为没经验,几小时后才解决问题,把binlog由二进制解析成可读的文本,但是查看解析后的文件,仍然可读性较差,很多字段还是@,中间还有很多集群同步的信息干扰等等,中间的苦难不描述那么多了,反正是拿到了10G的解析后的数据。。。

四、缩小范围

缩小误删事件的范围,减少日志文件的大小,然后把10G的文本降低到6G,仍然还是没法看的,中间经过好多天在github、各大运维论坛查找mysql恢复工具,python2、3的工具找了不少,都是无能为力,几乎没啥作用… 这些脚本都有个前提,要求mysql开启了一些参数,比如row模式,检测对比,自己手中的生产库有些参数不满足,没法直接用,改造脚本来不及了,只好换个思路,用土法子,把解析的binlog数据提取出来

五、写脚本提取缩小范围后的binlog日志

找到insert语句的规律,自己编写shell脚本提取数据,把凌晨5点截止到下午误删时间中间的数据提取出来,转化成insert sql语句 不过时间已经过去一周了,虽然过程很乱,但是自己的头脑时清晰的,没有可用的现成的数据恢复工具,自己造工具。

六、结果

中间没有备份的数据基本上恢复,几百条数据全部提取成功,然后执行入库,完美解决。。。

PS:整个过程有惊无险,总结几点:

1、要熟悉mysql的机制,了解当前数据存放在哪个二进制文件
2、最重要的前提,有日备份,没有这点,我也是无能为力解决这次问题
3、找一些现成的工具和测试工具浪费了我大量的时间,有得必有失,不可能别人或者某个大厂的工具正好满足你,结果还是需要自己解析binlog并提取字段参数
4、庆幸的是,时间上没给我太大的压力,一周才整理完几个G的文件解析并拿到合适的数据
5、冷静分析问题,虽然没经历过这些事故,但是以自己的经验和冷静,最终完美找回99.9%,为啥还有0.1%,误删表的时候,数据库自动重启了,因为百万级别的表被删除已经引起服务器IO和mysql的IO异常了,mysql自动重启,重启期间的数据在业务日志中报错,因为精力有限,一周后没法再回头整理这些入库异常的信息。
6、最后查找事故的主角,谁删了这张表,查找了mysql日志,没记录到IP,不过就算记录到IP也没辙,因为我们有中间件读写分离,记录的也是中间件IP
7、事后反省,猪队友太多了,可能有人问不要给猪队友这种权限的账号,其实我们项目管理还比较正规的,我们有运维账号、业务账号、查询账号,正是运维的账号把表数据清理,空表留着。并不是drop表,运维账号有修改数据权限,没drop权限。
整个记录比较乱,只是不吐不快。。。