Skip to content

从ASM DISKS中定位表行在系统DISK中的物理偏移位置

该部分也是承接从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的基本原理。