2011年10月26日 星期三

SQL Server - 資料誤刪救援方式

        近日遇到一個客戶詢問的問題,由於他們的資料庫中有一個資料表的資料意外的被刪除,所以尋求我們協助還原資料,但可惜的是在進一步詢問後,客戶竟然完全沒有備份,所以只好透過內建的方法進行還原,大家一定會想到可以透過 DBCC LOG 或  fn_dblog 來觀察吧,但可惜的是這二個的資訊還是無法讓使用者比較直接又簡單的方式進行還原的動作,後來我終於找到方式解決,大家可以參考下列的步驟進行。
     
1、如果你有完整備份時,您可以透過交易記錄檔還原被 update 或 delete 的記錄。

還原到某個時間點

1-1. 使用 NORECOVERY 選項執行 RESTORE DATABASE 陳述式。
附註
如果部分還原順序排除任何FILESTREAM 檔案群組,則不支援時間點還原。您可以強制還原順序,以繼續進行。但是,絕對無法還原 RESTORE 陳述式中省略的 FILESTREAM 檔案群組。若要強制時間點還原,請指定 CONTINUE_AFTER_ERROR 選項,連同 STOPAT、STOPATMARK 或 STOPBEFOREMARK 選項,而且您也必須在後續的 RESTORE LOG 陳述式中指定這些項目。如果您指定 CONTINUE_AFTER_ERROR,則部分還原順序會成功,而 FILESTREAM 檔案群組則會變成無法復原。

1-2. 執行 RESTORE LOG 陳述式以套用每一個交易記錄備份,並指定:

  • 要套用交易記錄檔的資料庫名稱。
  • 要從其還原交易記錄備份的備份裝置。
  • RECOVERY 及 STOPAT 選項。如果交易記錄備份中不含所要求的時間 (例如,指定的時間超出交易記錄的結束時間),則會產生警告訊息,且此資料庫會維持未復原狀態。

範例
下列範例會將資料庫還原至 April 15, 202012:00 AM 時的狀態,並顯示含有多個記錄備份的還原作業。在備份裝置 AdventureWorks2008R2Backups 上,要還原的完整資料庫備份是裝置上的第三個備份組 (FILE = 3),第一個記錄備份是第四個備份組 (FILE = 4),而第二個記錄備份是第五個備份組 (FILE = 5)。

重要事項
AdventureWorks2008R2 資料庫使用簡單復原模式。若要允許記錄備份,在執行完整資料庫備份之前,請使用 ALTER DATABASE AdventureWorks2008R2 SET RECOVERY FULL 將該資料庫設定為使用完整復原模式。

RESTORE DATABASE AdventureWorks2008R2
FROM AdventureWorks2008R2Backups
WITH FILE=3, NORECOVERY;
go;

RESTORE LOG AdventureWorks2008R2
FROM
AdventureWorks2008R2Backups
WITH FILE=4, NORECOVERY,
STOPAT = 'Apr 15, 2020 12:00 AM';
go;

RESTORE LOG AdventureWorks2008R2
FROM
AdventureWorks2008R2Backups
WITH FILE=5, NORECOVERY,
STOPAT = 'Apr 15, 2020 12:00 AM';
RESTORE DATABASE AdventureWorks2008R2 WITH
RECOVERY;
go;

參考資料:
如何:還原到某個時間點 (Transact-SQL)
http://msdn.microsoft.com/zh-tw/library/ms179451.aspx

2、若沒有做過完整備份,我們沒有提供直接從交易記錄檔的方式,提供third-party 工具給您參考。 LiteSpeed http://www.quest.com/litespeed-for-sql-server/ 您可以用LiteSpeed找出所有資料後,再透過undo log的方式找回被誤刪的資料即可。

在下列的測試程式碼中,會建立資料庫,然後新增二筆紀錄,再刪除名稱為 'cary' 的紀錄,然後後再透過 LiteSpeed 的軟體救回資料。

測試程式碼:
CREATE TABLE dbo.cary_member (
sn smallint NOT NULL IDENTITY (1, 1),
name varchar(50) NULL
) ON [PRIMARY] go;

insert dbo.cary_member(name) values('cary'); go;

insert dbo.cary_member(name) values('sky'); go;

delete from dbo.cary_member where name = 'cary' go;


2-1. 啟動 LiteSpeed 之後,連線到資料庫,然後在左半邊的最下方,點選 Log Reader,然後就可以列出目前在Log Files中有的記錄。

2-2. 選取被刪除的記錄,然後選擇 [Undo/Redo Transaction]

2-3此時會跳出 [Undo/Redo Wizard],將你選擇的紀錄轉成DML語法。

2-4完成後系統會統計你進行的筆數與執行結。

2-5這時候再到資料庫中進行查詢,你就會發生資料已被救回來了。

2-6然後再回到 LiteSpeed的 Log Reader之中,確認Log 的紀錄,此時你會發現又多現一筆了,也就是新增後寫回的紀錄。



3、另外如果您要查詢是那一位使用者刪除的話,您可以透過下列的方式進行。

select [Current LSN], [Transaction ID], [Transaction Name],
[Begin Time], bb.name
from ::fn_dblog (null, null) aa inner join
master.sys.syslogins bb
on aa.[Transaction SID] = bb.sid
where [Transaction Name] LIKE '%DELETE%'


最後還是建議大家在資料庫的維護上,還是要有完整的備份規畫,要不然日後如果還有資料誤刪或毀損時,可不是每一次都可以這麼幸運的,建議大家可以參考下列的連結進行備份的規畫。

參考連結:
Introduction to Backup and Restore Strategies in SQL Server
http://msdn.microsoft.com/en-us/library/ms191239.aspx

關鍵字:SQL ServerData RecoveryDBCC LOGfn_dblogLiteSpeed

沒有留言:

張貼留言