oracle asm剖析系列(7)–Active Change Directory
本站文章除注明转载外,均为本站原创: 转载自love wife love life —Roger的Oracle/MySQL/PostgreSQL数据恢复博客
到这里为止,关于asm 的系列文章已经写了6篇,在这篇文章中将介绍Active Change Directory的结构。
何为ACD?大家如何把asm实例也看成一个微型的数据库实例的话,那么ACD信息,就好比是redo。换句话
将,ACD里面的信息,记录了asm的所有元数据block的操作记录。当然,有这个的好处是什么呢?
其实你可以想象,数据库实例中,如果实例crash掉,那么还可以借助redo去进行instance recover。
这里针对asm而已,ACD的功能有异曲同工之妙。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
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 ......... 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. SQL> |
这里需要说明的是,每一个asm实例,都用有其自己的ACD目录,换句话讲,如果你是双节点的rac,那么就有84m的ACD 目录信息。
如下是来自的的vm 11gR2 rac环境信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
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 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
[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中,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
[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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
[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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
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相关进程,来观察下相关的操作,已验证前面的提到的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
+++++++ 下面是 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离开进行观察:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
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信息如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
++++++++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来观察一下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
[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的机制。
Leave a Reply
You must be logged in to post a comment.