ASM spfile in a disk group
从ASM版本11.2开始,ASM spfile可以储存在ASM磁盘组里。事实上,在安装ASM时,OUI就已经把ASM spfile放在了磁盘组中。对于单实例环境和集群环境都是这样。在安装过程中创建的第一个磁盘组是spfile的默认位置,但这不是必要的。ASM spfile还是可以放在文件系统上,就是$ORACLE_HOME/dbs目录下。
New ASMCMD commands
为支持该特性,ASMCMD引入了新的命令用来备份,复制和移动ASM spfile。这些命令如下:
-
spbackup -- 备份ASM spfile为备份文件。备份文件并不具有特殊的文件类型 ,也不会被识别为spfile
-
spcopy -- 将ASM spfile从源位置复制到目标位置(不能复制spbackup出来的备份文件)
-
spmove -- 将ASM spfile从源位置移动到目标位置并且自动更新GPnP profile文件
CREATE PFILE FROM SPFILE和CREATE SPFILE FROM PFILE命令对于磁盘组中的spfile仍然可用。
ASM spfile in disk group DATA
在我的测试环境里,ASM spfile位于DATA磁盘组。现在来找到它:
$ asmcmd find --type ASMPARAMETERFILE +DATA "*"
+DATA/ASM/ASMPARAMETERFILE/REGISTRY.253.822856169
可以看到,ASM spfile存放在一个特别的位置,它的ASM文件号为253。储存在磁盘组中的ASM spfile是作为ASM的元数据文件被管理,一直具有ASM元数据文件号253.
当然了,在sqlplus中可以看到相同的结果:
$ sqlplus / as sysasm
SQL> show parameter spfile
NAME TYPE VALUE
------ ------ -------------------------------------------------
spfile string +DATA/ASM/ASMPARAMETERFILE/registry.253.822856169
SQL>
下面对ASM spfile做个备份:
$ asmcmd spbackup
+DATA/ASM/ASMPARAMETERFILE/REGISTRY.253.822856169
/tmp/ASMspfile.backup
下面查看备份文件的内容:
$ strings /tmp/ASMspfile.backup
+ASM.__oracle_base='/u01/app/grid'#ORACLE_BASE set from in memory
value
+ASM.asm_diskgroups='RECO','ACFS'#Manual Mount
*.asm_power_limit=1
*.large_pool_size=12M
*.remote_login_passwordfile='EXCLUSIVE'
可以看到,这就是一份ASM spfile的副本,内容包含了参数和相关的comment。
ASM spfile discovery
所以问题来了,当磁盘组还没mount时,ASM实例怎么读取spfile来启动呢?不仅如此,ASM不知道spfile位于哪个磁盘组,甚至于都不知道是否位于磁盘组上。再者,ASM实例也不知道ASM discovery string的值是什么。
ASM Admin guide文档里是这么描述的:
当ASM实例寻找初始化参数文件(即pfile或者spfile)时,将按照如下顺序:
1. 由GPnP profile指定的参数文件位置
2. 如果GPnP profile里没有指定,再按照下面顺序寻找:
3.
-
位于ASM HOME目录下的spfile,(比如 $ORACLE_HOME/dbs/spfile+ASM.ora)
-
位于ASM HOME目录下的pfile
这里没有提到和ASM discovery string有关的信息,但是至少提到了spfile和GPnP profile。ASM discovery string也是位于GPnP profile里的。下面是在Exadata环境中使用gpnptool命令获得的参数值:
$ gpnptool getpval -p=profile.xml -asm_dis -o-
o/*/*
$ gpnptool getpval -p=profile.xml -asm_spf -o-
+DBFS_DG/spfileASM.ora
在单实例环境中,没有GPnP profile,这些信息位于ASM资源(ora.asm)中,储存在OLR中。 下面是一个单实例的例子:
$ crsctl stat res ora.asm -p | egrep "ASM_DISKSTRING|SPFILE"
ASM_DISKSTRING=
SPFILE=+DATA/ASM/ASMPARAMETERFILE/registry.253.822856169
到目前为止,我们知道了ASM如何获得ASM磁盘和spfile的位置。但是磁盘组还没有mount时,ASM怎么读取spfile呢?
奥秘就在ASM磁盘头里。为了支持spfile储存在ASM磁盘组中,磁盘头中增加了两个条目:
-
kfdhdb.spfile - ASM spfile所在AU号
-
kfdhdb.spfflg - ASM spfile的标志位。如果值为1,那么ASM spfile就位于这个磁盘,AU号由kfdhdb.spfile指明。
在发现磁盘的过程中,ASM实例读取磁盘头,寻找spfile的相关信息。找到储存spfile的磁盘后,就可以读取初始参数文件。
下面在我的测试磁盘组DATA中做个演示,首先检查磁盘组状态和冗余类型
$ asmcmd lsdg -g DATA | cut -c1-26 Inst_ID State Type
1 MOUNTED NORMAL
可以看到磁盘组是mount状态,冗余类型是normal。也就是说ASM spfile会有两副本。那么我们会看到两个磁盘设置了kfdhdb.spfile和kfdhdb.spfflg的值。下面验证一下:
$ for disk in `asmcmd lsdsk -G DATA --suppressheader`
> do
> echo $disk
> kfed read $disk | grep spf
> done
/dev/sdc1
kfdhdb.spfile: 46 ; 0x0f4: 0x0000002e
kfdhdb.spfflg: 1 ; 0x0f8: 0x00000001
/dev/sdd1
kfdhdb.spfile: 2212 ; 0x0f4: 0x000008a4
kfdhdb.spfflg: 1 ; 0x0f8: 0x00000001
/dev/sde1
kfdhdb.spfile: 0 ; 0x0f4: 0x00000000
kfdhdb.spfflg: 0 ; 0x0f8: 0x00000000
可以看到,确实有两个磁盘储存了ASM spfile。下面看一下磁盘/dev/sdc1 46号AU的内容:
$ dd if=/dev/sdc1 bs=1048576 skip=46 count=1 | strings
+ASM.__oracle_base='/u01/app/grid'#ORACLE_BASE set from in memory value
+ASM.asm_diskgroups='RECO','ACFS'#Manual Mount
*.asm_power_limit=1
*.large_pool_size=12M
*.remote_login_passwordfile='EXCLUSIVE'
1+0 records in
1+0 records out
1048576 bytes (1.0 MB) copied, 0.0352732 s, 29.7 MB/s
磁盘/dev/sdc1的46号AU就是我们要找的ASM spfile。
ASM spfile alias block
除了以上两个条目,还增加了一个新的元数据块类型 - KFBTYP_ASMSPFALS。它用来描述ASM spfile别名,位于ASM spfile的最后一个块。 下面看一下46号AU的最后一个块:
$ kfed read /dev/sdc1 aun=46 blkn=255
kfbh.endian: 1 ; 0x000: 0x01
kfbh.hard: 130 ; 0x001: 0x82
kfbh.type: 27 ; 0x002: KFBTYP_ASMSPFALS
kfbh.datfmt: 1 ; 0x003: 0x01
kfbh.block.blk: 255 ; 0x004: blk=255
kfbh.block.obj: 253 ; 0x008: file=253
kfbh.check: 806373865 ; 0x00c: 0x301049e9
kfbh.fcn.base: 0 ; 0x010: 0x00000000
kfbh.fcn.wrap: 0 ; 0x014: 0x00000000
kfbh.spare1: 0 ; 0x018: 0x00000000
kfbh.spare2: 0 ; 0x01c: 0x00000000
kfspbals.incarn: 822856169 ; 0x000: 0x310bc9e9
kfspbals.blksz: 512 ; 0x004: 0x00000200
kfspbals.size: 3 ; 0x008: 0x0003
kfspbals.path.len: 0 ; 0x00a: 0x0000
kfspbals.path.buf: ; 0x00c: length=0
这个元数据块里没有很多信息。大多数条目是块头信息(以kfbh开头的条目)。真正的ASM spfile别名的数据(以kfspbals开头的条目)只有几条。spfile file版本号是文件名(REGISTRY.253.822856169)的一部分,块大小为512字节,文件大小是3个块。以上输出中路径相关条目的信息为空,是指不存在ASM spfile别名。
下面创建一个spfile别名。首先从现有的spfile创建一个pfile,然后根据该pfile创建一个spfile别名:
$ sqlplus / as sysasm
SQL> create pfile='/tmp/pfile+ASM.ora' from spfile;
File created.
SQL> shutdown abort;
ASM instance shutdown
SQL> startup pfile='/tmp/pfile+ASM.ora';
ASM instance started
Total System Global Area 1135747072 bytes
Fixed Size 2297344 bytes
Variable Size 1108283904 bytes
ASM Cache 25165824 bytes
ASM diskgroups mounted
SQL> create spfile='+DATA/spfileASM.ora' from
pfile='/tmp/pfile+ASM.ora';
File created.
SQL> exit
再次定位ASM spfile会显示两条返回结果:
$ asmcmd find --type ASMPARAMETERFILE +DATA "*"
+DATA/ASM/ASMPARAMETERFILE/REGISTRY.253.843597139
+DATA/spfileASM.ora
可以看到ASM spfile本身和它的别名。下面确认下spfileASM.ora是别名文件:
$ asmcmd ls -l +DATA/spfileASM.ora
Type Redund Striped Time Sys Name
ASMPARAMETERFILE MIRROR COARSE MAR 30 20:00:00 N
spfileASM.ora =>
+DATA/ASM/ASMPARAMETERFILE/REGISTRY.253.843597139
下面再看下spfile别名块的信息:
$ kfed read /dev/sdc1 aun=46 blkn=255
kfbh.endian: 1 ; 0x000: 0x01
kfbh.hard: 130 ; 0x001: 0x82
kfbh.type: 27 ; 0x002: KFBTYP_ASMSPFALS
kfbh.datfmt: 1 ; 0x003: 0x01
kfbh.block.blk: 255 ; 0x004: blk=255
kfbh.block.obj: 253 ; 0x008: file=253
kfbh.check: 2065104480 ; 0x00c: 0x7b16fe60
kfbh.fcn.base: 0 ; 0x010: 0x00000000
kfbh.fcn.wrap: 0 ; 0x014: 0x00000000
kfbh.spare1: 0 ; 0x018: 0x00000000
kfbh.spare2: 0 ; 0x01c: 0x00000000
kfspbals.incarn: 843597139 ; 0x000: 0x32484553
kfspbals.blksz: 512 ; 0x004: 0x00000200
kfspbals.size: 3 ; 0x008: 0x0003
kfspbals.path.len: 13 ; 0x00a: 0x000d
kfspbals.path.buf: spfileASM.ora ; 0x00c: length=13
现在可以看到别名文件名的信息了。由于新建了spfile,版本号也变了。
Conclusion
从ASM 11.2开始,ASM spfile可以储存在磁盘组里。同时为了支持该特性,新增了对应的ASMCMD命令,我们也有了新的ASM元数据结构。
本文来自云栖社区合作伙伴“DBGEEK”