【转】ASM File Directory

1

The ASM file number 1 – the ASM File Directory – keeps track of all files in a disk group. As the disk groups are independent storage units, each disk group will have its own ASM file directory.

 

While this is an internal (ASM metadata) file, it is managed like any other file in the disk group. It will have its own entry in the ASM file directory (yes, pointing to itself), it will be mirrored in a normal and high redundancy disk group and will automatically grow to keep information about new files.

 

Each ASM file directory entry maintains the following information:

  • File size
  • File block size
  • File type
  • File redundancy level
  • File striping configuration
  • Direct extent pointers for up to 60 extents
  • Indirect extent pointers (if the file has more than 60 extents)
  • File creation time-stamp
  • File last modification time-stamp
  • Pointer to the file name in the ASM Alias Directory

 

A sequential number is assigned to each new file managed by ASM. That file number corresponds to the block number in the ASM file directory. Thus, block 1 of the ASM file directory describes itself – the file number 1. Block 2 is about file 2, block 300 is about file 300, block 4000 is about file 4000, and so on.

 

Note that there is no ASM file 0, so block 0 of the ASM file directory is not describing any files.

 

The ASM file directory and the ASM Allocation Table are complementary data structures. The ALTER DISKGROUP CHECK command checks if those two data structures are in agreement.

 

V$ASM_FILE and V$ASM_ALIAS views

 

Most of the information maintained in the ASM file directories can be accessed via the V$ASM_FILE view. That view displays one row for every ASM file in every mounted disk group. Note that this view will not show ASM metadata files. The V$ASM_FILE does not have the filename column, so for a meaningful output, we would have to query it together with the V$ASM_ALIAS view.

 

Here is an example:

 

SQL> SELECT f.group_number, f.file_number, a.name, f.type

FROM v$asm_file f, v$asm_alias a

WHERE f.group_number=a.group_number and f.file_number=a.file_number

ORDER BY 1, 2;

 

GROUP_NUMBER FILE_NUMBER NAME                   TYPE

———— ———– ———————- —————-

1         253 REGISTRY.253.769023761 ASMPARAMETERFILE

1         256 SYSTEM.256.769030243   DATAFILE

1         257 SYSAUX.257.769030245   DATAFILE

1         258 UNDOTBS1.258.769030245 DATAFILE

1         259 USERS.259.769030245    DATAFILE

1         260 Current.260.769030435  CONTROLFILE

1         261 Current.261.769030431  CONTROLFILE

1         262 group_1.262.769030439  ONLINELOG

1         263 group_1.263.769030445  ONLINELOG

1         264 group_2.264.769030453  ONLINELOG

3         256 Current.256.771527253  CONTROLFILE

3         257 group_1.257.771527259  ONLINELOG

3         258 group_1.258.771527263  ONLINELOG

 

34 rows selected.

 

SQL>

 

Note that the files in different disk groups can have the same ASM file number.

 

Locating the ASM file directory

 

We can query the fixed table X$KFFXP in the ASM instance, to find out which allocation units belong to file 1, in disk group DATA:

 

SQL> SELECT xnum_kffxp “Virtual extent”,

pxn_kffxp “Physical extent”,

au_kffxp “Allocation unit”,

disk_kffxp “Disk”

FROM x$kffxp

WHERE group_kffxp=1 — Diskgroup 1 (DATA)

and number_kffxp=1 — File 1 (file directory)

ORDER BY 1, 2;

 

Virtual extent Physical extent Allocation unit       Disk

————– ————— ————— ———-

0               0              10          0

0               1              10          1

0               2              10          2

1               3              48          2

1               4              46          1

1               5              47          0

 

6 rows selected.

 

SQL>

 

The result shows two things – that the ASM file directory is triple mirrored (note the three physical extents for each virtual extent) and that the current size of the ASM file directory is 2 (virtual) extents.

 

With the allocation unit size of 1MB and the ASM metadata block size of 4KB, one allocation unit can hold up to 256 directory entries. As numbers 1-255 are reserved for the ASM metadata files, extent 0 will only have enough room for the ASM metadata files. Extent 1 will hold information about next 256 files managed by the ASM and so on.

 

ASM file directory entries for database files

 

Let’s see which files are managed by my ASM instance. To find out, I run the following query against the ASM instance:

 

SQL> SELECT file_number “ASM file number”, name “File name”

FROM v$asm_alias

WHERE group_number=1

ORDER BY 1;

 

ASM file number File name

————— ———————-

253 REGISTRY.253.769023761

256 SYSTEM.256.769030243

257 SYSAUX.257.769030245

258 UNDOTBS1.258.769030245

259 USERS.259.769030245

260 Current.260.769030435

261 Current.261.769030431

262 group_1.262.769030439

263 group_1.263.769030445

264 group_2.264.769030453

265 group_2.265.769030461

266 group_3.266.769030471

267 group_3.267.769030479

268 TEMP.268.769030503

269 EXAMPLE.269.769030517

270 spfile.270.769030977

 

SQL>

 

As we see my ASM instance is managing a typical set of database files. Let’s have a closer look at those files.

 

File directory entries for control files

 

Query the database for its control files.

 

SQL> SELECT name “File”,

block_size “Block size”,

block_size*(file_size_blks+1) “File size”

FROM v$controlfile;

 

File                                       Block size  File size

—————————————— ———- ———-

+DATA/BR/CONTROLFILE/current.262.822925011      16384   17973248

+DATA/BR/CONTROLFILE/current.261.822925013      16384   17973248

 

SQL>

 

Let’s now look at the ASM file directory entry for ASM file 262 (current.262.822925011). First, we query the X$KFFXP view in the ASM instance, to get the extent and AU distribution:

 

SQL> SELECT xnum_kffxp “Virtual extent”,

pxn_kffxp “Physical extent”,

au_kffxp “Allocation unit”,

disk_kffxp “Disk”

FROM x$kffxp

WHERE group_kffxp=1 — Diskgroup 1 (DATA)

and number_kffxp=262 — File 262 (control file)

and xnum_kffxp <> 2147483648

ORDER BY 1, 2;

 

Virtual extent Physical extent Allocation unit Disk

————– ————— ————— —-

0               0             776    3

0               1             778    1

0               2             779    2

1               3             781    0

1               4             777    3

1               5             779    1

2               6             780    2

2               7             780    1

2               8             778    3

23              69             795    1

23              70             793    3

23              71             798    0

 

72 rows selected.

 

SQL>

 

We see that there are 24 (virtual) extents allocated for this file and that the file is triple mirrored. The following query gives me the disk numbers and paths for ASM disks in disk group DATA:

 

SQL> SELECT disk_number, path

FROM v$asm_disk

WHERE group_number=1

ORDER BY 1;

 

DISK_NUMBER PATH

———– ———

0 /dev/sdb1

1 /dev/sdc1

2 /dev/sdd1

3 /dev/sde1

 

SQL>

 

Let’s now use the kfed tool to look at the ASM file directory entry for this file. Remember, that will be block 262, i.e. block 6 (262-256) in the (virtual) extent 1 of the ASM file directory. The extent 1 is in AU 48 on disk 2, also mirrored in AU 46 on disk 1, and mirrored in AU 47 on disk 0. We only need to look at one of those. Let’s look at block 6 in AU 48, on disk 2:

 

$ kfed read /dev/sdd1 aun=48 blkn=6 | more

kfbh.endian:                          1 ; 0x000: 0x01

kfbh.hard:                        130 ; 0x001: 0x82

kfbh.type:                            4 ; 0x002: KFBTYP_FILEDIR

kfbh.datfmt:                          1 ; 0x003: 0x01

kfbh.block.blk:                   262 ; 0x004: blk=262

kfffdb.node.incarn:         822925011 ; 0x000: A=1 NUMM=0x18866b69

kfffdb.node.frlist.number: 4294967295 ; 0x004: 0xffffffff

kfffdb.node.frlist.incarn:            0 ; 0x008: A=0 NUMM=0x0

kfffdb.hibytes:                       0 ; 0x00c: 0x00000000

kfffdb.lobytes:              17973248 ; 0x010: 0x01124000

kfffdb.xtntcnt:                    72 ; 0x014: 0x00000048

kfffdb.xtnteof:                    72 ; 0x018: 0x00000048

kfffdb.blkSize:                 16384 ; 0x01c: 0x00004000

kfffdb.flags:                      19 ; 0x020: O=1 S=1 S=0 D=0 C=1 I=0 R=0 A=0

kfffdb.fileType:                    1 ; 0x021: 0x01

kfffde[0].xptr.au:                776 ; 0x4a0: 0x00000308

kfffde[0].xptr.disk:                3 ; 0x4a4: 0x0003

kfffde[0].xptr.flags:               0 ; 0x4a6: L=0 E=0 D=0 S=0

kfffde[0].xptr.chk:                34 ; 0x4a7: 0x22

kfffde[1].xptr.au:                778 ; 0x4a8: 0x0000030a

kfffde[1].xptr.disk:                1 ; 0x4ac: 0x0001

kfffde[1].xptr.flags:               0 ; 0x4ae: L=0 E=0 D=0 S=0

kfffde[1].xptr.chk:                34 ; 0x4af: 0x22

kfffde[2].xptr.au:                779 ; 0x4b0: 0x0000030b

kfffde[2].xptr.disk:                2 ; 0x4b4: 0x0002

kfffde[2].xptr.flags:               0 ; 0x4b6: L=0 E=0 D=0 S=0

kfffde[2].xptr.chk:                32 ; 0x4b7: 0x20

 

$

 

The first part of the kfed output (the kfbh fields) confirm this is an ASM file directory block (kfbh.type=KFBTYP_FILEDIR), for file 262 (kfbh.block.blk=262).

 

The second part of the kfed output (the kfffdb fields) shows:

  • File incarnation number (kfffdb.node.incarn=822925011), which is part of the file name
  • File size in bytes (kfffdb.lobytes=17973248)
  • Physical extent count (kfffdb.xtntcnt=72)
  • File block size in bytes (kfffdb.blkSize=16384)
  • File type (kfffdb.fileType=1), i.e. the database control file

 

The third part of the output (the kfffde fields) shows the physical extent distribution that agrees with the query output from X$KFFXP:

 

Physical extent 0 is in AU 776 (kfffde[0].xptr.au=776), on disk 3 (kfffde[0].xptr.disk=3)

Physical extent 1 is in AU 778 (kfffde[1].xptr.au=778), on disk 1 (kfffde[1].xptr.disk=1)

Physical extent 2 is in AU 779 (kfffde[2].xptr.au=779), on disk 2 (kfffde[2].xptr.disk=2)

 

And so on.

 

File directory entries for large files

 

NOTE: Large files in this context are the files with more than 60 extents.

 

Query the database to find some large files:

 

SQL> SELECT name, bytes/1024/1024 “Size (MB)”

FROM v$datafile;

 

NAME                                          Size (MB)

——————————————– ———-

+DATA/br/datafile/system.256.769030243              720

+DATA/br/datafile/sysaux.257.769030245              590

+DATA/br/datafile/undotbs1.258.769030245            105

+DATA/br/datafile/users.259.769030245                 5

+DATA/br/datafile/example.269.769030517         345.625

 

SQL>

 

Directly addressed extents

 

For an example of the ASM file directory entry for a large file, we will look at the system datafile (system.256.769030243). Note the datafile ASM file number (256) and size (720 MB).

 

SQL> SELECT xnum_kffxp “Extent”, au_kffxp “AU”, disk_kffxp “Disk”

FROM x$kffxp

WHERE group_kffxp=1 and number_kffxp=256 and xnum_kffxp <> 2147483648

ORDER BY 1,2;

 

Extent         AU       Disk

———- ———- ———-

0         42          1

0         48          2

1         43          1

1         49          0

2         44          1

2         45          3

720       1111          1

720       1119          2

 

1442 rows selected.

 

SQL>

 

We see that there are 1442 physical extents allocated for this file.

 

Let’s now use kfed to look at the ASM file directory entry for this file. Remember, that will be block 256, i.e. block 0 (256-256) in extent 1 of the ASM file directory. Let’s look at block 0 in AU 48, on disk 0:

 

$ kfed read /dev/sdb1 aun=48 blkn=0 | more

kfbh.endian:                          1 ; 0x000: 0x01

kfbh.hard:                          130 ; 0x001: 0x82

kfbh.type:                            4 ; 0x002: KFBTYP_FILEDIR

kfffdb.node.incarn:           769030243 ; 0x000: A=1 NUMM=0x16eb3c31

kfffdb.node.frlist.number:   4294967295 ; 0x004: 0xffffffff

kfffdb.node.frlist.incarn:            0 ; 0x008: A=0 NUMM=0x0

kfffdb.hibytes:                       0 ; 0x00c: 0x00000000

kfffdb.lobytes:               754982912 ; 0x010: 0x2d002000

kfffdb.xtntcnt:                    1442 ; 0x014: 0x000005a2

kfffdb.xtnteof:                    1442 ; 0x018: 0x000005a2

kfffdb.blkSize:                    8192 ; 0x01c: 0x00002000

kfffdb.flags:                        17 ; 0x020: O=1 S=0 S=0 D=0 C=1 I=0 R=0 A=0

kfffdb.fileType:                     12 ; 0x021: 0x0c

kfffde[0].xptr.au:                   48 ; 0x4a0: 0x00000030

kfffde[0].xptr.disk:                  2 ; 0x4a4: 0x0002

kfffde[0].xptr.flags:                 0 ; 0x4a6: L=0 E=0 D=0 S=0

kfffde[0].xptr.chk:                  24 ; 0x4a7: 0x18

kfffde[1].xptr.au:                   42 ; 0x4a8: 0x0000002a

kfffde[1].xptr.disk:                  1 ; 0x4ac: 0x0001

kfffde[1].xptr.flags:                 0 ; 0x4ae: L=0 E=0 D=0 S=0

kfffde[1].xptr.chk:                   1 ; 0x4af: 0x01

kfffde[2].xptr.au:                   49 ; 0x4b0: 0x00000031

kfffde[2].xptr.disk:                  0 ; 0x4b4: 0x0000

kfffde[2].xptr.flags:                 0 ; 0x4b6: L=0 E=0 D=0 S=0

kfffde[60].xptr.au:                  58 ; 0x680: 0x0000003a

kfffde[60].xptr.disk:                 1 ; 0x684: 0x0001

kfffde[60].xptr.flags:                0 ; 0x686: L=0 E=0 D=0 S=0

kfffde[60].xptr.chk:                 17 ; 0x687: 0x11

kfffde[61].xptr.au:                  64 ; 0x688: 0x00000040

kfffde[61].xptr.disk:                 0 ; 0x68c: 0x0000

kfffde[61].xptr.flags:                0 ; 0x68e: L=0 E=0 D=0 S=0

kfffde[61].xptr.chk:                106 ; 0x68f: 0x6a

kfffde[62].xptr.au:                  63 ; 0x690: 0x0000003f

kfffde[62].xptr.disk:                 2 ; 0x694: 0x0002

kfffde[62].xptr.flags:                0 ; 0x696: L=0 E=0 D=0 S=0

kfffde[62].xptr.chk:                 23 ; 0x697: 0x17

kfffde[63].xptr.au:          4294967295 ; 0x698: 0xffffffff

kfffde[63].xptr.disk:             65535 ; 0x69c: 0xffff

kfffde[63].xptr.flags:                0 ; 0x69e: L=0 E=0 D=0 S=0

 

$

 

The extents 0-59 (kfffde[0]-kfffde[59]) are called directly addressed as they point directly to data extents. The extents numbers over 59, are called indirectly addressed as they point to extents holding the information about the rest of the file extents.

 

Indirectly addressed extents

 

Let’s look at allocation unit 58 (kfffde[60].xptr.au=58) on disk 1 (kfffde[60].xptr.disk=1).

 

$ kfed read /dev/sdc1 aun=58 | more

kfbh.endian:                          1 ; 0x000: 0x01

kfbh.hard:                          130 ; 0x001: 0x82

kfbh.type:                           12 ; 0x002: KFBTYP_INDIRECT

kffixe[0].xptr.au:                   59 ; 0x00c: 0x0000003b

kffixe[0].xptr.disk:                  3 ; 0x010: 0x0003

kffixe[0].xptr.flags:                 0 ; 0x012: L=0 E=0 D=0 S=0

kffixe[0].xptr.chk:                  18 ; 0x013: 0x12

kffixe[1].xptr.au:                   64 ; 0x014: 0x00000040

kffixe[1].xptr.disk:                  2 ; 0x018: 0x0002

kffixe[1].xptr.flags:                 0 ; 0x01a: L=0 E=0 D=0 S=0

kffixe[1].xptr.chk:                 104 ; 0x01b: 0x68

kffixe[2].xptr.au:                   59 ; 0x01c: 0x0000003b

kffixe[2].xptr.disk:                  1 ; 0x020: 0x0001

kffixe[2].xptr.flags:                 0 ; 0x022: L=0 E=0 D=0 S=0

kffixe[2].xptr.chk:                  16 ; 0x023: 0x10

 

$

 

We see that this is indeed an indirect extent block (kfbh.type=KFBTYP_INDIRECT) and that it holds the extent distribution information for the rest of the system datafile.

 

Conclusion

 

The ASM file directory maintains the information about all files in a disk group – both internal, ASM metadata files, and user or database files. The information about the database files is externalized via the V$ASM_FILE view.

Comment

*

沪ICP备14014813号-2

沪公网安备 31010802001379号