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分刪除數據的。這裏不用太在乎,只要把時間點指定到你誤刪除的時間以前便可。而因爲日誌尾部備份都是最後一個備份文件,因此這裏選則紅框部分便可:

 

 

如今再檢查一下:

 

 

能夠看到,數據已經還原成功。

相關文章
相關標籤/搜索