这是oracle asm系列的第3篇,这篇文章中我将重点介绍disk directory元数据的结构。首先从asm disk header中,
我们可以看到如下的相关信息:
虽然disk header block中的信息并没有直接反应出来disk directory的信息,但是,你可以想象,既然alocate table元数据
都在第2个AU里面,而那么必然disk directory信息也在该AU里面,因为进行在读取alocate table信息时,必然要先读取disk directory。
有同学看不明白,这里补充一点,如何定位到具体位置.
那么如何定位到disk directory的具体位置呢?其实很简单,元数据也是一个file,如下:
从这里可以看到,该disk的disk directory信息是存在第3个au中,元数据在第1个block,其他block是数据:
如下部分是另外一个disk group中一个disk的信息,以这个为例进行解释:
从上面的信息我们可以看出,asm disk directory的结构大概如下,分为3个部分:
1)kfbh, 该部分表示block header,这部分内容都是基本上一样的,没什么可说的
2)kffdnd,这部分是目录结构信息
3)kfddde,这部分结构也是disk directory元数据中最为重要的一部分结构,其实通过前面的kfed 的内容,我基本上就能知道个大概了。
我这里就拿上面的kfddde[0]为例,进行说明,如下:
下面我接着继续剖析:
下面的这部分内容是zone信息,我是这样理解的,同一个磁盘组,asm将该磁盘组中的所有disk看成一个整体,然后
将这些disks进行划分,有点类似分区的感觉或在VG的基础上创建LV的感觉,这里需要注意的是,如果你的磁盘组中有
3个盘,那么这里就会分配3个zone,如果是4个就会分配4个,总之,是一一对应的。 这样也就保证了同一个磁盘组中
的数据是绝对分散的。
到这里,关于asm disk directory 基本上就描述完了,最后再补充下关于asm diskgroup,在add/drop disk时,asm的reblance情况。

从上面的图内容,我们可以看到,其实在reblance的过程中,不仅仅是我们实际的业务数据会进行均衡操作,还包括asm的元数据。
oracle提供了一个试图v$asm_operation,可以同来观察asm disk reblance的过程、以及估计reblance的剩余时间等等。
其中disk reblance操作是由rbal进程来完成的,而数据库参数asm_power_limit则控制着rbal进程的个数,如果当你在进行
add disk/drop disk等操作时,容量很大的情况下,可以考虑设置较大的参数,那样reblance操作可能会相对快很多. 例如:
alter diskgroup data1 add disk '/dev/sdd' reblance power 5;
不过需要注意一点的是,最好不要在业务期间做reblance,因为该操作本身是比较消耗资源的,而且容易出问题。
我们可以看到如下的相关信息:
[oracle@10gasm ~]$ kfed read /dev/sdd | more
kfbh.endian: 1 ; 0x000: 0x01
kfbh.hard: 130 ; 0x001: 0x82
kfbh.type: 1 ; 0x002: KFBTYP_DISKHEAD
kfbh.datfmt: 1 ; 0x003: 0x01
kfbh.block.blk: 0 ; 0x004: T=0 NUMB=0x0
kfbh.block.obj: 2147483648 ; 0x008: TYPE=0x8 NUMB=0x0
kfbh.check: 1775505402 ; 0x00c: 0x69d40ffa
kfbh.fcn.base: 2095 ; 0x010: 0x0000082f
..........
kfdhdb.secsize: 512 ; 0x0b8: 0x0200
kfdhdb.blksize: 4096 ; 0x0ba: 0x1000
kfdhdb.ausize: 1048576 ; 0x0bc: 0x00100000
kfdhdb.mfact: 113792 ; 0x0c0: 0x0001bc80
kfdhdb.dsksize: 1024 ; 0x0c4: 0x00000400
kfdhdb.pmcnt: 2 ; 0x0c8: 0x00000002
kfdhdb.fstlocn: 1 ; 0x0cc: 0x00000001
kfdhdb.altlocn: 2 ; 0x0d0: 0x00000002 ---aloocate table
kfdhdb.f1b1locn: 2 ; 0x0d4: 0x00000002 ---file directory
kfdhdb.redomirrors[0]: 0 ; 0x0d8: 0x0000
kfdhdb.redomirrors[1]: 65535 ; 0x0da: 0xffff虽然disk header block中的信息并没有直接反应出来disk directory的信息,但是,你可以想象,既然alocate table元数据
都在第2个AU里面,而那么必然disk directory信息也在该AU里面,因为进行在读取alocate table信息时,必然要先读取disk directory。
有同学看不明白,这里补充一点,如何定位到具体位置.
那么如何定位到disk directory的具体位置呢?其实很简单,元数据也是一个file,如下:
[oracle@10gasm ~]$ kfed read /dev/sdb |grep f1
kfdhdb.mntstmp.lo: 1325908992 ; 0x0b4: USEC=0x0 MSEC=0x1f1 SECS=0x30 MINS=0x13
kfdhdb.f1b1locn: 2 ; 0x0d4: 0x00000002
[oracle@10gasm ~]$ kfed read /dev/sdb aun=2 blkn=2 |grep au |head -5
kfffde[0].xptr.au: 3 ; 0x4a0: 0x00000003
kfffde[1].xptr.au: 3 ; 0x4a8: 0x00000003
kfffde[2].xptr.au: 4294967294 ; 0x4b0: 0xfffffffe
kfffde[3].xptr.au: 4294967295 ; 0x4b8: 0xffffffff
kfffde[4].xptr.au: 4294967295 ; 0x4c0: 0xffffffff
[oracle@10gasm ~]$从这里可以看到,该disk的disk directory信息是存在第3个au中,元数据在第1个block,其他block是数据:
[oracle@10gasm ~]$ kfed read /dev/sdb aun=3 blkn=0 | more
kfbh.endian: 1 ; 0x000: 0x01
kfbh.hard: 130 ; 0x001: 0x82
kfbh.type: 6 ; 0x002: KFBTYP_DISKDIR
kfbh.datfmt: 1 ; 0x003: 0x01
kfbh.block.blk: 0 ; 0x004: T=0 NUMB=0x0
kfbh.block.obj: 2 ; 0x008: TYPE=0x0 NUMB=0x2
kfbh.check: 17204479 ; 0x00c: 0x010684ff
kfbh.fcn.base: 1789 ; 0x010: 0x000006fd
kfbh.fcn.wrap: 0 ; 0x014: 0x00000000
kfbh.spare1: 0 ; 0x018: 0x00000000
kfbh.spare2: 0 ; 0x01c: 0x00000000
kffdnd.bnode.incarn: 1 ; 0x000: A=1 NUMM=0x0
kffdnd.bnode.frlist.number: 4294967295 ; 0x004: 0xffffffff
kffdnd.bnode.frlist.incarn: 0 ; 0x008: A=0 NUMM=0x0
kffdnd.overfl.number: 4294967295 ; 0x00c: 0xffffffff
kffdnd.overfl.incarn: 0 ; 0x010: A=0 NUMM=0x0
kffdnd.parent.number: 0 ; 0x014: 0x00000000
kffdnd.parent.incarn: 1 ; 0x018: A=1 NUMM=0x0
kffdnd.fstblk.number: 0 ; 0x01c: 0x00000000
kffdnd.fstblk.incarn: 1 ; 0x020: A=1 NUMM=0x0
kfddde[0].entry.incarn: 1 ; 0x024: A=1 NUMM=0x0
kfddde[0].entry.hash: 0 ; 0x028: 0x00000000
kfddde[0].entry.refer.number:4294967295 ; 0x02c: 0xffffffff
kfddde[0].entry.refer.incarn: 0 ; 0x030: A=0 NUMM=0x0
kfddde[0].dsknum: 0 ; 0x034: 0x0000
kfddde[0].state: 2 ; 0x036: KFDSTA_NORMAL
kfddde[0].ub1spare: 0 ; 0x037: 0x00
kfddde[0].dskname: DATA2_0000 ; 0x038: length=10
kfddde[0].fgname: DATA2_0000 ; 0x058: length=10
kfddde[0].crestmp.hi: 32982470 ; 0x078: HOUR=0x6 DAYS=0xe MNTH=0x1 YEAR=0x7dd
kfddde[0].crestmp.lo: 330482688 ; 0x07c: USEC=0x0 MSEC=0xb1 SECS=0x3b MINS=0x4
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: 1024 ; 0x08c: 0x00000400
kfddde[0].spare[0]: 0 ; 0x090: 0x00000000
kfddde[0].spare[1]: 0 ; 0x094: 0x00000000
kfddde[0].spare[2]: 0 ; 0x098: 0x00000000
kfddde[0].spare[3]: 0 ; 0x09c: 0x00000000
kfddde[0].spare[4]: 0 ; 0x0a0: 0x00000000
kfddde[0].zones[0].start: 0 ; 0x0a4: 0x00000000
kfddde[0].zones[0].size: 1024 ; 0x0a8: 0x00000400
kfddde[0].zones[0].used: 113 ; 0x0ac: 0x00000071
kfddde[0].zones[0].spare: 0 ; 0x0b0: 0x00000000
kfddde[0].zones[0].classes[0].imbal[0]:111 ; 0x0b4: 0x0000006f
kfddde[0].zones[0].classes[0].imbal[1]:0 ; 0x0b8: 0x00000000
kfddde[0].zones[0].classes[0].imbal[2]:0 ; 0x0bc: 0x00000000
...........如下部分是另外一个disk group中一个disk的信息,以这个为例进行解释:
[oracle@10gasm ~]$ kfed read /dev/sdc aun=2 blkn=0 |more
kfbh.endian: 1 ; 0x000: 0x01
kfbh.hard: 130 ; 0x001: 0x82
kfbh.type: 6 ; 0x002: KFBTYP_DISKDIR
kfbh.datfmt: 1 ; 0x003: 0x01
kfbh.block.blk: 0 ; 0x004: T=0 NUMB=0x0
kfbh.block.obj: 2 ; 0x008: TYPE=0x0 NUMB=0x2
kfbh.check: 4261246045 ; 0x00c: 0xfdfd745d
kfbh.fcn.base: 2541 ; 0x010: 0x000009ed
kfbh.fcn.wrap: 0 ; 0x014: 0x00000000
kfbh.spare1: 0 ; 0x018: 0x00000000
kfbh.spare2: 0 ; 0x01c: 0x00000000
kffdnd.bnode.incarn: 1 ; 0x000: A=1 NUMM=0x0
kffdnd.bnode.frlist.number: 4294967295 ; 0x004: 0xffffffff
kffdnd.bnode.frlist.incarn: 0 ; 0x008: A=0 NUMM=0x0
kffdnd.overfl.number: 4294967295 ; 0x00c: 0xffffffff
kffdnd.overfl.incarn: 0 ; 0x010: A=0 NUMM=0x0
kffdnd.parent.number: 0 ; 0x014: 0x00000000
kffdnd.parent.incarn: 1 ; 0x018: A=1 NUMM=0x0
kffdnd.fstblk.number: 0 ; 0x01c: 0x00000000
kffdnd.fstblk.incarn: 1 ; 0x020: A=1 NUMM=0x0
kfddde[0].entry.incarn: 1 ; 0x024: A=1 NUMM=0x0
kfddde[0].entry.hash: 0 ; 0x028: 0x00000000
kfddde[0].entry.refer.number:4294967295 ; 0x02c: 0xffffffff
kfddde[0].entry.refer.incarn: 0 ; 0x030: A=0 NUMM=0x0
kfddde[0].dsknum: 0 ; 0x034: 0x0000
kfddde[0].state: 2 ; 0x036: KFDSTA_NORMAL
kfddde[0].ub1spare: 0 ; 0x037: 0x00
kfddde[0].dskname: DATA1_0000 ; 0x038: length=10
kfddde[0].fgname: DATA1_0000 ; 0x058: length=10
kfddde[0].crestmp.hi: 32977478 ; 0x078: HOUR=0x6 DAYS=0x12 MNTH=0xc YEAR=0x7dc
kfddde[0].crestmp.lo: 2407340032 ; 0x07c: USEC=0x0 MSEC=0x346 SECS=0x37 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: 1024 ; 0x08c: 0x00000400
kfddde[0].spare[0]: 0 ; 0x090: 0x00000000
kfddde[0].spare[1]: 0 ; 0x094: 0x00000000
kfddde[0].spare[2]: 0 ; 0x098: 0x00000000
kfddde[0].spare[3]: 0 ; 0x09c: 0x00000000
kfddde[0].spare[4]: 0 ; 0x0a0: 0x00000000
kfddde[0].zones[0].start: 0 ; 0x0a4: 0x00000000
kfddde[0].zones[0].size: 1024 ; 0x0a8: 0x00000400
kfddde[0].zones[0].used: 336 ; 0x0ac: 0x00000150
kfddde[0].zones[0].spare: 0 ; 0x0b0: 0x00000000
kfddde[0].zones[0].classes[0].imbal[0]:334 ; 0x0b4: 0x0000014e
kfddde[0].zones[0].classes[0].imbal[1]:0 ; 0x0b8: 0x00000000
kfddde[0].zones[0].classes[0].imbal[2]:0 ; 0x0bc: 0x00000000
.........
kfddde[0].zones[3].classes[3].imbal[3]:0 ; 0x1e0: 0x00000000
kfddde[1].entry.incarn: 1 ; 0x1e4: A=1 NUMM=0x0
kfddde[1].entry.hash: 1 ; 0x1e8: 0x00000001
kfddde[1].entry.refer.number:4294967295 ; 0x1ec: 0xffffffff
kfddde[1].entry.refer.incarn: 0 ; 0x1f0: A=0 NUMM=0x0
kfddde[1].dsknum: 1 ; 0x1f4: 0x0001
kfddde[1].state: 2 ; 0x1f6: KFDSTA_NORMAL
kfddde[1].ub1spare: 0 ; 0x1f7: 0x00
kfddde[1].dskname: DATA1_0001 ; 0x1f8: length=10
kfddde[1].fgname: DATA1_0001 ; 0x218: length=10
kfddde[1].crestmp.hi: 32977478 ; 0x238: HOUR=0x6 DAYS=0x12 MNTH=0xc YEAR=0x7dc
kfddde[1].crestmp.lo: 2407340032 ; 0x23c: USEC=0x0 MSEC=0x346 SECS=0x37 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: 1024 ; 0x24c: 0x00000400
kfddde[1].spare[0]: 0 ; 0x250: 0x00000000
kfddde[1].spare[1]: 0 ; 0x254: 0x00000000
kfddde[1].spare[2]: 0 ; 0x258: 0x00000000
kfddde[1].spare[3]: 0 ; 0x25c: 0x00000000
kfddde[1].spare[4]: 0 ; 0x260: 0x00000000
kfddde[1].zones[0].start: 0 ; 0x264: 0x00000000
kfddde[1].zones[0].size: 1024 ; 0x268: 0x00000400
kfddde[1].zones[0].used: 337 ; 0x26c: 0x00000151
kfddde[1].zones[0].spare: 0 ; 0x270: 0x00000000
kfddde[1].zones[0].classes[0].imbal[0]:335 ; 0x274: 0x0000014f
kfddde[1].zones[0].classes[0].imbal[1]:0 ; 0x278: 0x00000000
kfddde[1].zones[0].classes[0].imbal[2]:0 ; 0x27c: 0x00000000
..........
kfddde[1].zones[3].classes[3].imbal[3]:0 ; 0x3a0: 0x00000000
kfddde[2].entry.incarn: 1 ; 0x3a4: A=1 NUMM=0x0
kfddde[2].entry.hash: 2 ; 0x3a8: 0x00000002
kfddde[2].entry.refer.number:4294967295 ; 0x3ac: 0xffffffff
kfddde[2].entry.refer.incarn: 0 ; 0x3b0: A=0 NUMM=0x0
kfddde[2].dsknum: 2 ; 0x3b4: 0x0002
kfddde[2].state: 2 ; 0x3b6: KFDSTA_NORMAL
kfddde[2].ub1spare: 0 ; 0x3b7: 0x00
kfddde[2].dskname: DATA1_0002 ; 0x3b8: length=10
kfddde[2].fgname: DATA1_0002 ; 0x3d8: length=10
kfddde[2].crestmp.hi: 32977623 ; 0x3f8: HOUR=0x17 DAYS=0x16 MNTH=0xc YEAR=0x7dc
kfddde[2].crestmp.lo: 2996656128 ; 0x3fc: USEC=0x0 MSEC=0x356 SECS=0x29 MINS=0x2c
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: 1024 ; 0x40c: 0x00000400
kfddde[2].spare[0]: 0 ; 0x410: 0x00000000
kfddde[2].spare[1]: 0 ; 0x414: 0x00000000
kfddde[2].spare[2]: 0 ; 0x418: 0x00000000
kfddde[2].spare[3]: 0 ; 0x41c: 0x00000000
kfddde[2].spare[4]: 0 ; 0x420: 0x00000000
kfddde[2].zones[0].start: 0 ; 0x424: 0x00000000
kfddde[2].zones[0].size: 1024 ; 0x428: 0x00000400
kfddde[2].zones[0].used: 336 ; 0x42c: 0x00000150
kfddde[2].zones[0].spare: 0 ; 0x430: 0x00000000
kfddde[2].zones[0].classes[0].imbal[0]:334 ; 0x434: 0x0000014e
kfddde[2].zones[0].classes[0].imbal[1]:0 ; 0x438: 0x00000000
kfddde[2].zones[0].classes[0].imbal[2]:0 ; 0x43c: 0x00000000
..........
kfddde[2].zones[3].classes[3].imbal[3]:0 ; 0x560: 0x00000000
kfddde[3].entry.incarn: 2 ; 0x564: A=0 NUMM=0x1
kfddde[3].entry.hash: 0 ; 0x568: 0x00000000
kfddde[3].entry.refer.number: 0 ; 0x56c: 0x00000000
kfddde[3].entry.refer.incarn: 0 ; 0x570: A=0 NUMM=0x0
kfddde[3].dsknum: 3 ; 0x574: 0x0003
kfddde[3].state: 6 ; 0x576: KFDSTA_FORCING
kfddde[3].ub1spare: 0 ; 0x577: 0x00
kfddde[3].dskname: DATA1_0003 ; 0x578: length=10
kfddde[3].fgname: DATA1_0003 ; 0x598: length=10
kfddde[3].crestmp.hi: 32977623 ; 0x5b8: HOUR=0x17 DAYS=0x16 MNTH=0xc YEAR=0x7dc
kfddde[3].crestmp.lo: 2996656128 ; 0x5bc: USEC=0x0 MSEC=0x356 SECS=0x29 MINS=0x2c
kfddde[3].failstmp.hi: 0 ; 0x5c0: HOUR=0x0 DAYS=0x0 MNTH=0x0 YEAR=0x0
kfddde[3].failstmp.lo: 0 ; 0x5c4: USEC=0x0 MSEC=0x0 SECS=0x0 MINS=0x0
kfddde[3].timer: 0 ; 0x5c8: 0x00000000
kfddde[3].size: 1024 ; 0x5cc: 0x00000400
kfddde[3].spare[0]: 0 ; 0x5d0: 0x00000000
kfddde[3].spare[1]: 0 ; 0x5d4: 0x00000000
kfddde[3].spare[2]: 0 ; 0x5d8: 0x00000000
kfddde[3].spare[3]: 0 ; 0x5dc: 0x00000000
kfddde[3].spare[4]: 0 ; 0x5e0: 0x00000000
kfddde[3].zones[0].start: 0 ; 0x5e4: 0x00000000
kfddde[3].zones[0].size: 1024 ; 0x5e8: 0x00000400
kfddde[3].zones[0].used: 2 ; 0x5ec: 0x00000002
kfddde[3].zones[0].spare: 0 ; 0x5f0: 0x00000000
kfddde[3].zones[0].classes[0].imbal[0]:0 ; 0x5f4: 0x00000000
...........
kfddde[3].zones[3].classes[3].imbal[3]:0 ; 0x720: 0x00000000
kfddde[4].entry.incarn: 0 ; 0x724: A=0 NUMM=0x0
kfddde[4].entry.hash: 0 ; 0x728: 0x00000000
kfddde[4].entry.refer.number: 0 ; 0x72c: 0x00000000
kfddde[4].entry.refer.incarn: 0 ; 0x730: A=0 NUMM=0x0
kfddde[4].dsknum: 0 ; 0x734: 0x0000
kfddde[4].state: 0 ; 0x736: KFDSTA_INVALID
kfddde[4].ub1spare: 0 ; 0x737: 0x00
kfddde[4].dskname: ; 0x738: length=0
kfddde[4].fgname: ; 0x758: length=0
kfddde[4].crestmp.hi: 0 ; 0x778: HOUR=0x0 DAYS=0x0 MNTH=0x0 YEAR=0x0
kfddde[4].crestmp.lo: 0 ; 0x77c: USEC=0x0 MSEC=0x0 SECS=0x0 MINS=0x0
kfddde[4].failstmp.hi: 0 ; 0x780: HOUR=0x0 DAYS=0x0 MNTH=0x0 YEAR=0x0
kfddde[4].failstmp.lo: 0 ; 0x784: USEC=0x0 MSEC=0x0 SECS=0x0 MINS=0x0
kfddde[4].timer: 0 ; 0x788: 0x00000000
kfddde[4].size: 0 ; 0x78c: 0x00000000
kfddde[4].spare[0]: 0 ; 0x790: 0x00000000
kfddde[4].spare[1]: 0 ; 0x794: 0x00000000
kfddde[4].spare[2]: 0 ; 0x798: 0x00000000
kfddde[4].spare[3]: 0 ; 0x79c: 0x00000000
kfddde[4].spare[4]: 0 ; 0x7a0: 0x00000000
kfddde[4].zones[0].start: 0 ; 0x7a4: 0x00000000
kfddde[4].zones[0].size: 0 ; 0x7a8: 0x00000000
kfddde[4].zones[0].used: 0 ; 0x7ac: 0x00000000
kfddde[4].zones[0].spare: 0 ; 0x7b0: 0x00000000
kfddde[4].zones[0].classes[0].imbal[0]:0 ; 0x7b4: 0x00000000
..........从上面的信息我们可以看出,asm disk directory的结构大概如下,分为3个部分:
1)kfbh, 该部分表示block header,这部分内容都是基本上一样的,没什么可说的
2)kffdnd,这部分是目录结构信息
kffdnd.bnode.incarn: 1 ; 0x000: A=1 NUMM=0x0 ----分配信息,包括block的分支号和指向next freelist block的指针
kffdnd.bnode.frlist.number: 4294967295 ; 0x004: 0xffffffff
kffdnd.bnode.frlist.incarn: 0 ; 0x008: A=0 NUMM=0x0
kffdnd.overfl.number: 4294967295 ; 0x00c: 0xffffffff
kffdnd.overfl.incarn: 0 ; 0x010: A=0 NUMM=0x0 ---overfl,表示指向同层级的下一个block
kffdnd.parent.number: 0 ; 0x014: 0x00000000 ---表示指向上一层的block
kffdnd.parent.incarn: 1 ; 0x018: A=1 NUMM=0x0
kffdnd.fstblk.number: 0 ; 0x01c: 0x00000000 ---这里的fst应该不是指的free space table,我猜测应该是指的第一个block。
kffdnd.fstblk.incarn: 1 ; 0x020: A=1 NUMM=0x03)kfddde,这部分结构也是disk directory元数据中最为重要的一部分结构,其实通过前面的kfed 的内容,我基本上就能知道个大概了。
我这里就拿上面的kfddde[0]为例,进行说明,如下:
kfddde[0].entry.incarn: 1 ; 0x024: A=1 NUMM=0x0
kfddde[0].entry.hash: 0 ; 0x028: 0x00000000
kfddde[0].entry.refer.number:4294967295 ; 0x02c: 0xffffffff
kfddde[0].entry.refer.incarn: 0 ; 0x030: A=0 NUMM=0x0
---- 上面这部分是kfddde.entry信息,里面包括了分支号,hash值、以及指向下一层级相关block的指针,这部分内容无需过多关注
kfddde[0].dsknum: 0 ; 0x034: 0x0000 ---diskgroup中,该disk的disk编号,从0开始排序,该值为0,说明该disk是这个磁盘组中的第一个disk
kfddde[0].state: 2 ; 0x036: KFDSTA_NORMAL ---disk状态。其中2表示normal。在asm中,该值对应v$asm_disk.state,主要有如下几种值:
UNKNOWN ---disk不被diskgroup所识别,通常是diskgroup没有mount。
NORMAL ---disk目前处于online状态,操作正常。
ADDING ---表示disk正在被加入到diskgroup当中,其中add disk过程涉及到一系列的操作,包括更新pst,fst,disk dir以及reblance等各项操作。
DROPPING ---表示disk正在被从某个diskgroup中删除,该操作可以认为是adding的相反过程
HUNG ---该状态表示在drop disk的过程中,由于diskgroup 空间不足而不能完成reblance操作而导致disk处于hung状态。
FORCING ---该状态表示disk已经从diskgroup中移除,但是其disk上的数据尚未被卸载,很可能是强制drop。
DROPPED ---表示disk已经从diskgroup中删除且完成了一系列的相关操作。
关于这个,大家可以去参考官方文档的v$asm_disk.state,我这里再补充一点网上搜到的内容:
#define KFDSTA_INVALID ((kfdsta)0) /* Illegal value */
#define KFDSTA_UNKNOWN ((kfdsta)1) /* ASM disk state not known */
#define KFDSTA_NORMAL ((kfdsta)2) /* Happy disk */
#define KFDSTA_UNUSED ((kfdsta)3) /* Unused State - Open */
#define KFDSTA_DROPPING ((kfdsta)4) /* Disk being dropped from group */
#define KFDSTA_HUNG ((kfdsta)5) /* Disk drop operation hung */
#define KFDSTA_FORCING ((kfdsta)6) /* Disk beinng drop forced */
#define KFDSTA_DROPPED ((kfdsta)7) /* Disk no longer part of group */
#define KFDSTA_ADDING ((kfdsta)8) /* Disk being globally validated */下面我接着继续剖析:
kfddde[0].ub1spare: 0 ; 0x037: 0x00
kfddde[0].dskname: DATA1_0000 ; 0x038: length=10 --磁盘名称,这是asm中定义的diskname.
kfddde[0].fgname: DATA1_0000 ; 0x058: length=10 --这表示failgroup diskname,由于我这里是external冗余,所以failgroup就是本身。
kfddde[0].crestmp.hi: 32977478 ; 0x078: HOUR=0x6 DAYS=0x12 MNTH=0xc YEAR=0x7dc
kfddde[0].crestmp.lo: 2407340032 ; 0x07c: USEC=0x0 MSEC=0x346 SECS=0x37 MINS=0x23 ---这里表示该disk的创建时间戳
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 ---这里表示disk 失败的时间戳
kfddde[0].timer: 0 ; 0x088: 0x00000000
kfddde[0].size: 1024 ; 0x08c: 0x00000400 ---disk大小,由于au默认是1m,所以这里是1024m。
kfddde[0].spare[0]: 0 ; 0x090: 0x00000000
kfddde[0].spare[1]: 0 ; 0x094: 0x00000000
kfddde[0].spare[2]: 0 ; 0x098: 0x00000000
kfddde[0].spare[3]: 0 ; 0x09c: 0x00000000
kfddde[0].spare[4]: 0 ; 0x0a0: 0x00000000 ---这部分spare信息没有什么实际意义下面的这部分内容是zone信息,我是这样理解的,同一个磁盘组,asm将该磁盘组中的所有disk看成一个整体,然后
将这些disks进行划分,有点类似分区的感觉或在VG的基础上创建LV的感觉,这里需要注意的是,如果你的磁盘组中有
3个盘,那么这里就会分配3个zone,如果是4个就会分配4个,总之,是一一对应的。 这样也就保证了同一个磁盘组中
的数据是绝对分散的。
kfddde[0].zones[0].start: 0 ; 0x0a4: 0x00000000 ---zone的起始位置
kfddde[0].zones[0].size: 1024 ; 0x0a8: 0x00000400 ---该disk的总大小
kfddde[0].zones[0].used: 336 ; 0x0ac: 0x00000150 ---该disk的已使用量,这里表示该disk,也就是我们的/dev/sdc用了336m.
kfddde[0].zones[0].spare: 0 ; 0x0b0: 0x00000000
kfddde[0].zones[0].classes[0].imbal[0]:334 ; 0x0b4: 0x0000014e ---这里我不确定是什么意思,猜测应该是该disk中的data数据大小,除开asm元数据的数据使用量。
kfddde[0].zones[0].classes[0].imbal[1]:0 ; 0x0b8: 0x00000000 意思就该disk中,我们的数据实际上占据了334m.
kfddde[0].zones[0].classes[0].imbal[2]:0 ; 0x0bc: 0x00000000到这里,关于asm disk directory 基本上就描述完了,最后再补充下关于asm diskgroup,在add/drop disk时,asm的reblance情况。

从上面的图内容,我们可以看到,其实在reblance的过程中,不仅仅是我们实际的业务数据会进行均衡操作,还包括asm的元数据。
oracle提供了一个试图v$asm_operation,可以同来观察asm disk reblance的过程、以及估计reblance的剩余时间等等。
其中disk reblance操作是由rbal进程来完成的,而数据库参数asm_power_limit则控制着rbal进程的个数,如果当你在进行
add disk/drop disk等操作时,容量很大的情况下,可以考虑设置较大的参数,那样reblance操作可能会相对快很多. 例如:
alter diskgroup data1 add disk '/dev/sdd' reblance power 5;
不过需要注意一点的是,最好不要在业务期间做reblance,因为该操作本身是比较消耗资源的,而且容易出问题。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




