ASM 翻译系列第三十九弹:物理元数据AT表

时间:2022-05-05
本文章向大家介绍ASM 翻译系列第三十九弹:物理元数据AT表,主要内容包括Allocation Table、Finding The Allocation Table、Allocation table entries、Free space、The stride、How Many Allocation Tables、Conclusion、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。

原作者:Bane Radulovic

译者: 魏兴华

审核: 魏兴华

DBGeeK联合出品

原文链接:http://asmsupportguy.blogspot.sg/2013/08/allocation-table.html

Allocation Table

每一块由ASM管理的磁盘都会至少包含一个Allocation Table ,简称AT表,它是用来描述磁盘的AU分布情况的,AT表里的每一个条目都代表了磁盘上的一个AU,一旦某个AU被分配出去,AT表中此条目的内容会被更新,例如此AU属于的extent号和属于哪一个文件。

Finding The Allocation Table

AT表是由N个AT块组成的(不同的AU大小,N的值会不同),它位于ASM磁盘头所在的AU。下面例子里kfed工具的输出显示,AT表开始于磁盘头所在AU(0号AU)的第二个块。

$ kfed read /dev/sdc1 | grep kfdhdb.altlocn
kfdhdb.altlocn:                       2 ; 0x0d0: 0x00000002

我们通过kfed工具来进一步看一下AT表第一个块的细节信息:

$ kfed read /dev/sdc1 blkn=2 | more
kfbh.endian:                          1 ; 0x000: 0x01
kfbh.hard:                          130 ; 0x001: 0x82
kfbh.type:                            3 ; 0x002: KFBTYP_ALLOCTBL
...
kfdatb.aunum:                         0 ; 0x000: 0x00000000
kfdatb.shrink:                      448 ; 0x004: 0x01c0
...

kfdatb.aunum=0意味着AU0是这个AT块所描述的第一个AU,kfdatb.shrink=448 意味着这个AT 块可以包含448个AU的信息。因此不难猜测,在下一个AT块,kfdatb.aunum的值应该为448(AU编号是从0号开始),它包含的是AU 448到AU (448+448)的信息,我们通过kfed来证明一下:

$ kfed read /dev/sdc1 blkn=3 | grep kfdatb.aunum
kfdatb.aunum:                       448 ; 0x000: 0x000001c0

同样,第三个AT块(AU的第四个块)应该显示kfdatb.aunum=896:

$ kfed read /dev/sdc1 blkn=4 | grep kfdatb.aunum
kfdatb.aunum:                       896 ; 0x000: 0x00000380

以此类推。

Allocation table entries

使用kfed工具可以读取AT表的内容,对于已经从磁盘中分配出去的AU,会在AT表相关条目上记录相应的extent号,文件号和au的状态,对于已经分配出去的AU,flag V=1,否则,flag V=0,例如AU还没有分配给具体的文件或者已经释放掉的AU,V的值会是0。

我们通过kfed工具来看下AT表上块的内容:

$ kfed read /dev/sdc1 blkn=3 | more
kfbh.endian:                          1 ; 0x000: 0x01
kfbh.hard:                          130 ; 0x001: 0x82
kfbh.type:                            3 ; 0x002: KFBTYP_ALLOCTBL
...
kfdatb.aunum:                       448 ; 0x000: 0x000001c0
...
kfdate[142].discriminator:            1 ; 0x498: 0x00000001
kfdate[142].allo.lo:                  0 ; 0x498: XNUM=0x0
kfdate[142].allo.hi:            8388867 ; 0x49c: V=1 I=0 H=0 FNUM=0x103
kfdate[143].discriminator:            1 ; 0x4a0: 0x00000001
kfdate[143].allo.lo:                  1 ; 0x4a0: XNUM=0x1
kfdate[143].allo.hi:            8388867 ; 0x4a4: V=1 I=0 H=0 FNUM=0x103
kfdate[144].discriminator:            1 ; 0x4a8: 0x00000001
kfdate[144].allo.lo:                  2 ; 0x4a8: XNUM=0x2
kfdate[144].allo.hi:            8388867 ; 0x4ac: V=1 I=0 H=0 FNUM=0x103
kfdate[145].discriminator:            1 ; 0x4b0: 0x00000001
kfdate[145].allo.lo:                  3 ; 0x4b0: XNUM=0x3
kfdate[145].allo.hi:            8388867 ; 0x4b4: V=1 I=0 H=0 FNUM=0x103
kfdate[146].discriminator:            1 ; 0x4b8: 0x00000001
kfdate[146].allo.lo:                  4 ; 0x4b8: XNUM=0x4
kfdate[146].allo.hi:            8388867 ; 0x4bc: V=1 I=0 H=0 FNUM=0x103
kfdate[147].discriminator:            1 ; 0x4c0: 0x00000001
kfdate[147].allo.lo:                  5 ; 0x4c0: XNUM=0x5
kfdate[147].allo.hi:            8388867 ; 0x4c4: V=1 I=0 H=0 FNUM=0x103
kfdate[148].discriminator:            0 ; 0x4c8: 0x00000000
kfdate[148].free.lo.next:            16 ; 0x4c8: 0x0010
kfdate[148].free.lo.prev:            16 ; 0x4ca: 0x0010
kfdate[148].free.hi:                  2 ; 0x4cc: V=0 ASZM=0x2
kfdate[149].discriminator:            0 ; 0x4d0: 0x00000000
kfdate[149].free.lo.next:             0 ; 0x4d0: 0x0000
kfdate[149].free.lo.prev:             0 ; 0x4d2: 0x0000
kfdate[149].free.hi:                  0 ; 0x4d4: V=0 ASZM=0x0
...

译者注:kfdate[i].allo.lo的值代表了文件的物理的extent号,即视图X$KFFXP的PXN_KFFXP字段。

上面摘录的信息显示,ASM的259号文件 (十六进制FNUM=0x103转换后)在AT表中占用了一些条目,从kfdate[142] 开始到 kfdate[147],共包含了6个AU,AU的绝对AU号计算方式为kfdate[i] + offset (kfdatb.aunum=448),也就是说142+448=590, 143+448=591 ... 147+448=595,可以通过查询X$KFFXP视图得到证实:

SQL> select AU_KFFXP
from X$KFFXP
where GROUP_KFFXP=1  -- disk group 1
and NUMBER_KFFXP=259 -- file 259
;
  AU_KFFXP
----------
       590
       591
       592
       593
       594
       595
6 rows selected.

译者注:视图X$KFFXP记录的信息,准确的说是extent的信息而非AU,当文件的extent数量大于20000的时候,AU_KFFXP字段的值仅仅代表了这个extent的起始AU号。例如下面的语句查看了496号文件的前几个extent和大于20000以后的4个extent,前几个的AU_KFFXP(Allocation unit)值是连续的,大于20000的Allocation unit值是跳跃的,这是因为AU_KFFXP的值只代表了这个extent起始的AU号。SIZE_KFFXP的值代表了这个extent是由几个AU组成的。

select XNUM_KFFXP "Virtual extent", PXN_KFFXP "Physical extent", LXN_KFFXP "Extent copy", DISK_KFFXP "Disk", AU_KFFXP "Allocation unit",SIZE_KFFXP
from X$KFFXP
where GROUP_KFFXP=1 and NUMBER_KFFXP=496 and SIZE_KFFXP=1 and DISK_KFFXP=2
and rownum<10
union all
select XNUM_KFFXP "Virtual extent", PXN_KFFXP "Physical extent", LXN_KFFXP "Extent copy", DISK_KFFXP "Disk", AU_KFFXP "Allocation unit",SIZE_KFFXP
from X$KFFXP
where GROUP_KFFXP=1 and NUMBER_KFFXP=496 and AU_KFFXP>384224 and DISK_KFFXP=2
;
Virtual extent Physical extent Extent copy   Disk Allocation unit SIZE_KFFXP
-------------- --------------- ----------- ---------- --------------- ----------
         2           5       1      2          380130          1
         6          12       0      2          380131          1
        16          32       0      2          380132          1
        24          49       1      2          380133          1
        26          52       0      2          380134          1
        29          59       1      2          380135          1
        36          72       0      2          380136          1
        46          92       0      2          380137          1
        50         101       1      2          380138          1
     21150       42300       0      2          384228          4
     21156       42313       1      2          384232          4
     21160       42320       0      2          384236          4
     21170       42340       0      2          384240          4

通过在AT表中搜索某个虚拟extent号大于20000的extent也可以看出,它是由4个AU组成的。

for (( i=0; i<256; i++ ))
do
kfed read /dev/mmm/path-102.321.01.fioa  blkn=$i | grep 45340
done
kfdate[388].allo.lo:              45340 ; 0xc48: XNUM=0xb11c
kfdate[389].allo.lo:              45340 ; 0xc50: XNUM=0xb11c
kfdate[390].allo.lo:              45340 ; 0xc58: XNUM=0xb11c
kfdate[391].allo.lo:              45340 ; 0xc60: XNUM=0xb11c

Free space

在上面kfed的输出中,我们可以看到kfdate[148] 和 kfdate[149]是free的AU,因为标志V=0(kfdate[148].free.hi: 2 ; 0x4cc: V=0 ASZM=0x2),后面的输出被我人为的截断掉了,其实这个AT块中还有很多没有被分配出去的free的AU。

The stride

每一个AT块(4K)可以描述448个AU(kfed输出的kfdatb.shrink值表明了这一点),每一个AT表有254个块(Free Space Table块中的 kfdfsb.max的值表明了这一点,关于Free Space Table块的内容请参考本系列的Free Space Table章节)。这意味着一个AT表可以用来描述254*448= 113792个AU。这在ASM里被称为一个stride,一个stride可以描述的AU在ASM的磁盘头的kfdhdb.mfact部分看到:

$ kfed read /dev/sdc1 | grep kfdhdb.mfact

kfdhdb.mfact: 113792 ; 0x0c0: 0x0001bc80

在我们例子中,AU的size是1M,AU0可以装载256个元数据块,块0是磁盘头块,块1是Free Space Table,剩余254个块就是作为AT表的块。

假如AU的size是4M(Exadata的默认值),一个stride能够容纳的AU就会是454272或者说是454272*4= 1817088M,越大的AU size,stride也可以变得更大。

How Many Allocation Tables

大的ASM磁盘stride的数量会不止一个,每一个stride都会有它自己的物理元数据,也就是会有它自己的AT表。

例如,我们找一个大的磁盘,看下第二个stride的物理元数据,它同样是位于这个stride的第一个AU中,我们来看下:

$ kfed read /dev/sdc1 | grep mfact

kfdhdb.mfact: 113792 ; 0x0c0: 0x0001bc80

上面显示了第一个stride包含了113792 AU,可以推算出第二个stride位于第113792 AU中(注意AU号是从0号开始计算的),AT表位于这个AU中的第2-255个块。

$ kfed read /dev/sdc1 aun=113792 blkn=2 | grep type

kfbh.type: 3 ; 0x002: KFBTYP_ALLOCTBL

...

$ kfed read /dev/sdc1 aun=113792 blkn=255 | grep type

kfbh.type: 3 ; 0x002: KFBTYP_ALLOCTBL

跟我们预测的一样,我们有第二个AT在第113792AU中,继续,如果有第三个stride,那么AT同样位于stride的开始AU处。

$ kfed read /dev/sdc1 aun=227584 blkn=2 | grep type

kfbh.type: 3 ; 0x002: KFBTYP_ALLOCTBL

Conclusion

每一个ASM磁盘可能会包含不止一个AT表,AT表描述了磁盘的AU分配情况,AT表中的每一个条目代表了磁盘上的一个AU,如果磁盘比较大,可以有不止一个stride,每一个stride都会有它自己的AT表。

文件。