手动修改asm disk header
2024-07-21 02:52:07
供稿:网友
手动修改asm disk headerPosted on 2012 年 10 月 26 日 by xiaoyu手工修改asm disk header的分析[Oracle@standby ~]$ dd if=/dev/zero of=/dev/oracleasm/disks/DATA01 bs=4096 count=11+0 records in1+0 records out4096 bytes (4.1 kB) copied, 0.000715 seconds, 5.7 MB/sSQL> startup;ASM instance started Total System Global Area 79691776 bytesFixed Size 1217812 bytesVariable Size 53308140 bytesASM Cache 25165824 bytesORA-15032: not all alterations performedORA-15063: ASM discovered an insufficient number of disks for diskgroup"DATA_ASM" SQL> col path for a20SQL> select disk_Number,group_number,path,header_status from v$asm_disk; DISK_NUMBER GROUP_NUMBER PATH HEADER_STATU----------- ------------ -------------------- ------------ 0 0 ORCL:DATA01 CANDIDATE 2 0 ORCL:DATA03 MEMBER 1 0 ORCL:DATA02 MEMBER[oracle@standby ~]$ kfed read /dev/oracleasm/disks/DATA01 |morekfbh.endian: 0 ; 0x000: 0x00kfbh.hard: 0 ; 0x001: 0x00kfbh.type: 0 ; 0x002: KFBTYP_INVALIDkfbh.datfmt: 0 ; 0x003: 0x00kfbh.block.blk: 0 ; 0x004: T=0 NUMB=0x0kfbh.block.obj: 0 ; 0x008: TYPE=0x0 NUMB=0x0kfbh.check: 0 ; 0x00c: 0x00000000kfbh.fcn.base: 0 ; 0x010: 0x00000000kfbh.fcn.wrap: 0 ; 0x014: 0x00000000kfbh.spare1: 0 ; 0x018: 0x00000000kfbh.spare2: 0 ; 0x01c: 0x00000000[oracle@standby ~]$ kfed read /dev/oracleasm/disks/DATA02 >/home/oracle/disk2.txt已经通过同组的diskgroup获得了一个asm disk header,接下来如何去改写这个asm disk header是重点,小鱼这里简单的说明下。[oracle@localhost bdump]$ vi /home/oracle/disk2.txt kfbh.endian: 1 ; 0x000: 0x01 /*字节版本标识不需修改*/kfbh.hard: 130 ; 0x001: 0x82kfbh.type: 1 ; 0x002: KFBTYP_DISKHEAD /*metadata block type,其中的类型有1.KFBTYP_DISKHEAD 2.KFBYP_FREESPC 3.KFBTYP_ALLOCTBL 4.KFBTYP_FILEDIR 5.KFBTYP_LISTHEAD 6.KFBTYP_DISKDIR 17.KFBTYP_PST+META等*/kfbh.datfmt: 1 ; 0x003: 0x01 /*取值1表示已经格式化*/kfbh.block.blk: 0 ; 0x004: T=0 NUMB=0x0 /*block location of this block* disk header should have T=0 and NUMB=0*0 取值为0*/kfbh.block.obj: 2147483649 ; 0x008: TYPE=0x8 NUMB=0x0 /* block object id Disk header的type 为8,numb为0,numb是asm disk在group中的编号kfdhdb.dksnum*/kfbh.check: 1188800843 ; 0x00c: 0x46dba94b /*一致性检验的value*/kfbh.fcn.base: 0 ; 0x010: 0x00000000 /* change number of last change*/kfbh.fcn.wrap: 0 ; 0x014: 0x00000000kfbh.spare1: 0 ; 0x018: 0x00000000kfbh.spare2: 0 ; 0x01c: 0x00000000kfdhdb.driver.PRovstr: ORCLDISKDATA02 ; 0x000: length=14kfdhdb.driver.reserved[0]: 1096040772 ; 0x008: 0x41544144kfdhdb.driver.reserved[1]: 12848 ; 0x00c: 0x00003230kfdhdb.driver.reserved[2]: 0 ; 0x010: 0x00000000kfdhdb.driver.reserved[3]: 0 ; 0x014: 0x00000000kfdhdb.driver.reserved[4]: 0 ; 0x018: 0x00000000kfdhdb.driver.reserved[5]: 0 ; 0x01c: 0x00000000kfdhdb.compat: 168820736 ; 0x020: 0x0a100000 /*软件的版本*/kfdhdb.dsknum: 1 ; 0x024: 0x0001 /* disk num*,可以通过disk directory 获得*/kfdhdb.grptyp: 1 ; 0x026: KFDGTP_EXTERNAL /*冗余方式,可以通过PST获得*/kfdhdb.hdrsts: 3 ; 0x027: KFDHDR_MEMBER /*disk header status*/kfdhdb.dskname: DATA02 ; 0x028: length=6 /*dskname*/kfdhdb.grpname: DATA_ASM ; 0x048: length=8 /*grpname*/kfdhdb.fgname: DATA02 ; 0x068: length=6 /*fgname*/kfdhdb.capname: ; 0x088: length=0kfdhdb.crestmp.hi: 32975365 ; 0x0a8: HOUR=0x5 DAYS=0x10 MNTH=0xa YEAR=0x7dckfdhdb.crestmp.lo: 2388063232 ; 0x0ac: USEC=0x0 MSEC=0x1bd SECS=0x25 MINS=0x23 /*create timestamp通过disk directory 获得*/kfdhdb.mntstmp.hi: 32975394 ; 0x0b0: HOUR=0x2 DAYS=0x11 MNTH=0xa YEAR=0x7dckfdhdb.mntstmp.lo: 1266600960 ; 0x0b4: USEC=0x0 MSEC=0x3b3 SECS=0x37 MINS=0x12 /*mount timestamp,根据规则自定值*/kfdhdb.secsize: 512 ; 0x0b8: 0x0200 /* disk sector size */kfdhdb.blksize: 4096 ; 0x0ba: 0x1000 /* block bytes*/kfdhdb.ausize: 1048576 ; 0x0bc: 0x00100000 /* au size */kfdhdb.mfact: 113792 ; 0x0c0: 0x0001bc80 /* Stride between phys addr AUs 默认取值113792 */kfdhdb.dsksize: 3820 ; 0x0c4: 0x00000eec /* Disk size 可通过KFBTYP_FREESPC获得,也可通过disk directory获得*/kfdhdb.pmcnt: 2 ; 0x0c8: 0x00000002 /* Number of physically addressed allocation units */kfdhdb.fstlocn: 1 ; 0x0cc: 0x00000001 /* First FreeSpace table blk num 用于记录freespace信息的首个block,通过KFBTYP_FREESPC 获得*/kfdhdb.altlocn: 2 ; 0x0d0: 0x00000002 /* First Alocation table blk num 用于记录allocation信息的首个block ,通过KFBTYP_ALLOCTBL 获得*/kfdhdb.f1b1locn: 0 ; 0x0d4: 0x00000000 /* File Directory blk 1 AU num File Directory起始地址 */kfdhdb.redomirrors[0]: 0 ; 0x0d8: 0x0000kfdhdb.redomirrors[1]: 0 ; 0x0da: 0x0000kfdhdb.redomirrors[2]: 0 ; 0x0dc: 0x0000kfdhdb.redomirrors[3]: 0 ; 0x0de: 0x0000kfdhdb.dbcompat: 168820736 ; 0x0e0: 0x0a100000 /* database version*/kfdhdb.grpstmp.hi: 32975365 ; 0x0e4: HOUR=0x5 DAYS=0x10 MNTH=0xa YEAR=0x7dckfdhdb.grpstmp.lo: 2387767296 ; 0x0e8: USEC=0x0 MSEC=0x9c SECS=0x25 MINS=0x23 /* diskgroup create time 可根据规则重新定义 */kfdhdb.ub4spare[0]: 0 ; 0x0ec: 0x00000000kfdhdb.ub4spare[1]: 0 ; 0x0f0: 0x00000000kfdhdb.ub4spare[2]: 0 ; 0x0f4: 0x00000000kfdhdb.ub4spare[3]: 0 ; 0x0f8: 0x00000000kfdhdb.ub4spare[4]: 0 ; 0x0fc: 0x00000000kfdhdb.ub4spare[5]: 0 ; 0x100: 0x00000000kfdhdb.ub4spare[6]: 0 ; 0x104: 0x00000000........kfdhdb.acdb.aba.seq: 0 ; 0x1d4: 0x00000000kfdhdb.acdb.aba.blk: 0 ; 0x1d8: 0x00000000kfdhdb.acdb.ents: 0 ; 0x1dc: 0x0000kfdhdb.acdb.ub2spare: 0 ; 0x1de: 0x0000其实眼下我们需要修改的是下面的几个数据:kfbh.block.obj: 2147483649 ; 0x008: TYPE=0x8 NUMB=0x0 kfbh.block.obj: 2147483649 ; 0x008: TYPE=0x8 NUMB=0x0 ( block object id Disk header的type 为8, numb是asm disk在group中的编号kfdhdb.dksnum),其实可以通过第一个au的free au和au table来获取obj。[oracle@standby ~]$ kfed read /dev/oracleasm/disks/DATA01 aun=0 blkn=1|morekfbh.endian: 1 ; 0x000: 0x01kfbh.hard: 130 ; 0x001: 0x82kfbh.type: 2 ; 0x002: KFBTYP_FREESPCkfbh.datfmt: 1 ; 0x003: 0x01kfbh.block.blk: 1 ; 0x004: T=0 NUMB=0x1kfbh.block.obj: 2147483648 ; 0x008: TYPE=0x8 NUMB=0x0此时直接通过DATA01磁盘的free au来获取,事实上同一个disk的第一个au中的kfbh.block .obj都是相同的取值。Kfbh.block.obj从2147483649修改为2147483648。 kfdhdb.driver.provstr: ORCLDISKDATA02 ; 0x000: length=14由于使用的是asmlib,需要修改diskname。kfdhdb.dsknum: 1 ; 0x024: 0x0001 由于通过上面的obj已经清楚了该disk是第一块disk,所以需要修改为kfdhdb.dsknum: 0 ; 0x024: 0x0000.kfdhdb.grptyp: 1 ; 0x026: KFDGTP_EXTERNAL冗余方式,这个可以根据pst来获取,当然同样的disk 磁盘组的冗余方式是相同的。[oracle@standby ~]$ kfed read /dev/oracleasm/disks/DATA01 aun=1 blkn=0|morekfbh.endian: 1 ; 0x000: 0x01kfbh.hard: 130 ; 0x001: 0x82kfbh.type: 17 ; 0x002: KFBTYP_PST_METAkfbh.datfmt: 1 ; 0x003: 0x01kfbh.block.blk: 256 ; 0x004: T=0 NUMB=0x100kfbh.block.obj: 2147483648 ; 0x008: TYPE=0x8 NUMB=0x0......kfdpHdrB.copyCnt: 1 ; 0x010: 0x01disk的第二个au也就是pst信息中存储了冗余方式kfdpHdrB.copyCnt: 1 ; 0x010: 0x01外部冗余。 kfdhdb.dskname: DATA02 ; 0x028: length=6 /*dskname*/kfdhdb.grpname: DATA_ASM ; 0x048: length=8 /*grpname*/kfdhdb.fgname: DATA02 ; 0x068: length=6 /*fgname*/kfdhdb.crestmp.hi: 32975365 ; 0x0a8: HOUR=0x5 DAYS=0x10 MNTH=0xa YEAR=0x7dckfdhdb.crestmp.lo: 2388063232 ; 0x0ac: USEC=0x0 MSEC=0x1bd SECS=0x25 MINS=0x23kfdhdb.secsize: 512 ; 0x0b8: 0x0200这些信息就需要相应的disk directory了,如果大家有认真看过我前面介绍的vage的asm文件管理的剖析的文章,思路还是很清晰的,disk directory是文件号2,其au分布信息存储在文件号1的第一个au的2号block上,而DATA01磁盘就是0号磁盘。[oracle@standby ~]$ kfed read /dev/oracleasm/disks/DATA01 aun=2 blkn=2|morekfbh.endian: 1 ; 0x000: 0x01kfbh.hard: 130 ; 0x001: 0x82kfbh.type: 4 ; 0x002: KFBTYP_FILEDIR……kfffde[0].xptr.au: 2 ; 0x4a0: 0x00000002kfffde[0].xptr.disk: 1 ; 0x4a4: 0x0001kfffde[0].xptr.flags: 0 ; 0x4a6: L=0 E=0 D=0 C=0 S=0kfffde[0].xptr.chk: 41 ; 0x4a7: 0x29kfffde[1].xptr.au: 4294967295 ; 0x4a8: 0xffffffffkfffde[1].xptr.disk: 65535 ; 0x4ac: 0xffffkfffde[1].xptr.flags: 0 ; 0x4ae: L=0 E=0 D=0 C=0 S=0kfffde[1].xptr.chk: 42 ; 0x4af: 0x2a以上信息告诉disk directory的au是disknum 1的aunum 2上,而刚好DATA02的obj知道了他是disknum1。[oracle@standby ~]$ kfed read /dev/oracleasm/disks/DATA02 aun=2|morekfbh.endian: 1 ; 0x000: 0x01kfbh.hard: 130 ; 0x001: 0x82kfbh.type: 6 ; 0x002: KFBTYP_DISKDIR……kfddde[0].dsknum: 0 ; 0x034: 0x0000kfddde[0].state: 2 ; 0x036: KFDSTA_NORMALkfddde[0].ub1spare: 0 ; 0x037: 0x00kfddde[0].dskname: DATA01 ; 0x038: length=6kfddde[0].fgname: DATA01 ; 0x058: length=6kfddde[0].crestmp.hi: 32975365 ; 0x078: HOUR=0x5 DAYS=0x10 MNTH=0xa YEAR=0x7dckfddde[0].crestmp.lo: 2388063232 ; 0x07c: USEC=0x0 MSEC=0x1bd SECS=0x25 MINS=0x23kfddde[0].failstmp.hi: 0 ; 0x080: HOUR=0x0 DAYS=0x0 MNTH=0x0 YEAR=0x0kfddde[0].failstmp.lo: 0 ; 0x084: USEC=0x0 MSEC=0x0 SECS=0x0 MINS=0x0kfddde[0].timer: 0 ; 0x088: 0x00000000kfddde[0].size: 3820 ; 0x08c: 0x00000eec…..kfddde[1].dsknum: 1 ; 0x1f4: 0x0001kfddde[1].state: 2 ; 0x1f6: KFDSTA_NORMALkfddde[1].ub1spare: 0 ; 0x1f7: 0x00kfddde[1].dskname: DATA02 ; 0x1f8: length=6kfddde[1].fgname: DATA02 ; 0x218: length=6kfddde[1].crestmp.hi: 32975365 ; 0x238: HOUR=0x5 DAYS=0x10 MNTH=0xa YEAR=0x7dckfddde[1].crestmp.lo: 2388063232 ; 0x23c: USEC=0x0 MSEC=0x1bd SECS=0x25 MINS=0x23kfddde[1].failstmp.hi: 0 ; 0x240: HOUR=0x0 DAYS=0x0 MNTH=0x0 YEAR=0x0kfddde[1].failstmp.lo: 0 ; 0x244: USEC=0x0 MSEC=0x0 SECS=0x0 MINS=0x0kfddde[1].timer: 0 ; 0x248: 0x00000000kfddde[1].size: 3820 ; 0x24c: 0x00000eec kfddde[2].dsknum: 2 ; 0x3b4: 0x0002kfddde[2].state: 2 ; 0x3b6: KFDSTA_NORMALkfddde[2].ub1spare: 0 ; 0x3b7: 0x00kfddde[2].dskname: DATA03 ; 0x3b8: length=6kfddde[2].fgname: DATA03 ; 0x3d8: length=6kfddde[2].crestmp.hi: 32975365 ; 0x3f8: HOUR=0x5 DAYS=0x10 MNTH=0xa YEAR=0x7dckfddde[2].crestmp.lo: 2388063232 ; 0x3fc: USEC=0x0 MSEC=0x1bd SECS=0x25 MINS=0x23kfddde[2].failstmp.hi: 0 ; 0x400: HOUR=0x0 DAYS=0x0 MNTH=0x0 YEAR=0x0kfddde[2].failstmp.lo: 0 ; 0x404: USEC=0x0 MSEC=0x0 SECS=0x0 MINS=0x0kfddde[2].timer: 0 ; 0x408: 0x00000000kfddde[2].size: 4643 ; 0x40c: 0x00001223disk directory信息已经全部获得,通过这些信息可以对着修改 kfdhdb.pmcnt: 2 ; 0x0c8: 0x00000002kfdhdb.fstlocn: 1 ; 0x0cc: 0x00000001kfdhdb.altlocn: 2 ; 0x0d0: 0x0000000kfdhdb.f1b1locn: 0 ; 0x0d4: 0x00000000kfdhdb.pmcnt:是physical metadata占用的au,取值是2个au不用修改。 kfdhdb.fstlocn是free au的首个blknum,而free au是开始于每个disk 的au 0的blkn 1上[oracle@standby ~]$ kfed read /dev/oracleasm/disks/DATA01 aun=0 blkn=1 |morekfbh.endian: 1 ; 0x000: 0x01kfbh.hard: 130 ; 0x001: 0x82kfbh.type: 2 ; 0x002: KFBTYP_FREESPC kfdhdb.altlocn是allocate table的au最开始的blknum[oracle@standby ~]$ kfed read /dev/oracleasm/disks/DATA01 aun=0 blkn=2 |morekfbh.endian: 1 ; 0x000: 0x01kfbh.hard: 130 ; 0x001: 0x82kfbh.type: 3 ; 0x002: KFBTYP_ALLOCTBLallocate table的au最开始于aun 0的blkn 2。 kfdhdb.f1b1locn是file directory的最开始aun,也就是aun 2,其中第一个blkn 0用于系统保留,blkn 1开始是file directory的开始。[oracle@standby ~]$ kfed read /dev/oracleasm/disks/DATA01 aun=2 blkn=1 |morekfbh.endian: 1 ; 0x000: 0x01kfbh.hard: 130 ; 0x001: 0x82kfbh.type: 4 ; 0x002: KFBTYP_FILEDIR小鱼初步带领大家分析了一下asm disk header的信息,然后上面的故障相信很好处理,直接对着修改即可,如果同组diskgroup的所有disk header信息都丢失,也可以手工构造一个,构造的大部分数据都可以对着上面的分析方式对着修改,小鱼关于asm kfed读取header分析参考了部分文档,谢谢!手工重构asm disk headerhttp://www.easyora.net/blog/manual_fix_asm_disk_header1.htmlasm disk header备份恢复于重建http://blog.csdn.net/tianlesoftware/article/details/6743677vage的asm文件管理解析http://www.itpub.net/thread-1597605-1-1.html