天天看點

Oracle ASM 翻譯系列第十五彈:ASM Internal ASM File Directory

本篇主要介紹asm的1号檔案,asm的1号檔案是asm的檔案目錄,它記錄了磁盤組中的所有檔案資訊,由于在asm中,每一個磁盤組都是獨立的存儲單元,是以每一個磁盤組都會有屬于它自己的檔案目錄。

雖然這是一個内部的檔案,但asm執行個體會把它當做其它asm檔案一樣管理,在asm的檔案目錄中也會有它自己的條目(指向了它自己),在一個normal和high備援的磁盤組中,它也會做鏡像,随着新檔案的産生,檔案目錄的大小也會相應地增長。

每一個asm檔案目錄的條目都會包含如下的資訊:

· 檔案大小

· 檔案塊大小

· 檔案類型

· 檔案的備援級别

· 檔案的條帶配置

· 前60個extent的位置指針

· 如果檔案超過60個extent,那麼會有indirect extent 的指針

· 檔案建立時間戳

· 檔案最後的修改時間戳

· 指向asm alias目錄的檔案名

每個新增加的asm檔案會配置設定到一個号碼,這個号碼是随着新增檔案而順序遞增的。檔案的号碼與檔案目錄中的block号碼也是完全對應的,也就是說,檔案目錄的1号block描述了他自己也就是1号檔案的資訊。2号block是描述2号檔案的,300号block是描述300号檔案的,4000号block是關于4000号檔案的,以此類推。如下,是asm的257号檔案,kfbh.block.blk指出了檔案目錄裡塊的編号,此編号也是檔案的編号。

kfed read /dev/qdata/vdf aun=50 blkn=1| grep kfbh.block.blk

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

不存在編号為0的asm檔案,是以檔案目錄的0号block不描述任何檔案的資訊。

asm檔案目錄與asm的at表是兩個相輔相成的資料結構。alter diskgroup check指令可以檢查兩個資料結構是不是一緻的。

譯者注:通過為alter diskgroup check語句可以用來校驗磁盤組元資訊的内部一緻性,可以指定在磁盤組、磁盤、檔案、failgroup級别進行元資訊一緻性的校驗,能夠成功執行此指令的前提條件是磁盤組必須處于mount狀态。預設情況下,check disk group 子句會校驗所有的元資訊目錄,在校驗過程中如果有錯誤資訊,會記錄在asm的alert檔案中,check語句一般會執行如下的操作:1)檢查磁盤的一緻性 2)檢查檔案extent map和at表之間的一緻性 3)檢查alias元資訊目錄和檔案目錄之間對應關系的正确性 4)檢查alias目錄樹的正确性 5) 檢查asm元資訊目錄是否有不可通路的塊。我們可以在語句中添加repair或norepair關鍵字來指定asm是否嘗試修複檢查過程中發生的錯誤,預設為norepair。

asm檔案目錄中描述的大部分資訊都可以通過v$asm_file視圖查詢到。對于處于mount狀态的磁盤組中的每個檔案,該視圖中會以一行來展示。然而,該視圖中并不會顯示asm元資訊檔案的資訊。v$asm_file視圖中沒有描述檔案名的列,是以為了得到一個有意義的輸出,同時我們還需要聯合v$asm_alias視圖。

請看如下示例。

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>

不同磁盤組中的檔案可以有相同的檔案編号。

我們可以在asm執行個體中通過查詢x$kffxp視圖來擷取磁盤組data中編号為1的檔案所配置設定的au。

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)

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.

以上結果中我們可以有兩個發現:asm檔案目錄為三重備援(每個virtual extent都有3個physical extent);目前asm檔案目錄包含兩個virtual extent。

當au大小為1mb且asm元資訊block大小為4kb時,一個au可以容納256個目錄條目。檔案編号1-255是為asm元資訊檔案預留,是以0号extent隻用來容納元資訊檔案的條目,1号extent則容納接下來的256個非元資訊檔案的資訊,以此類推。

譯者注:譯者認為這裡作者遺漏了一個很重要的定位asm一号檔案的方法,通過kfed 讀取asm磁盤頭的kfdhdb.f1b1locn部分,可以獲得asm一号檔案所在的au,例如下面的例子裡顯示了一号檔案在磁盤的2号au處,如果kfdhdb.f1b1locn的值為0,代表這個磁盤并沒有一号檔案的拷貝。

#kfed read /dev/qdata/vdh| grep kfdhdb.f1b1locn

kfdhdb.f1b1locn:                      2 ; 0x0d4: 0x00000002

接下來我們通過以下查詢看看哪些檔案是被我的asm執行個體所管理的。

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

我們看到asm執行個體管理着一組典型的資料庫檔案。接下來再繼續深入剖析。

查詢該資料庫的控制檔案名。

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

接下來看一下262号檔案(current.262.822925011)對應的的檔案目錄條目。首先,通過查詢x$kffxp獲得該檔案的extent和au分布:

and number_kffxp=262 -- file 262 (control file)

and xnum_kffxp <> 2147483648

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.

我們看到執行個體為該檔案配置設定了24個virtual extent,并且該檔案是三倍備援。接下來查詢data磁盤組包含的磁盤的編号和路徑。

sql> select disk_number, path

from v$asm_disk

disk_number path

----------- ---------

         0 /dev/sdb1

         1 /dev/sdc1

         2 /dev/sdd1

         3 /dev/sde1

現在我們通過kfed工具來檢視該檔案的asm檔案目錄條目,它會在檔案目錄的262号block,也就是檔案目錄中1号extent的6号block(262減去256得出6)。1号extent位于2号磁盤的第48個au,并在1号磁盤的第46個au和0号磁盤的第47個au上分别存在一份備援。我們隻需要看其中一個即可。下面我們來看看2号磁盤的第48個au。

$ 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

$

通過以上kfed指令輸出中的第一部分kfbh字段,我們确認這是一個asm檔案目錄的block(kfbh.type=kfbtyp_filedir),而且是描述262号檔案的(kfbh.block.blk=262)。

第二部分kfffdb字段則包含:

· file incarnation number (kfffdb.node.incarn=822925011), 檔案的incarnation号,屬于檔案名的一部分

· file size in bytes (kfffdb.lobytes=17973248) 檔案的大小

· physical extent count (kfffdb.xtntcnt=72) 檔案的實體extent數

· file block size in bytes (kfffdb.blksize=16384) 檔案的塊大小

· file type (kfffdb.filetype=1), i.e. the database control file 檔案的類型,這裡為控制檔案

第三部分kfffde為實體extent分布,這部分輸出與從x$kffxp中查詢到的結果一緻:

physical extent 0 在 au 776 (kfffde[0].xptr.au=776), 在 disk 3 (kfffde[0].xptr.disk=3) physical extent 1 在 au 778 (kfffde[1].xptr.au=778), 在 disk 1 (kfffde[1].xptr.disk=1) physical extent 2 在 au 779 (kfffde[2].xptr.au=779), 在 disk 2 (kfffde[2].xptr.disk=2)

以此類推

本文中所指的大檔案指的是超過60個extent的檔案。

先到資料庫中找出幾個大的檔案:

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

以system表空間的資料檔案為例,我們看一下該檔案對應的檔案目錄條目。該檔案編号為256,大小為720mb。

sql> select xnum_kffxp "extent", au_kffxp "au", disk_kffxp "disk"

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.

我們看到asm執行個體為該檔案配置設定了1442個實體extent。

我們再次用kfed工具來檢視該檔案的檔案目錄條目。它位于asm檔案目錄的256号block,這個塊位于48号au,塊0。讓我們檢視0号disk第48個au的0号block。

譯者注:1号檔案的第一個au保留的是1-255号檔案的資訊(元資訊檔案),我們的256号檔案,要從1号檔案的第二個au開始算起,由于au的塊編号是從0号塊開始,是以256号檔案位于第二個au也就是48号au的0号塊。

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

kfbh.hard:                          130 ; 0x001: 0x82

kfffdb.node.incarn:           769030243 ; 0x000: a=1 numm=0x16eb3c31

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

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

0-59号extent(kfffde[0]-kfffde[59])被稱作directly addressed extent,因為它們直接指向資料extent。而編号59以上的extent,被稱為indirectly addressed extent,因為它們指向的extent持有的是剩餘extent的資訊。

接下來對1号磁盤(kfffde[60].xptr.disk=1)的58号au(kfffde[60].xptr.au=58)進行檢視。

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

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:            

<b>本文來自雲栖社群合作夥伴“dbgeek”</b>