数据误操作,教你使用ApexSQLLog工具从 SQLServer日志恢复数据!
小伙伴问我这咋办,首先没有备份,那么只有从数据库日志查找,然后看能不能通过日志找回之前的数据,再还原到刷状态之前的数据。然后就找到了ApexSQLLog工具,接下来我介绍下这款工具的使用和如何恢复数据。ApexSQLLog有几个版本,我是用的是ApexSQLLog2014支持SqlServer更高的版本,数据库使用的是SqlSerVer2014。
ApexSQLLog2014
提取码: np4f
-
首先建一个测试库,和一张测试表。
测试库ApexSQLLogTest和测试用的表TestUser,然后我手动编辑了三条数据进去,保存编辑的数据。
-
用ApexSQLLog打开测试库日志
选择要连接的数据库,也可以从最近的session中打开,打开筛选过的记录可以保存未session。
然后选中要筛选的日志文件,如果有备份数据库文件也会自动查找到并在这里罗列出来,自己按情况选择。
-
条件筛选
我们选择日志文件后就进入到筛选条件选择,可以在筛选条件里面自由组合。
可以选择时间段(Time range)、操作(operations)、表(tables)。
高级选项(advanced options)里面还有用户、字段条件等可以选择。
-
查看日志数据
当我们组合完筛选条件后,就进入到日志分析界面,可以看到我们之前手动插入的三条数据实际已经在日志里面了,分成了三条insert语句。在选中其中一条日志的时候在下面可以看到执行的各字段值的修改情况。
可以点击 下面的Row history查看记录,Redo script可以生成执行的操作, Undo script可以还原到之前的数据。我们恢复数据就是使用Undo script。
-
恢复数据测试。
我们使用update语句将Status状态全都重置为3。
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如下,会提示没有主键。
今天不小心对数据库执行了一次误操作,心想有没有什么工具能恢复这次误操作呢?于是找到了Log Explorer 4.2,可惜它最多只支持SQL 2005,在SQL 2008上无法使用,然后又找到了ApexSQL Log,最新版本最高支持SQL 2008以及SQL 2012,试用版可以提供功能无限制14天的免费试用期,功能倒真是强大
直接下载安装,官方下载地址: http://www.apexsql.com/sql_tools_log.aspx
安装完成,打开主界面:
点击“New”:
输入数据库相关信息后点击“Open”:
点击“Evaluate Product”:
表格列出之前进行的操作,在进行误操作的行上点击鼠标右键会出现很多菜单,“Create Undo Script”就是创建一个恢复脚本:
生成此脚本后执行即可恢复误操作:
1、事务解析
USE TestDB1GOSELECT * FROM [sys].[fn_dblog](NULL,NULL)
2、fn_dblog()字段解析
begin transaction tran_testuse TestDB1insert into test values(1,0)commit
begin transaction use TestDB1insert into test values(0,0)commit
use TestDB1insert into test values(0,0)
useTestDB1create table test(a int,b int,primary key(a),)
3、Operation与Context
create table dbo.OrderDetail(OrderID int not null,ItemID int not null,ItemNumber varchar(10),QTY int,Price decimal(8,2),ADate date,AUser char(20),UDate datetime,UUser varchar(20)constraint pk_OrderDetail primary key(OrderID,ItemID))
-- 操作1: 新增3行insert into dbo.OrderDetail(OrderID,ItemID,ItemNumber,QTY,Price,ADate,AUser,UDate,UUser)select 1001,1,'D001',100,45.62,'2015-01-02','Xh6','2015-01-03 20:15:18','Lx4' union allselect 1001,2,'Z001_2',150,180,'2015-01-02','cx5','2015-01-08 02:45:32','Yx3' union allselect 1002,1,'Z001_2',300,182.07,'2015-12-12','CL1','2015-12-18 02:45:32','LY6'select * from dbo.OrderDetail
-- 操作2: 更新1行update dbo.OrderDetail set QTY=999 where OrderID=1001 and ItemID=1select * from dbo.OrderDetail
-- 操作3: 更新3行update dbo.OrderDetail set ItemNumber='!@#$%'select * from dbo.OrderDetail
-- 操作4: 删除3行delete from dbo.OrderDetailselect * from dbo.OrderDetail
-- 恢复原操作4(删除3行) insert into dbo.OrderDetail([OrderID],[ItemID],[ItemNumber],[QTY],[Price],[ADate],[AUser],[UDate],[UUser]) values(1002, 1, '!@#$%', 300, 182.07, '2015-12-12', 'CL1', '2015-12-18 02:45:32.000', 'LY6');insert into dbo.OrderDetail([OrderID],[ItemID],[ItemNumber],[QTY],[Price],[ADate],[AUser],[UDate],[UUser]) values(1001, 2, '!@#$%', 150, 180.00, '2015-01-02', 'cx5', '2015-01-08 02:45:32.000', 'Yx3');insert into dbo.OrderDetail([OrderID],[ItemID],[ItemNumber],[QTY],[Price],[ADate],[AUser],[UDate],[UUser]) values(1001, 1, '!@#$%', 999, 45.62, '2015-01-02', 'Xh6', '2015-01-03 20:15:18.000', 'Lx4');-- 恢复原操作3(更新3行)update dbo.OrderDetail set [ItemNumber]='Z001_2' where [OrderID]=1002 and [ItemID]=1update dbo.OrderDetail set [ItemNumber]='Z001_2' where [OrderID]=1001 and [ItemID]=2update dbo.OrderDetail set [ItemNumber]='D001' where [OrderID]=1001 and [ItemID]=1-- 恢复原操作2(更新1行)update dbo.OrderDetail set [QTY]=100 where [OrderID]=1001 and [ItemID]=1
select * from dbo.OrderDetail
About Me
........................................................................................................................ ● 本文作者:小麦苗,部分内容整理自网络,若有侵权请联系小麦苗删除 ● 本文在个人微 信公众号( DB宝)上有同步更新 ● QQ群号: 230161599 、618766405,微信群私聊 ● 个人QQ号(646634621),微 信号(db_bao),注明添加缘由 ● 于 2020年11月完成 ● 最新修改时间:2020年11月 ● 版权所有,欢迎分享本文,转载请保留出处 ........................................................................................................................ ● 小麦苗的微店: https://weidian.com/s/793741433?wfr=c&ifr=shopdetail ● 小麦苗出版的数据库类丛书: http://blog.itpub.net/26736162/viewspace-2142121/ ● 小麦苗OCP、OCM、高可用、MySQL、DBA学习班: http://blog.itpub.net/26736162/viewspace-2148098/ ● 数据库笔试面试题库及解答: http://blog.itpub.net/26736162/viewspace-2134706/ ........................................................................................................................ 请扫描下面的二维码来关注小麦苗的微 信公众号( DB宝)及QQ群(230161599、618766405)、添加小麦苗微 信(db_bao), 学习最实用的数据库技术。
........................................................................................................................ |