ASM通过自身的磁盘组来存储元数据(Metadata),使其成为可以自描述的体系,ASM的元数据分为两类,物理元数据(Physical Metadata)和虚拟元数据(Virtual Metadata),前者存储于磁盘的固定位置,通常在ASM磁盘头;后者存储在ASM文件上,和常规ASM文件一样在所有磁盘之间均衡分布。ASM元数据不以AU为单位,而是以4K为单位进行存储,ASM实例的元数据由ASM自行维护,RDBMS实例不能访问和读写ASM元数据。
固定物理元数据的位置非常重要,因为ASM的初始化要依赖这个元数据,一般会占用磁盘组的前两个AU,其组成内容包括:Disk Header、Allocation Table (AT)、Free Space Table (FST)和Partnership Status Table (PST)。
每个ASM磁盘都有一个磁盘头(Disk Header),占用ASM磁盘第一个AU的第一个数据块,可以通过Oracle提供的工具kfed来查看磁盘头记录的ASM信息,缺省的这个工具并未提供,手工link库文件之后可以获得这个实用工具,但是这个工具的使用应当谨慎。
以下是使用kfed读取磁盘头的摘要输出信息,可以看到重要信息如块大小为4K,AU大小为1M,扇区大小为512 Byte :
[oracle@db210-rac1 oracle]$ kfed read /dev/rdsk/asmdata aun=0 kfbh.endian: 0 ; 0x000: 0x00 kfbh.hard: 130 ; 0x001: 0x82 kfbh.type: 1 ; 0x002: KFBTYP_DISKHEAD –〉类型,Disk Header 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: 3581262102 ; 0x00c: 0xd575b916 kfdhdb.driver.provstr: ORCLDISK ; 0x000: length=8 kfdhdb.compat: 168820736 ; 0x020: 0x0a100000 kfdhdb.dsknum: 0 ; 0x024: 0x0000 kfdhdb.grptyp: 1 ; 0x026: KFDGTP_EXTERNAL kfdhdb.hdrsts: 3 ; 0x027: KFDHDR_MEMBER kfdhdb.dskname: DATADG_0000 ; 0x028: length=11 kfdhdb.grpname: DATADG ; 0x048: length=6 kfdhdb.fgname: DATADG_0000 ; 0x068: length=11 kfdhdb.capname: ; 0x088: length=0 kfdhdb.crestmp.hi: 32938926 ; 0x0a8: HOUR=0xe DAYS=0x1d MNTH=0x6 YEAR=0x7da kfdhdb.crestmp.lo: 776479744 ; 0x0ac: USEC=0x0 MSEC=0x209 SECS=0x24 MINS=0xb kfdhdb.mntstmp.hi: 32951761 ; 0x0b0: HOUR=0x11 DAYS=0xe MNTH=0x3 YEAR=0x7db kfdhdb.mntstmp.lo: 1560528896 ; 0x0b4: USEC=0x0 MSEC=0xf2 SECS=0x10 MINS=0x17 kfdhdb.secsize: 512 ; 0x0b8: 0x0200 kfdhdb.blksize: 4096 ; 0x0ba: 0x1000 kfdhdb.ausize: 1048576 ; 0x0bc: 0x00100000 kfdhdb.mfact: 113792 ; 0x0c0: 0x0001bc80 kfdhdb.dsksize: 15360 ; 0x0c4: 0x00003c00 kfdhdb.pmcnt: 2 ; 0x0c8: 0x00000002 kfdhdb.fstlocn: 1 ; 0x0cc: 0x00000001 kfdhdb.altlocn: 2 ; 0x0d0: 0x00000002 kfdhdb.f1b1locn: 2 ; 0x0d4: 0x00000002
在Disk Header之后,紧接着分配的是Allocation Table,每个ASM磁盘都有一个分配表(AT),用于跟踪磁盘中空间的分配情况,其中包含ATE(Allocation Table Entry)数据结构用于跟踪磁盘中每个分配的AU。Free Space Table (FST)用于存放未被使用的AU信息。
以下kfed读取AU 0的第二个数据块(块号为1)就是FST的信息:
[oracle@db210-rac1 oracle]$ kfed read /dev/rdsk/asmdata aun=0 blkn=1|more kfbh.endian: 0 ; 0x000: 0x00 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 kfbh.check: 2164173679 ; 0x00c: 0x80feab6f
第二个数据块是AT信息:
[oracle@db210-rac1 oracle]$ kfed read /dev/rdsk/asmdata aun=0 blkn=2|more kfbh.endian: 0 ; 0x000: 0x00 kfbh.hard: 130 ; 0x001: 0x82 kfbh.type: 3 ; 0x002: KFBTYP_ALLOCTBL kfbh.datfmt: 1 ; 0x003: 0x01 kfbh.block.blk: 2 ; 0x004: T=0 NUMB=0x2
PST则用于跟踪磁盘的成员和伙伴关系,占用每个磁盘的第二个AU:
[oracle@db210-rac1 oracle]$ kfed read /dev/rdsk/asmdata aun=1 blkn=0|more kfbh.endian: 0 ; 0x000: 0x00 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 kfbh.check: 2889623470 ; 0x00c: 0xac3c27ae kfbh.fcn.base: 0 ; 0x010: 0x00000000
其最后一个数据块被保留用于磁盘组心跳(Heartbeat),防止磁盘组被不同集群同时加载,同RAC一样,ASM依赖CSS(Cluster Synchronization Services)机制防止集群中的脑裂(split brain),而PST心跳是防止集群间Split brain的一个补充机制,就如同RDBMS通过持续写控制文件心跳信息来防止集群外实例加载数据库一样。
以下就是读取AU 1,第256块获得的心跳信息:
[oracle@db210-rac1 oracle]$ kfed read /dev/rdsk/asmdata aun=1 blkn=255 kfbh.endian: 0 ; 0x000: 0x00 kfbh.hard: 130 ; 0x001: 0x82 kfbh.type: 19 ; 0x002: KFBTYP_HBEAT kfbh.datfmt: 1 ; 0x003: 0x01 kfbh.block.blk: 511 ; 0x004: T=0 NUMB=0x1ff kfbh.block.obj: 2147483648 ; 0x008: TYPE=0x8 NUMB=0x0 kfbh.check: 457645533 ; 0x00c: 0x1b471ddd kfbh.fcn.base: 0 ; 0x010: 0x00000000 kfbh.fcn.wrap: 0 ; 0x014: 0x00000000 kfbh.spare1: 0 ; 0x018: 0x00000000 kfbh.spare2: 0 ; 0x01c: 0x00000000 kfdpHbeatB.instance: 2 ; 0x000: 0x00000002 kfdpHbeatB.ts.hi: 32952240 ; 0x004: HOUR=0x10 DAYS=0x1d MNTH=0x3 YEAR=0x7db kfdpHbeatB.ts.lo: 2325458944 ; 0x008: USEC=0x0 MSEC=0x2ec SECS=0x29 MINS=0x22 kfdpHbeatB.rnd[0]: 4059330942 ; 0x00c: 0xf1f4797e kfdpHbeatB.rnd[1]: 1876288114 ; 0x010: 0x6fd5e272 kfdpHbeatB.rnd[2]: 4148064770 ; 0x014: 0xf73e7202 kfdpHbeatB.rnd[3]: 2042075551 ; 0x018: 0x79b7999f
物理元数据用于描述磁盘组的组成、空间分配等内容,而虚拟元数据则用于记录ASM文件在磁盘组上的分布,就如同inode信息一样。虚拟元数据也存储在ASM文件中,和其他ASM文件的分布管理完全相同。
在ASM模式下,ASM元数据文件占用了0~255个文件号,所以其他数据文件的ASM文件号是从256开始的:
SQL> select count(*),max(file_number),min(file_number) from v$asm_file; COUNT(*) MAX(FILE_NUMBER) MIN(FILE_NUMBER) ---------- ---------------- ---------------- 57 312 256 SQL> select * from v$asm_file where file_number=256; GROUP_NUMBER FILE_NUMBER COMPOUND_INDEX INCARNATION BLOCK_SIZE BLOCKS ------------ ----------- -------------- ----------- ---------- ---------- BYTES SPACE TYPE REDUND STRIPE CREATION_DAT MODIFICATION ---------- ---------- --------------- ------ ------ ------------ ------------ 1 256 16777472 3 8192 6401 52436992 53477376 DATAFILE UNPROT COARSE 08-APR-05 08-APR-05
最常见的虚拟元数据信息包含:File Directory、Disk Directory、Active Change Directory (ACD)、Continuing Operations Directory (COD)、Template Directory、Alias Directory、Attribute Directory、Staleness Directory、Staleness Registry等。
虚拟元数据中最首要的信息是File Directory,该目录记录了所有ASM File的元数据,每个ASM File在其中有一条记录,包含Incarnation number、File size、File block size、File type、Redundancy 、Striping 、File creation time、File modification time、File layout等信息。
ASM自身的元数据也是通过File Directory来管理的,第一个文件从AU 2开始:
SQL> select disk_kffxp, AU_kffxp, xnum_kffxp 2 from x$kffxp where group_kffxp=1 and number_kffxp =1; DISK_KFFXP AU_KFFXP XNUM_KFFXP ---------- ---------- ---------- 0 2 0 0 93 1
其类型即为FILEDIR:
[oracle@db210-rac1 oracle]$ kfed read /dev/rdsk/asmdata aun=2 blkn=1|more kfbh.endian: 0 ; 0x000: 0x00 kfbh.hard: 130 ; 0x001: 0x82 kfbh.type: 4 ; 0x002: KFBTYP_FILEDIR kfbh.datfmt: 1 ; 0x003: 0x01 kfbh.block.blk: 1 ; 0x004: T=0 NUMB=0x1 kfbh.block.obj: 1 ; 0x008: TYPE=0x0 NUMB=0x1 kfbh.check: 4266719718 ; 0x00c: 0xfe50f9e6 kfbh.fcn.base: 820 ; 0x010: 0x00000334 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
可以通过如下查询汇总ASM文件占用的空间情况:
SQL> select number_kffxp file#, disk_kffxp disk#, count(disk_kffxp) extents 2 from x$kffxp 3 where group_kffxp=1 4 group by number_kffxp, disk_kffxp 5 order by file#; FILE# DISK# EXTENTS ---------- ---------- ---------- 1 0 2 2 0 1 3 0 85 4 0 2 5 0 1 6 0 1 256 0 16 257 0 105 258 0 105 259 0 302 260 0 182 261 0 912 262 0 102 263 0 182 264 0 820 265 0 105 266 0 105
File Directory中最重要的信息是文件存储形式(File Layout),该结构描述ASM文件的空间分布,类似Inode的结构,是通过几级指针来完成的,File Directory包含一个文件前60个Extent指针,称为一级区(direct extents),接下来是二级区(indrect extent),每个二级区占用一个AU,可以包含300个二级区指针,每个二级区指针指向一个其他的“一级区”,这个“一级区”包含指向具体磁盘AU的指针,如下图所示:
这个结构与常规文件系统非常类似,对于以下介绍的UFS文件系统,inode也包括2类指针:直接指针(Direct Pointers)和间接指针(Indirect Pointers)
1. 直接指针
共有12个对数据块直接访问的直接指针,按照8k的块大小分配。
这12个直接指针可以为一直到96K(12x8k=96k)字节的容量的文件直接引用数据块。
2. 间接指针
有3种类型的间接指针:
一级间接指针:一个一级间接指针使用一个文件系统块记录到数据块的指针。这个文件系统块包含2048个8K字节数据块的附加地址(即2048个指针),可以用以标示和定位16M字节的数据。
二级间接指针:一个二级间接指针使用一个文件系统块进行空间扩展。一个文件系统块记录2048个指针,每个指针指向下一级间接指针,每个二级间接指针可以继续定位2048个数据块。由此,二级间接指针可以指向的32G字节的数据。
三级间接指针:类似的一个三级间接指针可以查找超过70T字节的数据。可是,在一个ufs文件系统中的最大的文件容量是1T。
通过下图我们可以直观的看到inode的层次及结构:
以下是Solaris中,UFS文件系统下,一个大文件的inode信息输出:
# filestat /home/rmc/bigfile Inodes per cyl group: 64 Inodes per block: 64 Cylinder Group no: 0 Cylinder Group blk: 64 File System Block Size: 8192 Device block size: 512 Number of device blocks: 204928 Start Block End Block Length (Device Blocks) ----------- ----------- ---------------------- 66272 -> 66463 192 66480 -> 99247 32768 1155904 -> 1188671 32768 1277392 -> 1310159 32768 1387552 -> 1420319 32768 1497712 -> 1530479 32768 1607872 -> 1640639 32768 1718016 -> 1725999 7984 1155872 -> 1155887 16 Number of extents: 9 Average extent size: 22769 Blocks
我们可以看到,第一个extent分配了192个操作系统块(512bytes/os block),192x512/1024=96k,正好是inode的一级块。而此后的6个extent都是32768个os block,正好是16M。
经过持续不断地发展演进,ASM已经成为了一个复杂的文件系统,和其他文件系统没有本质上的差异。最后总结一下,ASM的元数据是这样构成:
Oracle 10g/11g共有的元数据包括:
Disk header,Allocation table ,Free space table ,Partnership and status table ,File directory ,Disk directory ,Active change directory ,Continuing operations directory ,Template directory ,Alias directory
Oracle 11g新增的:
AVD volume file directory ,Disk free space directory ,Attributes directory,ASM User directory ,ASM user group directory ,Staleness directory
ASM实例会维护上述ASM元数据的完整和有效性,上述元数据对ASM实例来说至关重要,如果一旦出现问题,处理起来将会非常棘手。所以如果可能ASM元数据至少镜像3份,以保证安全。