kfed是一個沒有官方文檔記錄的ASM工具,它可以用來讀取和修改ASM的元數據塊。它本身是一個獨立的工具,獨立于ASM實例,因此不管實例是否啟動,ASM磁盤組是否mount ,它都可以正常使用。kfed為強大的地方在于它可以修復ASM損壞的元數據。
kfed的二進制文件在近的ASM版本中直接可用,如果你沒有在$ORACLE_HOME/bin看到,可以通過如下步驟來編譯獲得:
$ cd $ORACLE_HOME/rdbms/lib
$ make -f ins* ikfed
譯者注,在11G之前的版本,kfed工具默認沒有編譯,需要手工編譯后才能使用。11G之后版本軟件安裝完成后就已經對kfed完成了編譯,直接可以使用。
使用kfed來可以讀取一個ASM元數據塊(4K大小),它的語法是:
$ kfed read [aun=ii aus=jj blkn=kk dev=]asm_disk_name
命令行參數的介紹:
接下來是一個使用kfed工具的例子,展示了讀取ASM磁盤/dev/sda1的磁盤頭:
$ kfed read /dev/sda1 | more
kfbh.endian: 1 ; 0x000: 0x01 kfbh.hard: 130 ; 0x001: 0x82 kfbh.type: 1 ; 0x002: KFBTYP_DISKHEAD
kfbh.datfmt: 1 ; 0x003: 0x01 kfbh.block.blk: 0 ; 0x004: blk=0 kfbh.block.obj: 2147483648 ; 0x008: disk=0 kfbh.check: 3102721733 ; 0x00c: 0xb8efc6c5 kfbh.fcn.base: 0 ; 0x010: 0x00000000 kfbh.fcn.wrap: 0 ; 0x014: 0x00000000 ... kfdhdb.dsknum: 0 ; 0x024: 0x0000 kfdhdb.grptyp: 2 ; 0x026: KFDGTP_NORMAL
kfdhdb.hdrsts: 3 ; 0x027: KFDHDR_MEMBER
kfdhdb.dskname: DATA_0000 ; 0x028: length=9 kfdhdb.grpname: DATA ; 0x048: length=4 kfdhdb.fgname: DATA_0000 ; 0x068: length=9 kfdhdb.ausize: 1048576 ; 0x0bc: 0x00100000 kfdhdb.dsksize: 12284 ; 0x0c4: 0x00002ffc ...
上面的kfed命令非常的簡短,大多使用了默認值,等價于下面這個(所有的參數都顯式的設置成了它的默認值):
$ kfed read aun=0 aus=1048576 blkn=0 dev=/dev/sda1
我們能夠看到上面kfed的輸出被很好的格式化方便我們的閱讀,元數據塊的輸出也根據實際的內容做了分組。
在本例中,kfbh區域顯示了塊頭數據,重要的有kfbh.type-塊類型,這里為KFBTYP_DISKHEAD,表明為磁盤頭。
我們通過kfed工具查看ASM磁盤頭元數據塊的實際內容,kfdhdb區域:kfdhdb.dsknum代表本磁盤在磁盤組中的編號為0,kfdhdb.grptyp代表磁盤組的冗余級別為normal,kfdhdb.hdrsts代表磁盤頭的狀態為member,kfdhdb.dskname代表磁盤的名稱為DATA_0000等。
如果想了解磁盤頭的詳細信息,可以參照本系列【ASM disk header 】篇。
下一個例子里我們來展示下讀取ASM File Directory block-文件目錄塊,為了能夠達到此目的,我們需要使用kfed命令:
$ kfed read aun=10 blkn=1 dev=/dev/sda1 | more
kfbh.endian: 1 ; 0x000: 0x01 kfbh.hard: 130 ; 0x001: 0x82 kfbh.type: 4 ; 0x002: KFBTYP_FILEDIR ...
上面我通過指定AU 10和塊1來讀取ASM的文件目錄塊(kfbh.type KFBTYP_FILEDIR也說明了這是文件目錄塊),如果讀者對這塊不太熟悉,可以參照本系列的【ASM File Directory】篇來了解如何定位到ASM文件目錄塊。
如果一塊磁盤本應屬于某個ASM磁盤組,但是ASM磁盤頭的kfbh.type部分卻顯示了KFBTYP_INVALID,那么這說明了ASM的磁盤頭已經損壞,但是也別著急下結論,你查看的是否是正確的磁盤?是否是正確的磁盤分區?是否還可以通過其他的名字訪問磁盤(多路徑環境),如果你還不夠確定或者你的磁盤頭確實已經損壞,可以聯系Oracle支持來解決問題。
以上的辦法適用于所有的ASM元數據塊,如果ASM期待讀取到一個ASM元數據塊,然后讀取到了一堆的無意義的值,它將標注這個kfbh.type內容為KFBTYP_INVALID,同時ORA-15196也會出現在ASM或者DB的alert日志中。(取決于哪一個實例發現了這個問題)
kfed write命令可以對一個ASM元數據塊進行寫入,語法是:
$ kfed write [aun=ii aus=jj blkn=kk dev=]asm_disk_name text=new_contents chksum=yes
上面新的命令行的參數含義:
ASM元數據塊可能看上去是好的,但是事實上已經損壞,例如,元數據塊的checksum值可能是錯誤的,這種情況下我們需要去糾正它,其實,如果僅僅是checksum值不正確,可以很容易通過kfed讀取這個塊然后再寫回的方式進行糾正,kfed工具會計算新的checksum值,然后把正確的checksum值寫回。
接下來我們用一個完整的例子來演示如何修復一個元數據塊的不正確的checksum值,此元數據塊位于磁盤/dev/sda1的AU 0,塊2。
$ kfed read aun=0 blkn=2 dev=/dev/sda1 > /tmp/aun0_blkn2_sda1.kfed $ kfed write aun=0 blkn=2 dev=/dev/sda1 text=/tmp/aun0_blkn2_sda1.kfed chksum=yes
注意,遇到任何ASM元數據塊的損壞都請聯系Oracle的技術支持。
kfed的find命令會檢查一個AU上的所有塊,然后返回每一個塊的類型:
$ kfed find [aun=ii aus=jj dev=]asm_disk_name
find命令一定程度上跟之前的read命令很想象,但是find命令會對指定AU上的所有塊進行讀取操作。(read只會操作一個塊)
接下來我們通過kfed find命令識別AU 0上所有塊:
$ kfed find /dev/sda1
輸出的結果如預期,塊0為 type 1,塊1為type 2,其他的所有塊為type 3:
$ kfed find /dev/sda1 Block 0 has type 1 Block 1 has type 2 Block 2 has type 3 Block 3 has type 3 Block 4 has type 3 ... Block 255 has type 3
譯者注:塊0為磁盤頭,塊1為磁盤的 Free space table,塊2-塊255為磁盤的Allocation Table,對于Free space table的內容參考本系列的【Free space table】章節,對于Allocation Table的內容參考本系列的【Allocation Table】章節。
如果你看到任何其他別的輸出,說明了存在一個毀壞ASM元數據塊,這種情況下請聯系Oracle的支持尋求幫助。
由于我的AU大小是1MB,因此在這個AU上有256個塊,如果你的AU大小為4MB,上面同樣的命令會返回1024個塊。
我已經強調過,kfed的find命令只能查看ASM元數據塊的類型,不能查看實際的元數據塊的內容,一些ASM元數據塊的損壞其實是塊內容的損壞,例如塊類型是正確的,但是塊的內容已經損壞。這種毀壞只能在ASM讀取的時候才能檢測到,這種情況下,ORA-15196錯誤會拋出。
kfed工具是一個低調的,但是非常強大的工具,上面我們只是顯示了幾個命令,它還有很多其他的命令可以用,例如格式化一個空的ASM文件,檢查ASM元數據塊的健康性,展示數據結構的大小,以及執行一些鮮為人知的操作。
本站文章版權歸原作者及原出處所有 。內容為作者個人觀點, 并不代表本站贊同其觀點和對其真實性負責,本站只提供參考并不構成任何投資及應用建議。本站是一個個人學習交流的平臺,網站上部分文章為轉載,并不用于任何商業目的,我們已經盡可能的對作者和來源進行了通告,但是能力有限或疏忽,造成漏登,請及時聯系我們,我們將根據著作權人的要求,立即更正或者刪除有關內容。本站擁有對此聲明的最終解釋權。