The views expressed on this blog are my own and do not necessarily reflect the views of Oracle

January 2, 2012

ASM Disk Directory

The ASM file number 2 - the ASM disk directory - keeps track of all disks in the disk group. As disk groups are independent storage units, each disk group will have its own ASM disk directory.

As far as the ASM is concerned, the disk directory is just another file. It has its own entry in the ASM file directory, it is mirrored, as per the disk group redundancy policy, and it grows as needed.

Each disk directory entry maintains the following information:
  • Disk number
  • Disk state
  • ASM disk name (this can differ from the disk OS name)
  • Failgroup name
  • Create time-stamp
  • Failure time-stamp
  • Failure timer
  • Resize target
  • Relative location in the staleness registry
  • Disk repair time
  • Zone information


Most of the information maintained in the disk directory can be accessed via the V$ASM_DISK view. The view displays one row for every disk discovered, including the disks which are not part of any disk group. The ASM performs disk discovery every time this view is queried, so those queries are expensive.

The following example shows the query output from the V$ASM_DISK in an ASM instance:

SQL> SELECT group_number, disk_number, state, name, mount_status
FROM v$asm_disk;

------------ ----------- -------- ------------ -------
          0           0 NORMAL                CLOSED
          0           1 NORMAL                CLOSED
          0           2 NORMAL                CLOSED
          0           6 NORMAL                CLOSED
          1           0 NORMAL   ASMDISK1     CACHED
          1           1 NORMAL   ASMDISK2     CACHED
          1           2 NORMAL   ASMDISK3     CACHED
          1           3 NORMAL   ASMDISK4     CACHED
          2           0 NORMAL   ASMDISK5     CACHED
          2           1 NORMAL   ASMDISK6     CACHED

10 rows selected.


Note that we see all disks available to the ASM, including those that do not belong to a mounted disk group (GROUP_NUMBER=0).


The V$ASM_DISK_STAT displays the same information as the V$ASM_DISK does, but without performing discovery of new disks. The information comes from the SGA of the ASM instance. This results in a less expensive operation, but since discovery is not performed, the query result does not include the information about disks that are new to the system.

The following example shows the query output from the V$ASM_DISK_STAT in an ASM instance:

SQL> SELECT group_number, disk_number, state, name, mount_status
FROM v$asm_disk_stat;

------------ ----------- -------- ------------ -------
          1           0 NORMAL   ASMDISK1     CACHED
          1           1 NORMAL   ASMDISK2     CACHED
          1           2 NORMAL   ASMDISK3     CACHED
          1           3 NORMAL   ASMDISK4     CACHED
          2           0 NORMAL   ASMDISK5     CACHED
          2           1 NORMAL   ASMDISK6     CACHED

6 rows selected.


This time, we only see disks for the mounted disk groups.

Locating the disk directory

We can query the fixed table X$KFFXP in the ASM instance, to find out which allocation units belong to the ASM file number 2. I will also join the V$ASM_DISK_STAT to get the disk names. Let's do that for disk group 1:

SQL> SELECT x.xnum_kffxp "Extent",
x.au_kffxp "AU",
x.disk_kffxp "Disk #", "Disk name"
FROM x$kffxp x, v$asm_disk_stat d
WHERE x.group_kffxp=d.group_number
and x.disk_kffxp=d.disk_number
and x.group_kffxp=1
and x.number_kffxp=2
ORDER BY 1, 2;

   Extent         AU     Disk # Disk name
--------- ---------- ---------- ---------
        0          2          3 ASMDISK4
        0          3          0 ASMDISK1
        0          3          1 ASMDISK2


The result shows two things - that the ASM file directory is triple mirrored, and that the current size of the file directory is 3 physical extents (which in this case equals to 3 allocation units). It is worth pointing out that even in a normal redundancy disk group, the ASM disk directory is triple mirrored.

Let's now use the kfed to look at the disk directory entries for disk group 1. As the data is the same in all three allocation units, we can look at the first one, i.e. the allocation unit 2 on disk ASMDISK4:

$ kfed read /dev/oracleasm/disks/ASMDISK4 aun=2 | more
kfbh.endian:                          1 ; 0x000: 0x01
kfbh.hard:                          130 ; 0x001: 0x82
kfbh.type:                            6 ; 0x002: KFBTYP_DISKDIR
kfddde[0].entry.incarn:               1 ; 0x024: A=1 NUMM=0x0
kfddde[0].entry.hash:                 0 ; 0x028: 0x00000000
kfddde[0].entry.refer.number:4294967295 ; 0x02c: 0xffffffff
kfddde[0].entry.refer.incarn:         0 ; 0x030: A=0 NUMM=0x0
kfddde[0].dsknum:                     0 ; 0x034: 0x0000
kfddde[0].state:                      2 ; 0x036: KFDSTA_NORMAL
kfddde[0].ddchgfl:                  132 ; 0x037: 0x84
kfddde[0].dskname:             ASMDISK1 ; 0x038: length=8
kfddde[0].fgname:              ASMDISK1 ; 0x058: length=8
kfddde[0].crestmp.hi:          32960657 ; 0x078: HOUR=0x11 DAYS=0x4 MNTH=0xc YEAR=0x7db
kfddde[0].crestmp.lo:        2843202560 ; 0x07c: USEC=0x0 MSEC=0x1f5 SECS=0x17 MINS=0x2a
kfddde[0].failstmp.hi:                0 ; 0x080: HOUR=0x0 DAYS=0x0 MNTH=0x0 YEAR=0x0
kfddde[0].failstmp.lo:                0 ; 0x084: USEC=0x0 MSEC=0x0 SECS=0x0 MINS=0x0
kfddde[0].timer:                      0 ; 0x088: 0x00000000
kfddde[0].size:                    4094 ; 0x08c: 0x00000ffe
kfddde[0].srRloc.super.hiStart:       0 ; 0x090: 0x00000000
kfddde[0].srRloc.super.loStart:       0 ; 0x094: 0x00000000
kfddde[0].srRloc.super.length:        0 ; 0x098: 0x00000000
kfddde[0].srRloc.incarn:              0 ; 0x09c: 0x00000000
kfddde[0].dskrprtm:                   0 ; 0x0a0: 0x00000000
kfddde[0].zones[0].start:             0 ; 0x0a4: 0x00000000
kfddde[0].zones[0].size:           4094 ; 0x0a8: 0x00000ffe
kfddde[0].zones[0].used:             47 ; 0x0ac: 0x0000002f
kfddde[1].entry.incarn:               1 ; 0x1e4: A=1 NUMM=0x0
kfddde[1].entry.hash:                 1 ; 0x1e8: 0x00000001
kfddde[1].entry.refer.number:4294967295 ; 0x1ec: 0xffffffff
kfddde[1].entry.refer.incarn:         0 ; 0x1f0: A=0 NUMM=0x0
kfddde[1].dsknum:                     1 ; 0x1f4: 0x0001
kfddde[1].state:                      2 ; 0x1f6: KFDSTA_NORMAL
kfddde[1].ddchgfl:                  132 ; 0x1f7: 0x84
kfddde[1].dskname:             ASMDISK2 ; 0x1f8: length=8
kfddde[2].entry.incarn:               1 ; 0x3a4: A=1 NUMM=0x0
kfddde[2].entry.hash:                 2 ; 0x3a8: 0x00000002
kfddde[2].entry.refer.number:4294967295 ; 0x3ac: 0xffffffff
kfddde[2].entry.refer.incarn:         0 ; 0x3b0: A=0 NUMM=0x0
kfddde[2].dsknum:                     2 ; 0x3b4: 0x0002
kfddde[2].state:                      2 ; 0x3b6: KFDSTA_NORMAL
kfddde[2].ddchgfl:                  132 ; 0x3b7: 0x84
kfddde[2].dskname:             ASMDISK3 ; 0x3b8: length=8

The disk information is in the kfddde fields, where kfddde[0] is about disk 0, kfddde[1] is about disk 1, and so on. This way we can access all information about all disks for this disk group. As it can be seen, most of the information is externalized via the V$ASM_DISK views.


The ASM disk directory maintains the information about the disks in the ASM disk groups. That information is externalized via V$ASM_DISK views and can also be accessed via the kfed utility.