SQLServer 2008以上誤操作數據庫恢復方法


解決方法:
       對於這類問題,主要是找回誤操作之前的數據,在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分刪除數據的。這里不用太在意,只要把時間點指定到你誤刪除的時間之前即可。而由於日志尾部備份都是最后一個備份文件,所以這里選則紅框部分即可:

 

 

 

 

現在再檢查一下:

 

 

 


可以看到,數據已經還原成功。
---------------------
作者:發糞塗牆
來源:CSDN
原文:https://blog.csdn.net/dba_huangzj/article/details/8491327
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM