重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
创新互联建站网站建设公司是一家服务多年做网站建设策划设计制作的公司,为广大用户提供了成都网站制作、成都网站设计、外贸营销网站建设,成都网站设计,1元广告,成都做网站选创新互联建站,贴合企业需求,高性价比,满足客户不同层次的需求一站式服务欢迎致电。
市场占有率
ASM自动存储管理技术已经面世10多个年头,目前已经广泛使用于各个领域的数据库存储解决方案。 到2014年为止,ASM在RAC上的采用率接近60%,在单机环境中也超过了25%。
RAC集群环境中3种存储解决方案: ASM、集群文件系统和裸设备; 虽然仍有部分用户坚持使用古老的裸设备,但随着版本的升级,更多用户开始采用ASM这种ORACLE提供的免费解决方案。
在国内使用ASM的场景一般均采用 External Redundancy(11gR2除了存放ocr/votedisk 的DG外)。 一般在10.2.0.5和11.2.0.2之后的版本上ASM,还是较为稳定的。
下图为部分在产品环境中使用ASM的国外知名企业:
ASM FILE
ORACLE RDBMS Kernel内核与ASM在高层交互是基于ASM中存放的文件即ASM FILE。 这和ORACLE RDBMS去使用文件系统或其他逻辑卷的方式没有什么区别。 ASM中可以存放 数据文件,日志文件,控制文件,归档日志等等,对于数据库文件的存放基本和文件系统没啥2样。
一个ASM FILE的名字一般以一个”+”和DiskGroup名字开头。 当ORACLE RDBMS KERNEL内核的文件I/O层碰到一个以”+”开头的文件时,就会走到相关ASM的代码层中 而不是调用依赖于操作系统的文件系统I/O。 仅仅在File I/O层面才会认识到这是一个ASM 中的文件,而其上层的内核代码看来ASM FILE和OS FILE都是一样的。
ASM对ROWID和SEGMENT等RDBMS元素没有影响,不过是数据文件存放在ASM中,ASM并不会打破ORACLE数据库中的这些经典元素。
在一个ASM Diskgroup中仅仅允许存放已知的ORACLE文件类型。假设一个文件通过FTP拷贝到ASM Diskgroup中,则该文件的第一个块将被检验以便确认其类型,以及收集其他信息来构建这个文件的完整ASM文件名。 如果其文件头无法被识别,则该文件在DiskGroup中的创建将会报错。
仅有以下的文件类型可以存放在ASM Diskgroup中:
ORACLE 的2进制可执行文件和ASCII文件,例如alert.log和其他trace文件,则不推荐也不能存放在ASM Diskgroup里。
File Blocks
所有被ASM所支持的文件类型仍以其file block作为读和写的基本单位。在ASM中的文件仍保持其原有的 Block Size 例如 Datafile 仍是 2k~32k(默认8k),ASM并不能影响这些东西。
值得一提的是在ASM FILE NUmber 1 的FILEDIR中记录了每一种FILE TYPE对应的BLOCK SIZE,例如:
kfbh.endian: 1 ; 0x000: 0x01 kfbh.hard: 130 ; 0x001: 0x82 kfbh.type: 4 ; 0x002: KFBTYP_FILEDIR kfbh.datfmt: 1 ; 0x003: 0x01 kfbh.block.blk: 256 ; 0x004: blk=256 kfbh.block.obj: 1 ; 0x008: file=1 kfbh.check: 567282485 ; 0x00c: 0x21d00b35 kfbh.fcn.base: 220023 ; 0x010: 0x00035b77 kfbh.fcn.wrap: 0 ; 0x014: 0x00000000 kfbh.spare1: 0 ; 0x018: 0x00000000 kfbh.spare2: 0 ; 0x01c: 0x00000000 kfffdb.node.incarn: 838529807 ; 0x000: A=1 NUMM=0x18fd7987 kfffdb.node.frlist.number: 4294967295 ; 0x004: 0xffffffff kfffdb.node.frlist.incarn: 0 ; 0x008: A=0 NUMM=0x0 kfffdb.hibytes: 20 ; 0x00c: 0x00000014 kfffdb.lobytes: 8192 ; 0x010: 0x00002000 kfffdb.xtntcnt: 35488 ; 0x014: 0x00008aa0 kfffdb.xtnteof: 35488 ; 0x018: 0x00008aa0 kfffdb.blkSize: 8192 ; 0x01c: 0x00002000 kfffdb.flags: 17 ; 0x020: O=1 S=0 S=0 D=0 C=1 I=0 R=0 A=0 kfffdb.fileType: 2 ; 0x021: 0x02 kfffdb.dXrs: 17 ; 0x022: SCHE=0x1 NUMB=0x1 kfffdb.iXrs: 17 ; 0x023: SCHE=0x1 NUMB=0x1 kfffdb.dXsiz[0]: 20000 ; 0x024: 0x00004e20
这里的kfffdb.blkSize即是 一个数据文件的Block Size。
由于这个blocksize 总是2的次方,所以一个block总是在 一个AU allocation Unit中,而不会跨2个AU。
Data Extents
数据盘区Data Extents 是裸的存储,用以存放文件内容。每一个Data Extent在 11g之前对应某一个ASM disk上的一个Allocation Unit , 在11g之后 一个Extent可以对应多个AU,具体见《【Oracle ASM】Variable Extent Size 原理》。
Extent Map
Extent Map盘区图是盘区指针的列表,这些指针将支出所有属于一个文件的数据盘区。这些盘区是真正存放数据的裸存储空间。每一个盘区指针给出其所在的磁盘号和AU信息。为了保证可信,每一个盘区指针也会包含一个checksum byte来确认本指针未损坏。当这个checksum值和实际存放的Extent信息不匹配时可能出现ORA-600错误,例如ORA-00600: internal error code, arguments: [kffFdLoadXmap_86], [256], [0], [1], [68], [54], [29], [], [], [], [], []。
Virtual Data Extents
虚拟数据盘区 Virtual Data Extent是几个data extent的集合,这些data Extent中包含了相同的数据。 镜像Mirror是在虚拟Extent级别实现的。每一个虚拟extent为文件块提供一个盘区地址空间。每一个写入到文件块均是写入到一个虚拟extent中每一个Online在线的data extent中。 每一个对文件块的读取也是被重定位到一个虚拟extent中的主镜像extent (primary Extent),除非primary extent所在Disk被OFFLINE了。 对于没有冗余度(即external redundancy disk group上的FILE)的文件而言,一个虚拟Extent实际就是一个data Extent。
对于Normal redundancy+普通数据库文件而言, 一个虚拟Extent实际就是2个Data Extent。
对于High redundancy+普通数据库文件而言, 一个虚拟Extent实际就是3个Data Extent。
粗粒度条带化Coarse Grain Striping
粗粒度条带化就是对虚拟data Extent的简单联接。类似于传统卷管理器使用1MB作为stripe size。
细粒度条带化Fine Grain Striping
细粒度与粗粒度的区别在于,文件块不是线性地布局在每一个虚拟Extent上,而是文件将以1/8个虚拟Extent成长,由此文件块被在diskgroup内以1/8的条带化深度分布。 由此当该文件的block size 为8k,则block 0~15在虚拟Virtual Extent 0上面,而block 16-31 在Vritual Extent 1上面,blocks 112-127在vritual extent 7, block 128-143在block 0-15之后仍在virtual extent 0上。
File Templates
File Template文件模板当文件被创建时用以指定 条带化 (coarse 或 FINE) 和冗余度(external, normal, high)。 ORACLE默认已经为每一个ORACLE数据库文件提供了默认模板。可以修改默认模板 也可以客制化模板。修改模板只影响新创建的文件,而不是现有文件。 创建文件时可以指定使用某一个模板。
默认的模板如下:
Failure Group
ASM提供冗余,failure group用来保证单点错误不会造成同一数据的多份拷贝同时不可用。 如果ASM使用的多个ASM DISK LUN属于同一硬件 例如同一磁盘阵列,该硬件故障会导致这多个盘均不可用,则该硬件的失败应当被容错, 在ASM中一般将这些盘规划到同一个failure group中。多份冗余拷贝不会存放在同一个failure group的磁盘中,换句话说一个failure group中只有一份数据的拷贝,不会有第二份。
由于Failure Group的配置很大程度上与用户的本地规划有关,所以ASM允许用户自己指定Failure group的规划、组成。 但是如果用户自己没有指定Failure Group的规划,那么ASM会自动分配磁盘到必要的Failure Group。
使用External Redundancy的Diskgroup没有Failure Group。Normal redundancy Disk Groups要求至少2个Failure Group,High Redundancy Disk Groups要求3个Failure Group。
如果Normal redundancy Disk Groups中有多于2个的Failure Group,例如 Failure Group A、B、C,则一个Virtual Extent会自动在A、B、C之间找2个Failure Group存放2个mirror extent,不会存放3份拷贝。
High Redundancy Disk Groups与之类似。
实际上,国内对ASM的运行,绝大多数不依赖于ASM实现redundancy,而是使用 External Redundancy的, 在Maclean遇到的场景中External Redundancy占了70%以上。
实际应用中 Normal/High一般会和多个存储控制器Controller 结合来分配failure group,或者存在多路存储可用。
以下为一个示例, 一个normal redundancy 的Diskgroup 中存在8个Disk,并使用2个Failure Group:
当磁盘Disk H失败,这个失败要求在失败磁盘上所有的Extent均被修复, Extent 3和5会从现存的拷贝中复制到Failgroup 2 中可用的区域。在此例子中,Extent 5被从Disk A拷贝到Disk F,extent 3从Disk C 拷贝到Disk G,最后还会将失败的磁盘从Diskgroup中drop出去。
Disk Partners
Disk Partnership是一种基于2个磁盘之间的对称关系,存在于high 或 normal的redundancy diskgroup中。Diskgroup中的Disk与同一个Diskgroup内的其他几个disk组成结伴关系。ASM会自动创建和维护这种关系。镜像拷贝数据仅仅在已经与主数据镜像primary data extent组成partners关系的磁盘上分配。
Disk partnering用来减少由于同时2个磁盘故障导致的数据丢失的概率。原因在于当ASM配置中使用了较多的磁盘时(例如上千个),如果如果数据镜像是随机寻找次级磁盘来存放镜像拷贝,当2个磁盘丢失时有较大概率丢失数据。原因是如果采取随机存放镜像数据的话,出现数据的 primary和镜像数据同时存在于2个正好失败的磁盘上的概率是很高的。 如果我们不采取disk partnering,2个磁盘失败所造成的数据丢失的概率大大增加。
Disk partnering策略限制了用来保护某个磁盘数据拷贝的磁盘数目。ASM为一个磁盘限制了disk partners的总数为8。 这个数目越小,则双磁盘同时失败造成数据丢失概率越小。 但是这个数目越小,也会造成其他不便。所以ORACLE ASM研发团队最终选择了8这个数字。
ASM从本disk所在Failure group之外的FG 中挑选partners disk,由于一个ASM DISK有多个partners,所以其多个partners disk可能有的在同一个failure Group中。Partners被尽可能多的选择在不同的Failure Group中,这样做的目的也很明确,提高磁盘失败时的容错能力。askmaclean.com
如果一个ASM DISK失败了,其保护的extents可以通过其partners来重建。由于有多个partners所以其额外的I/O负载是在多个ASM disk中均衡损耗的。 这减少了修复故障的失败时间,因为更多的磁盘参与进来,可以获得更高的I/O吞吐量,所以加快了重构丢失数据镜像的速度。Partners被尽可能多的选择在不同的Failure Group中,这样做可以让重建丢失磁盘的负载均匀分布在尽可能多的硬盘资源上。 以上这些考虑均是基于同时不会有2个failgroup同时失败这个前提假设。
注意Partnering不是分区partitioning,Partnering仅仅是一种对称关系。如果Disk A将Disk B列出partner,则相对地Disk B也将Disk A列为partner。 但是partnering不是一种临时的关系。 同时假设disk A 和 Disk B是partners, 而Disk B和Disk C也是partners, 但这并不代表A和C是partners。
实际如果对partnering relationship有足够的传递性则可能表现为分区,如下图中的例子。但是分区仅仅是partnering可以提供的一种可能性。
partitioning分区仅仅是Partnering的特殊表现,Partnering本身已经能够保证在Disk磁盘以不规则的几何安排方式组织时仍能同一负载均衡,其移除了当额外的容量需要增加到现有系统时的许多限制。当然这仍不能保证在所有配置下都很完美,但ASM会基于现有给定的配置采取最佳的方案。
下面为一个Partning的例子:
ASM mirror 保护
ASM mirror 镜像保护可避免因丢失个别磁盘而丢失数据。每一个文件均有自己的ASM镜像策略属性, 对于该文件所辖的所有virtual extent来说同样基于该镜像策略。文件创建时会设置这个镜像策略属性,今后都无法修改。 ASM镜像要比操作系统镜像磁盘要来的灵活一些,至少它可以在文件级别指定需要的冗余度。
ASM mirror区分镜像extent的primary和secondary拷贝,但在更新extent时会同时写所有的拷贝镜像。 ASM总是先尝试读取primary 拷贝,仅当primary拷贝不可用时去读取secondary拷贝。
ASM metadata
Asm Metadata是存在于ASM disk header用以存放ASM Diskgroup 控制信息的数据,Metadata包括了该磁盘组中有哪些磁盘,多少可用的空间,其中存放的File的名字,一个文件有哪些Extent等等信息。
由于Asm metadata就存放在ASM DISK HEADER,所以ASM disk group是自解释的。所有的metadata元数据均存放在一个个metadata block中(默认block size 4096)。这些信息包括该metadata block的类型以及其逻辑位置。同样有checksum信息来确认block是否被损坏。所有的metadata block均是4k大小。实际使用时ASM实例会缓存这些ASm metadata。askmaclean.com
ASM Instance
ASM instance的主要任务之一就是管理ASM metadata元数据; ASM Instance类似于ORACLE RDBMS INSTANCE 有其SGA和大多数主要后台进程。在10.2中使用与RDBMS一样的2进制软件,到11.2中分家。但ASM instance加载的不是数据库,而是Disk Group; 并负责告诉RDBMS database instance必要的ASM 文件信息。 ASM实例和DB实例均需要访问ASM DISK。 ASM实例管理metadata元数据,这些元数据信息足以描述ASM 中的FILE的信息。 数据库实例仍旧直接访问文件,虽然它需要通过ASM实例来获得例如 文件Extent Map 盘区图等信息,但I/O仍由其自行完成,而不是说使用了ASM之后DB的文件I/O需要通过ASM来实现; 其仅仅是与ASM instance交互来获得文件位置、状态等信息。
有一些操作需要ASM实例介入处理,例如DB实例需要创建一个数据文件,则数据库服务进程直接连接到ASM实例来实现一些操作; 每一个数据库维护一个连接池到其ASM实例,来避免文件操作导致的反复连接。
ASM metadata通过一个独立的ASM实例来管理以便减少其被损坏的可能。ASM instance很相似于db instance,虽然它一般只使用ORACLE KERNEL内核的一小部分代码,则其遇到bug或导致buffer cache讹误或者写出讹误到磁盘的概率由此比DB实例要小。 数据库实例自己从来不更新ASM metadata。ASM metadata中每一个指针一般都有check byte以便验证。
和DB RAC一样,ASM instance 自己可以被集群化,一样是使用ORACLE Distributed Lock Manager(DLM)分布式锁管理器架构。在一个集群中每一个节点上可以有一个ASM instance。如果一个节点上有多个数据库、多个实例,则他们共享使用一个ASM instance 。
如果一个节点上的ASM instance失败了,则所有使用该ASM instance 均会失败。但其他节点上的ASM和数据库实例将做recover并继续操作。
Disk Discovery
Disk Discovery磁盘发现是指从OS层面找到那些ASM值得访问的磁盘。也用来找到那些需要被mount的diskgroup名下的磁盘ASM DISK,以及管理员希望将其加入到diskgroup中的Disk,或管理员会考虑将其加入到diskgroup的Disk。Discovery 使用一个discovery string( asm_diskstring)作为输入参数,并返回一系列可能的DISK。注意一个是要指定asm_diskstring,另一个是要求这些disk的权限可以被oracle/grid用户使用。精确的asm_diskstring discovery语法取决于操作系统平台和ASMLIB库。OS可接受的路径名生成的匹配,一般对于discovery strings也是可用的。一般推荐这个路径名下最好只有ASM Disk,来避免管理上的问题。
ASM实例会打开和读取由asm_diskstring指定的路径名匹配到的每一个文件并读取前4k的block, 这样做的目的是判断disk header的状态;如果它发现这是一个ASM disk header则会认为这是一个可以mount的diskgroup的一部分。如果发现这4k的block其无法识别,则认为该disk可以加入到ASM diskgroup中(candidate)。
ASM实例需要通过一个初始化参数来指定这个discovery strings,实际就是asm_diskstring; 注意 asm_diskstring中可以加入多个路径字符串,例如 ‘/dev/raw*’,’/dev/asm-disk*’ ; 同样的磁盘不会被发现2次(除非你欺骗ASM)。 在RAC cluster中如果一个磁盘不是在整个cluster范围内都可见,那么这个磁盘无法被加入到RAC的ASM DISKGROUP 中。 在实际使用中每一个节点上的磁盘名字可以不一样,但其实际介质要被操作系统识别,但是实际MACLEAN也强烈建议你保持每个节点上磁盘的名字一样,否则管理很麻烦。 所以这里引入UDEV等规则是有必要的。
Disk Group Mount 加载磁盘组
在数据库实例可以用Diskgroup上的文件之前,需要ASM实例去 mount 这个本地diskgroup。 Mount Diskgroup牵扯到发现所有的磁盘并找到上面已经有metadata数据的disk,并尝试将对应到一个diskgroup的DISK mount起来。 能 mount起来的前提还需要验证metadata来确保现在已经有足够数量的磁盘在哪里,例如使用3个DISK创建的external diskgroup ,当前OS下面只挂了2个Disk,则显然不能mount这个diskgroup。 之后还需要初始化SGA以便之后更新和管理这些metadata。
可以显示地去dismount一个diskgroup,但是如果diskgroup上的文件正在被client (例如DB)使用则dismount会报错。如果在ASM冗余算法容错能力内丢失磁盘,则不会导致diskgroup被强制dismount。但是如果超出了容错能力则会被强制dismount。 这种强制dismount会导致使用其上文件的DB instance被kill。
Disk ADD 增加磁盘
加入一个磁盘到现有的Diskgroup 来扩空间和增加吞吐量是很常见的需求。最简单的加入磁盘命令如 : alter diskgroup Data add disk ‘/dev/asm-disk5’; 如前文所述在RAC cluster中如果一个磁盘不是在整个cluster范围内都可见,那么这个磁盘无法被加入到RAC的ASM DISKGROUP 中。
如果add disk指定的磁盘的disk header发现了其他diskgroup的信息或者操作系统的一些信息,则需要alter diskgroup Data add disk ‘/dev/asm-disk5’ force ; 加入FORCE选项。实际使用中尽可能避免使用FORCE选项。
需要注意的事add disk命令返回后只代表disk header已经完成必要的metadata写入,但不代表该磁盘已经完成了rebalance操作。后续的rebalance会被引发并移动数据到新加入的磁盘中。一般推荐如果你要加入多个ASM DISK,那么在同一时间加入,而不是分多次加入。 但是一般不推荐同时做add disk和drop disk。
Disk Drop踢盘
可以从现有的Diskgroup里drop出disk,这些disk可以用作它途;当然由于asm disk失败,导致ASM实例自动drop 该失败的asm disk也是常见的。若一个ASM DISK常发生一些非致命的错误,则一般推荐将该Disk drop出来,以避免如果某天发生真的磁盘失败导致可能的数据丢失。 但是需要注意drop disk时 不要指定其路径名,而是指定ASM DISK NAME。
drop disk命令可能较短时间内返回,但是diskgroup必须完成rebalance后这个磁盘才能被挪作他用。rebalance将读取即将被drop掉disk的数据,并拷贝这些数据到其他磁盘上。FORCE选项可以用于避免读取该正被drop的磁盘。该FORCE选项当磁盘发生失败或磁盘确实需要立即被挪用。原来那些需要被拷贝的extent,使用FORCE选项后会从冗余的备份中读取,所以external redundancy不支持使用FORCE选项。当然如果使用FORCE选项最后会导致在NORMAL/HIGH冗余的Diskgroup下造成数据丢失的话,则FORCE选项也将不可用。
DROP DISK NOFORCE:
DROP DISK FORCE:
对磁盘的写入如果发生了严重的错误那么也会导致ASM自动强制去DROP该Disk。如果该disk的drop会造成数据丢失,那么diskgroup被强制dismount,该dismount也会造成数据库实例被kill。
Rebalance
rebalance diskgroup将在diskgroup范围内将数据在其DISK上移动,以保证文件们均匀分布在diskgroup中的所有磁盘上,同时也会考虑到每一个ASM DISK的大小。 当文件均匀地分布在所有磁盘上,则各个磁盘的使用量也会很接近。如此以保证负载均衡。rebalance的算法既不基于I/O统计信息也不基于其他统计结果; 完全取决于Diskgroup中disk的大小。
一旦diskgroup中发生了一些存储配置变化 例如disk add/drop/resize均会自动触发一次rebalance。power参数将决定有多少slave进程并发参数数据移动。所有的slave进程均从发生rebalance的实力启动并工作。rebalance可以手动调控,即便已经在进行一次rebalance中了,也可以指定其他节点上的实例做rebalance,只要管路员想要这样做。如果实例意外crash,那么未结束的rebalance将自动重新启动。
注意rebalance中的每一次extent 移动均会与数据库实例做协调,因为数据库实例可能同时需要读取或者写这个 extent,所以数据库在rebalance 同时能正常工作。 其对数据库的影响一般较小,原因是同一时间只有一个extent被锁定以便移动,且仅仅是阻塞写入。
ASMLIB
ASMLIB是通过在Linux上安装asmlib包来提供标准I/O接口,以便ASM发现和访问ASM disk。 关于ASMLIB详见:
关于udev与asmlib 以及Multipath的问题,提问前先看这个
Disk Header
一个ASM DISK的最前面4096字节为disk header,对于ASM而言是block 0 (blkn=0);许多操作系统会保留LUN的第一个block来存放分区表或其他OS信息。 一般不让ASM基础到这个block,因为ASM会毫不犹豫地覆盖这个block。在一些指定的平台上ORACLE从代码层跳过这些操作系统块,但实际操作时一般的惯例是只给ASM用那些上面没有分区表的LUN DISK。
对于这一点详细的展开是,例如你在AIX操作系统上使用PV作为ASM DISK,则PV上不能有PVID,同时如果一个PV已经分给ASM用了,但是由于系统管理员的疏忽而给PV分配了一个PVID,则该PV 头部的ASM disk header会被覆盖掉,这将直接导致disk header丢失;如果是External Redundancy那么这个diskgroup就直接mount不起来了。所以对那些会影响ASM disk header的操作要慎之又慎,同时最好定期备份disk header。
ASM disk header描述了该ASM disk和diskgroup的属性,通过对现有disk header的加载,ASM实例可以知道这个diskgroup的整体信息。
下面是一个典型的disk header的一部分, 其disk number为0 ,redundancy为KFDGTP_HIGH,diskname为DATA1_0000,diskgroup name 为DATA1,failgroup name为DATA1_0000:
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: blk=0 kfbh.block.obj: 2147483648 ; 0x008: disk=0 kfbh.check: 3107059325 ; 0x00c: 0xb931f67d kfbh.fcn.base: 0 ; 0x010: 0x00000000 kfbh.fcn.wrap: 0 ; 0x014: 0x00000000 kfbh.spare1: 0 ; 0x018: 0x00000000 kfbh.spare2: 0 ; 0x01c: 0x00000000 kfdhdb.driver.provstr: ORCLDISK ; 0x000: length=8 kfdhdb.driver.reserved[0]: 0 ; 0x008: 0x00000000 kfdhdb.driver.reserved[1]: 0 ; 0x00c: 0x00000000 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: 186646528 ; 0x020: 0x0b200000 kfdhdb.dsknum: 0 ; 0x024: 0x0000 kfdhdb.grptyp: 3 ; 0x026: KFDGTP_HIGH kfdhdb.hdrsts: 3 ; 0x027: KFDHDR_MEMBER kfdhdb.dskname: DATA1_0000 ; 0x028: length=10 kfdhdb.grpname: DATA1 ; 0x048: length=5 kfdhdb.fgname: DATA1_0000 ; 0x068: length=10 kfdhdb.capname: ; 0x088: length=0 kfdhdb.crestmp.hi: 32999670 ; 0x0a8: HOUR=0x16 DAYS=0x7 MNTH=0x2 YEAR=0x7de kfdhdb.crestmp.lo: 1788720128 ; 0x0ac: USEC=0x0 MSEC=0x36d SECS=0x29 MINS=0x1a kfdhdb.mntstmp.hi: 32999670 ; 0x0b0: HOUR=0x16 DAYS=0x7 MNTH=0x2 YEAR=0x7de kfdhdb.mntstmp.lo: 1812990976 ; 0x0b4: USEC=0x0 MSEC=0x3 SECS=0x1 MINS=0x1b kfdhdb.secsize: 512 ; 0x0b8: 0x0200 kfdhdb.blksize: 4096 ; 0x0ba: 0x1000 kfdhdb.ausize: 4194304 ; 0x0bc: 0x00400000 kfdhdb.mfact: 454272 ; 0x0c0: 0x0006ee80 kfdhdb.dsksize: 32375 ; 0x0c4: 0x00007e77 kfdhdb.pmcnt: 2 ; 0x0c8: 0x00000002 kfdhdb.fstlocn: 1 ; 0x0cc: 0x00000001 kfdhdb.altlocn: 2 ; 0x0d0: 0x00000002 kfdhdb.f1b1locn: 2 ; 0x0d4: 0x00000002 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: 186646528 ; 0x0e0: 0x0b200000 kfdhdb.grpstmp.hi: 32999670 ; 0x0e4: HOUR=0x16 DAYS=0x7 MNTH=0x2 YEAR=0x7de kfdhdb.grpstmp.lo: 1783335936 ; 0x0e8: USEC=0x0 MSEC=0x2e3 SECS=0x24 MINS=0x1a kfdhdb.vfstart: 0 ; 0x0ec: 0x00000000 kfdhdb.vfend: 0 ; 0x0f0: 0x00000000 kfdhdb.spfile: 0 ; 0x0f4: 0x00000000 kfdhdb.spfflg: 0 ; 0x0f8: 0x00000000 kfdhdb.ub4spare[0]: 0 ; 0x0fc: 0x00000000 kfdhdb.ub4spare[1]: 0 ; 0x100: 0x00000000 kfdhdb.ub4spare[2]: 0 ; 0x104: 0x00000000 kfdhdb.ub4spare[3]: 0 ; 0x108: 0x00000000
下面的信息是在同一个diskgroup中的所有disk的header上均会复制一份的:
下面的信息是每一个asm disk独有的:
Freespace Table
AU=0 的blkn=1 包含的是free space table;其中包含了该AU中allocation table中每一个block上大致的可用剩余FREE SPACE可用空间信息。通过参考free space table可以避免在已经分配完的allocation table中查找空间。
[oracle@mlab2 dbs]$ kfed read /oracleasm/asm-disk01 blkn=1 aun=0 aus=4194304|less kfbh.endian: 1 ; 0x000: 0x01 kfbh.hard: 130 ; 0x001: 0x82 kfbh.type: 2 ; 0x002: KFBTYP_FREESPC kfbh.datfmt: 2 ; 0x003: 0x02 kfbh.block.blk: 1 ; 0x004: blk=1 kfbh.block.obj: 2147483648 ; 0x008: disk=0 kfbh.check: 3847932395 ; 0x00c: 0xe55ac9eb kfbh.fcn.base: 22557 ; 0x010: 0x0000581d kfbh.fcn.wrap: 0 ; 0x014: 0x00000000 kfbh.spare1: 0 ; 0x018: 0x00000000 kfbh.spare2: 0 ; 0x01c: 0x00000000 kfdfsb.aunum: 0 ; 0x000: 0x00000000 kfdfsb.max: 1014 ; 0x004: 0x03f6 kfdfsb.cnt: 73 ; 0x006: 0x0049 kfdfsb.bound: 0 ; 0x008: 0x0000 kfdfsb.flag: 1 ; 0x00a: B=1 kfdfsb.ub1spare: 0 ; 0x00b: 0x00 kfdfsb.spare[0]: 0 ; 0x00c: 0x00000000 kfdfsb.spare[1]: 0 ; 0x010: 0x00000000 kfdfsb.spare[2]: 0 ; 0x014: 0x00000000 kfdfse[0].fse: 0 ; 0x018: FREE=0x0 FRAG=0x0 kfdfse[1].fse: 0 ; 0x019: FREE=0x0 FRAG=0x0 kfdfse[2].fse: 0 ; 0x01a: FREE=0x0 FRAG=0x0 kfdfse[3].fse: 0 ; 0x01b: FREE=0x0 FRAG=0x0 kfdfse[4].fse: 0 ; 0x01c: FREE=0x0 FRAG=0x0 kfdfse[5].fse: 0 ; 0x01d: FREE=0x0 FRAG=0x0 kfdfse[6].fse: 0 ; 0x01e: FREE=0x0 FRAG=0x0 kfdfse[7].fse: 0 ; 0x01f: FREE=0x0 FRAG=0x0 kfdfse[8].fse: 0 ; 0x020: FREE=0x0 FRAG=0x0 kfdfse[9].fse: 0 ; 0x021: FREE=0x0 FRAG=0x0 kfdfse[10].fse: 0 ; 0x022: FREE=0x0 FRAG=0x0 kfdfse[11].fse: 119 ; 0x023: FREE=0x7 FRAG=0x7 kfdfse[12].fse: 16 ; 0x024: FREE=0x0 FRAG=0x1 kfdfse[13].fse: 16 ; 0x025: FREE=0x0 FRAG=0x1 kfdfse[14].fse: 16 ; 0x026: FREE=0x0 FRAG=0x1 kfdfse[15].fse: 16 ; 0x027: FREE=0x0 FRAG=0x1 kfdfse[16].fse: 16 ; 0x028: FREE=0x0 FRAG=0x1 kfdfse[17].fse: 16 ; 0x029: FREE=0x0 FRAG=0x1 kfdfse[18].fse: 16 ; 0x02a: FREE=0x0 FRAG=0x1 kfdfse[19].fse: 16 ; 0x02b: FREE=0x0 FRAG=0x1 kfdfse[20].fse: 16 ; 0x02c: FREE=0x0 FRAG=0x1 kfdfse[21].fse: 16 ; 0x02d: FREE=0x0 FRAG=0x1 kfdfse[22].fse: 16 ; 0x02e: FREE=0x0 FRAG=0x1 kfdfse[23].fse: 16 ; 0x02f: FREE=0x0 FRAG=0x1 kfdfse[24].fse: 16 ; 0x030: FREE=0x0 FRAG=0x1 kfdfse[25].fse: 16 ; 0x031: FREE=0x0 FRAG=0x1 kfdfse[26].fse: 16 ; 0x032: FREE=0x0 FRAG=0x1 kfdfse[27].fse: 16 ; 0x033: FREE=0x0 FRAG=0x1 kfdfse[28].fse: 16 ; 0x034: FREE=0x0 FRAG=0x1
aunum_kfdfsb First AU of first ATB of this FSB
max_kfdfsb Max number of FSEs per FSB
cnt_kfdfsb Number of FSEs up to end of disk
spare_kfdfsb spares for future
kfdfse – Kernel Files Disk Free Space Entry.
max_kfdfsb describes the number of free space entries which would
be used in this free space table if the disk were large enough to
provide all of the AUs which can be described by a single physical
metadata AU. cnt_kfdfsb describes the number of free space entries
which correspond to AUs which are actually present on the disk. In
the case where there are additional physical metadata AUs beyond the
one containing this kfdfsb, then max_kfdfsb will equal cnt_kfdfsb.
There are complications with the interpretation of cnt_kfdfsb when
a disk is being grown or shrunk. It is possible in these cases to
have allocated AUs past the range indicated by cnt_kfdfsb which have
not yet been relocated into the new area of the disk.
The Free Space Table provides a summary of which allocation table
blocks have free space. There is one kfdfse in the FST for each
Allocation Table block described by the FST.
The first key parameter is the stripe width of the array. Stripe width refers to the number of parallel stripes that can be written to or read from simultaneously. This is of course equal to the number of disks in the array. So a four-disk striped array would have a stripe width of four.
Allocation Table
Aun=0的后254个metadata block用以存放AU分配信息。 每一个metadata描述448个AU的状态, 如果一个AU已经分配给一个文件,则allocation table 记录其ASM文件号和data extent号。对于还是FREE的AU则被link到free list上。
kfbh.endian: 1 ; 0x000: 0x01 kfbh.hard: 130 ; 0x001: 0x82 kfbh.type: 3 ; 0x002: KFBTYP_ALLOCTBL kfbh.datfmt: 2 ; 0x003: 0x02 kfbh.block.blk: 2 ; 0x004: blk=2 kfbh.block.obj: 2147483648 ; 0x008: disk=0 kfbh.check: 2376540464 ; 0x00c: 0x8da72130 kfbh.fcn.base: 44495 ; 0x010: 0x0000adcf kfbh.fcn.wrap: 0 ; 0x014: 0x00000000 kfbh.spare1: 0 ; 0x018: 0x00000000 kfbh.spare2: 0 ; 0x01c: 0x00000000 kfdatb.aunum: 0 ; 0x000: 0x00000000 kfdatb.shrink: 448 ; 0x004: 0x01c0 kfdatb.ub2pad: 0 ; 0x006: 0x0000 kfdatb.auinfo[0].link.next: 112 ; 0x008: 0x0070 kfdatb.auinfo[0].link.prev: 112 ; 0x00a: 0x0070 kfdatb.auinfo[1].link.next: 120 ; 0x00c: 0x0078 kfdatb.auinfo[1].link.prev: 120 ; 0x00e: 0x0078 kfdatb.auinfo[2].link.next: 136 ; 0x010: 0x0088 kfdatb.auinfo[2].link.prev: 136 ; 0x012: 0x0088 kfdatb.auinfo[3].link.next: 20 ; 0x014: 0x0014 kfdatb.auinfo[3].link.prev: 20 ; 0x016: 0x0014 kfdatb.auinfo[4].link.next: 168 ; 0x018: 0x00a8 kfdatb.auinfo[4].link.prev: 168 ; 0x01a: 0x00a8 kfdatb.auinfo[5].link.next: 296 ; 0x01c: 0x0128 kfdatb.auinfo[5].link.prev: 296 ; 0x01e: 0x0128 kfdatb.auinfo[6].link.next: 552 ; 0x020: 0x0228 kfdatb.auinfo[6].link.prev: 3112 ; 0x022: 0x0c28 kfdatb.spare: 0 ; 0x024: 0x00000000 kfdate[0].discriminator: 1 ; 0x028: 0x00000001 kfdate[0].allo.lo: 0 ; 0x028: XNUM=0x0 kfdate[0].allo.hi: 8388608 ; 0x02c: V=1 I=0 H=0 FNUM=0x0 kfdate[1].discriminator: 1 ; 0x030: 0x00000001 kfdate[1].allo.lo: 0 ; 0x030: XNUM=0x0 kfdate[1].allo.hi: 8388608 ; 0x034: V=1 I=0 H=0 FNUM=0x0 kfdate[2].discriminator: 1 ; 0x038: 0x00000001 kfdate[2].allo.lo: 0 ; 0x038: XNUM=0x0 kfdate[2].allo.hi: 8388609 ; 0x03c: V=1 I=0 H=0 FNUM=0x1 kfdate[3].discriminator: 1 ; 0x040: 0x00000001 kfdate[3].allo.lo: 8 ; 0x040: XNUM=0x8 kfdate[3].allo.hi: 8388611 ; 0x044: V=1 I=0 H=0 FNUM=0x3 kfdate[4].discriminator: 1 ; 0x048: 0x00000001 kfdate[4].allo.lo: 19 ; 0x048: XNUM=0x13 kfdate[4].allo.hi: 8388611 ; 0x04c: V=1 I=0 H=0 FNUM=0x3 kfdate[5].discriminator: 1 ; 0x050: 0x00000001 kfdate[5].allo.lo: 29 ; 0x050: XNUM=0x1d kfdate[5].allo.hi: 8388611 ; 0x054: V=1 I=0 H=0 FNUM=0x3 kfdate[6].discriminator: 1 ; 0x058: 0x00000001 kfdate[6].allo.lo: 30 ; 0x058: XNUM=0x1e kfdate[6].allo.hi: 8388611 ; 0x05c: V=1 I=0 H=0 FNUM=0x3 kfdate[7].discriminator: 1 ; 0x060: 0x00000001 kfdate[7].allo.lo: 0 ; 0x060: XNUM=0x0 kfdate[7].allo.hi: 8388612 ; 0x064: V=1 I=0 H=0 FNUM=0x4 kfdate[8].discriminator: 1 ; 0x068: 0x00000001
Partner and Status Table
一般来说aun=1 是保留给Partner and Status Table(PST)的拷贝使用的。 一般5个ASM DISK将包含一份PST拷贝。多数的PST内容必须相同且验证有效。否则无法判断哪些ASM DISK实际拥有相关数据。
在 PST中每一条记录对应Diskgroup中的一个ASM DISK。每一条记录会对一个ASM disk枚举其partners的ASM DISK。同时会有一个flag来表示该DISK是否是ONLINE可读写的。这些信息对recovery是否能做很重要。
PST表的Blkn=0是PST的header,存放了如下的信息:
PST的最后一个块是heartbeat block,当diskgroup mount时其每3秒心跳更新一次。
以下为PST header
kfed read /oracleasm/asm-disk01 aun=1 blkn=0 aus=4194304 |less kfbh.endian: 1 ; 0x000: 0x01 kfbh.hard: 130 ; 0x001: 0x82 kfbh.type: 17 ; 0x002: KFBTYP_PST_META kfbh.datfmt: 2 ; 0x003: 0x02 kfbh.block.blk: 1024 ; 0x004: blk=1024 kfbh.block.obj: 2147483648 ; 0x008: disk=0 kfbh.check: 3813974007 ; 0x00c: 0xe3549ff7 kfbh.fcn.base: 0 ; 0x010: 0x00000000 kfbh.fcn.wrap: 0 ; 0x014: 0x00000000 kfbh.spare1: 0 ; 0x018: 0x00000000 kfbh.spare2: 0 ; 0x01c: 0x00000000 kfdpHdrPairBv1.first.super.time.hi:32999670 ; 0x000: HOUR=0x16 DAYS=0x7 MNTH=0x2 YEAR=0x7de kfdpHdrPairBv1.first.super.time.lo:1788841984 ; 0x004: USEC=0x0 MSEC=0x3e4 SECS=0x29 MINS=0x1a kfdpHdrPairBv1.first.super.last: 2 ; 0x008: 0x00000002 kfdpHdrPairBv1.first.super.next: 2 ; 0x00c: 0x00000002 kfdpHdrPairBv1.first.super.copyCnt: 5 ; 0x010: 0x05 kfdpHdrPairBv1.first.super.version: 1 ; 0x011: 0x01 kfdpHdrPairBv1.first.super.ub2spare: 0 ; 0x012: 0x0000 kfdpHdrPairBv1.first.super.incarn: 1 ; 0x014: 0x00000001 kfdpHdrPairBv1.first.super.copy[0]: 0 ; 0x018: 0x0000 kfdpHdrPairBv1.first.super.copy[1]: 1 ; 0x01a: 0x0001 kfdpHdrPairBv1.first.super.copy[2]: 2 ; 0x01c: 0x0002 kfdpHdrPairBv1.first.super.copy[3]: 3 ; 0x01e: 0x0003 kfdpHdrPairBv1.first.super.copy[4]: 4 ; 0x020: 0x0004 kfdpHdrPairBv1.first.super.dtaSz: 15 ; 0x022: 0x000f kfdpHdrPairBv1.first.asmCompat:186646528 ; 0x024: 0x0b200000 kfdpHdrPairBv1.first.newCopy[0]: 0 ; 0x028: 0x0000 kfdpHdrPairBv1.first.newCopy[1]: 0 ; 0x02a: 0x0000 kfdpHdrPairBv1.first.newCopy[2]: 0 ; 0x02c: 0x0000 kfdpHdrPairBv1.first.newCopy[3]: 0 ; 0x02e: 0x0000 kfdpHdrPairBv1.first.newCopy[4]: 0 ; 0x030: 0x0000 kfdpHdrPairBv1.first.newCopyCnt: 0 ; 0x032: 0x00 kfdpHdrPairBv1.first.contType: 1 ; 0x033: 0x01 kfdpHdrPairBv1.first.spares[0]: 0 ; 0x034: 0x00000000 kfdpHdrPairBv1.first.spares[1]: 0 ; 0x038: 0x00000000 kfdpHdrPairBv1.first.spares[2]: 0 ; 0x03c: 0x00000000 kfdpHdrPairBv1.first.spares[3]: 0 ; 0x040: 0x00000000 kfdpHdrPairBv1.first.spares[4]: 0 ; 0x044: 0x00000000 kfdpHdrPairBv1.first.spares[5]: 0 ; 0x048: 0x00000000 kfdpHdrPairBv1.first.spares[6]: 0 ; 0x04c: 0x00000000 kfdpHdrPairBv1.first.spares[7]: 0 ; 0x050: 0x00000000 kfdpHdrPairBv1.first.spares[8]: 0 ; 0x054: 0x00000000 kfdpHdrPairBv1.first.spares[9]: 0 ; 0x058: 0x00000000 kfdpHdrPairBv1.first.spares[10]: 0 ; 0x05c: 0x00000000 kfdpHdrPairBv1.first.spares[11]: 0 ; 0x060: 0x00000000 kfdpHdrPairBv1.first.spares[12]: 0 ; 0x064: 0x00000000 kfdpHdrPairBv1.first.spares[13]: 0 ; 0x068: 0x00000000 kfdpHdrPairBv1.first.spares[14]: 0 ; 0x06c: 0x00000000 kfdpHdrPairBv1.first.spares[15]: 0 ; 0x070: 0x00000000 kfdpHdrPairBv1.first.spares[16]: 0 ; 0x074: 0x00000000 kfdpHdrPairBv1.first.spares[17]: 0 ; 0x078: 0x00000000 kfdpHdrPairBv1.first.spares[18]: 0 ; 0x07c: 0x00000000 kfdpHdrPairBv1.first.spares[19]: 0 ; 0x080: 0x00000000
以下为PST table block:
kfed read /oracleasm/asm-disk02 aun=1 blkn=3 aus=4194304 |less kfbh.endian: 1 ; 0x000: 0x01 kfbh.hard: 130 ; 0x001: 0x82 kfbh.type: 18 ; 0x002: KFBTYP_PST_DTA kfbh.datfmt: 2 ; 0x003: 0x02 kfbh.block.blk: 1027 ; 0x004: blk=1027 kfbh.block.obj: 2147483649 ; 0x008: disk=1 kfbh.check: 4204644293 ; 0x00c: 0xfa9dc7c5 kfbh.fcn.base: 0 ; 0x010: 0x00000000 kfbh.fcn.wrap: 0 ; 0x014: 0x00000000 kfbh.spare1: 0 ; 0x018: 0x00000000 kfbh.spare2: 0 ; 0x01c: 0x00000000 kfdpDtaEv1[0].status: 127 ; 0x000: I=1 V=1 V=1 P=1 P=1 A=1 D=1 kfdpDtaEv1[0].fgNum: 1 ; 0x002: 0x0001 kfdpDtaEv1[0].addTs: 2022663849 ; 0x004: 0x788f66a9 kfdpDtaEv1[0].partner[0]: 49154 ; 0x008: P=1 P=1 PART=0x2 kfdpDtaEv1[0].partner[1]: 49153 ; 0x00a: P=1 P=1 PART=0x1 kfdpDtaEv1[0].partner[2]: 49155 ; 0x00c: P=1 P=1 PART=0x3 kfdpDtaEv1[0].partner[3]: 49166 ; 0x00e: P=1 P=1 PART=0xe kfdpDtaEv1[0].partner[4]: 49165 ; 0x010: P=1 P=1 PART=0xd kfdpDtaEv1[0].partner[5]: 49164 ; 0x012: P=1 P=1 PART=0xc kfdpDtaEv1[0].partner[6]: 49156 ; 0x014: P=1 P=1 PART=0x4 kfdpDtaEv1[0].partner[7]: 49163 ; 0x016: P=1 P=1 PART=0xb kfdpDtaEv1[0].partner[8]: 10000 ; 0x018: P=0 P=0 PART=0x2710 kfdpDtaEv1[0].partner[9]: 0 ; 0x01a: P=0 P=0 PART=0x0 kfdpDtaEv1[0].partner[10]: 0 ; 0x01c: P=0 P=0 PART=0x0 kfdpDtaEv1[0].partner[11]: 0 ; 0x01e: P=0 P=0 PART=0x0 kfdpDtaEv1[0].partner[12]: 0 ; 0x020: P=0 P=0 PART=0x0 kfdpDtaEv1[0].partner[13]: 0 ; 0x022: P=0 P=0 PART=0x0 kfdpDtaEv1[0].partner[14]: 0 ; 0x024: P=0 P=0 PART=0x0 kfdpDtaEv1[0].partner[15]: 0 ; 0x026: P=0 P=0 PART=0x0 kfdpDtaEv1[0].partner[16]: 0 ; 0x028: P=0 P=0 PART=0x0 kfdpDtaEv1[0].partner[17]: 0 ; 0x02a: P=0 P=0 PART=0x0 kfdpDtaEv1[0].partner[18]: 0 ; 0x02c: P=0 P=0 PART=0x0 kfdpDtaEv1[0].partner[19]: 0 ; 0x02e: P=0 P=0 PART=0x0 kfdpDtaEv1[1].status: 127 ; 0x030: I=1 V=1 V=1 P=1 P=1 A=1 D=1 kfdpDtaEv1[1].fgNum: 2 ; 0x032: 0x0002 kfdpDtaEv1[1].addTs: 2022663849 ; 0x034: 0x788f66a9 kfdpDtaEv1[1].partner[0]: 49155 ; 0x038: P=1 P=1 PART=0x3 kfdpDtaEv1[1].partner[1]: 49152 ; 0x03a: P=1 P=1 PART=0x0 kfdpDtaEv1[1].partner[2]: 49154 ; 0x03c: P=1 P=1 PART=0x2 kfdpDtaEv1[1].partner[3]: 49166 ; 0x03e: P=1 P=1 PART=0xe kfdpDtaEv1[1].partner[4]: 49157 ; 0x040: P=1 P=1 PART=0x5 kfdpDtaEv1[1].partner[5]: 49156 ; 0x042: P=1 P=1 PART=0x4 kfdpDtaEv1[1].partner[6]: 49165 ; 0x044: P=1 P=1 PART=0xd kfdpDtaEv1[1].partner[7]: 49164 ; 0x046: P=1 P=1 PART=0xc kfdpDtaEv1[1].partner[8]: 10000 ; 0x048: P=0 P=0 PART=0x2710 kfdpDtaEv1[1].partner[9]: 0 ; 0x04a: P=0 P=0 PART=0x0 kfdpDtaEv1[1].partner[10]: 0 ; 0x04c: P=0 P=0 PART=0x0 kfdpDtaEv1[1].partner[11]: 0 ; 0x04e: P=0 P=0 PART=0x0 kfdpDtaEv1[1].partner[12]: 0 ; 0x050: P=0 P=0 PART=0x0 kfdpDtaEv1[1].partner[13]: 0 ; 0x052: P=0 P=0 PART=0x0 kfdpDtaEv1[1].partner[14]: 0 ; 0x054: P=0 P=0 PART=0x0 kfdpDtaEv1[1].partner[15]: 0 ; 0x056: P=0 P=0 PART=0x0 kfdpDtaEv1[1].partner[16]: 0 ; 0x058: P=0 P=0 PART=0x0
aun=1 的最后第二个block中备份了一份KFBTYP_DISKHEAD
[oracle@mlab2 hzy]$ kfed read /oracleasm/asm-disk02 aun=1 blkn=1022 aus=4194304 |less kfbh.endian: 1 ; 0x000: 0x01 kfbh.hard: 130 ; 0x001: 0x82 kfbh.type: 1 ; 0x002: KFBTYP_DISKHEAD kfbh.datfmt: 1 ; 0x003: 0x01 kfbh.block.blk: 1022 ; 0x004: blk=1022 kfbh.block.obj: 2147483649 ; 0x008: disk=1 kfbh.check: 3107059260 ; 0x00c: 0xb931f63c kfbh.fcn.base: 0 ; 0x010: 0x00000000 kfbh.fcn.wrap: 0 ; 0x014: 0x00000000 kfbh.spare1: 0 ; 0x018: 0x00000000 kfbh.spare2: 0 ; 0x01c: 0x00000000 kfdhdb.driver.provstr: ORCLDISK ; 0x000: length=8 kfdhdb.driver.reserved[0]: 0 ; 0x008: 0x00000000 kfdhdb.driver.reserved[1]: 0 ; 0x00c: 0x00000000 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: 186646528 ; 0x020: 0x0b200000 kfdhdb.dsknum: 1 ; 0x024: 0x0001 kfdhdb.grptyp: 3 ; 0x026: KFDGTP_HIGH kfdhdb.hdrsts: 3 ; 0x027: KFDHDR_MEMBER kfdhdb.dskname: DATA1_0001 ; 0x028: length=10 kfdhdb.grpname: DATA1 ; 0x048: length=5 kfdhdb.fgname: DATA1_0001 ; 0x068: length=10 kfdhdb.capname: ; 0x088: length=0 kfdhdb.crestmp.hi: 32999670 ; 0x0a8: HOUR=0x16 DAYS=0x7 MNTH=0x2 YEAR=0x7de kfdhdb.crestmp.lo: 1788720128 ; 0x0ac: USEC=0x0 MSEC=0x36d SECS=0x29 MINS=0x1a kfdhdb.mntstmp.hi: 32999670 ; 0x0b0: HOUR=0x16 DAYS=0x7 MNTH=0x2 YEAR=0x7de kfdhdb.mntstmp.lo: 1812990976 ; 0x0b4: USEC=0x0 MSEC=0x3 SECS=0x1 MINS=0x1b kfdhdb.secsize: 512 ; 0x0b8: 0x0200 kfdhdb.blksize: 4096 ; 0x0ba: 0x1000 kfdhdb.ausize: 4194304 ; 0x0bc: 0x00400000
AUN=1 的最后一个block为KFBTYP_HBEAT 心跳表:
[oracle@mlab2 hzy]$ kfed read /oracleasm/asm-disk02 aun=1 blkn=1023 aus=4194304 |less kfbh.endian: 1 ; 0x000: 0x01 kfbh.hard: 130 ; 0x001: 0x82 kfbh.type: 19 ; 0x002: KFBTYP_HBEAT kfbh.datfmt: 2 ; 0x003: 0x02 kfbh.block.blk: 2047 ; 0x004: blk=2047 kfbh.block.obj: 2147483649 ; 0x008: disk=1 kfbh.check: 1479766671 ; 0x00c: 0x5833728f kfbh.fcn.base: 0 ; 0x010: 0x00000000 kfbh.fcn.wrap: 0 ; 0x014: 0x00000000 kfbh.spare1: 0 ; 0x018: 0x00000000 kfbh.spare2: 0 ; 0x01c: 0x00000000 kfdpHbeatB.instance: 1 ; 0x000: 0x00000001 kfdpHbeatB.ts.hi: 32999734 ; 0x004: HOUR=0x16 DAYS=0x9 MNTH=0x2 YEAR=0x7de kfdpHbeatB.ts.lo: 3968041984 ; 0x008: USEC=0x0 MSEC=0xe1 SECS=0x8 MINS=0x3b kfdpHbeatB.rnd[0]: 1065296177 ; 0x00c: 0x3f7f2131 kfdpHbeatB.rnd[1]: 857037208 ; 0x010: 0x33155998 kfdpHbeatB.rnd[2]: 2779184235 ; 0x014: 0xa5a6fc6b kfdpHbeatB.rnd[3]: 2660793989 ; 0x018: 0x9e987e85
如下场景中PST 可能被重定位:
Extents Set
extents set 是data extent的集合,以此来维护virtual extent的冗余拷贝。ASM FILE1 中的extent 指针在extent map中是连续的,如下面的数据:
SQL> select pxn_kffxp,xnum_kffxp from x$kffxp where number_kffxp=257; PXN_KFFXP XNUM_KFFXP ---------- ---------- 0 0 1 0 2 0 3 1 4 1 5 1 6 2 7 2 8 2 9 3 10 3
以上查询中PXN_KFFXP为文件号257文件的物理extent号,而XNUM_KFFXP为逻辑extent号。 此文件位于一个High redundancy diskgroup上,所以一个extent set 包含3份相同的virtual extent数据。
可以把上述查询就看做文件号257文件的extent map,其逻辑extent号是连续递增的。
在一个extent sets中第一个extent就是primary extent。 在external redundancy模式下仅有一个primary extent。Normal redundancy下有一个二级extent在primary之后,high的情况下有2个二级extent。
对于normal redundancy下的文件,每一个extent set 都由2个分布在不同磁盘同时也是2个不同failure group的data extent组成。这2个data extent在extent map上是紧挨着的。primary extent的extent number总是偶数,其唯一的一个二级extent总是奇数。当一个extent被移动时一般会引发extent set中所有extent对应的移动,以满足冗余要求。
High Redundancy diskgroup默认使用三路镜像。三路镜像下的Vritual Extent有一个primary和2个二级secondary data extents。secondary data extents需要存放在不同的failure group,所以其要求至少三个failure group来实现high redundancy。
在特殊情况下可能存在data extent的丢失,例如当failure group不可用导致无处可放时。
secondary extent将被均匀分配在primary extent对应的disk partners上;即便有磁盘失败仍能保持对extent set的写出是负载均衡的。
File Directory (file #1)
具体请参考 深入了解Oracle ASM(二):ASM File number 1 文件目录 http://www.askmaclean.com/archives/asm-file-number-1-the-file-directory.html
ASM实例启动
在ASM文件可以通过ASM实例来访问之前,ASM实例必须先启动。 在11.2下 不管是RAC还是StandAlone环境下ASM实例都会随系统BOOT自动启动。 启动一个ASM实例和启动一个数据库实例类似。 SGA和一组后台进程在启动过程中被创建出来。初始化参数instance_type决定了是ASM 实例还是数据库实例。除非STARTUP时使用了 NOMOUNT选项,否则默认STARTUP会执行ALTER DISKGROUP ALL MOUNT。
ASM实例启动过程中将加入到CSS中的+ASM成员组中。这将允许本实例与其他+ASM实例共享锁。数据库实例不会加入到这个成员组中,因为数据库实例的实例名不能以”+”开头。
Discovery 发现磁盘
Discovery 过程是在找到磁盘以便后续的操作。Discovery 到DISK STRING匹配的位置去找寻磁盘,并返回那些其认为合适的磁盘。对discovery一般存在于2种场景下; 第一种是使用asm_diskstring中指定的所有字符串来找出所有ASM实例必要访问的磁盘。 第二种是指定磁盘路径用以create diskgroup或者add disk to diskgroup。
第一种discovery也叫做shallow discovery, 只会返回asm_diskstring指定下的磁盘。第二种也叫做deep discovery,是读取每一个磁盘的第一个块。 disk header在这里用以分类磁盘是否可用,是被ASM外的其他东西实用(例如LVM),还是已经被其他diskgroup实用。discovery操作并不会 mount diskgroup或者写任何磁盘头。
Create Disk Group 创建磁盘组
创建diskgroup 需要指定多个磁盘路径,且这些磁盘需要通过如下的检测:
所有的磁盘均会以写入一个disk header的形式来验证。该 disk header中mount timestamp为0 ,由此可知diskgroup还没有被mount 过。之后free space block和allocation table blocks 元数据块将被写入。
其中部分磁盘被选出来 存放Partnership and Status Table ,PST 表。 PST被初始化记录所有的磁盘为在线状态。High redundancy disk group 每一个failure group对应一个 PST,最多5个拷贝。 normal redundancy group至多3个PST拷贝。external redundancy disk group有一个PST。
接着后续的metadata block将被初始化,并均匀分布在新创建的diskgroup的所有磁盘上。
【Oracle ASM Metadata】Alias Directory (file #6)
【Oracle ASM】Continuing Operations Directory (file #4)
【Oracle ASM Metadata】Template Directory (file #5)
【Oracle ASM】ASM FILE NUMBER 3 Active Change Directory
深入了解Oracle ASM(二):ASM File number 1 文件目录
【Oracle ASM】ASM FILE NUMBER #2 DISK Directory
当diskgroup完全初始化完成后mount timestamp将写入到disk header。 这将标记diskgroup已经格式好并可以被mount。其他实例也可以mount该disk group。
Drop Disk Group
diskgroup 可以被drop掉的前提是其上所有的文件都处于关闭状态且仅有本地实例在mount它。 可以通过在集群件的所有ASM上通信来确认这2点。drop diskgroup会在该DG下所有的磁盘头写入header_status为FORMER状态。
Mount Disk Group
Mount Disk Group使Disk Group其对本地ASM 实例和连接到该实例的数据库实例可用。 在该diskgroup中的文件在 OPEN/create/delete之前必须先被本地ASM实例mount; 一般启动ASM时同时mount 多个diskgroup较高效。 典型情况下是ASM_DISKGROUPS匹配到的所有的diskgroup均通过ALTER DISKGROUP ALL MOUNT 在ASM实例启动时被mount 。
下面是mount 一个diskgroup的步骤:
Discovery
会通过ASM_DISKSTRING.做一个deep discovery; 每一个disk header均包含了其所属于的diskgroup;该步骤应当要找到所有要被mount 的diskgroup下属的所有磁盘。 在disk header上获得如下信息:
当discovery时若发现2个磁盘的disk header一样则可能报错,这样做的目的是为了避免损坏disk group。
注意从diskgroup创建之后每一个ASM DISK的OS设备名可能发生变化,或者在集群中的每个节点上都不一样,这不要紧只需要discovery能找到它们并通过验证即可。
第一次mount的实例