解剖sqlserver 第十七篇 使用 orcamdf corruptor 故意损坏数据库(译) http://improve.dk/corrupting-databases-purpose-using-orcamdf-corruptor/ 有时候你必须先作恶,后行善。情况就是 当你想磨练你的数据库修复技能 我现在添加了一个corruptor 类到orca
解剖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)godbcc page([sss],1,16,3)godbcc 执行完毕。如果 dbcc 输出了错误信息,请与系统管理员联系。page: (1:16)buffer:buf @0x0000000080fdeb80bpage = 0x0000000080a74000 bhash = 0x0000000000000000 bpageno = (1:16)bdbid = 8 breferences = 0 bcputicks = 0bsamplecount = 0 buse1 = 19980 bstat = 0xc00009blog = 0x32159 bnext = 0x0000000000000000page header:page @0x0000000080a74000m_pageid = (1:16) m_headerversion = 1 m_type = 1m_typeflagbits = 0x4 m_level = 0 m_flagbits = 0x200m_objid (allocunitid.idobj) = 7 m_indexid (allocunitid.idind) = 0 metadata: allocunitid = 458752metadata: partitionid = 458752 metadata: indexid = 1 metadata: objectid = 7m_prevpage = (0:0) m_nextpage = (1:130) pminlen = 73m_slotcnt = 49 m_freecnt = 4225 m_freedata = 4331m_reservedcnt = 0 m_lsn = (1037:459:3) m_xactreserved = 0m_xdesid = (0:455) m_ghostreccnt = 0 m_tornbits = -563242027allocation statusgam (1:2) = allocated sgam (1:3) = not allocated pfs (1:1) = 0x60 mixed_ext allocated 0_pct_full diff (1:6) = changedml (1:7) = not min_loggedslot 0 offset 0x60 length 77record type = primary_record record attributes = null_bitmap record size = 77memory dump @0x000000000dc7a0600000000000000000: 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) 8auid = 196608slot 0 column 2 offset 0xc length 1 length (physical) 1type = 1slot 0 column 3 offset 0xd length 8 length (physical) 8ownerid = 196608slot 0 column 4 offset 0x15 length 4 length (physical) 4status = 0slot 0 column 5 offset 0x19 length 2 length (physical) 2fgid = 1pgfirst = [binary data] slot 0 column 6 offset 0x1b length 6 length (physical) 6pgfirst = 0x1f0000000100pgroot = [binary data] slot 0 column 7 offset 0x21 length 6 length (physical) 6pgroot = 0x570000000100pgfirstiam = [binary data] slot 0 column 8 offset 0x27 length 6 length (physical) 6pgfirstiam = 0x560000000100slot 0 column 9 offset 0x2d length 8 length (physical) 8pcused = 11slot 0 column 10 offset 0x35 length 8 length (physical) 8pcdata = 9slot 0 column 11 offset 0x3d length 8 length (physical) 8pcreserved = 17slot 0 column 12 offset 0x45 length 4 length (physical) 4dbfragid = 1slot 0 offset 0x0 length 0 length (physical) 0keyhashvalue = (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》
第十七篇完