SQLServer 2008以上误操作数据库恢复方法——日志尾部备份(转)
问题:
经常看到有人误删数据,或者误操作,特别是update和delete的时候没有加where,然后就喊爹喊娘了。人非圣贤孰能无过,做错可以理解,但不能纵容,这个以后再说,现在先来解决问题。
遇到这种情况,一般都是没有做备份,不然也不会来发问了。首先要冷静,否则会有更大的灾难。直到你放弃。
解决方法:
对于这类问题,主要是找回误操作之前的数据,在2008之前,有个很出名的工具Log Exploer,听说还挺好用的,这个网上大把教程,这里就不多说了。但是唯一遗憾的是,不支持2008及更高版本,这时除了其他第三方工具,那么最常用 的就是本文提到的方法——日志尾部备份。本文实验环境2008R2,对于2008及其以上版本可以使用这个方法,其实2005也可以,2000很少用,没 试过,只是2008之前可以使用Log Exploer,所以就没必要用这种方法。
下面图文并茂讲解操作方法,至于原理,不属于本文范围,而且我相信真遇到误操作的时候,估计没人会看原理了。
步骤:
(1)、检查数据库的恢复模式,如图:


或者使用脚本检查:
- SELECT recovery_model,recovery_model_desc
- FROM sys.databases
- WHERE name ='AdventureWorks'
结果如下:

确保数据库的恢复模式最起码不能为【简单】。至于如何修改成完整模式,我觉得这些应该没必要多说了。
切记,对于任何重要环境,不仅仅是客户正式环境(俗称生产环 境),都强烈建议使用【完整恢复模式】,虽然对于另外两种(大容量日志(BULK_LOGGED)、简单(SIMPLE))来说,完整恢复模式产生的日志 会大,但是在出现问题的时候,就会觉得这些都不算什么了。并且我也想不到任何理由对于正式环境不使用完整恢复模式。只要管理得当,完整恢复模式的日志也不 会太变态。
(2)、这里其实隐含另外一步,曾经做过最少一次的完整备份。因为所有类型的备份都基于完整备份,如果没有最少一次完整备份,其他类型的备份都是多余的,所以在这里强调一下,在创建完一个新数据库之后,强烈建议甚至强制做一次完整备份。
- SELECT database_name,recovery_model,name
- FROM msdb.dbo.backupset
使用上面的语句粗略可以看到有那些数据库做过备份,由于测试,所以做了几次备份,可以看到我这个时间点已经做了备份了。

(3)、确保别人不再连接数据库,然后做一次日志尾部备份:
首先先创建一点数据:
- /*
- 由于tempdb永远为简单恢复模式,所以不适合做案例。
- 这里使用微软的示例数据库AdventureWorks
- */
- USE AdventureWorks
- GO
- IF OBJECT_ID('testRestore') IS NOT NULL
- DROP TABLE testRestore
- GO
- CREATE TABLE testRestore
- (
- id INT IDENTITY(1, 1) ,
- NAME VARCHAR(50)
- );
- --插入测试数据:
- INSERT INTO testRestore(Name)
- SELECT 'test1'
- UNION ALL
- SELECT 'test2'
- UNION ALL
- SELECT 'test3'
- UNION ALL
- SELECT 'test4'
- UNION ALL
- SELECT 'test5'
- UNION ALL
- SELECT 'test6'
- UNION ALL
- SELECT 'test7'
- UNION ALL
- SELECT 'test8'
- SELECT * FROM testRestore
检查一下结果:

然后来做个删除操作,为了定位是啥时候发生的,我加了一个waitfor命令,让它在某个时间发生,这样恢复的时候就有准确性:
- USE AdventureWorks
- GO
- WAITFOR TIME '21:45'
- DELETE FROM dbo.testRestore
现在来看看数据:
- USE AdventureWorks
- GO
- SELECT * FROM dbo.testRestore

到这一步,灾难出现了。但是切记要冷静。
下面就是本文的重点开始,做一次日志备份,最重要是选择【备份日志尾部】

然后在【选项】页选择:除【事务日志】除,其他红框包裹的地方为强烈建议勾选的地方。并且保证数据库不要有别人在连接,因为备份日志尾部会使数据库处于还原状态,拒绝其他会话的连接,如果不断开其他连接,是备份不了的。

然后按确定,当然,可以使用上方的【脚本】来生成语句:
- USE Master
- GO
- BACKUP LOG [AdventureWorks] TO DISK = N'E:\AdventureWorks.bak' WITH NO_TRUNCATE , NOFORMAT, NOINIT, NAME = N'AdventureWorks-事务日志 备份', SKIP, NOREWIND, NOUNLOAD, NORECOVERY , COMPRESSION, STATS = 10, CHECKSUM
- GO
- declare @backupSetId as int
- select @backupSetId = position from msdb..backupset where database_name=N'AdventureWorks' and backup_set_id=(select max(backup_set_id) from msdb..backupset where database_name=N'AdventureWorks' )
- if @backupSetId is null begin raiserror(N'验证失败。找不到数据库“AdventureWorks”的备份信息。', 16, 1) end
- RESTORE VERIFYONLY FROM DISK = N'E:\AdventureWorks.bak' WITH FILE = @backupSetId, NOUNLOAD, NOREWIND
- GO
此时,数据库会处于【正在还原】的状态

如果发现备份不了可以用下面语句查看,并把spid杀掉:
- SELECT * FROM sys.sysprocesses WHERE dbid=DB_ID('AdventureWorks')
执行结果:

然后kill掉。
接着继续备份。
然后进行还原,如图:
先要还原完整备份,选择最近的那次,由于日志备份的特性(以后其他文章再说),只认最后一次备份,所以要选择最新的那次,否则还原不了。

这里又有一个注意事项,记得选择:

接着还原日志文件,这是最最重要的一步:

然后:

由于实验的时候出了点问题,后面重做了,所以时间选择到22:19分,我是在22:20分删除数据的。这里不用太在意,只要把时间点指定到你误删除的时间之前即可。而由于日志尾部备份都是最后一个备份文件,所以这里选则红框部分即可:

现在再检查一下:

可以看到,数据已经还原成功。
总结:
平时不做备份,出问题来喊急,这是苟有自取,还有一些脑袋发热的人喜欢看到ldf很大就直接删除,那以后出问题就别怪微软了。
本文中的方法看上去有点繁琐,但是实操几次就觉得好了,但是步骤建议严格按照上面说的,因为一旦操作错误,就很麻烦,此时再次强调——冷静冷静再冷静!!!!!!
这种方法有几个缺点:
1、 如果你发现误操作以后还有很多人做了操作,那么你还原成功后,别人的操作就会冲掉,所以发生误操作后,要马上停止别人对数据库的操作。
2、 这个方法要对数据库独占,所以你想偷偷恢复是不行的了。勇敢承认错误吧。
对于核心数据表,还是要先做好预防操作,可以看:SQLServer恢复表级数据。
SQLServer 2008以上误操作数据库恢复方法——日志尾部备份(转)的更多相关文章
- [转]SQLServer 2008以上误操作数据库恢复方法——日志尾部备份
原文出处:http://blog.csdn.net/dba_huangzj/article/details/8491327 问题: 经常看到有人误删数据,或者误操作,特别是update和delete的 ...
- SQLServer 2008以上误操作数据库恢复方法—日志尾部备份
原文出处:http://blog.csdn.net/dba_huangzj/article/details/8491327 问题: 经常看到有人误删数据,或者误操作,特别是update和delete的 ...
- SQL Server 2008以上误操作数据库恢复方法——日志尾部备份
原文出处:http://blog.csdn.net/dba_huangzj/article/details/8491327 问题: 经常看到有人误删数据,或者误操作,特别是update和delete的 ...
- SQLServer 2008以上误操作数据库恢复方法
解决方法: 对于这类问题,主要是找回误操作之前的数据,在2008之前,有个很出名的工具Log Exploer,听说还挺好用的,这个网上大把教程,这里就不多说了.但是唯一遗憾的是,不支持20 ...
- binlog2sql实现MySQL误操作的恢复
对于MySQL数据库中的误操作删除数据的恢复问题,可以使用基于MySQL中binlog做到类似于闪回或者生成反向操作的SQL语句来实现,是MySQL中一个非常实用的功能.原理不难理解,基于MySQL的 ...
- MySQL binlog2sql实现MySQL误操作的恢复
对于MySQL数据库中的误操作删除数据的恢复问题,可以使用基于MySQL中binlog做到类似于闪回或者生成反向操作的SQL语句来实现,是MySQL中一个非常实用的功能.原理不难理解,基于MySQL的 ...
- 用ADO操作数据库的方法步骤(ZT)
http://www.cppblog.com/changshoumeng/articles/113437.html 学习ADO时总结的一些经验 用ADO操作数据库的方法步骤 ADO接口简介 ADO库包 ...
- 摘:用ADO操作数据库的方法步骤
用ADO操作数据库的方法步骤 ADO接口简介 ADO库包含三个基本接口:_ConnectionPtr接口._CommandPtr接口和_RecordsetPtr接口. _ConnectionPtr接口 ...
- 用ADO操作数据库的方法步骤
用ADO操作数据库的方法步骤 学习ADO时总结的一些经验 - 技术成就梦想 - 51CTO技术博客 http://freetoskey.blog.51cto.com/1355382/989218 ...
随机推荐
- phonegap 附件下载及打开附件
出处:http://my.oschina.net/u/1011854/blog/169434 再次 谢谢作者! 在开发web app并且使用phonegap的情况下,附件下载着实是一件令人头疼的事,什 ...
- 在VS 2015 RTM 版中 提示 未能正确加载 NuGetPackage包
在原来的项目中曾经启用了Nuget在编译时还原包功能.这样就会在 *.sln在平行目录生成 一个.Nuget文件夹, 删除了它,就好了. 我分析原因是, VS 2015 使用的是 NugetP ...
- shell之任务控制
http://linux.cn/article-2680-1.html 你的 shell 会留有一张当前作业的表单,称为作业表.当你键入命令时,shell 会给它分配一个 jobID(也称作 JOBS ...
- 【转】第7篇:Xilium CefGlue 关于 CLR Object 与 JS 交互类库封装报告:全自动注册与反射方法分析
作者: 牛A与牛C之间 时间: 2013-12-12 分类: 技术文章 | 2条评论 | 编辑文章 主页 » 技术文章 » 第7篇:Xilium CefGlue 关于 CLR Object 与 JS ...
- python之chardet库
chardet库是python的字符编码检测器,能够检测出各种编码的类型,例如: import chardet import urllib.request testdata = urllib.requ ...
- java.io.IOException: ORA-22920: 未锁定含有 LOB 值的行
究其原因是因为没有锁定要更新的行记录.将 mysql="select filebody from filelist where filename=?"中的SQL语句加上 ...
- SharePoint 2010 最佳实践学习总结------第1章 SharePoint Foundation开发基础
----前言 这段时间项目出在验收阶段,不是很忙,就潜心把SharePoint学一下,不求有多深刻,初衷只是先入门再说.后续会发布一系列的学习总结.主要学习的书籍为<SharePoint2010 ...
- [转]oracle for update和for update nowait的区别
1概念小结:(针对以下引用区域内容) 1.1 普通select语句不加锁. 1.2 for update和for update nowait都试图将符合条件的数据加上行级锁.用于排斥其他针对这个表的写 ...
- mvc checked=\"checked\"
<input id="IsDiscount" type="checkbox" @(Model != null && Model.IsDis ...
- Learning Puppet — Resources and the RAL
Learning Puppet — Resources and the RAL Welcome to Learning Puppet! This series covers the basics of ...