Starting with ASM version 11.2, the ASM spfile can be stored in an ASM disk group. Indeed, during a new ASM installation, the Oracle Universal Installer (OUI) will place the ASM spfile in the disk group that gets created during the installation. This is true for both Oracle Restart (single instance environments) and Cluster installations. It should be noted that the first disk group created during the installation is the default spfile location, but not a requirement. The spfile can still be on a file system, in say $ORACLE_HOME/dbs directory.
New ASMCMD commands
To support this feature, new ASMCMD commands were introduced to back up, copy and move the ASM spfile. The commands are:
- spbackup - backs up an ASM spfile to a backup file. The backup file is not a special file type and is not identified as an spfile.
- spcopy - copies an ASM spfile from the source location to an spfile in the destination location.
- spmove - moves an ASM spfile from source to destination and automatically updates the GPnP profile.
The SQL commands CREATE PFILE FROM SPFILE and CREATE SPFILE FROM PFILE are still valid for the ASM spfile stored in the disk group.
ASM spfile in disk group DATA
In my environment, the ASM spfile is (somewhere) in the disk group DATA. Let's find it:
$ asmcmd find --type ASMPARAMETERFILE +DATA "*"
+DATA/ASM/ASMPARAMETERFILE/REGISTRY.253.822856169
As we can see, the ASM spfile is in a special location and it has ASM file number 253. The ASM spfile stored in the disk group is a registry file, and will always be the ASM metadata file number 253.
Of course, we see the same thing from the sqlplus:
$ sqlplus / as sysasm
SQL> show parameter spfile
NAME TYPE VALUE
------ ------ -------------------------------------------------
spfile string +DATA/ASM/ASMPARAMETERFILE/registry.253.822856169
SQL>
Let's make a backup of that ASM spfile.
$ asmcmd spbackup +DATA/ASM/ASMPARAMETERFILE/REGISTRY.253.822856169 /tmp/ASMspfile.backup
And check out the contents of the file:
$ 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'
As we can see, this is a copy of the ASM spfile, that includes the parameters and associated comments.
ASM spfile discovery
So, how can the ASM instance read the spfile on startup, if the spfile is in a disk group that is not mounted yet? Not only that - the ASM doesn't really know which disk group has the spfile, or even if the spfile is in a disk group. And what is the value of the ASM discovery string?
When an Oracle ASM instance searches for an initialization parameter file, the search order is:
- The location of the initialization parameter file specified in the Grid Plug and Play (GPnP) profile.
- If the location has not been set in the GPnP profile, then the search order changes to:
- SPFILE in the Oracle ASM instance home (e.g. $ORACLE_HOME/dbs/spfile+ASM.ora)
- PFILE in the Oracle ASM instance home
This does not tell us anything about the ASM discovery string, but at least it tells us about the spfile and the GPnP profile. It turns out the ASM discovery string is also in the GPnP profile. Here are the values from an Exadata environment:
$ gpnptool getpval -p=profile.xml -asm_dis -o-
o/*/*
$ gpnptool getpval -p=profile.xml -asm_spf -o-
+DBFS_DG/spfileASM.ora
There is no GPnP profile in a single instance set up, so this information is in the ASM resource (ora.asm), stored in the Oracle Local Repository (OLR). Here are the values from a single instance environment:
$ crsctl stat res ora.asm -p | egrep "ASM_DISKSTRING|SPFILE"
ASM_DISKSTRING=
SPFILE=+DATA/ASM/ASMPARAMETERFILE/registry.253.822856169
So far so good. Now the ASM knows where to look for ASM disks and where the spfile is. But the disk group is not mounted yet, as the ASM instance still hasn't started up, so how can ASM read the spfile?
The trick is in the ASM disk headers. To support the ASM spfile in a disk group, two new fields were added to the ASM disk header:
- kfdhdb.spfile - Allocation unit number of the ASM spfile.
- kfdhdb.spfflg - ASM spfile flag. If this value is 1, the ASM spfile is on this disk in allocation unit kfdhdb.spfile.
As part of the disk discovery process, the ASM instance reads the disk headers and looks for the spfile information. Once it finds the disks that have the spfile, it can read the actual initialization parameters.
Let's have a look at my disk group DATA. First check the disk group state and redundancy
$ asmcmd lsdg -g DATA | cut -c1-26
Inst_ID State Type
1 MOUNTED NORMAL
The disk group is mounted and the redundancy is normal. This means the ASM spfile will be mirrored, so we should see two disks with kfdhdb.spfile and kfdhdb.spfflg values set. Let's have a look:
$ 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
As we can see, two disks have the ASM spfile.
Let's check the contents of the Allocation Unit 46 on disk /dev/sdc1:
$ 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
The AU 46 on disk /dev/sdc1 indeed contains the ASM spfile.
ASM spfile alias block
In addition to the new ASM disk header fields, there is a new metadata block type - KFBTYP_ASMSPFALS - that describes the ASM spfile alias. The ASM spfile alias block will be the last block in the ASM spfile.
Let's have a look at the last block of the Allocation Unit 46:
$ 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
There is not much in this metadata block. Most of the entries have the block header info (fields kfbh.*). The actual ASM spfile alias data (fields kfspbals.*) has only few entries. The spfile file incarnation (822856169) is part of the file name (REGISTRY.253.822856169), the block size is 512 (bytes) and the file size is 3 blocks. The path info is empty, meaning I don't actually have the ASM spfile alias.
Let's create one. I will first create a pfile from the existing spfile and then create the spfile alias from that pfile.
$ 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
Looking for the ASM spfile again shows two entries:
$ asmcmd find --type ASMPARAMETERFILE +DATA "*"
+DATA/ASM/ASMPARAMETERFILE/REGISTRY.253.843597139
+DATA/spfileASM.ora
We now see the ASM spfile itself (REGISTRY.253.843597139) and its alias (spfileASM.ora). Having a closer look at spfileASM.ora confirms this is indeed the alias for the registry file:
$ 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
Check the ASM spfile alias block now:
$ 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
Now we see that the alias file name appears in the ASM spfile alias block. Note the new incarnation number, as this is a new ASM spfile, created from the pfile.
Conclusion
Starting with ASM version 11.2, the ASM spfile can be stored in an ASM disk group. To support this feature, we now have new ASMCMD commands and, under the covers, we have new ASM metadata structures.