手动修改asm disk header

手动修改asm disk header
Posted on   2012 年 10 月 26 日   by   xiaoyu
手工修改asm disk header的分析
[oracle@standby ~]$ dd if=/dev/zero of=/dev/oracleasm/disks/DATA01 bs=4096 count=1
1+0 records in
1+0 records out
4096 bytes (4.1 kB) copied, 0.000715 seconds, 5.7 MB/s
SQL> startup;
ASM instance started
 
Total System Global Area   79691776 bytes
Fixed Size                  1217812 bytes
Variable Size              53308140 bytes
ASM Cache                  25165824 bytes
ORA-15032: not all alterations performed
ORA-15063: ASM discovered an insufficient number of disks for diskgroup
"DATA_ASM"
 
SQL> col path for a20
SQL> 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 |more
kfbh.endian:                          0 ; 0x000: 0x00
kfbh.hard:                            0 ; 0x001: 0x00
kfbh.type:                            0 ; 0x002: KFBTYP_INVALID
kfbh.datfmt:                          0 ; 0x003: 0x00
kfbh.block.blk:                       0 ; 0x004: T=0 NUMB=0x0
kfbh.block.obj:                       0 ; 0x008: TYPE=0x0 NUMB=0x0
kfbh.check:                           0 ; 0x00c: 0x00000000
kfbh.fcn.base:                        0 ; 0x010: 0x00000000
kfbh.fcn.wrap:                        0 ; 0x014: 0x00000000
kfbh.spare1:                          0 ; 0x018: 0x00000000
kfbh.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: 0x82
kfbh.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: 0x00000000
kfbh.spare1:                          0 ; 0x018: 0x00000000
kfbh.spare2:                          0 ; 0x01c: 0x00000000
kfdhdb.driver.provstr:   ORCLDISKDATA02 ; 0x000: length=14
kfdhdb.driver.reserved[0]:   1096040772 ; 0x008: 0x41544144
kfdhdb.driver.reserved[1]:        12848 ; 0x00c: 0x00003230
kfdhdb.driver.reserved[2]:            0 ; 0x010: 0x00000000
kfdhdb.driver.reserved[3]:            0 ; 0x014: 0x00000000
kfdhdb.driver.reserved[4]:            0 ; 0x018: 0x00000000
kfdhdb.driver.reserved[5]:            0 ; 0x01c: 0x00000000
kfdhdb.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=0
kfdhdb.crestmp.hi:             32975365 ; 0x0a8: HOUR=0x5 DAYS=0x10 MNTH=0xa YEAR=0x7dc
kfdhdb.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=0x7dc
kfdhdb.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: 0x0000
kfdhdb.redomirrors[1]:                0 ; 0x0da: 0x0000
kfdhdb.redomirrors[2]:                0 ; 0x0dc: 0x0000
kfdhdb.redomirrors[3]:                0 ; 0x0de: 0x0000
kfdhdb.dbcompat:              168820736 ; 0x0e0: 0x0a100000 /* database version*/
kfdhdb.grpstmp.hi:             32975365 ; 0x0e4: HOUR=0x5 DAYS=0x10 MNTH=0xa YEAR=0x7dc
kfdhdb.grpstmp.lo:           2387767296 ; 0x0e8: USEC=0x0 MSEC=0x9c SECS=0x25 MINS=0x23   /* diskgroup create time  可根据规则重新定义 */
kfdhdb.ub4spare[0]:                   0 ; 0x0ec: 0x00000000
kfdhdb.ub4spare[1]:                   0 ; 0x0f0: 0x00000000
kfdhdb.ub4spare[2]:                   0 ; 0x0f4: 0x00000000
kfdhdb.ub4spare[3]:                   0 ; 0x0f8: 0x00000000
kfdhdb.ub4spare[4]:                   0 ; 0x0fc: 0x00000000
kfdhdb.ub4spare[5]:                   0 ; 0x100: 0x00000000
kfdhdb.ub4spare[6]:                   0 ; 0x104: 0x00000000
........
kfdhdb.acdb.aba.seq:                  0 ; 0x1d4: 0x00000000
kfdhdb.acdb.aba.blk:                  0 ; 0x1d8: 0x00000000
kfdhdb.acdb.ents:                     0 ; 0x1dc: 0x0000
kfdhdb.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|more
kfbh.endian:                          1 ; 0x000: 0x01
kfbh.hard:                          130 ; 0x001: 0x82
kfbh.type:                            2 ; 0x002: KFBTYP_FREESPC
kfbh.datfmt:                          1 ; 0x003: 0x01
kfbh.block.blk:                       1 ; 0x004: T=0 NUMB=0x1
kfbh.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|more
kfbh.endian:                          1 ; 0x000: 0x01
kfbh.hard:                          130 ; 0x001: 0x82
kfbh.type:                           17 ; 0x002: KFBTYP_PST_META
kfbh.datfmt:                          1 ; 0x003: 0x01
kfbh.block.blk:                     256 ; 0x004: T=0 NUMB=0x100
kfbh.block.obj:              2147483648 ; 0x008: TYPE=0x8 NUMB=0x0
......
kfdpHdrB.copyCnt:                     1 ; 0x010: 0x01
disk的第二个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=0x7dc
kfdhdb.crestmp.lo:           2388063232 ; 0x0ac: USEC=0x0 MSEC=0x1bd SECS=0x25 MINS=0x23
kfdhdb.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|more
kfbh.endian:                          1 ; 0x000: 0x01
kfbh.hard:                          130 ; 0x001: 0x82
kfbh.type:                            4 ; 0x002: KFBTYP_FILEDIR
……
kfffde[0].xptr.au:                    2 ; 0x4a0: 0x00000002
kfffde[0].xptr.disk:                  1 ; 0x4a4: 0x0001
kfffde[0].xptr.flags:                 0 ; 0x4a6: L=0 E=0 D=0 C=0 S=0
kfffde[0].xptr.chk:                  41 ; 0x4a7: 0x29
kfffde[1].xptr.au:           4294967295 ; 0x4a8: 0xffffffff
kfffde[1].xptr.disk:              65535 ; 0x4ac: 0xffff
kfffde[1].xptr.flags:                 0 ; 0x4ae: L=0 E=0 D=0 C=0 S=0
kfffde[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|more
kfbh.endian:                          1 ; 0x000: 0x01
kfbh.hard:                          130 ; 0x001: 0x82
kfbh.type:                            6 ; 0x002: KFBTYP_DISKDIR
……
kfddde[0].dsknum:                     0 ; 0x034: 0x0000
kfddde[0].state:                      2 ; 0x036: KFDSTA_NORMAL
kfddde[0].ub1spare:                   0 ; 0x037: 0x00
kfddde[0].dskname:               DATA01 ; 0x038: length=6
kfddde[0].fgname:                DATA01 ; 0x058: length=6
kfddde[0].crestmp.hi:          32975365 ; 0x078: HOUR=0x5 DAYS=0x10 MNTH=0xa YEAR=0x7dc
kfddde[0].crestmp.lo:        2388063232 ; 0x07c: USEC=0x0 MSEC=0x1bd SECS=0x25 MINS=0x23
kfddde[0].failstmp.hi:                0 ; 0x080: HOUR=0x0 DAYS=0x0 MNTH=0x0 YEAR=0x0
kfddde[0].failstmp.lo:                0 ; 0x084: USEC=0x0 MSEC=0x0 SECS=0x0 MINS=0x0
kfddde[0].timer:                      0 ; 0x088: 0x00000000
kfddde[0].size:                    3820 ; 0x08c: 0x00000eec
…..
kfddde[1].dsknum:                     1 ; 0x1f4: 0x0001
kfddde[1].state:                      2 ; 0x1f6: KFDSTA_NORMAL
kfddde[1].ub1spare:                   0 ; 0x1f7: 0x00
kfddde[1].dskname:               DATA02 ; 0x1f8: length=6
kfddde[1].fgname:                DATA02 ; 0x218: length=6
kfddde[1].crestmp.hi:          32975365 ; 0x238: HOUR=0x5 DAYS=0x10 MNTH=0xa YEAR=0x7dc
kfddde[1].crestmp.lo:        2388063232 ; 0x23c: USEC=0x0 MSEC=0x1bd SECS=0x25 MINS=0x23
kfddde[1].failstmp.hi:                0 ; 0x240: HOUR=0x0 DAYS=0x0 MNTH=0x0 YEAR=0x0
kfddde[1].failstmp.lo:                0 ; 0x244: USEC=0x0 MSEC=0x0 SECS=0x0 MINS=0x0
kfddde[1].timer:                      0 ; 0x248: 0x00000000
kfddde[1].size:                    3820 ; 0x24c: 0x00000eec
 
kfddde[2].dsknum:                     2 ; 0x3b4: 0x0002
kfddde[2].state:                      2 ; 0x3b6: KFDSTA_NORMAL
kfddde[2].ub1spare:                   0 ; 0x3b7: 0x00
kfddde[2].dskname:               DATA03 ; 0x3b8: length=6
kfddde[2].fgname:                DATA03 ; 0x3d8: length=6
kfddde[2].crestmp.hi:          32975365 ; 0x3f8: HOUR=0x5 DAYS=0x10 MNTH=0xa YEAR=0x7dc
kfddde[2].crestmp.lo:        2388063232 ; 0x3fc: USEC=0x0 MSEC=0x1bd SECS=0x25 MINS=0x23
kfddde[2].failstmp.hi:                0 ; 0x400: HOUR=0x0 DAYS=0x0 MNTH=0x0 YEAR=0x0
kfddde[2].failstmp.lo:                0 ; 0x404: USEC=0x0 MSEC=0x0 SECS=0x0 MINS=0x0
kfddde[2].timer:                      0 ; 0x408: 0x00000000
kfddde[2].size:                    4643 ; 0x40c: 0x00001223
disk directory信息已经全部获得,通过这些信息可以对着修改
 
kfdhdb.pmcnt:                        2 ; 0x0c8: 0x00000002
kfdhdb.fstlocn:                       1 ; 0x0cc: 0x00000001
kfdhdb.altlocn:                       2 ; 0x0d0: 0x0000000
kfdhdb.f1b1locn:                      0 ; 0x0d4: 0x00000000
kfdhdb.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 |more
kfbh.endian:                          1 ; 0x000: 0x01
kfbh.hard:                          130 ; 0x001: 0x82
kfbh.type:                            2 ; 0x002: KFBTYP_FREESPC
 
kfdhdb.altlocn是allocate table的au最开始的blknum
[oracle@standby ~]$ kfed read /dev/oracleasm/disks/DATA01 aun=0 blkn=2 |more
kfbh.endian:                          1 ; 0x000: 0x01
kfbh.hard:                          130 ; 0x001: 0x82
kfbh.type:                            3 ; 0x002: KFBTYP_ALLOCTBL
allocate 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 |more
kfbh.endian:                          1 ; 0x000: 0x01
kfbh.hard:                          130 ; 0x001: 0x82
kfbh.type:                            4 ; 0x002: KFBTYP_FILEDIR
小鱼初步带领大家分析了一下asm disk header的信息,然后上面的故障相信很好处理,直接对着修改即可,如果同组diskgroup的所有disk header信息都丢失,也可以手工构造一个,构造的大部分数据都可以对着上面的分析方式对着修改,小鱼关于asm kfed读取header分析参考了部分文档,谢谢!
手工重构asm disk header
http://www.easyora.net/blog/manual_fix_asm_disk_header1.html
asm disk header备份恢复于重建
http://blog.csdn.net/tianlesoftware/article/details/6743677
vage的asm文件管理解析
http://www.itpub.net/thread-1597605-1-1.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值