有時候我們想要知道一個特定的database block位于asm的哪個磁盤,磁盤的哪個au以及au的哪一個塊。本篇文章将向大家展示如何解決這個問題。
首先在資料庫裡建立測試表空間:
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
----- ---------------------------------- ----------
6 +data/br/datafile/t1.272.797809075 t1
sql>
注意到asm file number是272。
現在建立一張測試表并插入資料:
sql> create table tab1 (n number, name varchar2(16))
tablespace t1;
table created.
sql> insert into tab1 values (1, 'cat');
1 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
------------
135
查詢資料檔案的塊大小:
sql> select block_size from v$datafile where file#=6;
block_size
----------
8192
可以看到插入的資料位于135号塊,資料檔案塊大小為8k。
連接配接asm執行個體,查詢272号檔案的區分布:
sql> select group_number from v$asm_diskgroup where name='data';
group_number
1
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=272 -- asm file 272
and group_kffxp=1 -- group number 1
order by 1;
pxn_kffxp xnum_kffxp disk_kffxp au_kffxp
---------- ---------- ---------- ----------
0 0 0 1175
1 0 3 1170
2 1 3 1175
3 1 2 1179
4 2 1 1175
...
可以看到檔案的區分布在所有磁盤,由于資料檔案為normal備援,每個區都是兩副本。注意我說的是資料檔案為normal備援。預設情況下,檔案會繼承磁盤組的備援政策。控制檔案是個例外:即使在normal備援的磁盤組,如果磁盤組包含至少3個failgroup,控制檔案也會被建立為high備援。
查詢磁盤組的au大小:
sql> select value from v$asm_attribute where
name='au_size' and group_number=1;
value
-------
1048576
au大小為1mb。注意每個磁盤組可以有不同的au大小。
現在已知測試資料在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 (2,3);
disk_number name
----------- ------------------------------
2 asmdisk3
3 asmdisk4
我使用了asmlib,是以在os層面,對應的磁盤名為:
/dev/oracleasm/disks/asmdisk3和/dev/oracleasm/disks/asmdisk4
測試資料位于1175号au的第7個塊。我們首先将這個au的資料dd出來:
$ dd if=/dev/oracleasm/disks/asmdisk4 bs=1024k count=1 skip=1175 of=au1175.dd
1+0 records in
1+0 records out
1048576 bytes (1.0 mb) copied, 0.057577 seconds, 18.2 mb/s
$ ls -l au1175.dd
-rw-r--r-- 1 grid oinstall 1048576 oct 27 22:45 au1175.dd
$
注意幾個參數的含義:
· bs=1024k -- au的大小
· skip=1175 -- 我們需要導出的au
· count=1 -- 隻需要導出一個au
然後将7号塊的資料從au中導出:
$ dd if=au1175.dd bs=8k count=1 skip=7 of=block135.dd
注意bs指定為8k(資料塊大小),skip指定為7(要導出的塊号)。
檢視資料塊内容:
$ od -c block135.dd
0017760 \0 \0 , 001 002 002 301 002 003 c a t 001 006 332 217
0020000
在内容的最後可以看到插入的資料 -- cat.注意oracle資料塊從下向上填充。如果去檢視磁盤/dev/oracleasm/disks/asmdisk3的1179号au,結果是一樣的。
要定位asm中資料塊的位置,需要知道資料塊位于哪個資料檔案。然後通過x$kffxp視圖檢視資料檔案的區分布。還需要資料塊大小和asm au大小去定位資料塊位于哪個au。 以上操作和asm或者rdbms的版本無關。(v$asm_attribute視圖除外,因為在10g中沒有該視圖)在normal和high備援模式下,将會有多副本資料。但是定位資料塊的方法是相同的。
<b>本文來自雲栖社群合作夥伴“dbgeek”</b>