Oracle内核系列-揭秘ASM磁盘头信息

马育义 2015-12-17 09:53:32

转载声明:本文为DBA+社群原创文章,转载必须连同本订阅号二维码全文转载,并注明作者名字及来源:DBA+社群(dbaplus)。

 

 

专家简介

 
 

 


马育义

【DBA+社群】广州群副

 

拥有5年DBA运维经验,精通Oracle数据库管理,深入理解Oracle 体系结构,擅长使用RAC、Dataguard、Goldengate等技术解决Oracle数据库运维故障。精通Oracle数据库安装配置、性能诊断、故障处理、备份解决方案的设计与实施。Oracle OCP认证讲师,在Oracle OCP和OCM的培训方面也有较为丰富的经验,曾多次负责广东移动、深圳航空的DBA培训工作。

 

 

1
ASM元数据
 

 

1.1基础概念

 

 

1.1.1 ASM File

 

从10g开始,数据文件的存储除了使用裸设备和文件系统外,还可以存放在ASM中。简单的理解,存放在ASM中的数据文件,日志文件,控制文件,归档日志等等,就是ASM FILE。仅有以下的文件类型可以存放在ASM Diskgroup中:

 

  • Control File

  • Datafile

  • Temporary data file

  • Online Redo Log

  • Archive Log

  • RMAN backup

  • Datafile Copy

  • SPFILE

  • Disaster Recovery Configuration

  • Flashback Log

  • Change Tracking Bitmap

  • DataPump Dumpset

 

一个ASM FILE的名字一般以一个”+”和DiskGroup名字开头。 当ORACLE RDBMS KERNEL内核的文件I/O层碰到一个以”+”开头的文件时,就会走到相关ASM的代码层中 而不是调用依赖于操作系统的文件系统I/O。 仅仅在File I/O层面才会认识到这是一个ASM 中的文件,而其上层的内核代码看来ASM FILE和OS FILE都是一样的。

 

举例:

+DATAA/orcl/datafile/system.256.689832921

格式说明: +DATA/orcl/datafile/tbs_name.asm_filenumber.incarnation_number

 

  • orcl:数据库名称

  • datafile: 文件类型,表示是数据文件

  • tbs_name: 表空间名

  • asm file#: 表示ASM file编号,$asm_file.file_number

  • incarnation number: 从时间戳提取,唯一值。

 

在一个ASM Diskgroup中仅仅允许存放已知的ORACLE文件类型。假设一个文件通过cp拷贝到ASM Diskgroup中,则该文件的第一个块将被检验以便确认其类型,以及收集其他信息来构建这个文件的完整ASM文件名。 如果其文件头无法被识别,则该文件在DiskGroup中的创建将会报错。

 

1.1.2 ASM AU

 

ASM在分配空间时,以AU为单位进行,AU即Allocation units,是组成ASM disk的基本单元。在Oracle 10gR2中,ASM AU的缺省单位大小是1M,相应的条带化大小是128K,可以通过调整_asm_ausize隐含参数来调整AU大小,调整_asm_stripesize控制相应的条带化大小。

 

11g后可以在创建磁盘组时可以配置AU 大小,AU的允许大小有1、2、4、8、16、32 或64 MB。

 

 

1.1.3 File Blocks

 

所有被ASM所支持的文件类型仍以其file block作为读和写的基本单位。在ASM中的文件仍保持其原有的 Block Size 例如数据文件默认为8k,ASM并不能影响这些东西。值得一提的是在ASM FILE NUmber 1 的FILEDIR中记录了每一种FILE TYPE对应的BLOCK SIZE。

 

1.1.4 ASM元数据

 

ASM的元数据都存储在ASM磁盘中,用以存放ASM Diskgroup控制信息的数据,Metadata包括了该磁盘组中有哪些磁盘,多少可用的空间,其中存放的File的名字,一个文件有哪些Extent等等信息。

 

元数据分成2类,一类是物理元数据(Physical Metadata),一类是虚拟元数据(Virtual Metadata)。物理元数据存储在磁盘的固定位置,通常在ASM磁盘头。虚拟元数据后者存储在ASM文件上,和常规的ASM File一样在所有磁盘之间均匀分布。事实上虚拟元数据也是当做一个个ASM File来维护的。

 

所有的元数据block均是4k大小,并且有checksum信息来确认block是否被损坏。

 

1.1.5 ASM磁盘头

 

一个ASM DISK的最前面4096字节为disk header,对于ASM而言是block 0 (blkn=0)。ASM disk header描述了该ASM disk和diskgroup的属性,通过对现有disk header的加载,ASM实例可以知道这个diskgroup的整体信息。所以对那些会影响ASM disk header的操作要慎之又慎,同时最好定期备份disk header。

 

 

 

1.2物理元数据

 

物理元数据存储在磁盘的固定位置,通常在ASM磁盘头,其由以下组成:

 

 

1.3逻辑元数据

 

物理元数据用于描述磁盘组的组成、空间分配等内容。而虚拟元数据则用于记录ASM文件在磁盘上的分布,虚拟元数据也存在于ASM文件当中,和其他ASM文件的分布和管理完全相同。虚拟元数据一般包含:

 

 

 

1.4数据查询

 

1.4.1 通过File Directory查询

 

ASM的物理元数据都保存在AU 0和AU 1中,其他的虚拟元数据的位置要到File Directory去查询,该目录记录了所有ASM File的元数据,每个ASM File在它里面都有一条记录,它记录了每个ASM File的extent对应的disk number和au number。

 

File Directory的起始点存储在磁盘0的2号AU上面。2号AU总共有256个块。每一个块大概4KB。第0个块是用于文件头留用。从第1个块开始记录文件asm file number为1的磁盘分布信息,而第2个块开始记录asm file number为2的磁盘分布信息。以此类推,刚好从asm file number从1-255都保存在2号AU上面。所以File#1至少包含了2个AU,因为我们的数据库文件的file number是从256开始的。

 

想知道虚拟元数据的分布情况,就要先找到File#1的disk number和au number的分布信息,就需要读取0号磁盘的2号AU的第一个块。

 

Oracle提供了一个KFOD工具,10gR2以上都有自带,用于列举搜索磁盘。我们先看看测试环境中有哪些共享磁盘:

 

 

在我的测试环境中,磁盘组DATA有两个磁盘raw3和raw4:

 

 

ASM block的查看,Oracle提供了一个kfed工具。11g后可直接在oracle用户下使用,而10g则需要编译一下:

 

 

查找File#1的AU分布情况:

 

 

我们可以看到File#1有2个AU:

  • DISK 0,AU[2]

  • DISK 1,AU[2]

 

 

案例:查询控制文件的AU信息

 

现在我想查看控制文件的AU信息,先计算控制文件的AU信息在File Directory的哪个块:

 

 

接下来我们读取1号磁盘的2号AU的第4个块。这个AU是从块0来记录256号文件的。无需进行预留。为什么是第4个块?

 

260-255=5  默认从0号块开始,所以第4个块代表了260号文件

 

然后我们查出包括控制文件的AU信息。

 

 

最后我们找一个AU来确认一下是否是控制文件。我们用操作系统的dd命令读取0号文件的第834号AU信息。

 

 

1.4.2 通过X$KFFXP查询

 

通过视图X$KFFXP可以更直观地查看ASM file的物理分配AU情况。该视图主要是反映了File Extent Map的映射关系。ASM把文件分成多个Extent,而Extent是由AU构成的。

 

 

通过X$KFFXP和v$asm_alias、v$asm_disk、v$asm_diskgroup等相连,可以方便地查询到各个ASM File的AU分布情况:

 

 

2
ASM磁盘头

 

 

2.1ASM磁盘头含义

 

 

ASM disk header描述了该ASM disk和diskgroup的属性,通过对现有disk header的加载,ASM实例可以知道这个diskgroup的整体信息。

下面是一个典型的disk header的组成:

 

 

下面的信息是在同一个diskgroup中的所有disk的header上均会复制一份的:

 

  • Disk group name and creation timestamp

  • Physical sector size of all disks in the disk group

  • Allocation unit size

  • Metadata block size

  • Software version compatibility

  • Default redundancy

  • Mount timestamp

 

下面的信息是每一个asm disk独有的:

 

  • ASM disk name (not OS path name)

  • Disk number within disk group

  • Failure group name

  • Disk size in allocation units

 

2.2磁盘头元数据校验

 

 

ASM磁盘头的查看,我们可以直接使用Oracle提供的kfed工具。

 

 

但是这样不一样能发现元数据有异常的情况,我们可以使用kfed find命令检验AU[0]所有块的元数据类型是否正常。如果出现非以下结果的块,说明ASM元数据块有所损坏。

 

 

注:以上只是检验元数据块的类型是否正常,如果元数据块中内容有误,目前还是没有办法可以直接检查出来。

 

2.3磁盘头的备份恢复

 

 

ASM磁盘头的重要性无庸置疑,通过观察ASM磁盘头各项含义后,我们发现ASM磁盘头并不类似其他ASM File一样经常变化修改,这使得对ASM磁盘头的备份具体有行性。

 

2.3.1 11.1.0.7之前

 

对于10.2 到11.1.0.6的ASM,磁盘头的备份方法就是dd或者kfed。

 

  • dd备份:

 

 

  • dd恢复演示:

1、模拟磁盘头损坏

 

 

此时再挂载磁盘组报错:

 

 

2、检查磁盘头内容

kfed检查ASM 磁盘头,Kfed输出显示磁盘头的信息全部都是0,说明ASM磁盘头被覆盖或损坏了。

 

 

3、使用前面的dd备份恢复

 

 

4、重新挂载磁盘组

 

 

  • kfed备份:

 

 

kfed恢复:

 

 

注意:如果既无dd备份也无kfed备份,则只能手动修复磁盘头,后面有详细介绍。

 

2.3.2  11.1.0.7之后

 

从10.2.0.5、11.1.0.7、11.2之后ASM磁盘头会自动备份到AU#1的倒数第二个block。对于AU size是1MB的DISKGROUP,每个AU包括block数量=1024KB/4KB=256个,因此备份信息位于AU#1的第254号block(block从0号开始)。当然可以计算得到:

 

 

查看ASM磁盘头备份信息,备份信息与ASM disk header信息完全一致(blk、check除外):

 

 

因此可以直接使用kfed命令修复磁盘头。

1、模拟磁盘头损坏

 

 

此时再挂载磁盘组报错:

 

 

2、kfed修复磁盘头

 

 

3、查看新的磁盘头

 

 

2.4手工重构磁盘头

 

 

针对10g和11gR1,由于ASM没有自动备份磁盘头。在某些磁盘维护操作时很容易误删除磁盘头数据,此时就只能通过手工重构磁盘头。

重构磁盘头主要需要修改下列值:

 

  • kfbh.endian

  • kfbh.block.obj

  • kfdhdb.driver.provstr

  • kfdhdb.dsknum

  • kfdhdb.grptyp

  • kfdhdb.dskname

  • kfdhdb.grpname

  • kfdhdb.fgname

  • kfdhdb.crestmp.hi

  • kfdhdb.crestmp.lo

  • kfdhdb.mntstmp.hi

  • kfdhdb.mntstmp.lo

  • kfdhdb.dsksize

  • kfdhdb.fstlocn

  • kfdhdb.altlocn

  • kfdhdb.f1b1locn

  • kfdhdb.grpstmp.hi

  • kfdhdb.grpstmp.lo

 

当然还有些情况,需要具体问题具体分析,比如使用了11.2的版本的,就需要有VOTEDISK和SPFILE的那几个参数值,上面列出来的是针对10g和11gR1。

 

如1.3中所介绍的,Disk Directory包含大量磁盘头信息,是我们手工重构磁盘头的数据来源。而如果只是磁盘组中一块磁盘头损坏,则可以更加方便地参考其他正常磁盘头的信息。

 

在我的测试环境中,磁盘组DATA有两个磁盘raw3和raw4:

 

 

先暴力摧毁raw3的磁盘头:

 

 

我们先利用raw4生成一个磁盘头,再重构成raw3的磁盘头:

 

 

修改必要的值,与raw3的实际情况配合,以下是要修改的项。

 

修改/tmp/raw3.head后,写入到raw3的磁盘头中,重新挂载磁盘组成功。

 

 

即日起,凡是推送在【DBAplus社群】平台的文章,阅读量超过1000,该文章作者可获得赠书一本。大家如有好的干货文章也可以向我们的订阅号投稿,投稿邮箱:1017465571@qq.com。近期赠书有:白鳝《思想的天空》、杨志洪《Oracle核心技术》……

 

 

小编精心为大家挑选了近日最受欢迎的几篇热文:

 

回复001,看丁俊的《【重磅干货】看了此文,Oracle SQL优化文章不必再看!》;

回复002,看吕海波的《去不去O,谁说了算?》;

回复003,看胡怡文《PG,一道横跨oltp到olap的梦想之桥》;

回复004,看郭耀龙《假事务之名,深入研究UNDO与REDO》;

回复005,看杨志洪《【职场心路】一个老DBA的自白》;

回复006,看周俊《被埋没的SQL优化利器——Oracle SQL monitor》;

回复007,看袁伟翔《揭秘Oracle数据库truncate原理》;

回复008,看杨奇龙《数据库性能测试》;

回复009,看丁启良《LINUX类主机JAVA应用程序占用CPU、内存过高分析手段》;

回复010,看黎君原《扒一扒Oracle数据库迁移中的各种坑》。

 

 

关于DBA+社群

DBA+社群是全中国最大的涵盖各种数据库、中间件及架构师线条的微信社群!有100+专家发起人,建有15大城市微信群,6大专业产品群,多达10000+跨界DBA加入队伍。每天1个热议话题,每周2次线上技术分享,不定期线下聚会与原创专家团干货分享,更多精彩,欢迎关注dbaplus微信订阅号!

扫码关注

DBAplus社群

超越DBA圈子,连接的不仅仅是DBA

最新评论
访客 2023年08月20日

230721

访客 2023年08月16日

1、导入Mongo Monitor监控工具表结构(mongo_monitor…

访客 2023年08月04日

上面提到: 在问题描述的架构图中我们可以看到,Click…

访客 2023年07月19日

PMM不香吗?

访客 2023年06月20日

如今看都很棒

活动预告