前几天同事不小心误操作,将SQLServer库的一张表的一个状态字段给刷成了一个统一状态,由于是update执行所以原来的相关状态无法确定。发生这种事情的时候我的小伙伴背后 一凉。
由于是在开发试运行中的项目,还没来得及进行备份处理,所以从备份恢复宣告失败。就算有备份那么恢复的也是备份时间节点的数据,意味着使用平台做的数据需要从备份时间重新做过,而且有可能有遗漏。
小伙伴问我这咋办,首先没有备份,那么只有从数据库日志查找,然后看能不能通过日志找回之前的数据,再还原到刷状态之前的数据。然后就找到了ApexSQLLog工具,接下来我介绍下这款工具的使用和如何恢复数据。ApexSQLLog有几个版本,我是用的是ApexSQLLog2014支持SqlServer更高的版本,数据库使用的是SqlSerVer2014。
ApexSQLLog2014 提取码: np4f
高级选项(advanced options)里面还有用户、字段条件等可以选择。
可以点击 下面的Row history查看记录,Redo script可以生成执行的操作, Undo script可以还原到之前的数据。我们恢复数据就是使用Undo script。
update TestUser set Status=3
然后刷新下日志,会看到多出了三条Update日志记录,点击第一条看到下面的Status字段从0变为了3。
我们选中这三条记录右键或者上面的菜单栏功能,用create undo script 生成恢复sql。
-- This UNDO script was generated with ApexSQL Log 2014.04.1133 on 2020-06-10 11:18:47.601
-- NOTE: Operations in UNDO scripts are always output in descending order.
-- SERVER VIP-966\SQLEXPRESS
-- DATABASE ApexSQLLogTest
-- UPDATE (00000024:000000A0:0004) done at 2020-06-10 11:09:36.293 by VIP-966\Administrator in transaction 0000:0000034B (Committed)
BEGIN TRANSACTION
UPDATE [dbo].[TestUser] SET [Status] = 2 WHERE [Id] = 3
IF @@ROWCOUNT <= 1 COMMIT TRANSACTION ELSE BEGIN ROLLBACK TRANSACTION; PRINT 'ERROR: STATEMENT AFFECTED MORE THAN ONE ROW. ALL THE CHANGES WERE ROLLED BACK.' END
-- UPDATE (00000024:000000A0:0003) done at 2020-06-10 11:09:36.293 by VIP-966\Administrator in transaction 0000:0000034B (Committed)
BEGIN TRANSACTION
UPDATE [dbo].[TestUser] SET [Status] = 1 WHERE [Id] = 2
IF @@ROWCOUNT <= 1 COMMIT TRANSACTION ELSE BEGIN ROLLBACK TRANSACTION; PRINT 'ERROR: STATEMENT AFFECTED MORE THAN ONE ROW. ALL THE CHANGES WERE ROLLED BACK.' END
-- UPDATE (00000024:000000A0:0002) done at 2020-06-10 11:09:36.293 by VIP-966\Administrator in transaction 0000:0000034B (Committed)
BEGIN TRANSACTION
UPDATE [dbo].[TestUser] SET [Status] = 0 WHERE [Id] = 1
IF @@ROWCOUNT <= 1 COMMIT TRANSACTION ELSE BEGIN ROLLBACK TRANSACTION; PRINT 'ERROR: STATEMENT AFFECTED MORE THAN ONE ROW. ALL THE CHANGES WERE ROLLED BACK.' END
GO
-- FINISHED ON 2020-06-10 11:18:47.697
-- TOTAL OPERATIONS PROCESSED 3
-- END OF FILE
最后我们就可以使用这个脚本去恢复数据了。
我们在使用日志恢复的时候如果表有主键会根据主键生成sql,如上图sql中 where后面的条件。如果表没有主键那么生成的sql后面的where条件会带上所有的字段。在我帮小伙伴恢复数据的时候发现他的表没有设置主键,而且字段有20多个,3万多条数据生成的sql都是100多M,还要拆分执行。 比如我把Id主键去了再更新下Status状态到4,生成的sql如下,会提示没有主键。
以上就是一次数据恢复的分享,如果下次你也遇到这种情况希望能帮到你。