sql service ---- update和delete 误操做数据 ---- 恢复数据

原文出处:http://blog.csdn.net/dba_huangzj/article/details/8491327mysql

问题:

         常常看到有人误删数据,或者误操做,特别是update和delete的时候没有加where,而后就喊爹喊娘了。人非圣贤孰能无过,作错能够理解,但不能纵容,这个之后再说,如今先来解决问题。sql

        遇到这种状况,通常都是没有作备份,否则也不会来发问了。首先要冷静,不然会有更大的灾难。直到你放弃。数据库

 

解决方法:

       对于这类问题,主要是找回误操做以前的数据,在2008以前,有个很出名的工具Log Exploer,据说还挺好用的,这个网上大把教程,这里就很少说了。可是惟一遗憾的是,不支持2008及更高版本,这时除了其余第三方工具,那么最经常使用的就是本文提到的方法——日志尾部备份。本文实验环境2008R2,对于2008及其以上版本可使用这个方法,其实2005也能够,2000不多用,没试过,只是2008以前可使用Log Exploer,因此就不必用这种方法。工具

      下面图文并茂讲解操做方法,至于原理,不属于本文范围,并且我相信真遇到误操做的时候,估计没人会看原理了。测试

步骤:

(1)、检查数据库的恢复模式,如图:spa

 

 

或者使用脚本检查:.net

[sql]  view plain copy print?
  1. SELECT recovery_model,recovery_model_desc  
  2. FROM sys.databases  
  3. WHERE name ='AdventureWorks'  

 

结果以下:日志

 

        确保数据库的恢复模式最起码不能为【简单】。至于如何修改为完整模式,我以为这些应该不必多说了。blog

 

       切记,对于任何重要环境,不只仅是客户正式环境(俗称生产环境),都强烈建议使用【完整恢复模式】,虽然对于另外两种(大容量日志(BULK_LOGGED)、简单(SIMPLE))来讲,完整恢复模式产生的日志会大,可是在出现问题的时候,就会以为这些都不算什么了。而且我也想不到任何理由对于正式环境不使用完整恢复模式。只要管理得当,完整恢复模式的日志也不会太变态。教程

 

(2)、这里其实隐含另一步,曾经作过最少一次的完整备份。由于全部类型的备份都基于完整备份,若是没有最少一次完整备份,其余类型的备份都是多余的,因此在这里强调一下,在建立完一个新数据库以后,强烈建议甚至强制作一次完整备份。

[sql]  view plain copy print?
  1. SELECT  database_name,recovery_model,name   
  2. FROM msdb.dbo.backupset  

 

使用上面的语句粗略能够看到有那些数据库作过备份,因为测试,因此作了几回备份,能够看到我这个时间点已经作了备份了。

 

(3)、确保别人再也不链接数据库,而后作一第二天志尾部备份:

首先先建立一点数据:

[sql]  view plain copy print?
  1. /*  
  2. 因为tempdb永远为简单恢复模式,因此不适合作案例。  
  3. 这里使用微软的示例数据库AdventureWorks  
  4. */  
  5. USE AdventureWorks  
  6. GO  
  7. IF OBJECT_ID('testRestore') IS NOT NULL   
  8.     DROP TABLE testRestore  
  9. GO  
  10. CREATE TABLE testRestore  
  11.     (  
  12.       id INT IDENTITY(1, 1) ,  
  13.       NAME VARCHAR(50)  
  14.     );  
  15. --插入测试数据:     
  16. INSERT INTO testRestore(Name)  
  17. SELECT 'test1'  
  18. UNION ALL   
  19. SELECT 'test2'  
  20. UNION ALL   
  21. SELECT 'test3'  
  22. UNION ALL   
  23. SELECT 'test4'  
  24. UNION ALL   
  25. SELECT 'test5'  
  26. UNION ALL   
  27. SELECT 'test6'  
  28. UNION ALL   
  29. SELECT 'test7'  
  30. UNION ALL   
  31. SELECT 'test8'  
  32. SELECT * FROM testRestore  

检查一下结果:



而后来作个删除操做,为了定位是啥时候发生的,我加了一个waitfor命令,让它在某个时间发生,这样恢复的时候就有准确性:

[sql]  view plain copy print?
  1. USE AdventureWorks  
  2. GO  
  3. WAITFOR TIME '21:45'  
  4. DELETE FROM dbo.testRestore  

 

如今来看看数据:

[sql]  view plain copy print?
  1. USE AdventureWorks  
  2. GO  
  3. SELECT * FROM dbo.testRestore  


 

到这一步,灾难出现了。可是切记要冷静。

下面就是本文的重点开始,作一第二天志备份,最重要是选择【备份日志尾部】

 

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

 

 

而后按肯定,固然,可使用上方的【脚本】来生成语句:

 

[sql]  view plain copy print?
  1. USE Master  
  2. GO  
  3. 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  
  4. GO  
  5. declare @backupSetId as int  
  6. 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' )  
  7. if @backupSetId is null begin raiserror(N'验证失败。找不到数据库“AdventureWorks”的备份信息。', 16, 1) end  
  8. RESTORE VERIFYONLY FROM  DISK = N'E:\AdventureWorks.bak' WITH  FILE = @backupSetId,  NOUNLOAD,  NOREWIND  
  9. GO  

 

此时,数据库会处于【正在还原】的状态

 

 

若是发现备份不了能够用下面语句查看,并把spid杀掉:

 

[sql]  view plain copy print?
  1. SELECT  * FROM sys.sysprocesses WHERE dbid=DB_ID('AdventureWorks')  

 

执行结果:

 

而后kill掉。

接着继续备份。

 

而后进行还原,如图:

先要还原完整备份,选择最近的那次,因为日志备份的特性(之后其余文章再说),只认最后一次备份,因此要选择最新的那次,不然还原不了。

 

 

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

 

 

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

 

 

而后:


 

 

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

 

 

如今再检查一下:

 

 

能够看到,数据已经还原成功。

相关文章
相关标签/搜索