工具地址:
https://download.csdn.net/download/Joker_ZJN/90849511
要是下不了,私信找我要,或者去网上搜都可以,应该好找
目录
博主差点经历一场生产事故
博主现在在一家有三十年历史的软件公司,由于公司成立时间长,有很多历史项目需要进行维护,在维护过程中必须去生产环境中手动执行一些SQL,手动执行就一定可能会出现失误,最容易的失误就是update和delete没有跟上where条件。博主在昨天执行一条Update语句的时候就没有跟上where条件,事发现场:
OK,事情已经发生了,惊慌肯定是惊慌的,要是不能恢复就是一场生产事故,客户几十年的数据都被弄乱了,但更重要的是如何去恢复。以下是博主的处理顺序:
-
立即停止系统,联系客户告知系统暂时进行维护停服一段时间,目的是不再产生新的数据和数据库操作日志。
-
马上备份一份当前的数据,因为接下来要进行各种操作,先备份一份当前数据。
-
去找备份,因为生产库来说应该是开起了每日备份的,去找找备份文件在哪里,要是能找到头一天备份的文件,那么就还原到头一天,大不了今天的业务重新做。
故事就不讲太长了,免的大家没有耐心看了,上面的三步走完结果是:
之前维护的人太坑,生产环境没有每天备份。
到这一步还能怎么办?也就剩最后的机会了,也就是这篇文章我们要聊的主角:数据库操作日志。
基于mysql聊聊数据库的log
关系型数据库要实现事务,必须要有两个日志:
-
重做日志(redo log),记录本次SQL执行之前的数据状态,也就是之前执行过的SQL
-
回滚日志(undo log),记录本次SQL执行后的新数据状态,也就是现在的所有执行过的SQL
事务执行中直接去写回滚日志,事务回滚通过重做日志来回滚。重做日志、回滚日志在目前主流的数据库中实现不同,但肯定都是有对应存在的:
分类 | Oracle | Mysql | SQL Server |
---|---|---|---|
重做日志 | Redo Logs + Archive Logs | Redo log | Transaction Log |
回滚日志 | Undo Tablespace | Undo log | Log Records in Transaction Log |
大家常见的、面试常问到的mysql除了以上两个日志外,还维护了一个bin log,这个bin log里面记录了所有数据库操作,是拿来专门恢复数据时候用的。下面是redo log、undo log、bin log三者之间的协作流程:
先记录undo log,然后写redo log,写redo log成功则同步写bin log,由于redo log和bin log必须同成功、同失败,所以用了两阶段提交来保证,这里不展开。
sql server回滚误操作
上面聊了数据库的这些操作日志,说明一个什么问题?
由于数据库是用操作日志记录下了历史操作的,那么即使是没有数据库的备份文件,托底的方案一定是基于这些log能把数据恢复出来的。
稍微有一点麻烦的是这些log是数据库内部使用的,并不方便直接拿来回滚数据。mysql准备了一个bin log专门拿来恢复数据,但是很遗憾博主面对的这个项目用的是sql server,sql server是没有bin log这种方便拿来恢复数据的log的,但市面上有一些工具,就是拿来专门解析undo log和redo log来进行数据恢复的。下面是博主用的工具,用来解决了差点发生的生产事故:
ApexSQLLog——专门拿来基于log恢复sql server数据的工具
然后就是选择时段和过滤条件:
这里尽量把时间区间选择短一点,只要涵盖事发时间就是,不然太多log了。
切记要点Operations里面去选择看你要找的操作具体是什么类型,不然数据库每天那么多操作拉出来的log根本看不完:
然后会查出你想要的对于数据库的历史操作:
选择你要回滚的操作,工具支持生成逆操作的语句:
去出事儿的库里面执行一下逆操作的语句即可救命。