透過 SQL Server 挽救方法找出已刪除資料 Ways to Find out What Data Was Deleted by SQL Server Repair

當發生問題時,有可能你別無選擇必須使用 DBCC CHECKDB並搭配 REPAIR_ALLOW_DATA_LOSS選項時,該選項可能會造成一些資料的遺失.這時你的任務將變成要找出有那些資料遺失,同時盡可能重建遺失資料或反映資料庫其他固定部分的遺失.

執行修復之前,你必須先嘗試透過DBCC CHECKDB 檢查有那些頁面是損壞的.這樣你才知道有什麼樣的資料在上面.同時請注意以下錯誤訊息:

Server: Msg 8928, Level 16, State 1, Line 2

Object ID 645577338, index ID 0: Page (1:168582) could not be processed. See other errors for details.

你可以嘗試使用 DBCC PAGE 去檢查 page(1:168582).這會讓你知道該頁面的損壞程度如何,你可能也會在頁面上看到某些紀錄,當頁面被修復釋放後,就可搞清楚遺失那些資料.

修復執行完成後,你可能會清楚有那些資料已經被刪除了.但如果你對該資料庫沒有很熟悉的話,可以透過兩個方法來輔助:

●執行修復作業之前,請先把損壞的資料庫複製一個副本,然後比較修復前和修復成功後的資料庫,這樣你就可以知道少了那些資料.

●執行修復作業之前,可先啟動外顯交易(explicit transaction).這樣修復作業會形成內部交易.當修復完成後,你可以檢查資料庫修復了那些部分,但如果你要恢復修復作業,你也可以簡單輕鬆回滾(roll back)外顯交易(explicit transaction).

修復完成後,你可能會查詢已修復的資料庫有那些資料已經被修復.例如,你會考慮查詢一個已修復成功的叢集索引並帶有識別欄位的分葉節點.並找出被刪除紀錄範圍的查詢可能如下:

 -- Start of the missing range is when a value does not have a plus-1 neighbor.
 SELECT MIN(salesID + 1) FROM DemoRestoreOrRepair.dbo.sales as A
 WHERE NOT EXISTS (
        SELECT salesID FROM DemoRestoreOrRepair.dbo.sales as B
        WHERE B.salesID = A.salesID + 1);
 GO
 -- End of the missing range is when a value does not have a minus-1 neighbor
 SELECT MAX(salesID - 1) FROM DemoRestoreOrRepair.dbo.sales as A
 WHERE NOT EXISTS (
        SELECT salesID FROM DemoRestoreOrRepair.dbo.sales as B
        WHERE B.salesID = A.salesID - 1);
 GO

修復完成後,你至少應該要執行一次完整備份,並且實行主要原因分析,然後找出是什麼原因造成的損壞.

來源出處: Microsoft Press, Microsoft SQL Server 2008 Internals (by Kalen Delaney, Paul S. Randal, Kimberly L. Tripp, Conor Cunningham, Adam Machanic, and Ben Nevarez).