This post is about the amount of space allocated to ASM based files.
The smallest amount of space ASM allocates is an allocation unit (AU). The default AU size is 1 MB, except in Exadata where the default AU size is 4 MB.
The space for ASM based files is allocated in extents, which consist of one or more AUs. In version 11.2, the first 20000 extents consist of 1 AU, next 20000 extents have 4 AUs, and extents beyond that have 16 AUs. This is known as variable size extent feature. In version 11.1, the extent growth was 1-8-64 AUs. In version 10, we don't have variable size extents, so all extents sizes are exactly 1 AU.
Bytes vs space
The definition for V$ASM_FILE view says the following for BYTES and SPACE columns:
- BYTES - Number of bytes in the file
- SPACE - Number of bytes allocated to the file
There is a subtle difference in the definition and very large difference in numbers. Let's have a closer look. For the examples in this post I will use database and ASM version 11.2.0.3, with ASMLIB based disks.
First get some basic info about disk group DATA where most of my datafiles are. Run the following SQL connected to the database instance.
SQL> select NAME, GROUP_NUMBER, ALLOCATION_UNIT_SIZE/1024/1024 "AU size (MB)", TYPE
from V$ASM_DISKGROUP
where NAME='DATA';
NAME GROUP_NUMBER AU size (MB) TYPE
---------------- ------------ ------------ ------
DATA 1 1 NORMAL
Now create one small file (under 60 extents) and one large file (over 60 extents).
SQL> create tablespace T1 datafile '+DATA' size 10 M;
Tablespace created.
SQL> create tablespace T2 datafile '+DATA' size 100 M;
Tablespace created.
Get the ASM file numbers for those two files:
SQL> select NAME, round(BYTES/1024/1024) "MB" from V$DATAFILE;
NAME MB
------------------------------------------ ----------
...
+DATA/br/datafile/t1.272.818281717 10
+DATA/br/datafile/t2.271.818281741 100
The small file is ASM file number 272 and the large file is ASM file number 271.
Get the bytes and space information (in AUs) for these two files.
SQL> select FILE_NUMBER, round(BYTES/1024/1024) "Bytes (AU)", round(SPACE/1024/1024) "Space (AUs)", REDUNDANCY
from V$ASM_FILE
where FILE_NUMBER in (271, 272) and GROUP_NUMBER=1;
FILE_NUMBER Bytes (AU) Space (AUs) REDUND
----------- ---------- ----------- ------
272 10 22 MIRROR
271 100 205 MIRROR
The bytes shows the actual file size. For the small file, bytes shows the file size is 10 AUs = 10 MB (the AU size is 1 MB). The space required for the small file is 22 AUs. 10 AUs for the actual datafile, 1 AU for the file header and because the file is mirrored, double that, so 22 AUs in total.
For the large file, bytes shows the file size is 100 AUs = 100 MB. So far so good. But the space required for the large file is 205 AUs, not 202 as one might expect. What are those extra 3 AUs for? Let's find out.
ASM space
The following query (run in ASM instance) will show us the extent distribution for ASM file 271.
SQL> select XNUM_KFFXP "Virtual extent", PXN_KFFXP "Physical extent", DISK_KFFXP "Disk number", AU_KFFXP "AU number"
from X$KFFXP
where GROUP_KFFXP=1 and NUMBER_KFFXP=271
order by 1,2;
Virtual extent Physical extent Disk number AU number
-------------- --------------- ----------- ----------
0 0 3 1155
0 1 0 1124
1 2 0 1125
1 3 2 1131
2 4 2 1132
2 5 0 1126
...
100 200 3 1418
100 201 1 1412
2147483648 0 3 1122
2147483648 1 0 1137
2147483648 2 2 1137
205 rows selected.
As the file is mirrored, we see that each virtual extent has two physical extents. But the interesting part of the result are the last three allocation units for virtual extent number 2147483648, that is triple mirrored. We will have a closer look at those with kfed, and for that we will need disk names.
Get the disk names.
SQL> select DISK_NUMBER, PATH
from V$ASM_DISK
where GROUP_NUMBER=1;
DISK_NUMBER PATH
----------- ---------------
0 ORCL:ASMDISK1
1 ORCL:ASMDISK2
2 ORCL:ASMDISK3
3 ORCL:ASMDISK4
Let's now check what type of data is in those allocation units.
$ kfed read /dev/oracleasm/disks/ASMDISK4 aun=1122 | grep type
kfbh.type: 12 ; 0x002: KFBTYP_INDIRECT
$ kfed read /dev/oracleasm/disks/ASMDISK1 aun=1137 | grep type
kfbh.type: 12 ; 0x002: KFBTYP_INDIRECT
$ kfed read /dev/oracleasm/disks/ASMDISK3 aun=1137 | grep type
kfbh.type: 12 ; 0x002: KFBTYP_INDIRECT
These additional allocation units hold ASM metadata for the large file. More specifically they hold extent map information that could not fit into the the ASM file directory block. The file directory needs extra space to keep track of files larger than 60 extents, so it needs an additional allocation unit to do so. While the file directory needs only few extra ASM metadata blocks, the smallest unit of space the ASM can allocate is an AU. And because this is metadata, this AU is triple mirrored (even in a normal redundancy disk group), hence 3 extra allocation units for the large file. In an external redundancy disk group, there would be only one extra AU per large file.
Conclusion
The amount of space ASM needs for a file, depends on two factors - the file size and the disk group redundancy.
In an external redundancy disk group, the required space will be the file size + 1 AU for the file header + 1 AU for indirect extents if the file is larger than 60 AUs.
In a normal redundancy disk group, the required space will be twice the file size + 2 AUs for the file header + 3 AUs for indirect extents if the file is larger than 60 AUs.
In a high redundancy disk group, the required space will be three times the file size + 3 AUs for the file header + 3 AUs for indirect extents if the file is larger than 60 AUs.