该部分也是承接从ASM直接读取数据的研究思考,主要是根据asm实例中的x$kffxp视图确定au的位置。
首先准备测试环境的脚本,数据块大小默认为8l:
SQL script to create tablespace col "File name" format a60 col "Tablespace name" format a20 --创建表空间: connect sys/ludatou as sysdba create tablespace test datafile '+TEST' size 5m; grant dba to luda; --创建测试表: connect luda/luda create table luda_tab (n number, name varchar2(16)) tablespace test; insert into luda_tab values (1, 'ASM_TEST'); commit; select ROWID, NAME from luda_tab;
通过以上查询可以知道luda_tab的行块所在位置为数据文件的133号数据块。
SQL> select ROWID from luda_tab; ROWID ------------------ AAAXgDAAHAAAACFAAA SQL> select DBMS_ROWID.ROWID_BLOCK_NUMBER('AAAXgDAAHAAAACFAAA') "Block number" from DUAL; Block number ------------ 133
数据库块大小为8k
SQL> show parameter db_block_size NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ db_block_size integer 8192
TEST表空间的数据文件ASM file number为256
SQL> select f.FILE#, f.NAME "File name", t.NAME "Tablespace name" from V$DATAFILE f, V$TABLESPACE t where t.NAME='TEST' and f.TS# = t.TS#; FILE# File name Tablespace name ---------- -------------------------------------------------- --------------- 7 +TEST/racnode1/datafile/test.256.852905863 TEST
TEST表空间所在的diskgroup号为4
SQL> select GROUP_NUMBER from V$ASM_DISKGROUP where NAME='TEST'; GROUP_NUMBER ------------ 4
4号diskgroup的au size为1M
SQL> select VALUE from V$ASM_ATTRIBUTE where NAME='au_size' and GROUP_NUMBER=4; VALUE ------------------------------------------------------------------------------ 1048576
Diskgroup 4的磁盘信息
SQL> select GROUP_NUMBER, DISK_NUMBER, NAME, path from V$ASM_DISK where GROUP_NUMBER=4; GROUP_NUMBER DISK_NUMBER NAME PATH ------------ ----------- ------------------------------ ------------------------------ 4 0 TEST_0000 /dev/asm_disk_1 4 1 TEST_0001 /dev/asm_disk_2
AU分部与OS磁盘的对应信息
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=256 -- ASM file 256 AND GROUP_KFFXP=4 -- group number 4 order by 1; PXN_KFFXP XNUM_KFFXP DISK_KFFXP AU_KFFXP ---------- ---------- ---------- ---------- 0 0 0 144 1 0 1 144 2 1 1 145 3 1 0 145 4 2 0 146 5 2 1 146 6 3 1 147 7 3 0 147 8 4 0 148 9 4 1 148 10 5 1 149 11 5 0 149
从上面的au分布与os磁盘的对应信息中可以看到256号asm file一共有12个au,au size为1m。由于diskgroup为normal reduncancy模式,所以每一个au在1号磁盘中还有一个镜像,所以一共是12个AU,占用12M。blocksize为8k,所以每个au包含的block数量为1024/8=128个,因为行块所在位置为133号数据块,所以该块应该处于数据文件的第二个au的5(133-128)号8k单元数据块,也就是磁盘/dev/asm_disk_1的145号AU,仔细观察可以发现extent也为对应的号数,由于冗余所以每个extent都有2个。
接下来确认行块在asm_disk_1以及asm_disk_2上
[grid@racnode1 luda]$ strings /dev/asm_disk_1 | grep ASM_TEST ASM_TEST [grid@racnode1 luda]$ strings /dev/asm_disk_2 | grep ASM_TEST ASM_TEST
接着使用dd导出磁盘中145号AU的数据
[grid@racnode1 luda]# dd if=/dev/asm_disk_1 bs=1024k count=1 skip=144 of=AU_145.data 1+0 records in 1+0 records out 1048576 bytes (1.0 MB) copied, 0.031567 seconds, 21.3 MB/s [grid@racnode1 luda]$ [grid@racnode1 luda]$ ls -l AU_145.data -rw-r--r-- 1 grid oinstall 1048576 Aug 13 22:45 AU_145.data [grid@racnode1 luda]$
下来就可以从145号au中取出第5个8k块的数据
[grid@racnode1 luda]$ dd if=AU_145.data bs=8k count=1 skip=4 of=block133.data
使用od观察该块即可找到我们想要的数据ASM_TEST。
[grid@racnode1 luda]$ od -c block133.data 0137760 002 301 002 \b A S M _ T E S T 001 006 i 356Looks good
到此通过AU与OS磁盘的映射关系,验证了可以找到对应行的数据。解释了如何通过asm直接读取object的基本原理。