本篇主要介紹ASM的1號文件,ASM的1號文件是ASM的文件目錄,它記錄了磁盤組中的所有文件信息,由于在ASM中,每一個磁盤組都是獨立的存儲單元,所以每一個磁盤組都會有屬于它自己的文件目錄。
雖然這是一個內部的文件,但ASM實例會把它當做其它ASM文件一樣管理,在ASM的文件目錄中也會有它自己的條目(指向了它自己),在一個normal和high冗余的磁盤組中,它也會做鏡像,隨著新文件的產生,文件目錄的大小也會相應地增長。
每一個ASM文件目錄的條目都會包含如下的信息:
每個新增加的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。
V$ASM_FILE and V$ASM_ALIAS views
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) 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>
以上結果中我們可以有兩個發現: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 ... SQL>
我們看到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 SQL>
接下來看一下262號文件(current.262.822925011)對應的的文件目錄條目。首先,通過查詢X$KFFXP獲得該文件的extent和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=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>
我們看到實例為該文件分配了24個virtual extent,并且該文件是三倍冗余。接下來查詢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>
現在我們通過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字段則包含:
第三部分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 SQL>
以system表空間的數據文件為例,我們看一下該文件對應的文件目錄條目。該文件編號為256,大小為720MB。
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>
我們看到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.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 ...
$
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.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 ...
$
我們看到,這確實是一個indirect extent block(kfbh.type=KFBTYP_INDIRECT),它持有該數據文件剩余的extent的分布信息。
譯者注:ASM 10G版本,ASM實例在初始化時,會向數據庫實例發送所有數據文件的Extent map,由于這種方式非常影響性能,數據庫文件如果很大,需要消耗很多的時間,因此在ASM 11G版本以后,初始化時僅發送Extent map中的前60個Extent(也就是元文件1中記錄的60個Extent),其余的在數據庫實例有需要時再發送。
ASM文件目錄維護了磁盤組中所有文件的相關信息,包括元信息文件、用戶創建的文件、數據庫文件。我們可以通過查詢V$ASM_FILE視圖來獲取數據庫文件的信息。
本站文章版權歸原作者及原出處所有 。內容為作者個人觀點, 并不代表本站贊同其觀點和對其真實性負責,本站只提供參考并不構成任何投資及應用建議。本站是一個個人學習交流的平臺,網站上部分文章為轉載,并不用于任何商業目的,我們已經盡可能的對作者和來源進行了通告,但是能力有限或疏忽,造成漏登,請及時聯系我們,我們將根據著作權人的要求,立即更正或者刪除有關內容。本站擁有對此聲明的最終解釋權。