2016年9月28日 星期三

Database Corruption Challenge – Steve Stedman

Database Corruption Challenge – Steve Stedman
from my MSDN blog - September 28, 2016


2016年9月13日 PASS
Database Corruption Challenge - Steve Stedman
Presented by Steve Stedman

1.備份資料庫,還原至測試機來進行修復工作(確保還原程序遭遇問題時,可以重頭再來修復一次)
2.如果決定用allow data loss,嘗試先找出可能遺失的資料並事先嘗試SELECT INTO保留下來
3.執行之前尋求是否有其他人的意見

定期執行
osql -E -Q"DBCC CHECKDB (AdventureWorks) WITH ALL_ERRORMSGS, NO_INFOMSGS" -oC:\outputfile.txt
sqlcmd -E -Q"DBCC CHECKDB (AdventureWorks) WITH ALL_ERRORMSGS, NO_INFOMSGS" -o C:\outputfile.txt

PS.WITH NO_INFOMSGS只顯示錯誤訊息,一般的information不顯示


基本流程
1.將有損毀的資料庫備份檔還原到測試機,切換成single_user mode。

ATLER DATABASE AdventureWorks SET SINGLE_USER WITH ROLLBACK_IMMEDIATELY;

2.取得錯誤訊

USE [master];
GO
DBCC CHECKDB (AdventureWorks) WITH NO_INFOMSGS;
GO
DBCC CHECKTABLE ('HumanResources.Employee') WITH NO_INFOMSGS;
GO

2.取回損毀的資料

(1)如果原資料表還能查詢的狀況

A.透過DBCC CHECKTABLE找出哪一筆或哪幾筆資料損毀

page(1, 280) ->page 280

DBCC TRACEON(3604)
DBCC PAGE(dbname, 1, 280,2) with no_infomsgs;
從結果找出m_type
m_type=1 ->data page
slotcount =27 -> number of rows in this page
所以如果執行allow data loss則會出現27然後修復完成(損毀的地方)

B.透過select with non-clustered Index取回一些資料。

select col1, col2 from table with (index=clusted_index1);

利用彙總函數,比對clustered index與non-clustered index資料是否有不同

PS.數值與日期欄位可用SUM(column),文字欄位可用 SUM(LEN(column))

若查出來值不同(例如col4不同),表示其中一個欄位有損毀

使用OUTER ALL JOIN 同一個TABLE 找出哪一筆的col4是NULL


因無法直接update or delete那一筆損毀的資料,若執行會出現錯誤

所以從non-cluster index SELECT資料到table_save暫存資料表


D.嘗試修復

DBCC CHECKTABLE(tableName, REPAIR_REBUILD)

通常無法修復

DBCC CHECKTABLE(tableName, REPAIR_ALLOW_DATA_LOSS)

出現找到錯誤,並已經修復
但執行select * from table發現只剩一半的資料,其他消失

E.將資料從table_save補回原資料表

接下就INSERT table select * from table_save
where table.id not in (select id from table)


(2)如果原資料表不能查詢的狀況

A.先透過select with non-clustered Index取回一些資料。(如果後面的步驟無法取得完整資料,最少還有這些)

B.嘗試透過DBCC IND, DBCC PAGE來取回損毀資料表(clustered index)的完整資料

C.再用TRUNCATE TABLE來移除損毀

D.INSERT SELECT from救回資料的資料表

3.修復資料庫並回存資料

truncate table Table_1
insert into Table_1 select * from Table_copy



沒有留言:

SQL Server Database Mirroring 資料庫鏡像

SQL Server Database Mirroring 資料庫鏡像