sitemap

RSS地图

收藏本站

设为首页

Oracle研究中心

当前位置:Oracle研究中心 > 产品DBA > Oracle ASM >

【学习笔记】Oracle ASM剖析系列(7)–Active Change Directory

时间:2016-12-16 10:55   来源:Oracle研究中心   作者:网络   点击:

天萃荷净 Oracle研究中心学习笔记:分享一篇关于Oracle数据库ASM的学习笔记,详细介绍Active Change Directory。

本站文章除注明转载外,均为本站原创: 转载自love wife & love life —Roger 的Oracle技术博客
本文链接地址: oracle asm剖析系列(7)–Active Change Directory

文章中将介绍Active Change Directory的结构。何为ACD?大家如何把asm实例也看成一个微型的数据库实例的话,那么ACD信息,就好比是redo。换句话将,ACD里面的信息,记录了asm的所有元数据block的操作记录。当然,有这个的好处是什么呢?

其实你可以想象,数据库实例中,如果实例crash掉,那么还可以借助redo去进行instance recover。

这里针对asm而已,ACD的功能有异曲同工之妙。

SQL> SELECT number_kffxp file#, disk_kffxp disk#, COUNT(disk_kffxp) extents
  2  FROM x$kffxp
  3  WHERE group_kffxp=1
  4        AND disk_kffxp <> 65534
  5  GROUP BY number_kffxp, disk_kffxp
  6  ORDER BY 1;

     FILE#      DISK#    EXTENTS
---------- ---------- ----------
         1          0          1
         1          1          1
         2          1          1
         3          0         21
         3          1         21  --file 3,即是active change directory,一个占据42个au size。
         4          0          1
         4          1          1
         5          0          1
         6          0          1
       256          0        240
       256          1        242
  .........Oracleо
       263          1         28
       264          0         10
       264          1         11
       265          1          1
       266          0         11
       266          1         10

30 ROWS selected.

SQL> SELECT x.xnum_kffxp "Extent",
  2    x.au_kffxp "AU",
  3    x.disk_kffxp "Disk #",
  4    d.name "Disk name"
  5   FROM x$kffxp x, v$asm_disk_stat d
  6   WHERE x.group_kffxp=d.group_number
  7    AND x.disk_kffxp=d.disk_number
  8    AND x.group_kffxp=1
  9    AND x.number_kffxp=3
10   ORDER BY 1, 2
11  /

    Extent         AU     Disk # Disk name
---------- ---------- ---------- ------------------------------
         0        149          0 DATA1_0000
         1          3          0 DATA1_0000
         2        256          1 DATA1_0001
         3        365          0 DATA1_0000
         4          5          1 DATA1_0001
         5        257          0 DATA1_0000
         6          7          1 DATA1_0001
         7          5          0 DATA1_0000
         8        142          1 DATA1_0001
   ............
        40        124          1 DATA1_0001
        41         19          1 DATA1_0001

42 ROWS selected.

这里需要说明的是,每一个asm实例,都用有其自己的ACD目录,换句话讲,如果你是双节点的rac,那么就有84m的ACD 目录信息。

如下是来自的的vm 11gR2 rac环境信息:

SQL> SELECT * FROM v$version WHERE rownum < 3;

BANNER
--------------------------------------------------------------------------------
Oracle DATABASE 11g Enterprise Edition Release 11.2.0.3.0 - Production
PL/SQL Release 11.2.0.3.0 - Production

SQL> SELECT number_kffxp file#, disk_kffxp disk#, COUNT(disk_kffxp) extents
  2  FROM x$kffxp
  3  WHERE group_kffxp=1
  4        AND disk_kffxp <> 65534
  5  GROUP BY number_kffxp, disk_kffxp
  6  ORDER BY 1;

     FILE#      DISK#    EXTENTS
---------- ---------- ----------
         1          0          1
         2          0          1
         3          0         85
         4          0          2
         5          0          1
         6          0          1
         8          0          1
         9          0          1

8 ROWS selected.、

我这是2个节点的rac,即有2个asm,所以这里file 3所占据的au extent为84个。

我们使用kfed来读取元数据,首先定位到active change directory 所在AU :

[oracle@10gasm ~]$ kfed read /dev/sdd aun=2 blkn=3 | more
kfbh.endian:                          1 ; 0x000: 0x01
kfbh.hard:                          130 ; 0x001: 0x82
kfbh.type:                            4 ; 0x002: KFBTYP_FILEDIR
kfbh.datfmt:                          1 ; 0x003: 0x01
kfbh.block.blk:                       3 ; 0x004: T=0 NUMB=0x3
kfbh.block.obj:                       1 ; 0x008: TYPE=0x0 NUMB=0x1
kfbh.check:                  1014394183 ; 0x00c: 0x3c766d47
kfbh.fcn.base:                     3840 ; 0x010: 0x00000f00
kfbh.fcn.wrap:                        0 ; 0x014: 0x00000000
kfbh.spare1:                          0 ; 0x018: 0x00000000
kfbh.spare2:                          0 ; 0x01c: 0x00000000
kfffdb.node.incarn:                   1 ; 0x000: A=1 NUMM=0x0
kfffdb.node.frlist.number:   4294967295 ; 0x004: 0xffffffff
kfffdb.node.frlist.incarn:            0 ; 0x008: A=0 NUMM=0x0
kfffdb.hibytes:                       0 ; 0x00c: 0x00000000
kfffdb.lobytes:                44040192 ; 0x010: 0x02a00000
kfffdb.xtntcnt:                      42 ; 0x014: 0x0000002a
kfffdb.xtnteof:                      42 ; 0x018: 0x0000002a
kfffdb.blkSize:                    4096 ; 0x01c: 0x00001000
kfffdb.flags:                        65 ; 0x020: O=1 S=0 S=0 D=0 C=0 I=0 R=1 A=0
kfffdb.fileType:                     15 ; 0x021: 0x0f
kfffdb.dXrs:                         17 ; 0x022: SCHE=0x1 NUMB=0x1
kfffdb.iXrs:                         17 ; 0x023: SCHE=0x1 NUMB=0x1
kfffdb.dXsiz[0]:             4294967295 ; 0x024: 0xffffffff
kfffdb.dXsiz[1]:                      0 ; 0x028: 0x00000000
kfffdb.dXsiz[2]:                      0 ; 0x02c: 0x00000000
kfffdb.iXsiz[0]:             4294967295 ; 0x030: 0xffffffff
kfffdb.iXsiz[1]:                      0 ; 0x034: 0x00000000
kfffdb.iXsiz[2]:                      0 ; 0x038: 0x00000000
kfffdb.xtntblk:                      42 ; 0x03c: 0x002a
kfffdb.break:                        60 ; 0x03e: 0x003c
kfffdb.priZn:                         0 ; 0x040: 0x00
kfffdb.secZn:                         0 ; 0x041: 0x00
kfffdb.ub2spare:                      0 ; 0x042: 0x0000
kfffdb.alias[0]:             4294967295 ; 0x044: 0xffffffff
kfffdb.alias[1]:             4294967295 ; 0x048: 0xffffffff
kfffdb.strpwdth:                      0 ; 0x04c: 0x00
kfffdb.strpsz:                        0 ; 0x04d: 0x00
kfffdb.usmsz:                         0 ; 0x04e: 0x0000
kfffdb.crets.hi:               32977478 ; 0x050: HOUR=0x6 DAYS=0x12 MNTH=0xc YEAR=0x7dc
kfffdb.crets.lo:             2407345152 ; 0x054: USEC=0x0 MSEC=0x34b SECS=0x37 MINS=0x23
kfffdb.modts.hi:               32977478 ; 0x058: HOUR=0x6 DAYS=0x12 MNTH=0xc YEAR=0x7dc
kfffdb.modts.lo:             2407345152 ; 0x05c: USEC=0x0 MSEC=0x34b SECS=0x37 MINS=0x23
kfffdb.spare[0]:                      0 ; 0x060: 0x00000000
..........
kfffdb.spare[14]:                     0 ; 0x098: 0x00000000
kfffdb.spare[15]:                     0 ; 0x09c: 0x00000000
kfffdb.usm:                             ; 0x0a0: length=0
kfffde[0].xptr.au:                  149 ; 0x4a0: 0x00000095
kfffde[0].xptr.disk:                  0 ; 0x4a4: 0x0000
kfffde[0].xptr.flags:                 0 ; 0x4a6: L=0 E=0 D=0 C=0 S=0
kfffde[0].xptr.chk:                 191 ; 0x4a7: 0xbf
kfffde[1].xptr.au:                    3 ; 0x4a8: 0x00000003
kfffde[1].xptr.disk:                  0 ; 0x4ac: 0x0000
kfffde[1].xptr.flags:                 0 ; 0x4ae: L=0 E=0 D=0 C=0 S=0
kfffde[1].xptr.chk:                  41 ; 0x4af: 0x29
kfffde[2].xptr.au:                  256 ; 0x4b0: 0x00000100
kfffde[2].xptr.disk:                  1 ; 0x4b4: 0x0001
kfffde[2].xptr.flags:                 0 ; 0x4b6: L=0 E=0 D=0 C=0 S=0
kfffde[2].xptr.chk:                  42 ; 0x4b7: 0x2a
.........
从上面信息可以看出,ACD元数据和数据应该包含在其中一个AU 149中,如下:

[oracle@10gasm ~]$ kfed read /dev/sdd aun=149 blkn=0 | more
kfbh.endian:                          1 ; 0x000: 0x01
kfbh.hard:                          130 ; 0x001: 0x82
kfbh.type:                            7 ; 0x002: KFBTYP_ACDC
kfbh.datfmt:                          1 ; 0x003: 0x01
kfbh.block.blk:                       0 ; 0x004: T=0 NUMB=0x0
kfbh.block.obj:                       3 ; 0x008: TYPE=0x0 NUMB=0x3
kfbh.check:                  1111745254 ; 0x00c: 0x4243e2e6
kfbh.fcn.base:                        0 ; 0x010: 0x00000000
kfbh.fcn.wrap:                        0 ; 0x014: 0x00000000
kfbh.spare1:                          0 ; 0x018: 0x00000000
kfbh.spare2:                          0 ; 0x01c: 0x00000000
kfracdc.eyec[0]:                     65 ; 0x000: 0x41
kfracdc.eyec[1]:                     67 ; 0x001: 0x43
kfracdc.eyec[2]:                     68 ; 0x002: 0x44
kfracdc.eyec[3]:                     67 ; 0x003: 0x43
kfracdc.thread:                       1 ; 0x004: 0x00000001  --thread 1,表示对应第一个asm实例。
kfracdc.lastAba.seq:         4294967295 ; 0x008: 0xffffffff
kfracdc.lastAba.blk:         4294967295 ; 0x00c: 0xffffffff
kfracdc.blk0:                         1 ; 0x010: 0x00000001
kfracdc.blks:                     10751 ; 0x014: 0x000029ff
kfracdc.ckpt.seq:                     5 ; 0x018: 0x00000005
kfracdc.ckpt.blk:                  1329 ; 0x01c: 0x00000531
kfracdc.fcn.base:                  3886 ; 0x020: 0x00000f2e
kfracdc.fcn.wrap:                     0 ; 0x024: 0x00000000
kfracdc.bufBlks:                     64 ; 0x028: 0x00000040
通常来讲,一个block是元数据,而后面的block就是实际数据了。继续读取Active change directory data:

[oracle@10gasm ~]$ kfed read /dev/sdd aun=149 blkn=1 | more
kfbh.endian:                          1 ; 0x000: 0x01
kfbh.hard:                          130 ; 0x001: 0x82
kfbh.type:                            8 ; 0x002: KFBTYP_CHNGDIR
kfbh.datfmt:                          1 ; 0x003: 0x01
kfbh.block.blk:                       1 ; 0x004: T=0 NUMB=0x1
kfbh.block.obj:                       3 ; 0x008: TYPE=0x0 NUMB=0x3
kfbh.check:                    17400326 ; 0x00c: 0x01098206
kfbh.fcn.base:                        0 ; 0x010: 0x00000000
kfbh.fcn.wrap:                        0 ; 0x014: 0x00000000
kfbh.spare1:                          0 ; 0x018: 0x00000000
kfbh.spare2:                          0 ; 0x01c: 0x00000000
kfracdb.aba.seq:                      2 ; 0x000: 0x00000002
kfracdb.aba.blk:                      0 ; 0x004: 0x00000000
kfracdb.ents:                         2 ; 0x008: 0x0002
kfracdb.ub2spare:                     0 ; 0x00a: 0x0000
kfracdb.lge[0].valid:                 1 ; 0x00c: V=1 B=0 M=0
kfracdb.lge[0].chgCount:              1 ; 0x00d: 0x01
kfracdb.lge[0].len:                  52 ; 0x00e: 0x0034
kfracdb.lge[0].kfcn.base:             1 ; 0x010: 0x00000001
kfracdb.lge[0].kfcn.wrap:             0 ; 0x014: 0x00000000
kfracdb.lge[0].bcd[0].kfbl.blk:       0 ; 0x018: T=0 NUMB=0x0
kfracdb.lge[0].bcd[0].kfbl.obj:       4 ; 0x01c: TYPE=0x0 NUMB=0x4
kfracdb.lge[0].bcd[0].kfcn.base:      0 ; 0x020: 0x00000000
kfracdb.lge[0].bcd[0].kfcn.wrap:      0 ; 0x024: 0x00000000
kfracdb.lge[0].bcd[0].oplen:          4 ; 0x028: 0x0004
kfracdb.lge[0].bcd[0].blkIndex:       0 ; 0x02a: 0x0000
kfracdb.lge[0].bcd[0].flags:          0 ; 0x02c: F=0 N=0
kfracdb.lge[0].bcd[0].opcode:       212 ; 0x02e: 0x00d4
kfracdb.lge[0].bcd[0].kfbtyp:         9 ; 0x030: KFBTYP_COD_BGO
kfracdb.lge[0].bcd[0].redund:        17 ; 0x031: SCHE=0x1 NUMB=0x1
kfracdb.lge[0].bcd[0].pad:        63903 ; 0x032: 0xf99f
kfracdb.lge[0].bcd[0].KFRCOD_CRASH:   1 ; 0x034: 0x00000001
kfracdb.lge[0].bcd[0].au[0]:         24 ; 0x038: 0x00000018
kfracdb.lge[0].bcd[0].disks[0]:       1 ; 0x03c: 0x0001
kfracdb.lge[1].valid:                 1 ; 0x040: V=1 B=0 M=0
kfracdb.lge[1].chgCount:              1 ; 0x041: 0x01
kfracdb.lge[1].len:                  52 ; 0x042: 0x0034
kfracdb.lge[1].kfcn.base:             2 ; 0x044: 0x00000002
kfracdb.lge[1].kfcn.wrap:             0 ; 0x048: 0x00000000
kfracdb.lge[1].bcd[0].kfbl.blk:       1 ; 0x04c: T=0 NUMB=0x1
kfracdb.lge[1].bcd[0].kfbl.obj:       4 ; 0x050: TYPE=0x0 NUMB=0x4
kfracdb.lge[1].bcd[0].kfcn.base:      0 ; 0x054: 0x00000000
kfracdb.lge[1].bcd[0].kfcn.wrap:      0 ; 0x058: 0x00000000
kfracdb.lge[1].bcd[0].oplen:          4 ; 0x05c: 0x0004
kfracdb.lge[1].bcd[0].blkIndex:       1 ; 0x05e: 0x0001
kfracdb.lge[1].bcd[0].flags:          0 ; 0x060: F=0 N=0
kfracdb.lge[1].bcd[0].opcode:       212 ; 0x062: 0x00d4
kfracdb.lge[1].bcd[0].kfbtyp:        15 ; 0x064: KFBTYP_COD_RBO
kfracdb.lge[1].bcd[0].redund:        17 ; 0x065: SCHE=0x1 NUMB=0x1
kfracdb.lge[1].bcd[0].pad:        63903 ; 0x066: 0xf99f
kfracdb.lge[1].bcd[0].KFRCOD_CRASH:   0 ; 0x068: 0x00000000
kfracdb.lge[1].bcd[0].au[0]:         24 ; 0x06c: 0x00000018
kfracdb.lge[1].bcd[0].disks[0]:       1 ; 0x070: 0x0001

其他ACD 所在的AU也是一样,所以这里我以上面kfed的数据为例,进行剖析。首先我们先来看ACD 元数据.我们可以看到,active change directory元数据,就2个部分;

1) kfbh,头部信息,没有什么可描述的,跟前面其他元数据结构头部描述一样。

kfbh.endian:                          1 ; 0x000: 0x01
kfbh.hard:                          130 ; 0x001: 0x82
kfbh.type:                            7 ; 0x002: KFBTYP_ACDC --ACDC,即是Active Change Diectory Checkpoint
kfbh.datfmt:                          1 ; 0x003: 0x01
kfbh.block.blk:                       0 ; 0x004: T=0 NUMB=0x0  这是对应的block号
kfbh.block.obj:                       3 ; 0x008: TYPE=0x0 NUMB=0x3
kfbh.check:                  1111745254 ; 0x00c: 0x4243e2e6
kfbh.fcn.base:                        0 ; 0x010: 0x00000000
kfbh.fcn.wrap:                        0 ; 0x014: 0x00000000
kfbh.spare1:                          0 ; 0x018: 0x00000000
kfbh.spare2:                          0 ; 0x01c: 0x00000000

2) kfracdc,这部分即表示active change directory checkpoint信息。

kfracdc.eyec[0]:                     65 ; 0x000: 0x41
kfracdc.eyec[1]:                     67 ; 0x001: 0x43
kfracdc.eyec[2]:                     68 ; 0x002: 0x44
kfracdc.eyec[3]:                     67 ; 0x003: 0x43
kfracdc.thread:                       1 ; 0x004: 0x00000001  --thread 1,表示对应第一个asm实例。
kfracdc.lastAba.seq:         4294967295 ; 0x008: 0xffffffff  --last ACD block address sequences
kfracdc.lastAba.blk:         4294967295 ; 0x00c: 0xffffffff  --last ACD block address block number
kfracdc.blk0:                         1 ; 0x010: 0x00000001
kfracdc.blks:                     10751 ; 0x014: 0x000029ff  --ACD 数据(元数据和数据)所占block总数,换算一下即为42m. 10751*4096/1024/1024=42
kfracdc.ckpt.seq:                     5 ; 0x018: 0x00000005  --checkpoint当前的sequences号
kfracdc.ckpt.blk:                  1329 ; 0x01c: 0x00000531  --checkpoint信息所占的block数
kfracdc.fcn.base:                  3886 ; 0x020: 0x00000f2e
kfracdc.fcn.wrap:                     0 ; 0x024: 0x00000000
kfracdc.bufBlks:                     64 ; 0x028: 0x00000040  --block总数

我们接着来分解ACD data的结构,其结构主要分为如下部分:

1)kcbh,头部信息,这部分内容描述的太多,不多说了。
2)kfracdb,这里部分结构里面包括了所有的ACD data数据,如下:


kfracdb.aba.seq:                      2 ; 0x000: 0x00000002  --ACD block address sequences
kfracdb.aba.blk:                      0 ; 0x004: 0x00000000  --ACD block address block number
kfracdb.ents:                         2 ; 0x008: 0x0002   ---这里应该是指的包含的extent数。即2m。
kfracdb.ub2spare:                     0 ; 0x00a: 0x0000

下面的lge即为ACD redo log records记录:
kfracdb.lge[0].valid:                 1 ; 0x00c: V=1 B=0 M=0
kfracdb.lge[0].chgCount:              1 ; 0x00d: 0x01
kfracdb.lge[0].len:                  52 ; 0x00e: 0x0034
kfracdb.lge[0].kfcn.base:             1 ; 0x010: 0x00000001
kfracdb.lge[0].kfcn.wrap:             0 ; 0x014: 0x00000000

下面的bcd信息是表示ACD block change description信息:
kfracdb.lge[0].bcd[0].kfbl.blk:       0 ; 0x018: T=0 NUMB=0x0
kfracdb.lge[0].bcd[0].kfbl.obj:       4 ; 0x01c: TYPE=0x0 NUMB=0x4
kfracdb.lge[0].bcd[0].kfcn.base:      0 ; 0x020: 0x00000000
kfracdb.lge[0].bcd[0].kfcn.wrap:      0 ; 0x024: 0x00000000
kfracdb.lge[0].bcd[0].oplen:          4 ; 0x028: 0x0004        ---表示长度,类似logfile dump的LEN
kfracdb.lge[0].bcd[0].blkIndex:       0 ; 0x02a: 0x0000
kfracdb.lge[0].bcd[0].flags:          0 ; 0x02c: F=0 N=0
kfracdb.lge[0].bcd[0].opcode:       212 ; 0x02e: 0x00d4          --opcode,类似数据库实例中的update/delete/insert操作的opcode编号
kfracdb.lge[0].bcd[0].kfbtyp:         9 ; 0x030: KFBTYP_COD_BGO  --操作类型,类似数据库实例中的update/delete/insert等类型
kfracdb.lge[0].bcd[0].redund:        17 ; 0x031: SCHE=0x1 NUMB=0x1 --这里表示冗余级别,17是unport,18是mirror,19表示high
kfracdb.lge[0].bcd[0].pad:        63903 ; 0x032: 0xf99f
kfracdb.lge[0].bcd[0].KFRCOD_CRASH:   1 ; 0x034: 0x00000001
kfracdb.lge[0].bcd[0].au[0]:         24 ; 0x038: 0x00000018
kfracdb.lge[0].bcd[0].disks[0]:       1 ; 0x03c: 0x0001
kfracdb.lge[1].valid:                 1 ; 0x040: V=1 B=0 M=0
kfracdb.lge[1].chgCount:              1 ; 0x041: 0x01            ---我这里应该这个data1磁盘组有2个disk,所以对应有2个lge条目。
kfracdb.lge[1].len:                  52 ; 0x042: 0x0034
kfracdb.lge[1].kfcn.base:             2 ; 0x044: 0x00000002
kfracdb.lge[1].kfcn.wrap:             0 ; 0x048: 0x00000000
kfracdb.lge[1].bcd[0].kfbl.blk:       1 ; 0x04c: T=0 NUMB=0x1
kfracdb.lge[1].bcd[0].kfbl.obj:       4 ; 0x050: TYPE=0x0 NUMB=0x4
kfracdb.lge[1].bcd[0].kfcn.base:      0 ; 0x054: 0x00000000
kfracdb.lge[1].bcd[0].kfcn.wrap:      0 ; 0x058: 0x00000000
kfracdb.lge[1].bcd[0].oplen:          4 ; 0x05c: 0x0004
kfracdb.lge[1].bcd[0].blkIndex:       1 ; 0x05e: 0x0001
kfracdb.lge[1].bcd[0].flags:          0 ; 0x060: F=0 N=0
kfracdb.lge[1].bcd[0].opcode:       212 ; 0x062: 0x00d4
kfracdb.lge[1].bcd[0].kfbtyp:        15 ; 0x064: KFBTYP_COD_RBO
kfracdb.lge[1].bcd[0].redund:        17 ; 0x065: SCHE=0x1 NUMB=0x1
kfracdb.lge[1].bcd[0].pad:        63903 ; 0x066: 0xf99f
kfracdb.lge[1].bcd[0].KFRCOD_CRASH:   0 ; 0x068: 0x00000000
kfracdb.lge[1].bcd[0].au[0]:         24 ; 0x06c: 0x00000018
kfracdb.lge[1].bcd[0].disks[0]:       1 ; 0x070: 0x0001

上面有部分信息,我目前也不清楚具体的含义,只能猜测个大概。从上面我们所了解的信息来看,当asm实例在对元数据进行变更以后,会将更改前的信息写入到ACD 数据中,而ACD data中记录了哪些数据呢?

主要是记录了这样一些数据:线程号,block号,opcode,sequences,记录长度等信息。

这样,当你处于运行的asm实例,突然crash后,那么重启asm实例以后,asm可以根据ACD信息去进行”instance recover”,从而保证能够正常启动asm实例。

到这里,大家或许有个疑问,既然asm 中也有类似数据库实例的redo机制?那么是否存在类似undo的机制呢?后面会描述。

最后我们通过strace asm相关进程,来观察下相关的操作,已验证前面的提到的内容:

+++++++ 下面是 strace asm_lgwr进程的输出信息
29998      3.785640 gettimeofday({1358315310, 77656}, NULL) = 0                                                               
29998      0.000055 gettimeofday({1358315310, 77707}, NULL) = 0                                                               
.........                                                              
29998      0.000087 gettimeofday({1358315310, 78109}, NULL) = 0                                                               
29998      0.000043 times(NULL)         = 455756707                                                                           
29998      0.000041 gettimeofday({1358315310, 78193}, NULL) = 0                                                               
29998      0.000042 getrusage(RUSAGE_SELF, {ru_utime={0, 400939}, ru_stime={0, 579911}, ...}) = 0                             
29998      0.000062 gettimeofday({1358315310, 78297}, NULL) = 0                                                               
29998      0.000042 getrusage(RUSAGE_SELF, {ru_utime={0, 400939}, ru_stime={0, 579911}, ...}) = 0                             
29998      0.000061 gettimeofday({1358315310, 78400}, NULL) = 0                                                               
29998      0.000044 gettimeofday({1358315310, 78444}, NULL) = 0                                                               
29998      0.000042 gettimeofday({1358315310, 78486}, NULL) = 0                                                               
29998      0.000047 gettimeofday({1358315310, 78599}, NULL) = 0                                                               
29998      0.000187 times(NULL)         = 455756708                                                                           
29998      0.000051 pwrite64(19, "\1\202\7\1\0\0\0\0\3\0\0\0\0\352CB\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096, 4194304) = 4096
29998      0.000821 times(NULL)         = 455756708                                                                           
29998      0.000091 times(NULL)         = 455756708                                                                           
29998      0.000052 pwrite64(20, "\1\202\7\1\0\0\0\0\3\0\0\0\0\352CB\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096, 4194304) = 4096
29998      0.000636 times(NULL)         = 455756708                                                                           
29998      0.000059 gettimeofday({1358315310, 80431}, NULL) = 0                                                               
.........                                                              
29998      0.000043 gettimeofday({1358315310, 80736}, NULL) = 0                                                               
29998      0.000044 gettimeofday({1358315310, 80780}, NULL) = 0                                                               
29998      0.000050 semtimedop(3506176, 0xbf910c48, 1, {3, 0}) = -1 EAGAIN (Resource temporarily unavailable)                 
29998      3.763776 gettimeofday({1358315313, 844612}, NULL) = 0              

[oracle@10gasm fd]$ ls -ltr
total 0
lrwx------ 1 oracle oinstall 64 Jan 15 21:36 9 -> /home/oracle/oracle/product/10.2.0/dbs/hc_+ASM.dat
l-wx------ 1 oracle oinstall 64 Jan 15 21:36 8 -> /home/oracle/admin/+ASM/bdump/alert_+ASM.log
lrwx------ 1 oracle oinstall 64 Jan 15 21:36 7 -> /home/oracle/oracle/product/10.2.0/dbs/lkinst+ASM (deleted)
l-wx------ 1 oracle oinstall 64 Jan 15 21:36 6 -> /home/oracle/admin/+ASM/bdump/alert_+ASM.log
l-wx------ 1 oracle oinstall 64 Jan 15 21:36 5 -> /home/oracle/admin/+ASM/udump/+asm_ora_29975.trc
lr-x------ 1 oracle oinstall 64 Jan 15 21:36 4 -> /dev/null
lr-x------ 1 oracle oinstall 64 Jan 15 21:36 3 -> /dev/null
lr-x------ 1 oracle oinstall 64 Jan 15 21:36 2 -> /dev/null
lrwx------ 1 oracle oinstall 64 Jan 15 21:36 15 -> /dev/sdd
lrwx------ 1 oracle oinstall 64 Jan 15 21:36 14 -> /home/oracle/oracle/product/10.2.0/dbs/hc_+ASM.dat
lr-x------ 1 oracle oinstall 64 Jan 15 21:36 13 -> /home/oracle/oracle/product/10.2.0/rdbms/mesg/oraus.msb
lr-x------ 1 oracle oinstall 64 Jan 15 21:36 12 -> /dev/zero
lr-x------ 1 oracle oinstall 64 Jan 15 21:36 11 -> /dev/zero
lrwx------ 1 oracle oinstall 64 Jan 15 21:36 10 -> /home/oracle/oracle/product/10.2.0/rdbms/audit/ora_29975.aud
lr-x------ 1 oracle oinstall 64 Jan 15 21:36 1 -> /dev/null
lr-x------ 1 oracle oinstall 64 Jan 15 21:36 0 -> /dev/null
lrwx------ 1 oracle oinstall 64 Jan 15 21:36 20 -> /dev/sde
lrwx------ 1 oracle oinstall 64 Jan 15 21:36 19 -> /dev/sdb
lrwx------ 1 oracle oinstall 64 Jan 15 21:36 18 -> /dev/sdb
lrwx------ 1 oracle oinstall 64 Jan 15 21:36 17 -> /dev/sde
lrwx------ 1 oracle oinstall 64 Jan 15 21:36 16 -> /dev/sdc
[oracle@10gasm fd]$

通过strace lgwr进程,你可以看到lgwr进行会更新ACD信息,通过上面的offset转换,你可以发现4194304其实就是au 4,这就是说,lgwr进程更新了au 4,blk 0里面的信息,即就是ACD metadata。

如下是au 4,bllock 0在我进行操作前后的对比,通过resize 一个datafile离开进行观察:

SQL> alter database datafile 6 resize 10m;

Database altered.

++++++操作前
[oracle@10gasm fd]$ kfed read /dev/sdb aun=4 blkn=0 | more
kfbh.endian:                          1 ; 0x000: 0x01
kfbh.hard:                          130 ; 0x001: 0x82
kfbh.type:                            7 ; 0x002: KFBTYP_ACDC
kfbh.datfmt:                          1 ; 0x003: 0x01
kfbh.block.blk:                       0 ; 0x004: T=0 NUMB=0x0
kfbh.block.obj:                       3 ; 0x008: TYPE=0x0 NUMB=0x3
kfbh.check:                  1111747177 ; 0x00c: 0x4243ea69
kfbh.fcn.base:                        0 ; 0x010: 0x00000000
kfbh.fcn.wrap:                        0 ; 0x014: 0x00000000
kfbh.spare1:                          0 ; 0x018: 0x00000000
kfbh.spare2:                          0 ; 0x01c: 0x00000000
kfracdc.eyec[0]:                     65 ; 0x000: 0x41
kfracdc.eyec[1]:                     67 ; 0x001: 0x43
kfracdc.eyec[2]:                     68 ; 0x002: 0x44
kfracdc.eyec[3]:                     67 ; 0x003: 0x43
kfracdc.thread:                       1 ; 0x004: 0x00000001
kfracdc.lastAba.seq:         4294967295 ; 0x008: 0xffffffff
kfracdc.lastAba.blk:         4294967295 ; 0x00c: 0xffffffff
kfracdc.blk0:                         1 ; 0x010: 0x00000001
kfracdc.blks:                     10751 ; 0x014: 0x000029ff
kfracdc.ckpt.seq:                     2 ; 0x018: 0x00000002
kfracdc.ckpt.blk:                    45 ; 0x01c: 0x0000002d
kfracdc.fcn.base:                   698 ; 0x020: 0x000002ba
kfracdc.fcn.wrap:                     0 ; 0x024: 0x00000000
kfracdc.bufBlks:                     64 ; 0x028: 0x00000040

+++++++操作后
[oracle@10gasm tmp]$ kfed read /dev/sdb aun=4 blkn=0 | more
kfbh.endian:                          1 ; 0x000: 0x01
kfbh.hard:                          130 ; 0x001: 0x82
kfbh.type:                            7 ; 0x002: KFBTYP_ACDC
kfbh.datfmt:                          1 ; 0x003: 0x01
kfbh.block.blk:                       0 ; 0x004: T=0 NUMB=0x0
kfbh.block.obj:                       3 ; 0x008: TYPE=0x0 NUMB=0x3
kfbh.check:                  1111747072 ; 0x00c: 0x4243ea00
kfbh.fcn.base:                        0 ; 0x010: 0x00000000
kfbh.fcn.wrap:                        0 ; 0x014: 0x00000000
kfbh.spare1:                          0 ; 0x018: 0x00000000
kfbh.spare2:                          0 ; 0x01c: 0x00000000
kfracdc.eyec[0]:                     65 ; 0x000: 0x41
kfracdc.eyec[1]:                     67 ; 0x001: 0x43
kfracdc.eyec[2]:                     68 ; 0x002: 0x44
kfracdc.eyec[3]:                     67 ; 0x003: 0x43
kfracdc.thread:                       1 ; 0x004: 0x00000001
kfracdc.lastAba.seq:         4294967295 ; 0x008: 0xffffffff
kfracdc.lastAba.blk:         4294967295 ; 0x00c: 0xffffffff
kfracdc.blk0:                         1 ; 0x010: 0x00000001
kfracdc.blks:                     10751 ; 0x014: 0x000029ff
kfracdc.ckpt.seq:                     2 ; 0x018: 0x00000002
kfracdc.ckpt.blk:                    48 ; 0x01c: 0x00000030
kfracdc.fcn.base:                   718 ; 0x020: 0x000002ce
kfracdc.fcn.wrap:                     0 ; 0x024: 0x00000000
kfracdc.bufBlks:                     64 ; 0x028: 0x00000040

可以看到,其实变化的地方也就只有ckpt信息.(check等信息属于hash值,每隔3s都会更新一次)在strace 进程的同时,我也跟踪了asm_dbw0进程,其trace信息如下:

++++++++asm_dbwr0 trace
29996      0.000054 gettimeofday({1358315306, 860688}, NULL) = 0
29996      0.000056 times(NULL)         = 455756451
29996      0.000091 times(NULL)         = 455756451
29996      0.000100 pwrite64(20, "\1\202\17\1\1\0\0\0\4\0\0\0\310\200\17\1\314\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096, 49287168) = 4096
29996      0.000867 times(NULL)         = 455756451
29996      0.000096 times(NULL)         = 455756451
29996      0.000056 pwrite64(21, "\1\202\17\1\1\0\0\0\4\0\0\0\310\200\17\1\314\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096, 49287168) = 4096
29996      0.000619 times(NULL)         = 455756451
29996      0.000051 gettimeofday({1358315306, 862624}, NULL) = 0
29996      0.000059 gettimeofday({1358315306, 862684}, NULL) = 0
29996      0.000071 gettimeofday({1358315306, 862756}, NULL) = 0
29996      0.000055 gettimeofday({1358315306, 862810}, NULL) = 0
29996      0.000128 gettimeofday({1358315306, 862944}, NULL) = 0
29996      0.000064 gettimeofday({1358315306, 863002}, NULL) = 0
29996      0.000052 times(NULL)         = 455756451
29996      0.000049 gettimeofday({1358315306, 863102}, NULL) = 0
29996      0.000167 times(NULL)         = 455756451
29996      0.000078 times(NULL)         = 455756451
29996      0.000095 pwrite64(20, "\1\202\20\1\2\0\0\0\4\0\0\0\357\305\350.\313\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096, 49291264) = 4096
29996      0.000622 times(NULL)         = 455756451
29996      0.000047 times(NULL)         = 455756451
29996      0.000049 pwrite64(21, "\1\202\20\1\2\0\0\0\4\0\0\0\357\305\350.\313\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096, 49291264) = 4096
29996      0.000602 times(NULL)         = 455756452
29996      0.000049 gettimeofday({1358315306, 864812}, NULL) = 0

[oracle@10gasm tmp]$ cd /proc/29996/fd
[oracle@10gasm fd]$ ls -ltr
total 0
lr-x------ 1 oracle oinstall 64 Jan 15 23:05 0 -> /dev/null
lrwx------ 1 oracle oinstall 64 Jan 15 23:05 9 -> /home/oracle/oracle/product/10.2.0/dbs/hc_+ASM.dat
l-wx------ 1 oracle oinstall 64 Jan 15 23:05 8 -> /home/oracle/admin/+ASM/bdump/alert_+ASM.log
lrwx------ 1 oracle oinstall 64 Jan 15 23:05 7 -> /home/oracle/oracle/product/10.2.0/dbs/lkinst+ASM (deleted)
l-wx------ 1 oracle oinstall 64 Jan 15 23:05 6 -> /home/oracle/admin/+ASM/bdump/alert_+ASM.log
l-wx------ 1 oracle oinstall 64 Jan 15 23:05 5 -> /home/oracle/admin/+ASM/udump/+asm_ora_29975.trc
lr-x------ 1 oracle oinstall 64 Jan 15 23:05 4 -> /dev/null
lr-x------ 1 oracle oinstall 64 Jan 15 23:05 3 -> /dev/null
lrwx------ 1 oracle oinstall 64 Jan 15 23:05 21 -> /dev/sde
lrwx------ 1 oracle oinstall 64 Jan 15 23:05 20 -> /dev/sdb
lr-x------ 1 oracle oinstall 64 Jan 15 23:05 2 -> /dev/null
lrwx------ 1 oracle oinstall 64 Jan 15 23:05 19 -> /dev/sde
lrwx------ 1 oracle oinstall 64 Jan 15 23:05 18 -> /dev/sdb
lrwx------ 1 oracle oinstall 64 Jan 15 23:05 17 -> /dev/sdd
lrwx------ 1 oracle oinstall 64 Jan 15 23:05 16 -> /dev/sdc
lrwx------ 1 oracle oinstall 64 Jan 15 23:05 15 -> /home/oracle/oracle/product/10.2.0/dbs/lk+ASM
lrwx------ 1 oracle oinstall 64 Jan 15 23:05 14 -> /home/oracle/oracle/product/10.2.0/dbs/hc_+ASM.dat
lr-x------ 1 oracle oinstall 64 Jan 15 23:05 13 -> /home/oracle/oracle/product/10.2.0/rdbms/mesg/oraus.msb
lr-x------ 1 oracle oinstall 64 Jan 15 23:05 12 -> /dev/zero
lr-x------ 1 oracle oinstall 64 Jan 15 23:05 11 -> /dev/zero
lrwx------ 1 oracle oinstall 64 Jan 15 23:05 10 -> /home/oracle/oracle/product/10.2.0/rdbms/audit/ora_29975.aud
lr-x------ 1 oracle oinstall 64 Jan 15 23:05 1 -> /dev/null

通过offset 49291264,可以看出dbwr0进程是在更新au 47的前面2个block,这里通过kfed来观察一下。

[oracle@10gasm fd]$ kfed read /dev/sdb aun=47 blkn=0 | more
kfbh.endian:                          1 ; 0x000: 0x01
kfbh.hard:                          130 ; 0x001: 0x82
kfbh.type:                            9 ; 0x002: KFBTYP_COD_BGO
kfbh.datfmt:                          1 ; 0x003: 0x01
kfbh.block.blk:                       0 ; 0x004: T=0 NUMB=0x0
kfbh.block.obj:                       4 ; 0x008: TYPE=0x0 NUMB=0x4
kfbh.check:                    17400324 ; 0x00c: 0x01098204
kfbh.fcn.base:                        1 ; 0x010: 0x00000001
kfbh.fcn.wrap:                        0 ; 0x014: 0x00000000
kfbh.spare1:                          0 ; 0x018: 0x00000000
kfbh.spare2:                          0 ; 0x01c: 0x00000000
kfrcbg.size:                          0 ; 0x000: 0x0000
kfrcbg.op:                            0 ; 0x002: 0x0000
kfrcbg.inum:                          0 ; 0x004: 0x00000000
kfrcbg.iser:                          0 ; 0x008: 0x00000000
kfrcbg.data:                          0 ; 0x00c: 0x00000000

[oracle@10gasm fd]$ kfed read /dev/sdb aun=47 blkn=1 | more
kfbh.endian:                          1 ; 0x000: 0x01
kfbh.hard:                          130 ; 0x001: 0x82
kfbh.type:                           15 ; 0x002: KFBTYP_COD_RBO
kfbh.datfmt:                          1 ; 0x003: 0x01
kfbh.block.blk:                       1 ; 0x004: T=0 NUMB=0x1
kfbh.block.obj:                       4 ; 0x008: TYPE=0x0 NUMB=0x4
kfbh.check:                    17793224 ; 0x00c: 0x010f80c8
kfbh.fcn.base:                      716 ; 0x010: 0x000002cc
kfbh.fcn.wrap:                        0 ; 0x014: 0x00000000
kfbh.spare1:                          0 ; 0x018: 0x00000000
kfbh.spare2:                          0 ; 0x01c: 0x00000000
kfrcrb[0].opcode:                     0 ; 0x000: 0x0000
kfrcrb[0].inum:                       0 ; 0x002: 0x0000
kfrcrb[0].iser:                       0 ; 0x004: 0x00000000
kfrcrb[0].pnum:                       0 ; 0x008: 0x00000000
.......
从上面输出信息可以看出,asm_dbwr0进程会更新COD信息,这也将是我们下一篇内容的主题。

最后简单总结一下:

1. Active change dictectory,也就是asm元数据file 3,一共占据42个AU 大小,简称ACD. 每个asm实例对应一份ACD信息,换句话讲,你是双节点asm rac,那么就有84M的ACD数据,以此类推.(事实上不管你AU是多大ACD的信息都是固定的大小)

2. asm中ACD就类似数据库实例中的redo,记录asm元数据操作记录,以便于asm crash后进行instance recover.

3. ACD信息所在AU,第一个block是其元数据,后面的block是data信息.

4. ACD data的数据,跟redo的结构有点类似,里面记录的也是thread,sequence,len,opcode等信息.

5. ACD 数据的变化是通过asm lgwr进程来完成的,该进程跟数据库实例的lgwr进程类似,也存在一个3s check的机制。

--------------------------------------ORACLE-DBA----------------------------------------

最权威、专业的Oracle案例资源汇总之【学习笔记】Oracle ASM剖析系列(7)–Active Change Directory

本文由大师惜分飞原创分享,网址:http://www.oracleplus.net/arch/1406.html

Oracle研究中心

关键词:

ACD的功能

Active Change Directory

Oracle ASM学习笔记