[SQL SERVER][TS] 找出遺失的資料

[SQL SERVER][TS] 找出遺失的資料

網友問題其中有問到如何 確認資料遺失狀況。

網友詢問如何恢復鏡像資料庫(主體資料庫因為某些例外造成鏡像資料庫同步處理失敗),

這篇重點放在如何找出遺失的資料。

這裡我假設主體資料庫有部分頁面毀損,所以一定得進行災難復原,

當然如果資料庫沒有毀損的話,你可以先比對前後兩個資料庫所有資料表總筆數差異,

然後找出差異的資料表,在去比對兩個資料表資料內容差異..等,anyway..回到主題,

當修復資料庫成功上線後,通常老闆或使用者也會問資料庫資料是否完整,

如果沒有的話,那又有那些資料遺失呢?

這裡我大概紀錄如何找出遺失資料的過程。

 

 

我先建立一個正常DB(含一個資料表和3筆資料)

use
mybroken
go
create table tbl
(
c1 int ,
c2 varchar(10),
c3 datetime
)

	
insert into tbl values(1,'rico',getdate()),(2,'sherry','20120717'),(3,'papa','20120718')

	
select * from tbl 

 

image

目前該資料表查詢正常(3筆資料也都存在)。

 

接下來我模擬該資料表毀損的狀況(大部分現實世界所遇到的狀況)。

image

先將資料庫離線。

 

我對 mybroken 資料庫做了一點手腳並恢復資料庫上線且查詢該資料表,這時將出現下列錯誤訊息。

image

image

image

page(1:78)無法讀取,即表示該頁面資料(8060 bytes)都將會遺失。

 

由於已經知道資料頁面位置,所以使用dbcc page 來顯示該頁面資訊,嘗試找出遺失資料。

DBCC TRACEON (3604)
DBCC PAGE (mybroken,1,78,3)

image

image

page header 部分,我們可以透過objecid和m_slotcnt屬性知道是那各物件和該資料頁面所含總筆數。

 

image

透過objectid可以知道objectname= tbl 。

 

image

image

image

上面我擷取部份資料頁面資訊,你可以看到第2、3筆資料及每個資料行(c1、c2、c3)的原始資料。

而當你修復該資料庫成功上線後,你也已經知道有那些資料會遺失。

 

現在我將修復該資料表錯誤(詳細過程可參考沒有Ldf檔案實做還原資料庫)。

use master
go

	
ALTER DATABASE mybroken SET SINGLE_USER;
--REPAIR_ALLOW_DATA_LOSS 修復可能會造成某些資料的遺失 
DBCC CHECKDB (mybroken, REPAIR_ALLOW_DATA_LOSS) WITH NO_INFOMSGS;
ALTER DATABASE mybroken SET MULTI_USER;

image

錯誤修復成功。

 

image

成功修復錯誤後,該資料表中相關資料也遺失了(前面過程我們已經知道會遺失那些資料了)。

 

Note: REPAIR_ALLOW_DATA_LOSS 該選項真的要僅慎使用,

因為尋找遺失資料的工作相當煩人也累人,

大部分比對工具幾乎都無法使用(因為資料頁面都無法讀取),

幾乎只能苦中作樂一一尋找原始資料,

除非真的沒有其他辦法可以恢復資料庫時,我才會考慮該選項。

 

最後你可以告訴老闆或使用者說,資料表 tbl 遺失3筆資料,

然後由你的老闆或使用者來決定相關遺失資料的重要性及是否恢復它。

 

而這過程大家可以參考我之前所翻譯的一篇文章

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

 

 

參考

How to use DBCC PAGE

More undocumented fun: DBCC IND, DBCC PAGE, and off-row columns

沒有Ldf檔案實做還原資料庫