本篇主要介紹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>