解剖SQLSERVER 第十七篇 使用 OrcaMDF Corruptor 故意損壞數據庫(譯)
http://improve.dk/corrupting-databases-purpose-using-orcamdf-corruptor/
有時候你必須先作惡,后行善。情況就是 當你想磨練你的數據庫修復技能
我現在添加了一個Corruptor 類到OrcaMDF里面 去測試新的RawDatabase 的功能。Corruptor 就跟他的名字一樣--他會故意損壞數據庫文件
Corruptor 本身是比較簡單的。Corruptor 會隨機選擇一些頁面并且簡單的使用0來完全復寫頁面。
根據頁面的類型,這可能會造成致命傷害
我不想多說什么了,不過萬一。。。請不要在你的生產庫上運行。這會損壞你的數據。
?
例子
有兩個 Corruptor.CorruptFile重載方法,他們都返回integers 的枚舉值 -- 一系列的pageid 列表并且被復寫0的
下面的代碼會損壞5%的頁面在AdventureWorks2008R2LT.mdf 文件里面,然后他會輸出每個被損壞了的頁面ID 。
你可以定義損壞頁面的百分比 只需要改變第二個參數
var
corruptedPageIDs = Corruptor.CorruptFile(
@"
C:\AdventureWorks2008R2LT.mdf
"
,
0.05
);
Console.WriteLine(
string
.Join(
"
,
"
, corruptedPageIDs));
606
,
516
,
603
,
521
,
613
,
621
,
118
,
47
,
173
,
579
,
323
,
217
,
358
,
515
,
615
,
271
,
176
,
596
,
417
,
379
,
269
,
409
,
558
,
103
,
8
,
636
,
200
,
361
,
60
,
486
,
366
,
99
,
87
為了使損壞更厲害,你也可以使用第二個重載方法,他允許你定義一個確切的損壞頁面的數目,在一個確定的pageid范圍內。
下面的代碼會確切的損壞pageid在0到49這個范圍內的10個頁面,因此會損壞大部分的元數據,大家知道系統表的數據基本都存儲在數據庫最靠前的頁面上
var
corruptedPageIDs = Corruptor.CorruptFile(
@"
C:\AdventureWorks2008R2LT.mdf
"
,
10
,
0
,
49
);
Console.WriteLine(
string
.Join(
"
,
"
, corruptedPageIDs));
16
,
4
,
0
,
32
,
15
,
14
,
30
,
2
,
49
,
9
?
在上面的情況我非常不幸的看到 下面這些頁面都被填充了0 包括:
file header page,page 2 is the first GAM page,page 9 is the boot page ,page 16 allocation unit metadata。
這樣的損壞程度,即使使用DBCC CHECKDB也沒辦法修復,留下給你的選擇只有從備份中還原
?
或者,你可以嘗試一下使用 OrcaMDF RawDatabase 去恢復盡可能多的數據,先到這里了,我以后還會繼續介紹。
?
DBCC
TRACEON(
3604
,
-
1
)
GO
DBCC
PAGE(
[
sss
]
,
1
,
16
,
3
)
GO
DBCC
執行完畢。如果
DBCC
輸出了錯誤信息,請與系統管理員聯系。
PAGE: (
1
:
16
)
BUFFER:
BUF
@0x0000000080FDEB80
bpage
=
0x0000000080A74000
bhash
=
0x0000000000000000
bpageno
=
(
1
:
16
)
bdbid
=
8
breferences
=
0
bcputicks
=
0
bsampleCount
=
0
bUse1
=
19980
bstat
=
0xc00009
blog
=
0x32159
bnext
=
0x0000000000000000
PAGE HEADER:
Page
@0x0000000080A74000
m_pageId
=
(
1
:
16
) m_headerVersion
=
1
m_type
=
1
m_typeFlagBits
=
0x4
m_level
=
0
m_flagBits
=
0x200
m_objId (AllocUnitId.idObj)
=
7
m_indexId (AllocUnitId.idInd)
=
0
Metadata: AllocUnitId
=
458752
Metadata: PartitionId
=
458752
Metadata: IndexId
=
1
Metadata: ObjectId
=
7
m_prevPage
=
(
0
:
0
) m_nextPage
=
(
1
:
130
) pminlen
=
73
m_slotCnt
=
49
m_freeCnt
=
4225
m_freeData
=
4331
m_reservedCnt
=
0
m_lsn
=
(
1037
:
459
:
3
) m_xactReserved
=
0
m_xdesId
=
(
0
:
455
) m_ghostRecCnt
=
0
m_tornBits
=
-
563242027
Allocation Status
GAM (
1
:
2
)
=
ALLOCATED SGAM (
1
:
3
)
=
NOT
ALLOCATED
PFS (
1
:
1
)
=
0x60
MIXED_EXT ALLOCATED 0_PCT_FULL DIFF (
1
:
6
)
=
CHANGED
ML (
1
:
7
)
=
NOT
MIN_LOGGED
Slot
0
Offset
0x60
Length
77
Record Type
=
PRIMARY_RECORD Record Attributes
=
NULL_BITMAP Record Size
=
77
Memory
Dump
@0x000000000DC7A060
0000000000000000
:
10004900
00000300
00000000
01000003
?..I.............
0000000000000010
:
00000000
00000000
0001001f
00000001
?................
0000000000000020
:
00570000
00010056
00000001
000b0000 ?.W.....V........
0000000000000030
:
00000000
00090000
00000000
00110000
?..... ..........
0000000000000040
:
00000000
00010000
000c0000
00
????????.............
Slot
0
Column
1
Offset
0x4
Length
8
Length (physical)
8
auid
=
196608
Slot
0
Column
2
Offset
0xc
Length
1
Length (physical)
1
type
=
1
Slot
0
Column
3
Offset
0xd
Length
8
Length (physical)
8
ownerid
=
196608
Slot
0
Column
4
Offset
0x15
Length
4
Length (physical)
4
status
=
0
Slot
0
Column
5
Offset
0x19
Length
2
Length (physical)
2
fgid
=
1
pgfirst
=
[
Binary data
]
Slot
0
Column
6
Offset
0x1b
Length
6
Length (physical)
6
pgfirst
=
0x1f0000000100
pgroot
=
[
Binary data
]
Slot
0
Column
7
Offset
0x21
Length
6
Length (physical)
6
pgroot
=
0x570000000100
pgfirstiam
=
[
Binary data
]
Slot
0
Column
8
Offset
0x27
Length
6
Length (physical)
6
pgfirstiam
=
0x560000000100
Slot
0
Column
9
Offset
0x2d
Length
8
Length (physical)
8
pcused
=
11
Slot
0
Column
10
Offset
0x35
Length
8
Length (physical)
8
pcdata
=
9
Slot
0
Column
11
Offset
0x3d
Length
8
Length (physical)
8
pcreserved
=
17
Slot
0
Column
12
Offset
0x45
Length
4
Length (physical)
4
dbfragid
=
1
Slot
0
Offset
0x0
Length
0
Length (physical)
0
KeyHashValue
=
(016862d84319)
?
SELECT COUNT(*) FROM sys.[allocation_units]
--131
SELECT * FROM sys.[allocation_units]
SELECT * FROM sys.[system_internals_allocation_units]
?
存儲在數據庫1:16頁面上(是[sys.system_internals_allocation_units]系統表)《深入解析sql2008》
?
第十七篇完
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

