Oracle ASM Filter Driver (ASMFD)

wl365365發表於2017-04-06

Oracle ASM Filter Driver (ASMFD) – New Features for Oracle ASM 12.1.0.2


轉載:

什麼是 Oracle ASM Filter Driver (ASMFD)?

簡單地說,這是一個可以取代 ASMLIB 和 udev 設定的新功能,並且還增加了 I/O Filter 功能,這也體現在該功能的命名中。ASMFD 目前只在 Linux 作業系統中有效,並且必須要使用最新版的 Oracle ASM 12.1.0.2。在之前,由於 Linux 作業系統對於塊裝置的發現順序不定,所以在系統重啟以後,無法保證原來的 /dev/sda 還是 sda,所以不能直接使用這樣原始的裝置名來做 ASM Disk 的 Path,因此出現了 ASMLIB,以 Label 的方式給予裝置一個固定的名字,而 ASM 則直接使用這個固定的名字來建立 ASM 磁碟,後來 ASMLIB 必須要 ULN 帳號才可以下載了,於是大家全部轉到了 udev 方式,我還因此寫了幾篇文章來闡述在 Linux 中如何設定 udev rule。比如:

How to use udev for Oracle ASM in Oracle Linux 6

Oracle Datafiles & Block Device & Parted & Udev

現在 Oracle 推出了 ASMFD,可以一舉取代 ASMLIB 和手動設定 udev rules 檔案的繁瑣,並且最重要的是 I/O Filter 功能。

什麼是 I/O Filter 功能?

文件原文如下:

The Oracle ASM Filter Driver rejects any I/O requests that are invalid. This action eliminates accidental overwrites of Oracle ASM disks that would cause corruption in the disks and files within the disk group. For example, the Oracle ASM Filter Driver filters out all non-Oracle I/Os which could cause accidental overwrites.

意思是:該功能可以拒絕所有無效的 I/O 請求,最主要的作用是防止意外覆寫 ASM 磁碟的底層盤,在後面的測試中可以看到對於 root 使用者的 dd 全盤清零這樣的變態操作也都是可以過濾的。

真是不錯,那麼該怎麼啟用這個功能呢?

通常我們原先的 ASM 中都應該使用的是 ASMLIB 或者 udev 繫結的裝置,這裡就直接描述如何將原先的裝置名重新命名為新的 AFD 裝置名。

--確認目前 ASMFD 模組(以下簡稱 AFD)的狀態,未載入。
[grid@dbserver1 ~]$ asmcmd afd_state
ASMCMD-9526: The AFD state is 'NOT INSTALLED' and filtering is 'DEFAULT' on host 'dbserver1.vbox.com'
 
--獲取當前 ASM 磁碟發現路徑,我這裡是使用 udev 繫結的名稱
[grid@dbserver1 ~]$ asmcmd dsget
parameter:/dev/asm*
profile:/dev/asm*
 
--設定 ASM 磁碟路徑,將新的 Disk String 加入
--可以看到在設定該引數時,ASM 會檢查現有已經載入的磁碟,如果不在發現路徑上,將會報錯。
[grid@dbserver1 ~]$ asmcmd dsset AFD:*
ORA-02097: parameter cannot be modified because specified value is invalid
ORA-15014: path '/dev/asm-disk7' is not in the discovery set (DBD ERROR: OCIStmtExecute)
 
--因此我們必須將新的路徑加在原始路徑後面,設定成多種路徑,該操作會執行一段時間,視 ASM 磁碟多少而定
[grid@dbserver1 ~]$ asmcmd dsset '/dev/asm*','AFD:*'
 
[grid@dbserver1 ~]$ asmcmd dsget
parameter:/dev/asm*, AFD:*
profile:/dev/asm*,AFD:*
 
--檢查現在 GI 環境中的節點。
[grid@dbserver1 ~]$ olsnodes -a
dbserver1       Hub
dbserver2       Hub
 
--以下命令必須在所有 Hub 節點上都執行,可以使用 Rolling 的方式。以下命令有些需要 root 使用者,有些需要 grid 使用者,請注意 # 
或者 $ 不同的提示符表示不同的使用者。
--先停止crs
[root@dbserver1 ~]# crsctl stop crs
 
--作 AFD Configure,實際上這是一個解壓程式包,安裝,並載入 Driver 的過程,需要消耗一些時間
[root@dbserver1 ~]# asmcmd afd_configure
Connected to an idle instance.
AFD-627: AFD distribution files found.
AFD-636: Installing requested AFD software.
AFD-637: Loading installed AFD drivers.
AFD-9321: Creating udev for AFD.
AFD-9323: Creating module dependencies - this may take some time.
AFD-9154: Loading 'oracleafd.ko' driver.
AFD-649: Verifying AFD devices.
AFD-9156: Detecting control device '/dev/oracleafd/admin'.
AFD-638: AFD installation correctness verified.
Modifying resource dependencies - this may take some time.
 
--結束以後,可以再次檢查 AFD 狀態,顯示已載入。
[root@dbserver1 ~]# asmcmd afd_state
Connected to an idle instance.
ASMCMD-9526: The AFD state is 'LOADED' and filtering is 'DEFAULT' on host 'dbserver1.vbox.com'
 
--接下來需要設定 AFD 自己的磁碟發現路徑了,其實這裡很像以前 ASMLIB 的操作。
--設定 AFD 磁碟發現路徑,必須先啟動 CRS,否則將會遇到下面的錯誤。同時也可以看到這個資訊是儲存在每個節點自己的 OLR 中,因此
必須在所有節點中都設定。
[root@dbserver1 ~]# asmcmd afd_dsget
Connected to an idle instance.
ASMCMD-9511: failed to obtain required AFD disk string from Oracle Local Repository
[root@dbserver1 ~]#
[root@dbserver1 ~]# asmcmd afd_dsset '/dev/sd*'
Connected to an idle instance.
ASMCMD-9512: failed to update AFD disk string in Oracle Local Repository.
 
--啟動 CRS
[root@dbserver1 ~]# crsctl start crs
CRS-4123: Oracle High Availability Services has been started.
 
--此時檢視後臺的 ASM 告警日誌,可以看到載入的磁碟仍然使用的是原始路徑。但是也可以看到 libafd 已經成功載入。
2014-11-20 17:01:04.545000 +08:00
NOTE: Loaded library: /opt/oracle/extapi/64/asm/orcl/1/libafd12.so
ORACLE_BASE from environment = /u03/app/grid
SQL> ALTER DISKGROUP ALL MOUNT /* asm agent call crs *//* {0:9:3} */
NOTE: Diskgroup used for Voting files is:
  CRSDG
Diskgroup with spfile:CRSDG
NOTE: Diskgroup used for OCR is:CRSDG
NOTE: Diskgroups listed in ASM_DISKGROUP are
  DATADG
NOTE: cache registered group CRSDG 1/0xB8E8EA0B
NOTE: cache began mount (first) of group CRSDG 1/0xB8E8EA0B
NOTE: cache registered group DATADG 2/0xB8F8EA0C
NOTE: cache began mount (first) of group DATADG 2/0xB8F8EA0C
NOTE: Assigning number (1,2) to disk (/dev/asm-disk3)
NOTE: Assigning number (1,1) to disk (/dev/asm-disk2)
NOTE: Assigning number (1,0) to disk (/dev/asm-disk1)
NOTE: Assigning number (1,5) to disk (/dev/asm-disk10)
NOTE: Assigning number (1,3) to disk (/dev/asm-disk8)
NOTE: Assigning number (1,4) to disk (/dev/asm-disk9)
NOTE: Assigning number (2,3) to disk (/dev/asm-disk7)
NOTE: Assigning number (2,2) to disk (/dev/asm-disk6)
NOTE: Assigning number (2,1) to disk (/dev/asm-disk5)
NOTE: Assigning number (2,5) to disk (/dev/asm-disk12)
NOTE: Assigning number (2,0) to disk (/dev/asm-disk4)
NOTE: Assigning number (2,6) to disk (/dev/asm-disk13)
NOTE: Assigning number (2,4) to disk (/dev/asm-disk11)
 
--將 afd_ds 設定為 ASM 磁碟的底層磁碟裝置名,這樣以後就不再需要手工配置 udev rules 了。
[grid@dbserver1 ~]$ asmcmd afd_dsset '/dev/sd*'
 
[grid@dbserver1 ~]$ asmcmd afd_dsget
AFD discovery string: /dev/sd*
 
--我在測試的時候,上面犯了一個錯誤,將路徑設定為了“dev/sd*”,缺少了最開始的根目錄。因此此處沒有發現任何磁碟,如果你的測試中,
這一步已經可以發現磁碟,請告訴我。
[grid@dbserver1 ~]$ asmcmd afd_lsdsk
There are no labelled devices.
 
--再次提醒,到此為止的所有命令,都必須要在叢集環境的所有節點中都執行。
--接下來就是將原先的 ASM 磁碟路徑從 udev 轉到 AFD
--先檢查現在的磁碟路徑
[root@dbserver1 ~]# ocrcheck -config
Oracle Cluster Registry configuration is :
         Device/File Name         :     +CRSDG
 
[root@dbserver1 ~]# crsctl query css votedisk
##  STATE    File Universal Id                File Name Disk group
--  -----    -----------------                --------- ---------
 1. ONLINE   4838a0ee7bfa4fbebf8ff9f58642c965 (/dev/asm-disk1) [CRSDG]
 2. ONLINE   72057097a36e4f02bfc7b5e23672e4cc (/dev/asm-disk2) [CRSDG]
 3. ONLINE   7906e2fb24d24faebf9b82bba6564be3 (/dev/asm-disk3) [CRSDG]
Located 3 voting disk(s).
 
[root@dbserver1 ~]# su - grid
[grid@dbserver1 ~]$ asmcmd lsdsk -G CRSDG
Path
/dev/asm-disk1
/dev/asm-disk10
/dev/asm-disk2
/dev/asm-disk3
/dev/asm-disk8
/dev/asm-disk9
 
--由於要修改 OCR 所在的磁碟,因此修改之前需要停止 Cluster。
[root@dbserver1 ~]# crsctl stop cluster -all
 
--直接修改會報錯,因為 /dev/asm-disk1 已經存在在 ASM 中了。
[grid@dbserver1 ~]$ asmcmd afd_label asmdisk01 /dev/asm-disk1
Connected to an idle instance.
ASMCMD-9513: ASM disk label set operation failed.
disk /dev/asm-disk1 is already provisioned for ASM
 
--必須要增加 migrate 關鍵字,才可以成功。
[grid@dbserver1 ~]$ asmcmd afd_label asmdisk01 /dev/asm-disk1 --migrate
Connected to an idle instance.
[grid@dbserver1 ~]$ asmcmd afd_lsdsk
Connected to an idle instance.
--------------------------------------------------------------------------------
Label                     Filtering   Path
================================================================================
ASMDISK01                   ENABLED   /dev/asm-disk1
 
--在我的測試 ASM 中,一共有 13 塊磁碟,因此依次修改。
asmcmd afd_label asmdisk01 /dev/asm-disk1 --migrate
asmcmd afd_label asmdisk02 /dev/asm-disk2 --migrate
asmcmd afd_label asmdisk03 /dev/asm-disk3 --migrate
asmcmd afd_label asmdisk04 /dev/asm-disk4 --migrate
asmcmd afd_label asmdisk05 /dev/asm-disk5 --migrate
asmcmd afd_label asmdisk06 /dev/asm-disk6 --migrate
asmcmd afd_label asmdisk07 /dev/asm-disk7 --migrate
asmcmd afd_label asmdisk08 /dev/asm-disk8 --migrate
asmcmd afd_label asmdisk09 /dev/asm-disk9 --migrate
asmcmd afd_label asmdisk10 /dev/asm-disk10 --migrate
asmcmd afd_label asmdisk11 /dev/asm-disk11 --migrate
asmcmd afd_label asmdisk12 /dev/asm-disk12 --migrate
asmcmd afd_label asmdisk13 /dev/asm-disk13 --migrate
 
[grid@dbserver1 ~]$ asmcmd afd_lsdsk
Connected to an idle instance.
--------------------------------------------------------------------------------
Label                     Filtering   Path
================================================================================
ASMDISK01                   ENABLED   /dev/asm-disk1
ASMDISK02                   ENABLED   /dev/asm-disk2
ASMDISK03                   ENABLED   /dev/asm-disk3
ASMDISK04                   ENABLED   /dev/asm-disk4
ASMDISK05                   ENABLED   /dev/asm-disk5
ASMDISK06                   ENABLED   /dev/asm-disk6
ASMDISK07                   ENABLED   /dev/asm-disk7
ASMDISK08                   ENABLED   /dev/asm-disk8
ASMDISK09                   ENABLED   /dev/asm-disk9
ASMDISK10                   ENABLED   /dev/asm-disk10
ASMDISK11                   ENABLED   /dev/asm-disk11
ASMDISK12                   ENABLED   /dev/asm-disk12
ASMDISK13                   ENABLED   /dev/asm-disk13
 
--在另外的節點中,不再需要作 label,而是直接 scan 即可,這跟使用 ASMLIB 的操作非常相像。
[grid@dbserver2 ~]$ asmcmd afd_scan
Connected to an idle instance.
[grid@dbserver2 ~]$ asmcmd afd_lsdsk
Connected to an idle instance.
--------------------------------------------------------------------------------
Label                     Filtering   Path
================================================================================
ASMDISK12                   ENABLED   /dev/asm-disk12
ASMDISK09                   ENABLED   /dev/asm-disk9
ASMDISK08                   ENABLED   /dev/asm-disk8
ASMDISK11                   ENABLED   /dev/asm-disk11
ASMDISK10                   ENABLED   /dev/asm-disk10
ASMDISK13                   ENABLED   /dev/asm-disk13
ASMDISK01                   ENABLED   /dev/asm-disk1
ASMDISK04                   ENABLED   /dev/asm-disk4
ASMDISK06                   ENABLED   /dev/asm-disk6
ASMDISK07                   ENABLED   /dev/asm-disk7
ASMDISK05                   ENABLED   /dev/asm-disk5
ASMDISK03                   ENABLED   /dev/asm-disk3
ASMDISK02                   ENABLED   /dev/asm-disk2
 
--重新啟動 Cluster
[root@dbserver1 ~]# crsctl start cluster -all
 
--可以看到 ASM 告警日誌中已經顯示開始使用新的名稱。關於其中 WARNING 的含義表示目前 AFD 還不支援 Advanced Format 格式的
磁碟,普通磁碟格式一個扇區是 512 位元組,而高階格式則為 4K 位元組。
2014-11-20 17:46:16.695000 +08:00
* allocate domain 1, invalid = TRUE
* instance 2 validates domain 1
NOTE: cache began mount (not first) of group CRSDG 1/0x508D0B98
NOTE: cache registered group DATADG 2/0x509D0B99
* allocate domain 2, invalid = TRUE
* instance 2 validates domain 2
NOTE: cache began mount (not first) of group DATADG 2/0x509D0B99
WARNING: Library 'AFD Library - Generic , version 3 (KABI_V3)' does not support advanced format disks
NOTE: Assigning number (1,0) to disk (AFD:ASMDISK01)
NOTE: Assigning number (1,1) to disk (AFD:ASMDISK02)
NOTE: Assigning number (1,2) to disk (AFD:ASMDISK03)
NOTE: Assigning number (1,3) to disk (AFD:ASMDISK08)
NOTE: Assigning number (1,4) to disk (AFD:ASMDISK09)
NOTE: Assigning number (1,5) to disk (AFD:ASMDISK10)
NOTE: Assigning number (2,0) to disk (AFD:ASMDISK04)
NOTE: Assigning number (2,1) to disk (AFD:ASMDISK05)
NOTE: Assigning number (2,2) to disk (AFD:ASMDISK06)
NOTE: Assigning number (2,3) to disk (AFD:ASMDISK07)
NOTE: Assigning number (2,4) to disk (AFD:ASMDISK11)
NOTE: Assigning number (2,5) to disk (AFD:ASMDISK12)
NOTE: Assigning number (2,6) to disk (AFD:ASMDISK13)
 
--檢查磁碟載入路徑,以及功能全部是 AFD 樣式了。
[grid@dbserver1 ~]$ asmcmd lsdsk
Path
AFD:ASMDISK01
AFD:ASMDISK02
AFD:ASMDISK03
AFD:ASMDISK04
AFD:ASMDISK05
AFD:ASMDISK06
AFD:ASMDISK07
AFD:ASMDISK08
AFD:ASMDISK09
AFD:ASMDISK10
AFD:ASMDISK11
AFD:ASMDISK12
AFD:ASMDISK13
 
--但是我們可以看到在資料字典中仍然存在之前的磁碟路徑。
SQL> select NAME,LABEL,PATH from V$ASM_DISK;
 
NAME                 LABEL                           PATH
-------------------- ------------------------------- ---------------------------------------------
                                                     /dev/asm-disk7
                                                     /dev/asm-disk6
                                                     /dev/asm-disk13
                                                     /dev/asm-disk12
                                                     /dev/asm-disk11
                                                     /dev/asm-disk4
                                                     /dev/asm-disk2
                                                     /dev/asm-disk9
                                                     /dev/asm-disk3
                                                     /dev/asm-disk5
                                                     /dev/asm-disk10
                                                     /dev/asm-disk8
                                                     /dev/asm-disk1
CRSDG_0000           ASMDISK01                       AFD:ASMDISK01
CRSDG_0001           ASMDISK02                       AFD:ASMDISK02
CRSDG_0002           ASMDISK03                       AFD:ASMDISK03
DATADG_0000          ASMDISK04                       AFD:ASMDISK04
DATADG_0001          ASMDISK05                       AFD:ASMDISK05
DATADG_0002          ASMDISK06                       AFD:ASMDISK06
DATADG_0003          ASMDISK07                       AFD:ASMDISK07
CRSDG_0003           ASMDISK08                       AFD:ASMDISK08
CRSDG_0004           ASMDISK09                       AFD:ASMDISK09
CRSDG_0005           ASMDISK10                       AFD:ASMDISK10
DATADG_0004          ASMDISK11                       AFD:ASMDISK11
DATADG_0005          ASMDISK12                       AFD:ASMDISK12
DATADG_0006          ASMDISK13                       AFD:ASMDISK13
 
26 rows selected.
 
--需要將 ASM 磁碟發現路徑(注意,這跟設定 AFD 磁碟發現路徑不是一個命令)中原先的路徑去除,只保留 AFD 路徑。
[grid@dbserver1 ~]$ asmcmd dsset 'AFD:*'
[grid@dbserver1 ~]$ asmcmd dsget
parameter:AFD:*
profile:AFD:*
 
--再次重啟 ASM,一切正常了。
SQL> select NAME,LABEL,PATH from V$ASM_DISK;
 
NAME                 LABEL                           PATH
-------------------- ------------------------------- -------------------------------------------------------
CRSDG_0000           ASMDISK01                       AFD:ASMDISK01
CRSDG_0001           ASMDISK02                       AFD:ASMDISK02
CRSDG_0002           ASMDISK03                       AFD:ASMDISK03
DATADG_0000          ASMDISK04                       AFD:ASMDISK04
DATADG_0001          ASMDISK05                       AFD:ASMDISK05
DATADG_0002          ASMDISK06                       AFD:ASMDISK06
DATADG_0003          ASMDISK07                       AFD:ASMDISK07
CRSDG_0003           ASMDISK08                       AFD:ASMDISK08
CRSDG_0004           ASMDISK09                       AFD:ASMDISK09
CRSDG_0005           ASMDISK10                       AFD:ASMDISK10
DATADG_0004          ASMDISK11                       AFD:ASMDISK11
DATADG_0005          ASMDISK12                       AFD:ASMDISK12
DATADG_0006          ASMDISK13                       AFD:ASMDISK13
 
13 rows selected.
 
--收尾工作,將原先的 udev rules 檔案移除。當然,這要在所有節點中都執行。以後如果伺服器再次重啟,AFD 就會完全接管了。
[root@dbserver1 ~]# mv /etc/udev/rules.d/99-oracle-asmdevices.rules ~oracle/

還有什麼發現?

其實,AFD 也在使用 udev。囧。

[grid@dbserver1 ~]$ cat /etc/udev/rules.d/53-afd.rules
#
# AFD devices
KERNEL=="oracleafd/.*", OWNER="grid", GROUP="asmdba", MODE="0770"
KERNEL=="oracleafd/*", OWNER="grid", GROUP="asmdba", MODE="0770"
KERNEL=="oracleafd/disks/*", OWNER="grid", GROUP="asmdba", MODE="0660"

Label 過後的磁碟在 /dev/oracleafd/disks 目錄中可以找到。

[root@dbserver2 disks]# ls -l /dev/oracleafd/disks
total 52
-rw-r--r-- 1 root root 9 Nov 20 18:52 ASMDISK01
-rw-r--r-- 1 root root 9 Nov 20 18:52 ASMDISK02
-rw-r--r-- 1 root root 9 Nov 20 18:52 ASMDISK03
-rw-r--r-- 1 root root 9 Nov 20 18:52 ASMDISK04
-rw-r--r-- 1 root root 9 Nov 20 18:52 ASMDISK05
-rw-r--r-- 1 root root 9 Nov 20 18:52 ASMDISK06
-rw-r--r-- 1 root root 9 Nov 20 18:52 ASMDISK07
-rw-r--r-- 1 root root 9 Nov 20 18:52 ASMDISK08
-rw-r--r-- 1 root root 9 Nov 20 18:52 ASMDISK09
-rw-r--r-- 1 root root 9 Nov 20 18:52 ASMDISK10
-rw-r--r-- 1 root root 9 Nov 20 18:52 ASMDISK11
-rw-r--r-- 1 root root 9 Nov 20 18:52 ASMDISK12
-rw-r--r-- 1 root root 9 Nov 20 18:52 ASMDISK13

這裡有一個很大不同,所有磁碟的屬主變成了 root,並且只有 root 才有寫入的許可權。很多文章認為,這就是 AFD 的 filter 功能體現了,因為現在用 oracle 或者 grid 使用者都沒有辦法直接對 ASM 磁碟進行寫入操作,自然就獲得了一層保護。比如以下命令會直接報許可權不足。

[oracle@dbserver1 disks]$ echo "do some evil" > ASMDISK99
-bash: ASMDISK99: Permission denied

但是如果你認為這就是 AFD 的保護功能,那也太小看 Oracle 了,僅僅是這樣也對不起名字中 Filter 字樣。且看後面分解。

作業系統中也可以看到 AFD 磁碟和底層磁碟的對應關係。

[grid@dbserver1 /]$ ls -l /dev/disk/by-label/
total 0
lrwxrwxrwx 1 root root 9 Nov 20 19:17 ASMDISK01 -> ../../sdc
lrwxrwxrwx 1 root root 9 Nov 20 19:17 ASMDISK02 -> ../../sdd
lrwxrwxrwx 1 root root 9 Nov 20 19:17 ASMDISK03 -> ../../sde
lrwxrwxrwx 1 root root 9 Nov 20 19:17 ASMDISK04 -> ../../sdf
lrwxrwxrwx 1 root root 9 Nov 20 19:17 ASMDISK05 -> ../../sdg
lrwxrwxrwx 1 root root 9 Nov 20 19:17 ASMDISK06 -> ../../sdh
lrwxrwxrwx 1 root root 9 Nov 20 19:17 ASMDISK07 -> ../../sdi
lrwxrwxrwx 1 root root 9 Nov 20 19:17 ASMDISK08 -> ../../sdj
lrwxrwxrwx 1 root root 9 Nov 20 19:17 ASMDISK09 -> ../../sdk
lrwxrwxrwx 1 root root 9 Nov 20 19:17 ASMDISK10 -> ../../sdl
lrwxrwxrwx 1 root root 9 Nov 20 19:17 ASMDISK11 -> ../../sdm
lrwxrwxrwx 1 root root 9 Nov 20 19:17 ASMDISK12 -> ../../sdn
lrwxrwxrwx 1 root root 9 Nov 20 19:17 ASMDISK13 -> ../../sdo

再次重啟伺服器以後,afd_lsdsk 的結果中顯示的路徑都已經變為底層磁碟,但是 Filtering 卻變成了 DISABLED。不要在意這裡的 Label 和 Path 的對應和上面的不一樣,因為有些是在節點 1 中執行的結果,有些是在節點 2 中執行的結果,而這也是 AFD 功能的展示,不管兩邊機器發現塊裝置的順序是不是一樣,只要繫結了 AFD 的 Label,就沒問題了。

ASMCMD> afd_lsdsk
--------------------------------------------------------------------------------
Label                     Filtering   Path
================================================================================
ASMDISK01                  DISABLED   /dev/sdd
ASMDISK02                  DISABLED   /dev/sde
ASMDISK03                  DISABLED   /dev/sdf
ASMDISK04                  DISABLED   /dev/sdg
ASMDISK05                  DISABLED   /dev/sdh
ASMDISK06                  DISABLED   /dev/sdi
ASMDISK07                  DISABLED   /dev/sdj
ASMDISK08                  DISABLED   /dev/sdk
ASMDISK09                  DISABLED   /dev/sdl
ASMDISK10                  DISABLED   /dev/sdm
ASMDISK11                  DISABLED   /dev/sdn
ASMDISK12                  DISABLED   /dev/sdo
ASMDISK13                  DISABLED   /dev/sdp

最後,該來測試一下 I/O Filter 功能了吧,等好久了!

對,這才是重點。

先看一下如何啟用或者禁用 Filter 功能。在我的測試中,單獨設定某塊盤啟用還是禁用是不生效的,只能全域性啟用或者禁用。

[grid@dbserver1 ~]$ asmcmd help afd_filter
afd_filter
        Sets the AFD filtering mode on a given disk path.
        If the command is executed without specifying a disk path then
        filtering is set at node level.
 
Synopsis
        afd_filter {-e | -d } [<disk-path>]
 
Description
        The options for afd_filter are described below
 
        -e      -  enable  AFD filtering mode
        -d      -  disable AFD filtering mode
 
Examples
        The following example uses afd_filter to enable AFD filtering
        on a given diskpath.
 
        ASMCMD [+] >afd_filter -e /dev/sdq
 
See Also
       afd_lsdsk afd_state

啟用 Filter 功能。

[grid@dbserver1 ~]$ asmcmd afd_filter -e
[grid@dbserver1 ~]$ asmcmd afd_lsdsk
Connected to an idle instance.
--------------------------------------------------------------------------------
Label                     Filtering   Path
================================================================================
ASMDISK01                   ENABLED   /dev/sdb
ASMDISK02                   ENABLED   /dev/sdc
ASMDISK03                   ENABLED   /dev/sdd
ASMDISK04                   ENABLED   /dev/sde
ASMDISK05                   ENABLED   /dev/sdf
ASMDISK06                   ENABLED   /dev/sdg
ASMDISK07                   ENABLED   /dev/sdh
ASMDISK08                   ENABLED   /dev/sdi
ASMDISK09                   ENABLED   /dev/sdj
ASMDISK10                   ENABLED   /dev/sdk
ASMDISK11                   ENABLED   /dev/sdl
ASMDISK12                   ENABLED   /dev/sdm
ASMDISK13                   ENABLED   /dev/sdn

為了以防萬一,不破壞我自己的實驗環境,增加了一塊磁碟來作測試。

[root@dbserver1 ~]# asmcmd afd_label asmdisk99 /dev/sdo
Connected to an idle instance.
[root@dbserver1 ~]# asmcmd afd_lsdsk
Connected to an idle instance.
--------------------------------------------------------------------------------
Label                     Filtering   Path
================================================================================
ASMDISK01                   ENABLED   /dev/sdb
ASMDISK02                   ENABLED   /dev/sdc
ASMDISK03                   ENABLED   /dev/sdd
ASMDISK04                   ENABLED   /dev/sde
ASMDISK05                   ENABLED   /dev/sdf
ASMDISK06                   ENABLED   /dev/sdg
ASMDISK07                   ENABLED   /dev/sdh
ASMDISK08                   ENABLED   /dev/sdi
ASMDISK09                   ENABLED   /dev/sdj
ASMDISK10                   ENABLED   /dev/sdk
ASMDISK11                   ENABLED   /dev/sdl
ASMDISK12                   ENABLED   /dev/sdm
ASMDISK13                   ENABLED   /dev/sdn
ASMDISK99                   ENABLED   /dev/sdo

建立一個新的磁碟組。

[grid@dbserver1 ~]$ sqlplus / AS sysasm
SQL> CREATE diskgroup DGTEST external redundancy disk 'AFD:ASMDISK99';
 
Diskgroup created.

先用 KFED 讀取一下磁碟頭,驗證一下確實無誤。

[grid@dbserver1 ~]$ kfed read AFD:ASMDISK99
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:                  1854585587 ; 0x00c: 0x6e8abaf3
kfbh.fcn.base:                        0 ; 0x010: 0x00000000
kfbh.fcn.wrap:                        0 ; 0x014: 0x00000000
kfbh.spare1:                          0 ; 0x018: 0x00000000
kfbh.spare2:                          0 ; 0x01c: 0x00000000
kfdhdb.driver.provstr:ORCLDISKASMDISK99 ; 0x000: length=17
kfdhdb.driver.reserved[0]:   1145918273 ; 0x008: 0x444d5341
kfdhdb.driver.reserved[1]:    961237833 ; 0x00c: 0x394b5349
kfdhdb.driver.reserved[2]:           57 ; 0x010: 0x00000039
kfdhdb.driver.reserved[3]:            0 ; 0x014: 0x00000000
kfdhdb.driver.reserved[4]:            0 ; 0x018: 0x00000000
kfdhdb.driver.reserved[5]:            0 ; 0x01c: 0x00000000
kfdhdb.compat:                168820736 ; 0x020: 0x0a100000
kfdhdb.dsknum:                        0 ; 0x024: 0x0000
kfdhdb.grptyp:                        1 ; 0x026: KFDGTP_EXTERNAL
kfdhdb.hdrsts:                        3 ; 0x027: KFDHDR_MEMBER
kfdhdb.dskname:               ASMDISK99 ; 0x028: length=9
kfdhdb.grpname:                  DGTEST ; 0x048: length=6
kfdhdb.fgname:                ASMDISK99 ; 0x068: length=9

直接使用 dd 嘗試將整個磁碟清零。dd 命令本身沒有任何錯誤返回。

[root@dbserver1 ~]# dd if=/dev/zero of=/dev/sdo
dd: writing to `/dev/sdo': No space left on device
409601+0 records in
409600+0 records out
209715200 bytes (210 MB) copied, 19.9602 s, 10.5 MB/s

之後重新 mount 磁碟組,如果磁碟被清零,在重新 mount 的時候一定會出現錯誤,而現在正常掛載。

SQL> ALTER diskgroup DGTEST dismount;
 
Diskgroup altered.
 
SQL> ALTER diskgroup DGTEST mount;
 
Diskgroup altered.

覺得不過癮?那再建立一個表空間,插入一些資料,做一次 checkpoint,仍然一切正常。

SQL> CREATE tablespace test datafile '+DGTEST' SIZE 100M;
 
Tablespace created.
 
SQL> CREATE TABLE t_afd (n NUMBER) tablespace test;
  TABLE created.
 
SQL> INSERT INTO t_afd VALUES(1);
  1 ROW created.
 
SQL> commit;
 
Commit complete.
 
SQL> ALTER system checkpoint;
 
System altered.
 
SQL> SELECT COUNT(*) FROM t_afd;
  COUNT(*) ---------- 1

但是詭異的是,這時候在作業系統級別直接去讀取 /dev/sdo 的內容,會顯示全部都已經被清空為 0 了。

[root@dbserver1 ~]# od -c -N 256 /dev/sdo
0000000  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
*
0000400

使用 strings 命令也完全看不到任何有意義的字元。

[root@dbserver1 disks]# strings /dev/sdo
[root@dbserver1 disks]#

但是,千萬不要被這樣的假象迷惑,以為磁碟真的被清空了,在 dd 的時候,/var/log/message 會產生大量日誌,明確表示這些在 ASM 管理的裝置上的 IO 操作都是不被支援,這才是 Filter 真正起作用的場合。

afd_mkrequest_fn: write IO on ASM managed device (major=8/minor=224)  not supported

使用 kfed,仍然可以讀取到正常的資訊。

[grid@dbserver1 ~]$ kfed read AFD:ASMDISK99
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:                  1854585587 ; 0x00c: 0x6e8abaf3
kfbh.fcn.base:                        0 ; 0x010: 0x00000000
kfbh.fcn.wrap:                        0 ; 0x014: 0x00000000
kfbh.spare1:                          0 ; 0x018: 0x00000000
kfbh.spare2:                          0 ; 0x01c: 0x00000000
kfdhdb.driver.provstr:ORCLDISKASMDISK99 ; 0x000: length=17
......

直到重新啟動伺服器(重新啟動 ASM,重新啟動 Cluster,在作業系統仍然看到的是清零後的資料),所有的資料又回來了。目前還不確認 Oracle 是使用了怎樣的重定向技術實現了這樣的神奇效果。

[root@dbserver1 ~]# od -c -N 256 /dev/sdo
0000000 001 202 001 001  \0  \0  \0  \0  \0  \0  \0 200   u 177   D   I
0000020  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
0000040   O   R   C   L   D   I   S   K   A   S   M   D   I   S   K   9
0000060   9  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
0000100  \0  \0 020  \n  \0  \0 001 003   A   S   M   D   I   S   K   9
0000120   9  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
0000140  \0  \0  \0  \0  \0  \0  \0  \0   D   G   T   E   S   T  \0  \0
0000160  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
0000200  \0  \0  \0  \0  \0  \0  \0  \0   A   S   M   D   I   S   K   9
0000220   9  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
0000240  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
*
0000300  \0  \0  \0  \0  \0  \0  \0  \0 022 257 367 001  \0   X  \0 247
0000320 022 257 367 001  \0   h 036 344  \0 002  \0 020  \0  \0 020  \0
0000340 200 274 001  \0 310  \0  \0  \0 002  \0  \0  \0 001  \0  \0  \0
0000360 002  \0  \0  \0 002  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
0000400
[root@dbserver1 ~]# 
[root@dbserver1 ~]# strings /dev/sdo | grep ASM
ORCLDISKASMDISK99
ASMDISK99
ASMDISK99
ORCLDISKASMDISK99
ASMDISK99
ASMDISK99
ASMDISK99
ASMDISK99
ASMPARAMETERFILE
ASMPARAMETERBAKFILE
ASM_STALE

最後將 Filter 禁用之後再測試。

[root@dbserver1 ~]# asmcmd afd_filter -d
Connected to an idle instance.
[root@dbserver1 ~]# asmcmd afd_lsdsk
Connected to an idle instance.
--------------------------------------------------------------------------------
Label                     Filtering   Path
================================================================================
ASMDISK01                  DISABLED   /dev/sdb
ASMDISK02                  DISABLED   /dev/sdc
ASMDISK03                  DISABLED   /dev/sdd
ASMDISK04                  DISABLED   /dev/sde
ASMDISK05                  DISABLED   /dev/sdf
ASMDISK06                  DISABLED   /dev/sdg
ASMDISK07                  DISABLED   /dev/sdh
ASMDISK08                  DISABLED   /dev/sdi
ASMDISK09                  DISABLED   /dev/sdj
ASMDISK10                  DISABLED   /dev/sdk
ASMDISK11                  DISABLED   /dev/sdl
ASMDISK12                  DISABLED   /dev/sdm
ASMDISK13                  DISABLED   /dev/sdn
ASMDISK99                  DISABLED   /dev/sdo

同樣使用 dd 命令清零整個磁碟。

[root@dbserver1 ~]# dd if=/dev/zero of=/dev/sdo
dd: writing to `/dev/sdo': No space left on device
409601+0 records in
409600+0 records out
209715200 bytes (210 MB) copied, 4.46444 s, 47.0 MB/s

重新 mount 磁碟組,如期報錯,磁碟組無法載入。

SQL> alter diskgroup DGTEST dismount;
 
Diskgroup altered.
 
SQL> alter diskgroup DGTEST mount;
alter diskgroup DGTEST mount
*
ERROR at line 1:
ORA-15032: not all alterations performed
ORA-15017: diskgroup "DGTEST" cannot be mounted
ORA-15040: diskgroup is incomplete

重新啟動資料庫,也會發現由於表空間中資料庫不存在而導致資料庫無法正常 Open。

SQL> startup
ORACLE instance started.
 
Total System Global Area  838860800 bytes
Fixed SIZE 2929936 bytes
Variable >SIZE 385878768 bytes DATABASE Buffers          226492416 bytes
Redo Buffers                5455872 bytes
In-Memory Area            218103808 bytes DATABASE mounted.
ORA-01157: cannot identify/LOCK DATA file 15 - see DBWR trace file
ORA-01110: DATA file 15: '+DGTEST/CDB12C/DATAFILE/test.256.864163075'

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22039464/viewspace-2136741/,如需轉載,請註明出處,否則將追究法律責任。

相關文章