原文: Where is my data
作者: Bane Radulovic
譯者:邱大龍,沃趣科技資料庫技術專家,主要參與公司産品實施、測試、維護以及優化。對SQL優化、資料遷移、備份容災等有深入的研究,對大資料量資料遷移、故障恢複、高并發下資料庫性能調優有豐富的經驗。
審校:魏興華
責編:仲培藝
有時候我們想要知道一個特定的database block位于ASM的哪個磁盤,磁盤的哪個AU以及AU的哪一個塊。本篇文章将向大家展示如何解決這個問題。
Database Instance
首先在資料庫裡建立測試表空間:
SQL> create tablespace T1 datafile '+DATA';
Tablespace created.
SQL> select f.FILE#, f.NAME "File", t.NAME "Tablespace"
from V$DATAFILE f, V$TABLESPACE t
where t.NAME='T1' and f.TS# = t.TS#;
FILE# File Tablespace
----- ---------------------------------- ----------
+DATA/br/datafile/t1. T1
SQL>
注意到ASM file number是272。
現在建立一張測試表并插入資料:
SQL> create table TAB1 (n number, name varchar2())
tablespace T1;
Table created.
SQL> insert into TAB1 values (, 'CAT');
row created.
SQL> commit;
Commit complete.
查詢塊号:
SQL> select ROWID, NAME from TAB1;
ROWID NAME
------------------ ----
AAASxxAAGAAAACHAAA CAT
SQL> select
DBMS_ROWID.ROWID_BLOCK_NUMBER('AAASxxAAGAAAACHAAA')
"Block number" from DUAL;
Block number
------------
查詢資料檔案的塊大小:
SQL> select BLOCK_SIZE from V$DATAFILE where FILE#=6;
BLOCK_SIZE
----------
可以看到插入的資料位于135号塊,資料檔案塊大小為8K。
ASM Instance
連接配接ASM執行個體,查詢272号檔案的區分布:
SQL> select GROUP_NUMBER from V$ASM_DISKGROUP where NAME='DATA';
GROUP_NUMBER
------------
SQL> select PXN_KFFXP, -- physical extent number
XNUM_KFFXP, -- virtual extent number
DISK_KFFXP, -- disk number
AU_KFFXP -- allocation unit number
from X$KFFXP
where NUMBER_KFFXP= -- ASM file 272
AND GROUP_KFFXP= -- group number 1
order by ;
PXN_KFFXP XNUM_KFFXP DISK_KFFXP AU_KFFXP
---------- ---------- ---------- ----------
...
SQL>
可以看到檔案的區分布在所有磁盤,由于資料檔案為Normal備援,每個區都是兩副本。注意我說的是資料檔案為Normal備援。預設情況下,檔案會繼承磁盤組的備援政策。控制檔案是個例外:即使在Normal備援的磁盤組,如果磁盤組包含至少3個failgroup,控制檔案也會被建立為high備援。
查詢磁盤組的AU大小:
SQL> select VALUE from V$ASM_ATTRIBUTE where
NAME='au_size' and GROUP_NUMBER=;
VALUE
-------
AU大小為1MB。注意每個磁盤組可以有不同的AU大小。
Where is my block
現在已知測試資料在272号ASM file的135号塊。資料塊為8K的情況下,每個AU可以包含128個塊。這就意味着135号塊位于第二個virtual extent的第7個塊。第二個virtual extent包含3号磁盤的1175号AU和2号磁盤的1179号AU。
查詢磁盤2和3的名字:
SQL> select DISK_NUMBER, NAME
from V$ASM_DISK
where DISK_NUMBER in (,);
DISK_NUMBER NAME
----------- ------------------------------
ASMDISK3
ASMDISK4
SQL>
我使用了ASMLIB,是以在OS層面,對應的磁盤名為:
/dev/oracleasm/disks/ASMDISK3和/dev/oracleasm/disks/ASMDISK4
Show me the money
測試資料位于1175号AU的第7個塊。我們首先将這個AU的資料dd出來:
$ dd if=/dev/oracleasm/disks/ASMDISK4 bs=k count= skip= of=AU1175.dd
+ records in
+ records out
bytes ( MB) copied, seconds, MB/s
$ ls -l AU1175.dd
-rw-r--r-- grid oinstall Oct : AU1175.dd
$
注意幾個參數的含義:
- bs=1024k – AU的大小
- skip=1175 – 我們需要導出的AU
- count=1 – 隻需要導出一個AU
然後将7号塊的資料從AU中導出:
$ dd if=AU1175.dd bs=k count= skip= of=block135.dd
注意bs指定為8k(資料塊大小),skip指定為7(要導出的塊号)。
檢視資料塊内容:
$ od -c block135.dd
...
\ \ , C A T
$
在内容的最後可以看到插入的資料 – CAT。注意Oracle資料塊從下向上填充。如果去檢視磁盤
/dev/oracleasm/disks/ASMDISK3
的1179号AU,結果是一樣的。
Conclusion
要定位ASM中資料塊的位置,需要知道資料塊位于哪個資料檔案。然後通過
X$KFFXP
視圖檢視資料檔案的區分布。還需要資料塊大小和ASM AU大小去定位資料塊位于哪個AU。以上操作和ASM或者RDBMS的版本無關。(
V$ASM_ATTRIBUTE
視圖除外,因為在10g中沒有該視圖)在Normal和high備援模式下,将會有多副本資料。但是定位資料塊的方法是相同的。