最近在测试ASM存放方式,也参考了网上很多资料,这里把自己的学习心得总结下,希望对有需要更深一步了解ASM的人提供参考。
要想用C语言读取ASM磁盘, 就一定要知道ASM是怎么存储数据的,下面就先通过创建一个磁盘组并在磁盘组上面创建表空间的方式介绍数据文件是怎么在ASM中怎么存储的。
1、首先有两个没有使用的磁盘'/dev/asm-diskf','/dev/asm-diske'
SQL> select HEADER_STATUS,path from v$asm_disk;
HEADER_STATUS PATH
------------------------------------ --------------------
CANDIDATE /dev/asm-diskf
CANDIDATE /dev/asm-diske
MEMBER /dev/asm-diskd
MEMBER /dev/asm-diskc
MEMBER /dev/asm-diskb
SQL>
磁盘头状态解释:
MEMBER 属于当前diskgroup的disk
FORMER 这个disk以前属于一个diskgroup,现在这个diskgroup被删除了
CANDIDATE 当使用裸设备,一个新的可以被diskgroup所用的disk
PROVISIONED 当使用asmlib,一个新的可以被diskgroup所用的disk
2、创建磁盘组TEST
SQL> create diskgroup test external redundancy disk '/dev/asm-diske','/dev/asm-diskf';
Diskgroup created.
SQL>
3、查看磁盘组和磁盘信息
<=======查看磁盘信息
SQL> col HEADER_STATUS for a10
SQL> col name for a20
SQL> col path for a20
SQL> select disk_number,
2 mount_status,
3 header_status,
4 mode_status,
5 state,
6 total_mb,
7 free_mb,
8 name,
9 path
10 from v$asm_disk order by name;
DISK_NUMBER MOUNT_STATUS HEADER_STA MODE_STATUS STATE TOTAL_MB FREE_MB NAME PATH
----------- --------------------- ---------- --------------------- ------------------------ ---------- ---------- -------------------- --------------------
0 CACHED MEMBER ONLINE NORMAL 10240 6843 DATA_0000 /dev/asm-diskc
0 CACHED MEMBER ONLINE NORMAL 3072 2394 FLASH_0000 /dev/asm-diskd
0 CACHED MEMBER ONLINE NORMAL 3072 2635 OCR_0000 /dev/asm-diskb
0 CACHED MEMBER ONLINE NORMAL 1000 974 TEST_0000 /dev/asm-diske
1 CACHED MEMBER ONLINE NORMAL 1000 974 TEST_0001 /dev/asm-diskf
SQL>
<======查看磁盘组信息,新创建的磁盘对应的磁盘组是4号
SQL> col name for a20
SQL> select group_number,
2 name,
3 sector_size,
4 block_size,
5 ALLOCATION_UNIT_SIZE,
6 STATE,
7 TYPE,
8 TOTAL_MB,
9 FREE_MB
10 from v$asm_diskgroup;
GROUP_NUMBER NAME SECTOR_SIZE BLOCK_SIZE ALLOCATION_UNIT_SIZE STATE TYPE TOTAL_MB FREE_MB
------------ -------------------- ----------- ---------- -------------------- --------------------------------- ------------------ ---------- ----------
1 DATA 512 4096 1048576 MOUNTED EXTERN 10240 6843
2 FLASH 512 4096 1048576 MOUNTED EXTERN 3072 2394
3 OCR 512 4096 1048576 MOUNTED EXTERN 3072 2635
4 TEST 512 4096 1048576 MOUNTED EXTERN 2000 1948
4、在磁盘组TEST上面创建表空间同时创建测试表T
<=======在磁盘组TEST上面创建一个10M大小的表空间
SQL> create tablespace test datafile '+TEST/test.dbf' size 10M;
Tablespace created.
SQL>
<========在表空间TEST上面创建一个测试表T
SQL> create table t(id int, name varchar2(20)) tablespace test;
Table created.
SQL> insert into t select level lv, dbms_random.string('l',20) from dual connect by level < 10;
9 rows created.
SQL> commit;
Commit complete.
SQL> select * from t;
ID NAME
---------- ----------------------------------------
1 lfafmbsgorccdfnrhjro
2 bhrhamcixmmiweqelndh
3 vzsyzgsvrvvextllrcnk
4 nfplwsgotrycikmbnkdr
5 ixmufytohdoytssrsznt
6 xryzgifldpdzaaetdjzd
7 wvnmkruakaulbbrofsgj
8 nxnhetswbrvovbfhitar
9 iaxfquogsldqgnlaogil
9 rows selected.
SQL>
<========查看表空间test对应的数据文件位置
SQL> col name for a50
SQL> select * from v$dbfile;
FILE# NAME
---------- --------------------------------------------------
4 +DATA/devdb/datafile/users.259.940551847
3 +DATA/devdb/datafile/undotbs1.258.940551847
2 +DATA/devdb/datafile/sysaux.257.940551847
1 +DATA/devdb/datafile/system.256.940551845
5 +DATA/devdb/datafile/undotbs2.264.940552089
6 +TEST/test.dbf <=======新创建的表空间TEST对应的数据文件
6 rows selected.
SQL>
5、查看数据文件test.dbf在asm中对应的文件号
SQL> select * from v$asm_alias where name like '%test.dbf%';
NAME GROUP_NUMBER FILE_NUMBER FILE_INCARNATION ALIAS_INDEX ALIAS_INCARNATION PARENT_INDEX REFERENCE_INDEX ALI SYS
-------------------- ------------ ----------- ---------------- ----------- ----------------- ------------ --------------- --- ---
test.dbf 4 256 995742567 1 1 67108864 83886079 N N
SQL>
6、查询数据文件test.dbf在asm中对应的AU分布信息
<==========查询256文件对应的AU分区信息
SQL> select group_kffxp, --磁盘组编号
number_kffxp, --文件编号
pxn_kffxp, --物理区号
xnum_kffxp, --逻辑区号
lxn_kffxp, --0=primary, 1=first mirror, 2=second mirror
disk_kffxp, --磁盘编号
au_kffxp --au号
from x$kffxp where number_kffxp=256 and group_kffxp = 4;
GROUP_KFFXP NUMBER_KFFXP PXN_KFFXP XNUM_KFFXP LXN_KFFXP DISK_KFFXP AU_KFFXP
----------- ------------ ---------- ---------- ---------- ---------- ----------
4 256 0 0 0 1 27
4 256 1 1 0 0 26
4 256 2 2 0 1 28
4 256 3 3 0 0 27
4 256 4 4 0 1 29
4 256 5 5 0 0 28
4 256 6 6 0 1 30
4 256 7 7 0 0 29
4 256 8 8 0 1 31
4 256 9 9 0 0 30
4 256 10 10 0 1 32
11 rows selected.
SQL>
创建的表空间TEST大小是10M,AU的大小是1M,可以看到表空间对应的AU为11个,也就是11M多出了1M,这1M是存放额外的信息,如果AU大小是1M的话,那么asm磁盘中对应的AU总是比表空间中对应的数据文件大1M。
上面查到的表空间TEST对应磁盘组的AU分布信息,可以通过kfed工具来验证的。通过创建数据文件可以发现,第一个创建的文件号总是256,其实0-255是存放元数据的。一个AU大小是1M,一个块大小是4k(查询v$asm_diskgroup视图BLOCK_SIZE列可以得到),所以1M/4k = 256,也就是说第一个AU都是存放的元数据,之前创建的数据文件都是从第二个AU开始的。如果磁盘组有多个磁盘组成,则在0号盘的第二个AU里面(查询v$asm_disk的DISK_NUMBER列为0的磁盘)的第二个AU。通过上面的查询磁盘信息可以知道,TEST磁盘组的第0号盘对应的磁盘为/dev/asm-diske,下面查询/dev/asm-diske的第二个AU数据
7、TEST磁盘组的0号磁盘的第2个AU
[grid@rac1]$kfed read /dev/asm-diske aun=2 blkn=1| more <======TEST磁盘组的0号磁盘的第2个AU
kfbh.endian: 1 ; 0x000: 0x01
kfbh.hard: 130 ; 0x001: 0x82
kfbh.type: 4 ; 0x002: KFBTYP_FILEDIR
kfbh.datfmt: 1 ; 0x003: 0x01
kfbh.block.blk: 1 ; 0x004: blk=1
kfbh.block.obj: 1 ; 0x008: file=1
kfbh.check: 4143342563 ; 0x00c: 0xf6f663e3
kfbh.fcn.base: 262 ; 0x010: 0x00000106
kfbh.fcn.wrap: 0 ; 0x014: 0x00000000
kfbh.spare1: 0 ; 0x018: 0x00000000
kfbh.spare2: 0 ; 0x01c: 0x00000000
kfffdb.node.incarn: 1 ; 0x000: A=1 NUMM=0x0
kfffdb.node.frlist.number: 4294967295 ; 0x004: 0xffffffff
kfffdb.node.frlist.incarn: 0 ; 0x008: A=0 NUMM=0x0
kfffdb.hibytes: 0 ; 0x00c: 0x00000000
kfffdb.lobytes: 2097152 ; 0x010: 0x00200000
kfffdb.xtntcnt: 2 ; 0x014: 0x00000002
kfffdb.xtnteof: 2 ; 0x018: 0x00000002
kfffdb.blkSize: 4096 ; 0x01c: 0x00001000
kfffdb.flags: 1 ; 0x020: O=1 S=0 S=0 D=0 C=0 I=0 R=0 A=0
kfffdb.fileType: 15 ; 0x021: 0x0f
kfffdb.dXrs: 17 ; 0x022: SCHE=0x1 NUMB=0x1
kfffdb.iXrs: 17 ; 0x023: SCHE=0x1 NUMB=0x1
kfffdb.dXsiz[0]: 4294967295 ; 0x024: 0xffffffff
kfffdb.dXsiz[1]: 0 ; 0x028: 0x00000000
kfffdb.dXsiz[2]: 0 ; 0x02c: 0x00000000
kfffdb.iXsiz[0]: 4294967295 ; 0x030: 0xffffffff
kfffdb.iXsiz[1]: 0 ; 0x034: 0x00000000
kfffdb.iXsiz[2]: 0 ; 0x038: 0x00000000
kfffdb.xtntblk: 2 ; 0x03c: 0x0002
kfffdb.break: 60 ; 0x03e: 0x003c
kfffdb.priZn: 0 ; 0x040: KFDZN_COLD
kfffdb.secZn: 0 ; 0x041: KFDZN_COLD
kfffdb.ub2spare: 0 ; 0x042: 0x0000
kfffdb.alias[0]: 4294967295 ; 0x044: 0xffffffff
kfffdb.alias[1]: 4294967295 ; 0x048: 0xffffffff
kfffdb.strpwdth: 0 ; 0x04c: 0x00
kfffdb.strpsz: 0 ; 0x04d: 0x00
kfffdb.usmsz: 0 ; 0x04e: 0x0000
kfffdb.crets.hi: 33075987 ; 0x050: HOUR=0x13 DAYS=0x18 MNTH=0xc YEAR=0x7e2
kfffdb.crets.lo: 219266048 ; 0x054: USEC=0x0 MSEC=0x6f SECS=0x11 MINS=0x3
kfffdb.modts.hi: 33075987 ; 0x058: HOUR=0x13 DAYS=0x18 MNTH=0xc YEAR=0x7e2
kfffdb.modts.lo: 219266048 ; 0x05c: USEC=0x0 MSEC=0x6f SECS=0x11 MINS=0x3
kfffdb.dasz[0]: 0 ; 0x060: 0x00
kfffdb.dasz[1]: 0 ; 0x061: 0x00
kfffdb.dasz[2]: 0 ; 0x062: 0x00
kfffdb.dasz[3]: 0 ; 0x063: 0x00
kfffdb.permissn: 0 ; 0x064: 0x00
kfffdb.ub1spar1: 0 ; 0x065: 0x00
kfffdb.ub2spar2: 0 ; 0x066: 0x0000
kfffdb.user.entnum: 0 ; 0x068: 0x0000
kfffdb.user.entinc: 0 ; 0x06a: 0x0000
kfffdb.group.entnum: 0 ; 0x06c: 0x0000
kfffdb.group.entinc: 0 ; 0x06e: 0x0000
kfffdb.spare[0]: 0 ; 0x070: 0x00000000
kfffdb.spare[1]: 0 ; 0x074: 0x00000000
kfffdb.spare[2]: 0 ; 0x078: 0x00000000
kfffdb.spare[3]: 0 ; 0x07c: 0x00000000
kfffdb.spare[4]: 0 ; 0x080: 0x00000000
kfffdb.spare[5]: 0 ; 0x084: 0x00000000
kfffdb.spare[6]: 0 ; 0x088: 0x00000000
kfffdb.spare[7]: 0 ; 0x08c: 0x00000000
kfffdb.spare[8]: 0 ; 0x090: 0x00000000
kfffdb.spare[9]: 0 ; 0x094: 0x00000000
kfffdb.spare[10]: 0 ; 0x098: 0x00000000
kfffdb.spare[11]: 0 ; 0x09c: 0x00000000
kfffdb.usm: ; 0x0a0: length=0
kfffde[0].xptr.au: 2 ; 0x4a0: 0x00000002
kfffde[0].xptr.disk: 0 ; 0x4a4: 0x0000 <=====0号盘2号AU
kfffde[0].xptr.flags: 0 ; 0x4a6: L=0 E=0 D=0 S=0
kfffde[0].xptr.chk: 40 ; 0x4a7: 0x28
kfffde[1].xptr.au: 26 ; 0x4a8: 0x0000001a
kfffde[1].xptr.disk: 1 ; 0x4ac: 0x0001 <=====1号盘的26AU
kfffde[1].xptr.flags: 0 ; 0x4ae: L=0 E=0 D=0 S=0
kfffde[1].xptr.chk: 49 ; 0x4af: 0x31
kfffde[2].xptr.au: 4294967295 ; 0x4b0: 0xffffffff
kfffde[2].xptr.disk: 65535 ; 0x4b4: 0xffff <=====65535代表没有使用
kfffde[2].xptr.flags: 0 ; 0x4b6: L=0 E=0 D=0 S=0
kfffde[2].xptr.chk: 42 ; 0x4b7: 0x2a
kfffde[3].xptr.au: 4294967295 ; 0x4b8: 0xffffffff
kfffde[3].xptr.disk: 65535 ; 0x4bc: 0xffff
kfffde[3].xptr.flags: 0 ; 0x4be: L=0 E=0 D=0 S=0
kfffde[3].xptr.chk: 42 ; 0x4bf: 0x2a
kfffde[4].xptr.au: 4294967295 ; 0x4c0: 0xffffffff
kfffde[4].xptr.disk: 65535 ; 0x4c4: 0xffff
kfffde[4].xptr.flags: 0 ; 0x4c6: L=0 E=0 D=0 S=0
kfffde[4].xptr.chk: 42 ; 0x4c7: 0x2a
kfffde[5].xptr.au: 4294967295 ; 0x4c8: 0xffffffff
kfffde[5].xptr.disk: 65535 ; 0x4cc: 0xffff
kfffde[5].xptr.flags: 0 ; 0x4ce: L=0 E=0 D=0 S=0
上面查询说明第一个AU(0号盘的2号AU)的0-255块存放的是元数据,新建表空间TEST对应的test.dbf存放在第二个AU的第一个块里面,通过查询0号盘的2号AU可以知道,第二个AU存放在1号盘(/dev/asm-diskf)的26号AU里面.
8、读取1号盘的26号AU的第一个块 (对应test.dbf在asm中的256文件号)
[grid@rac1]$kfed read /dev/asm-diskf aun=26 blkn=0| more
kfbh.endian: 1 ; 0x000: 0x01
kfbh.hard: 130 ; 0x001: 0x82
kfbh.type: 4 ; 0x002: KFBTYP_FILEDIR
kfbh.datfmt: 1 ; 0x003: 0x01
kfbh.block.blk: 256 ; 0x004: blk=256 <========代表256文件号
kfbh.block.obj: 1 ; 0x008: file=1
kfbh.check: 729566444 ; 0x00c: 0x2b7c4cec
kfbh.fcn.base: 289 ; 0x010: 0x00000121
kfbh.fcn.wrap: 0 ; 0x014: 0x00000000
kfbh.spare1: 0 ; 0x018: 0x00000000
kfbh.spare2: 0 ; 0x01c: 0x00000000
kfffdb.node.incarn: 995742567 ; 0x000: A=1 NUMM=0x1dace9b3
kfffdb.node.frlist.number: 4294967295 ; 0x004: 0xffffffff
kfffdb.node.frlist.incarn: 0 ; 0x008: A=0 NUMM=0x0
kfffdb.hibytes: 0 ; 0x00c: 0x00000000
kfffdb.lobytes: 10493952 ; 0x010: 0x00a02000
kfffdb.xtntcnt: 11 ; 0x014: 0x0000000b
kfffdb.xtnteof: 11 ; 0x018: 0x0000000b
kfffdb.blkSize: 8192 ; 0x01c: 0x00002000
kfffdb.flags: 17 ; 0x020: O=1 S=0 S=0 D=0 C=1 I=0 R=0 A=0
kfffdb.fileType: 2 ; 0x021: 0x02
kfffdb.dXrs: 17 ; 0x022: SCHE=0x1 NUMB=0x1
kfffdb.iXrs: 17 ; 0x023: SCHE=0x1 NUMB=0x1
kfffdb.dXsiz[0]: 4294967295 ; 0x024: 0xffffffff
kfffdb.dXsiz[1]: 0 ; 0x028: 0x00000000
kfffdb.dXsiz[2]: 0 ; 0x02c: 0x00000000
kfffdb.iXsiz[0]: 4294967295 ; 0x030: 0xffffffff
kfffdb.iXsiz[1]: 0 ; 0x034: 0x00000000
kfffdb.iXsiz[2]: 0 ; 0x038: 0x00000000
kfffdb.xtntblk: 11 ; 0x03c: 0x000b
kfffdb.break: 60 ; 0x03e: 0x003c
kfffdb.priZn: 0 ; 0x040: KFDZN_COLD
kfffdb.secZn: 0 ; 0x041: KFDZN_COLD
kfffdb.ub2spare: 0 ; 0x042: 0x0000
kfffdb.alias[0]: 106 ; 0x044: 0x0000006a
kfffdb.alias[1]: 1 ; 0x048: 0x00000001
kfffdb.strpwdth: 1 ; 0x04c: 0x01
kfffdb.strpsz: 20 ; 0x04d: 0x14
kfffdb.usmsz: 0 ; 0x04e: 0x0000
kfffdb.crets.hi: 33075987 ; 0x050: HOUR=0x13 DAYS=0x18 MNTH=0xc YEAR=0x7e2
kfffdb.crets.lo: 632091648 ; 0x054: USEC=0x0 MSEC=0x33d SECS=0x1a MINS=0x9
kfffdb.modts.hi: 33075987 ; 0x058: HOUR=0x13 DAYS=0x18 MNTH=0xc YEAR=0x7e2
kfffdb.modts.lo: 0 ; 0x05c: USEC=0x0 MSEC=0x0 SECS=0x0 MINS=0x0
kfffdb.dasz[0]: 0 ; 0x060: 0x00
kfffdb.dasz[1]: 0 ; 0x061: 0x00
kfffdb.dasz[2]: 0 ; 0x062: 0x00
kfffdb.dasz[3]: 0 ; 0x063: 0x00
kfffdb.permissn: 0 ; 0x064: 0x00
kfffdb.ub1spar1: 0 ; 0x065: 0x00
kfffdb.ub2spar2: 0 ; 0x066: 0x0000
kfffdb.user.entnum: 0 ; 0x068: 0x0000
kfffdb.user.entinc: 0 ; 0x06a: 0x0000
kfffdb.group.entnum: 0 ; 0x06c: 0x0000
kfffdb.group.entinc: 0 ; 0x06e: 0x0000
kfffdb.spare[0]: 0 ; 0x070: 0x00000000
kfffdb.spare[1]: 0 ; 0x074: 0x00000000
kfffdb.spare[2]: 0 ; 0x078: 0x00000000
kfffdb.spare[3]: 0 ; 0x07c: 0x00000000
kfffdb.spare[4]: 0 ; 0x080: 0x00000000
kfffdb.spare[5]: 0 ; 0x084: 0x00000000
kfffdb.spare[6]: 0 ; 0x088: 0x00000000
kfffdb.spare[7]: 0 ; 0x08c: 0x00000000
kfffdb.spare[8]: 0 ; 0x090: 0x00000000
kfffdb.spare[9]: 0 ; 0x094: 0x00000000
kfffdb.spare[10]: 0 ; 0x098: 0x00000000
kfffdb.spare[11]: 0 ; 0x09c: 0x00000000
kfffdb.usm: ; 0x0a0: length=0 <=====下面开始为TEST表空间的数据文件test.dbf(大小10M)对应的AU分布信息
kfffde[0].xptr.au: 27 ; 0x4a0: 0x0000001b
kfffde[0].xptr.disk: 1 ; 0x4a4: 0x0001 <=====1号盘的27号AU
kfffde[0].xptr.flags: 0 ; 0x4a6: L=0 E=0 D=0 S=0
kfffde[0].xptr.chk: 48 ; 0x4a7: 0x30
kfffde[1].xptr.au: 26 ; 0x4a8: 0x0000001a
kfffde[1].xptr.disk: 0 ; 0x4ac: 0x0000 <=====0号盘的26号AU
kfffde[1].xptr.flags: 0 ; 0x4ae: L=0 E=0 D=0 S=0
kfffde[1].xptr.chk: 48 ; 0x4af: 0x30
kfffde[2].xptr.au: 28 ; 0x4b0: 0x0000001c
kfffde[2].xptr.disk: 1 ; 0x4b4: 0x0001 <=====1号盘的28号AU
kfffde[2].xptr.flags: 0 ; 0x4b6: L=0 E=0 D=0 S=0
kfffde[2].xptr.chk: 55 ; 0x4b7: 0x37
kfffde[3].xptr.au: 27 ; 0x4b8: 0x0000001b
kfffde[3].xptr.disk: 0 ; 0x4bc: 0x0000 ......中间省略
kfffde[3].xptr.flags: 0 ; 0x4be: L=0 E=0 D=0 S=0
kfffde[3].xptr.chk: 49 ; 0x4bf: 0x31
kfffde[4].xptr.au: 29 ; 0x4c0: 0x0000001d
kfffde[4].xptr.disk: 1 ; 0x4c4: 0x0001
kfffde[4].xptr.flags: 0 ; 0x4c6: L=0 E=0 D=0 S=0
kfffde[4].xptr.chk: 54 ; 0x4c7: 0x36
kfffde[5].xptr.au: 28 ; 0x4c8: 0x0000001c
kfffde[5].xptr.disk: 0 ; 0x4cc: 0x0000
kfffde[5].xptr.flags: 0 ; 0x4ce: L=0 E=0 D=0 S=0
kfffde[5].xptr.chk: 54 ; 0x4cf: 0x36
kfffde[6].xptr.au: 30 ; 0x4d0: 0x0000001e
kfffde[6].xptr.disk: 1 ; 0x4d4: 0x0001
kfffde[6].xptr.flags: 0 ; 0x4d6: L=0 E=0 D=0 S=0
kfffde[6].xptr.chk: 53 ; 0x4d7: 0x35
kfffde[7].xptr.au: 29 ; 0x4d8: 0x0000001d
kfffde[7].xptr.disk: 0 ; 0x4dc: 0x0000
kfffde[7].xptr.flags: 0 ; 0x4de: L=0 E=0 D=0 S=0
kfffde[7].xptr.chk: 55 ; 0x4df: 0x37
kfffde[8].xptr.au: 31 ; 0x4e0: 0x0000001f
kfffde[8].xptr.disk: 1 ; 0x4e4: 0x0001
kfffde[8].xptr.flags: 0 ; 0x4e6: L=0 E=0 D=0 S=0
kfffde[8].xptr.chk: 52 ; 0x4e7: 0x34
kfffde[9].xptr.au: 30 ; 0x4e8: 0x0000001e
kfffde[9].xptr.disk: 0 ; 0x4ec: 0x0000
kfffde[9].xptr.flags: 0 ; 0x4ee: L=0 E=0 D=0 S=0
kfffde[9].xptr.chk: 52 ; 0x4ef: 0x34
kfffde[10].xptr.au: 32 ; 0x4f0: 0x00000020
kfffde[10].xptr.disk: 1 ; 0x4f4: 0x0001 <========对应的最后一个AU为0号盘的32AU
kfffde[10].xptr.flags: 0 ; 0x4f6: L=0 E=0 D=0 S=0
kfffde[10].xptr.chk: 11 ; 0x4f7: 0x0b
kfffde[11].xptr.au: 4294967295 ; 0x4f8: 0xffffffff
kfffde[11].xptr.disk: 65535 ; 0x4fc: 0xffff
kfffde[11].xptr.flags: 0 ; 0x4fe: L=0 E=0 D=0 S=0
kfffde[11].xptr.chk: 42 ; 0x4ff: 0x2a
kfffde[12].xptr.au: 4294967295 ; 0x500: 0xffffffff
kfffde[12].xptr.disk: 65535 ; 0x504: 0xffff
kfffde[12].xptr.flags: 0 ; 0x506: L=0 E=0 D=0 S=0
kfffde[12].xptr.chk: 42 ; 0x507: 0x2a
kfffde[13].xptr.au: 4294967295 ; 0x508: 0xffffffff
kfffde[13].xptr.disk: 65535 ; 0x50c: 0xffff
kfffde[13].xptr.flags: 0 ; 0x50e: L=0 E=0 D=0 S=0
kfffde[13].xptr.chk: 42 ; 0x50f: 0x2a
kfffde[14].xptr.au: 4294967295 ; 0x510: 0xffffffff
--More--
上面通过kfed查到的test.dbf对应的AU分布信息和x$kffxp视图查到的一样
<==========查询256文件对应的AU分区信息
SQL> select group_kffxp, --磁盘组编号
number_kffxp, --文件编号
pxn_kffxp, --物理区号
xnum_kffxp, --逻辑区号
lxn_kffxp, --0=primary, 1=first mirror, 2=second mirror
disk_kffxp, --磁盘编号
au_kffxp --au号
from x$kffxp where number_kffxp=256 and group_kffxp = 4;
GROUP_KFFXP NUMBER_KFFXP PXN_KFFXP XNUM_KFFXP LXN_KFFXP DISK_KFFXP AU_KFFXP
----------- ------------ ---------- ---------- ---------- ---------- ----------
4 256 0 0 0 1 27
4 256 1 1 0 0 26
4 256 2 2 0 1 28
4 256 3 3 0 0 27
4 256 4 4 0 1 29
4 256 5 5 0 0 28
4 256 6 6 0 1 30
4 256 7 7 0 0 29
4 256 8 8 0 1 31
4 256 9 9 0 0 30
4 256 10 10 0 1 32
11 rows selected.
也就说,表空间TEST对应的数据文件test.dbf里面存放的数据就存放在这些AU里面。如果能把这些AU里面的数据读出来,就可以把刚才在表空间TEST上面创建的表T的数据读出来。
9、先查询下磁盘组TEST上面创建的TEST表空间包含的对象T表存放的物理位置
SQL> col owner for a20
SQL> col segment_name for a20
SQL> select owner, SEGMENT_NAME,HEADER_FILE,HEADER_BLOCK from dba_segments where segment_name = 'T' and owner = 'SYS';
OWNER SEGMENT_NAME HEADER_FILE HEADER_BLOCK
-------------------- -------------------- ----------- ------------
SYS T 6 130
SQL> select dbms_rowid.rowid_relative_fno(rowid) as file#, dbms_rowid.rowid_block_number(rowid) as block#, id, name from t;
FILE# BLOCK# ID NAME
---------- ---------- ---------- --------------------------------------------------
6 133 1 lfafmbsgorccdfnrhjro
6 133 2 bhrhamcixmmiweqelndh
6 133 3 vzsyzgsvrvvextllrcnk
6 133 4 nfplwsgotrycikmbnkdr
6 133 5 ixmufytohdoytssrsznt
6 133 6 xryzgifldpdzaaetdjzd
6 133 7 wvnmkruakaulbbrofsgj
6 133 8 nxnhetswbrvovbfhitar
6 133 9 iaxfquogsldqgnlaogil
9 rows selected.
SQL>
这里要注意下,表T的头文件是存放在6号文件的130块里面,真正的数据文件是存放在133号文件里面
10、dump 6号文件的130块(块头)
SQL> alter system dump datafile 6 block 130;
System altered.
SQL> select VALUE from v$diag_info where name = 'Default Trace File';
VALUE
----------------------------------------------------------------------------------------------------
/u01/app/oracle/diag/rdbms/devdb/devdb1/trace/devdb1_ora_11105.trc
SQL>
查询产生的trace文件
lock dump from disk:
buffer tsn: 6 rdba: 0x01800082 (6/130) <======6号文件的130块
scn: 0x0000.0176d02d seq: 0x01 flg: 0x04 tail: 0xd02d2301
frmt: 0x02 chkval: 0x9b26 type: 0x23=PAGETABLE SEGMENT HEADER <======类型是段头
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x00007F8234D8A000 to 0x00007F8234D8C000
7F8234D8A000 0000A223 01800082 0176D02D 04010000 [#.......-.v.....]
7F8234D8A010 00009B26 00000000 00000000 00000000 [&...............]
7F8234D8A020 00000000 00000001 00000008 00000A9C [................]
7F8234D8A030 00000000 00000008 00000008 01800088 [................]
。
。
。
Inc # 0
Extent Map
-----------------------------------------------------------------
0x01800080 length: 8
Auxillary Map
--------------------------------------------------------
Extent 0 : L1 dba: 0x01800080 Data dba: 0x01800083 <=======一级块位图地址0x01800080
--------------------------------------------------------
Second Level Bitmap block DBAs
--------------------------------------------------------
DBA 1: 0x01800081 <=======二级块位图地址
GLOBAL CACHE ELEMENT DUMP (address: 0x683fa500):
把一级块位图的地址进行转换如下:
SQL> select to_number('01800080','xxxxxxxx') from dual;
TO_NUMBER('01800080','XXXXXXXX')
--------------------------------
25165952
SQL> select dbms_utility.data_block_address_file('25165952') from dual;
DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE('25165952')
------------------------------------------------
6
SQL> select dbms_utility.data_block_address_block('25165952') from dual;
DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK('25165952')
-------------------------------------------------
128
SQL>
关于块位图的解释和测试见:http://note.youdao.com/noteshare?id=92d85b4314f497fb16b15c931370d255
11、把6号文件的128块dump查看结果
Start dump data blocks tsn: 6 file#:6 minblk 128 maxblk 128
Block dump from cache:
Dump of buffer cache at level 4 for tsn=6 rdba=25165952
Block dump from disk:
buffer tsn: 6 rdba: 0x01800080 (6/128) <======6号文件的128块
scn: 0x0000.0176d02d seq: 0x01 flg: 0x04 tail: 0xd02d2001
frmt: 0x02 chkval: 0xc614 type: 0x20=FIRST LEVEL BITMAP BLOCK <=======类型是一级块位图
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x00007F236852BA00 to 0x00007F236852DA00
说明:
真正的数据文件(6号文件133号块)和前面的段信息和位图信息相差了5个块,一级块位图的位置在6号文件的128块(这点很重要,下面用dd+od方式证明的时候要用)
12、把6号文件133块dump出来(真正存放数据的块)
SQL>
SQL> alter system dump datafile 6 block 133;
System altered.
SQL> select VALUE from v$diag_info where name = 'Default Trace File';
VALUE
----------------------------------------------------------------------------------------------------
/u01/app/oracle/diag/rdbms/devdb/devdb1/trace/devdb1_ora_11105.trc
SQL>
查看/u01/app/oracle/diag/rdbms/devdb/devdb1/trace/devdb1_ora_11105.trc文件内容如下:
Start dump data blocks tsn: 6 file#:6 minblk 133 maxblk 133
Block dump from cache:
Dump of buffer cache at level 4 for tsn=6 rdba=25165957
BH (0x613bfff8) file#: 6 rdba: 0x01800085 (6/133) class: 1 ba: 0x6118a000
set: 6 pool: 3 bsz: 8192 bsi: 0 sflg: 1 pwc: 0,25
dbwrid: 0 obj: 78298 objn: 78298 tsn: 6 afn: 6 hint: f
hash: [0x6afbda78,0x80785988] lru: [0x69bb2028,0x697ccff8]
lru-flags: on_auxiliary_list
ckptq: [NULL] fileq: [NULL] objq: [NULL] objaq: [NULL]
st: FREE md: NULL fpin: 'ktspbwh2: ktspfmdb' tch: 0 lfb: 33 le: (nil)
flags:
Block dump from disk:
buffer tsn: 6 rdba: 0x01800085 (6/133)
scn: 0x0000.0176d030 seq: 0x01 flg: 0x06 tail: 0xd0300601
frmt: 0x02 chkval: 0x4251 type: 0x06=trans data
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x00007F8234D8A000 to 0x00007F8234D8C000
7F8234D8A000 0000A206 01800085 0176D030 06010000 [........0.v.....]
7F8234D8A010 00004251 00000001 000131DA 0176D02D [QB.......1..-.v.]
7F8234D8A020 00000000 0032F802 01800080 00060009 [......2.........]
7F8234D8A030 0000062A 00C00429 00230271 00002009 [*...)...q.#.. ..]
7F8234D8A040 0176D030 00000000 00000000 00000000 [0.v.............]
7F8234D8A050 00000000 00000000 00000000 00000000 [................]
7F8234D8A060 00000000 00090100 0024FFFF 1E811EA5 [..........$.....]
7F8234D8A070 00001E81 1EA50009 1EDB1EC0 1F111EF6 [................]
7F8234D8A080 1F471F2C 1F7D1F62 00000000 00000000 [,.G.b.}.........]
7F8234D8A090 00000000 00000000 00000000 00000000 [................]
Repeat 486 times
7F8234D8BF00 00000000 00000000 02012C00 1402C102 [.........,......]
7F8234D8BF10 6661666C 6773626D 6363726F 726E6664 [lfafmbsgorccdfnr] <=========这些就是表T里面存放的内容了
7F8234D8BF20 6F726A68 0202012C 621403C1 61687268 [hjro,......bhrha]
7F8234D8BF30 7869636D 77696D6D 6C657165 2C68646E [mcixmmiweqelndh,]
7F8234D8BF40 C1020201 7A761404 677A7973 76727673 [......vzsyzgsvrv]
7F8234D8BF50 74786576 63726C6C 012C6B6E 05C10202 [vextllrcnk,.....]
7F8234D8BF60 70666E14 6773776C 7972746F 6D6B6963 [.nfplwsgotrycikm]
7F8234D8BF70 646B6E62 02012C72 1406C102 756D7869 [bnkdr,......ixmu]
7F8234D8BF80 6F747966 796F6468 72737374 746E7A73 [fytohdoytssrsznt]
7F8234D8BF90 0202012C 781407C1 677A7972 646C6669 [,......xryzgifld]
7F8234D8BFA0 617A6470 64746561 2C647A6A C1020201 [pdzaaetdjzd,....]
7F8234D8BFB0 76771408 726B6D6E 616B6175 62626C75 [..wvnmkruakaulbb]
7F8234D8BFC0 73666F72 012C6A67 09C10202 6E786E14 [rofsgj,......nxn]
7F8234D8BFD0 73746568 76726277 6662766F 61746968 [hetswbrvovbfhita]
7F8234D8BFE0 02012C72 140AC102 66786169 676F7571 [r,......iaxfquog]
7F8234D8BFF0 71646C73 616C6E67 6C69676F D0300601 [sldqgnlaogil..0.]
Block header dump: 0x01800085
Object id on Block? Y
seg/obj: 0x131da csc: 0x00.176d02d itc: 2 flg: E typ: 1 - DATA
brn: 0 bdba: 0x1800080 ver: 0x01 opc: 0
inc: 0 exflg: 0
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0009.006.0000062a 0x00c00429.0271.23 --U- 9 fsc 0x0000.0176d030
0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
bdba: 0x01800085
data_block_dump,data header at 0x7f8234d8a064
===============
tsiz: 0x1f98
hsiz: 0x24
pbl: 0x7f8234d8a064
76543210
flag=--------
ntab=1
nrow=9
frre=-1
fsbo=0x24
fseo=0x1ea5
avsp=0x1e81
tosp=0x1e81
0xe:pti[0] nrow=9 offs=0
0x12:pri[0] offs=0x1ea5
0x14:pri[1] offs=0x1ec0
0x16:pri[2] offs=0x1edb
0x18:pri[3] offs=0x1ef6
0x1a:pri[4] offs=0x1f11
0x1c:pri[5] offs=0x1f2c
0x1e:pri[6] offs=0x1f47
0x20:pri[7] offs=0x1f62
0x22:pri[8] offs=0x1f7d
block_row_dump:
tab 0, row 0, @0x1ea5
tl: 27 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 02
col 1: [20] 6c 66 61 66 6d 62 73 67 6f 72 63 63 64 66 6e 72 68 6a 72 6f
tab 0, row 1, @0x1ec0
tl: 27 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 03
col 1: [20] 62 68 72 68 61 6d 63 69 78 6d 6d 69 77 65 71 65 6c 6e 64 68
tab 0, row 2, @0x1edb
tl: 27 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 04
col 1: [20] 76 7a 73 79 7a 67 73 76 72 76 76 65 78 74 6c 6c 72 63 6e 6b
tab 0, row 3, @0x1ef6
tl: 27 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 05
col 1: [20] 6e 66 70 6c 77 73 67 6f 74 72 79 63 69 6b 6d 62 6e 6b 64 72
tab 0, row 4, @0x1f11
tl: 27 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 06
col 1: [20] 69 78 6d 75 66 79 74 6f 68 64 6f 79 74 73 73 72 73 7a 6e 74
tab 0, row 5, @0x1f2c
tl: 27 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 07
col 1: [20] 78 72 79 7a 67 69 66 6c 64 70 64 7a 61 61 65 74 64 6a 7a 64
tab 0, row 6, @0x1f47
tl: 27 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 08
col 1: [20] 77 76 6e 6d 6b 72 75 61 6b 61 75 6c 62 62 72 6f 66 73 67 6a
tab 0, row 7, @0x1f62
tl: 27 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 09
col 1: [20] 6e 78 6e 68 65 74 73 77 62 72 76 6f 76 62 66 68 69 74 61 72
tab 0, row 8, @0x1f7d
tl: 27 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 0a
col 1: [20] 69 61 78 66 71 75 6f 67 73 6c 64 71 67 6e 6c 61 6f 67 69 6c
end_of_block_dump
下面再利用dd+od的方式读取(0号磁盘的26号AU)里面的数据,真正的数据和段信息还有位图信息是相差5个块的(上面已经证明过),这里使用dd的时候需要跳过5个块
13、使用dd+od读取第二个AU的第6个块
[grid@rac1]$dd if=/dev/asm-diske bs=1M skip=26 count=1 | dd bs=8192 skip=5 count=1| od -x |more <=====skip=5 跳过5个数据块
1+0 records in
1+0 records out
8192 bytes (8.2 kB) copied, 0.00224499 s, 3.6 MB/s 这面就是alter system dump datafile 6 block 133的结果
0000000 a206 0000 0085 0180 d030 0176 0000 0601 <=====这里的数据和dump的 7F8234D8A000 0000A206 01800085 0176D030 06010000 [........0.v.....]
0000020 4251 0000 0001 0000 31da 0001 d02d 0176 结果是一致的(需要进行大小端转换) 7F8234D8A010 00004251 00000001 000131DA 0176D02D [QB.......1..-.v.]
0000040 0000 0000 f802 0032 0080 0180 0009 0006 7F8234D8A020 00000000 0032F802 01800080 00060009 [......2.........]
0000060 062a 0000 0429 00c0 0271 0023 2009 0000 7F8234D8A030 0000062A 00C00429 00230271 00002009 [*...)...q.#.. ..]
0000100 d030 0176 0000 0000 0000 0000 0000 0000 7F8234D8A040 0176D030 00000000 00000000 00000000 [0.v.............]
0000120 0000 0000 0000 0000 0000 0000 0000 0000 7F8234D8A050 00000000 00000000 00000000 00000000 [................]
0000140 0000 0000 0100 0009 ffff 0024 1ea5 1e81 7F8234D8A060 00000000 00090100 0024FFFF 1E811EA5 [..........$.....]
0000160 1e81 0000 0009 1ea5 1ec0 1edb 1ef6 1f11 7F8234D8A070 00001E81 1EA50009 1EDB1EC0 1F111EF6 [................]
0000200 1f2c 1f47 1f62 1f7d 0000 0000 0000 0000 7F8234D8A080 1F471F2C 1F7D1F62 00000000 00000000 [,.G.b.}.........]
0000220 0000 0000 0000 0000 0000 0000 0000 0000 7F8234D8A090 00000000 00000000 00000000 00000000 [................]
*
0017400 0000 0000 0000 0000 2c00 0201 c102 1402 7F8234D8BF00 00000000 00000000 02012C00 1402C102 [.........,......]
0017420 666c 6661 626d 6773 726f 6363 6664 726e 7F8234D8BF10 6661666C 6773626D 6363726F 726E6664 [lfafmbsgorccdfnr] <=========这些就是表T里面存放的内容了
0017440 6a68 6f72 012c 0202 03c1 6214 7268 6168 7F8234D8BF20 6F726A68 0202012C 621403C1 61687268 [hjro,......bhrha]
0017460 636d 7869 6d6d 7769 7165 6c65 646e 2c68 7F8234D8BF30 7869636D 77696D6D 6C657165 2C68646E [mcixmmiweqelndh,]
0017500 0201 c102 1404 7a76 7973 677a 7673 7672 7F8234D8BF40 C1020201 7A761404 677A7973 76727673 [......vzsyzgsvrv]
0017520 6576 7478 6c6c 6372 6b6e 012c 0202 05c1 7F8234D8BF50 74786576 63726C6C 012C6B6E 05C10202 [vextllrcnk,.....]
0017540 6e14 7066 776c 6773 746f 7972 6963 6d6b 7F8234D8BF60 70666E14 6773776C 7972746F 6D6B6963 [.nfplwsgotrycikm]
0017560 6e62 646b 2c72 0201 c102 1406 7869 756d 7F8234D8BF70 646B6E62 02012C72 1406C102 756D7869 [bnkdr,......ixmu]
0017600 7966 6f74 6468 796f 7374 7273 7a73 746e 7F8234D8BF80 6F747966 796F6468 72737374 746E7A73 [fytohdoytssrsznt]
0017620 012c 0202 07c1 7814 7972 677a 6669 646c 7F8234D8BF90 0202012C 781407C1 677A7972 646C6669 [,......xryzgifld]
0017640 6470 617a 6561 6474 7a6a 2c64 0201 c102 7F8234D8BFA0 617A6470 64746561 2C647A6A C1020201 [pdzaaetdjzd,....]
0017660 1408 7677 6d6e 726b 6175 616b 6c75 6262 7F8234D8BFB0 76771408 726B6D6E 616B6175 62626C75 [..wvnmkruakaulbb]
0017700 6f72 7366 6a67 012c 0202 09c1 6e14 6e78 7F8234D8BFC0 73666F72 012C6A67 09C10202 6E786E14 [rofsgj,......nxn]
0017720 6568 7374 6277 7672 766f 6662 6968 6174 7F8234D8BFD0 73746568 76726277 6662766F 61746968 [hetswbrvovbfhita]
0017740 2c72 0201 c102 140a 6169 6678 7571 676f 7F8234D8BFE0 02012C72 140AC102 66786169 676F7571 [r,......iaxfquog]
0017760 6c73 7164 6e67 616c 676f 6c69 0601 d030 7F8234D8BFF0 71646C73 616C6E67 6C69676F D0300601 [sldqgnlaogil..0.]
0020000
[grid@rac1]$
可以看到,直接使用dd命令读取0号盘的26号AU的第6个块得到的数据和直接使用alter sytem dump datafile 看到的数据是一样的,上面的测试说明,只要找到数据文件对应的AU信息,是可以把磁盘里面的数据读出来的,下面通过C语言来实现根据磁盘组对应的AU分布信息把整个关联的AU读出来。现在的测试表空间TEST对应的数据文件test.dbf真正使用到的AU就是x$kffxp查到的AU(上面KFED的方式也已经证明了)。 test.dbf数据文件对应的AU分布信息如下:
简单的对应关系如下:
磁盘名字 AU号
/dev/asm-diskf 27
/dev/asm-diske 26
/dev/asm-diskf 28
/dev/asm-diske 27
/dev/asm-diskf 29
/dev/asm-diske 28
/dev/asm-diskf 30
/dev/asm-diske 29
/dev/asm-diskf 31
/dev/asm-diske 30
/dev/asm-diskf 32
由于C语言代码加上解释比较长,这里先把测试写到前面, 代码放到最后。
13、读取磁盘得到的数据文件256.dbf 如下:
[root@rac1 scripts]# cd /home/oracle/
[root@rac1 oracle]# ls -ltr *256*
-rw-r----- 1 oracle oinstall 11542528 Dec 25 05:07 256.dbf <=============新产生的数据文件
[root@rac1 oracle]#
14、把原来的'+TEST/test.dbf'数据文件替换成'/home/oracle/256.dbf'
SQL> alter tablespace test offline;
Tablespace altered.
SQL> alter tablespace test rename datafile '+TEST/test.dbf' to '/home/oracle/256.dbf';
Tablespace altered.
SQL>
SQL> recover datafile 6;
Media recovery complete.
SQL> alter tablespace test online;
Tablespace altered.
SQL> select TABLESPACE_NAME,FILE_NAME from dba_data_files;
TABLESPACE_NAME FILE_NAME
------------------------------------------------------------ -------------------------------------------
USERS +DATA/devdb/datafile/users.259.940551847
UNDOTBS1 +DATA/devdb/datafile/undotbs1.258.940551847
SYSAUX +DATA/devdb/datafile/sysaux.257.940551847
SYSTEM +DATA/devdb/datafile/system.256.940551845
UNDOTBS2 +DATA/devdb/datafile/undotbs2.264.940552089
TEST /home/oracle/256.dbf
SQL>
SQL> select * from t;
ID NAME
---------- ----------------------------------------
1 lfafmbsgorccdfnrhjro
2 bhrhamcixmmiweqelndh
3 vzsyzgsvrvvextllrcnk
4 nfplwsgotrycikmbnkdr
5 ixmufytohdoytssrsznt
6 xryzgifldpdzaaetdjzd
7 wvnmkruakaulbbrofsgj
8 nxnhetswbrvovbfhitar
9 iaxfquogsldqgnlaogil
9 rows selected.
SQL>
说明:
/home/oracle/256.dbf文件是通过c语言读取AU信息得到的(其实和RMAN恢复的差不多一个意思,这里只是通过C程序来试实现的)
参考网上相关资料后写的C语言代码如下:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include<string.h>
#include<stdio.h>
#include<malloc.h>
#define Diretc_Ext 61
#define AUinMetaB 480
#define F760 S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP
#define POS_AU 1184
#define POS_AU_OFFS 1024
#define KFBH_L 32
#define KFDHDB_L 236
#define XPTR_L 8
#define KFFFDB_L 160
#define KFFIXB_L 12
#define DKIF_L 20
/*
磁盘头格式
[grid@rac1]$kfed read /dev/asm-diske
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: 3440795174 ; 0x00c: 0xcd165e26
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: ORCLDISK ; 0x000: length=8
kfdhdb.driver.reserved[0]: 0 ; 0x008: 0x00000000
kfdhdb.driver.reserved[1]: 0 ; 0x00c: 0x00000000
kfdhdb.driver.reserved[2]: 0 ; 0x010: 0x00000000
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: TEST_0000 ; 0x028: length=9
kfdhdb.grpname: TEST ; 0x048: length=4
kfdhdb.fgname: TEST_0000 ; 0x068: length=9
kfdhdb.capname: ; 0x088: length=0
kfdhdb.crestmp.hi: 33075987 ; 0x0a8: HOUR=0x13 DAYS=0x18 MNTH=0xc YEAR=0x7e2
kfdhdb.crestmp.lo: 218028032 ; 0x0ac: USEC=0x0 MSEC=0x3b6 SECS=0xf MINS=0x3
kfdhdb.mntstmp.hi: 33075987 ; 0x0b0: HOUR=0x13 DAYS=0x18 MNTH=0xc YEAR=0x7e2
kfdhdb.mntstmp.lo: 230266880 ; 0x0b4: USEC=0x0 MSEC=0x266 SECS=0x1b MINS=0x3
kfdhdb.secsize: 512 ; 0x0b8: 0x0200
kfdhdb.blksize: 4096 ; 0x0ba: 0x1000
kfdhdb.ausize: 1048576 ; 0x0bc: 0x00100000
kfdhdb.mfact: 113792 ; 0x0c0: 0x0001bc80
kfdhdb.dsksize: 1000 ; 0x0c4: 0x000003e8
kfdhdb.pmcnt: 2 ; 0x0c8: 0x00000002
kfdhdb.fstlocn: 1 ; 0x0cc: 0x00000001
kfdhdb.altlocn: 2 ; 0x0d0: 0x00000002
kfdhdb.f1b1locn: 2 ; 0x0d4: 0x00000002
kfdhdb.redomirrors[0]: 0 ; 0x0d8: 0x0000
kfdhdb.redomirrors[1]: 0 ; 0x0da: 0x0000
kfdhdb.redomirrors[2]: 0 ; 0x0dc: 0x0000
kfdhdb.redomirrors[3]: 0 ; 0x0de: 0x0000
kfdhdb.dbcompat: 168820736 ; 0x0e0: 0x0a100000
kfdhdb.grpstmp.hi: 33075987 ; 0x0e4: HOUR=0x13 DAYS=0x18 MNTH=0xc YEAR=0x7e2
kfdhdb.grpstmp.lo: 217828352 ; 0x0e8: USEC=0x0 MSEC=0x2f3 SECS=0xf MINS=0x3
kfdhdb.vfstart: 0 ; 0x0ec: 0x00000000
kfdhdb.vfend: 0 ; 0x0f0: 0x00000000
kfdhdb.spfile: 0 ; 0x0f4: 0x00000000
kfdhdb.spfflg: 0 ; 0x0f8: 0x00000000
kfdhdb.ub4spare[0]: 0 ; 0x0fc: 0x00000000
kfdhdb.ub4spare[1]: 0 ; 0x100: 0x00000000
kfdhdb.ub4spare[2]: 0 ; 0x104: 0x00000000
kfdhdb.ub4spare[3]: 0 ; 0x108: 0x00000000
kfdhdb.ub4spare[4]: 0 ; 0x10c: 0x00000000
kfdhdb.ub4spare[5]: 0 ; 0x110: 0x00000000
kfdhdb.ub4spare[6]: 0 ; 0x114: 0x00000000
kfdhdb.ub4spare[7]: 0 ; 0x118: 0x00000000
kfdhdb.ub4spare[8]: 0 ; 0x11c: 0x00000000
kfdhdb.ub4spare[9]: 0 ; 0x120: 0x00000000
kfdhdb.ub4spare[10]: 0 ; 0x124: 0x00000000
kfdhdb.ub4spare[11]: 0 ; 0x128: 0x00000000
kfdhdb.ub4spare[12]: 0 ; 0x12c: 0x00000000
kfdhdb.ub4spare[13]: 0 ; 0x130: 0x00000000
kfdhdb.ub4spare[14]: 0 ; 0x134: 0x00000000
kfdhdb.ub4spare[15]: 0 ; 0x138: 0x00000000
kfdhdb.ub4spare[16]: 0 ; 0x13c: 0x00000000
kfdhdb.ub4spare[17]: 0 ; 0x140: 0x00000000
kfdhdb.ub4spare[18]: 0 ; 0x144: 0x00000000
kfdhdb.ub4spare[19]: 0 ; 0x148: 0x00000000
kfdhdb.ub4spare[20]: 0 ; 0x14c: 0x00000000
kfdhdb.ub4spare[21]: 0 ; 0x150: 0x00000000
kfdhdb.ub4spare[22]: 0 ; 0x154: 0x00000000
kfdhdb.ub4spare[23]: 0 ; 0x158: 0x00000000
kfdhdb.ub4spare[24]: 0 ; 0x15c: 0x00000000
kfdhdb.ub4spare[25]: 0 ; 0x160: 0x00000000
kfdhdb.ub4spare[26]: 0 ; 0x164: 0x00000000
kfdhdb.ub4spare[27]: 0 ; 0x168: 0x00000000
kfdhdb.ub4spare[28]: 0 ; 0x16c: 0x00000000
kfdhdb.ub4spare[29]: 0 ; 0x170: 0x00000000
kfdhdb.ub4spare[30]: 0 ; 0x174: 0x00000000
kfdhdb.ub4spare[31]: 0 ; 0x178: 0x00000000
kfdhdb.ub4spare[32]: 0 ; 0x17c: 0x00000000
kfdhdb.ub4spare[33]: 0 ; 0x180: 0x00000000
kfdhdb.ub4spare[34]: 0 ; 0x184: 0x00000000
kfdhdb.ub4spare[35]: 0 ; 0x188: 0x00000000
kfdhdb.ub4spare[36]: 0 ; 0x18c: 0x00000000
kfdhdb.ub4spare[37]: 0 ; 0x190: 0x00000000
kfdhdb.ub4spare[38]: 0 ; 0x194: 0x00000000
kfdhdb.ub4spare[39]: 0 ; 0x198: 0x00000000
kfdhdb.ub4spare[40]: 0 ; 0x19c: 0x00000000
kfdhdb.ub4spare[41]: 0 ; 0x1a0: 0x00000000
kfdhdb.ub4spare[42]: 0 ; 0x1a4: 0x00000000
kfdhdb.ub4spare[43]: 0 ; 0x1a8: 0x00000000
kfdhdb.ub4spare[44]: 0 ; 0x1ac: 0x00000000
kfdhdb.ub4spare[45]: 0 ; 0x1b0: 0x00000000
kfdhdb.ub4spare[46]: 0 ; 0x1b4: 0x00000000
kfdhdb.ub4spare[47]: 0 ; 0x1b8: 0x00000000
kfdhdb.ub4spare[48]: 0 ; 0x1bc: 0x00000000
kfdhdb.ub4spare[49]: 0 ; 0x1c0: 0x00000000
kfdhdb.ub4spare[50]: 0 ; 0x1c4: 0x00000000
kfdhdb.ub4spare[51]: 0 ; 0x1c8: 0x00000000
kfdhdb.ub4spare[52]: 0 ; 0x1cc: 0x00000000
kfdhdb.ub4spare[53]: 0 ; 0x1d0: 0x00000000
kfdhdb.acdb.aba.seq: 0 ; 0x1d4: 0x00000000
kfdhdb.acdb.aba.blk: 0 ; 0x1d8: 0x00000000
kfdhdb.acdb.ents: 0 ; 0x1dc: 0x0000
kfdhdb.acdb.ub2spare: 0 ; 0x1de: 0x0000
*/
struct disk_info
{
int disknum;
int ausize;
int blksize;
char *diskname;
int disk_fd; /*文件描述符,打开的磁盘文件描述符*/
};
/*
struct disk_info结构体对应kfed中的磁盘信息
[grid@rac1]$kfed read /dev/asm-diske |more
kfdhdb.dsknum: 0 ; 0x024: 0x0000
kfdhdb.dskname: TEST_0000 ; 0x028: length=9
kfdhdb.blksize: 4096 ; 0x0ba: 0x1000
kfdhdb.ausize: 1048576 ; 0x0bc: 0x00100000
kfdhdb.mfact: 113792 ; 0x0c0: 0x0001bc80
kfdhdb.dsksize: 1000 ; 0x0c4: 0x000003e8
kfdhdb.pmcnt: 2 ; 0x0c8: 0x00000002
kfdhdb.fstlocn: 1 ; 0x0cc: 0x00000001
kfdhdb.altlocn: 2 ; 0x0d0: 0x00000002
kfdhdb.f1b1locn: 2 ; 0x0d4: 0x00000002
kfdhdb.redomirrors[0]: 0 ; 0x0d8: 0x0000
kfdhdb.redomirrors[1]: 0 ; 0x0da: 0x0000
kfdhdb.redomirrors[2]: 0 ; 0x0dc: 0x0000
kfdhdb.redomirrors[3]: 0 ; 0x0de: 0x0000
kfdhdb.dbcompat: 168820736 ; 0x0e0: 0x0a100000
kfdhdb.grpstmp.hi: 33075987 ; 0x0e4: HOUR=0x13 DAYS=0x18 MNTH=0xc YEAR=0x7e2
kfdhdb.grpstmp.lo: 217828352 ; 0x0e8: USEC=0x0 MSEC=0x2f3 SECS=0xf MINS=0x3
kfdhdb.vfstart: 0 ; 0x0ec: 0x00000000
kfdhdb.vfend: 0 ; 0x0f0: 0x00000000
kfdhdb.spfile: 0 ; 0x0f4: 0x00000000
kfdhdb.spfflg: 0 ; 0x0f8: 0x00000000
*/
typedef unsigned short int uc2;
typedef unsigned int uc4;
typedef unsigned char uc1;
typedef unsigned char uc8[8];
typedef struct KFFIXB
{
uc4 dxsn;
uc2 xtntblk;
uc1 dXrs;
uc1 ub1spare;
uc4 ub4spare;
}KFFIXB;
/*
只有数据文件包含的AU大于60时才会用到间接AU
kffixb.dxsn: 30 ; 0x000: 0x0000001e
kffixb.xtntblk: 342 ; 0x004: 0x0156
kffixb.dXrs: 18 ; 0x006: SCHE=0x1 NUMB=0x2
kffixb.ub1spare: 0 ; 0x007: 0x00
kffixb.ub4spare: 0 ; 0x008: 0x00000000
*/
typedef struct XPTR
{
uc4 au;
uc2 disk;
uc1 flags;
uc1 chk;
}XPTR;
/*
对应AU分布信息的结构体
kfffde[0].xptr.au: 2 ; 0x4a0: 0x00000002
kfffde[0].xptr.disk: 0 ; 0x4a4: 0x0000
kfffde[0].xptr.flags: 0 ; 0x4a6: L=0 E=0 D=0 S=0
kfffde[0].xptr.chk: 40 ; 0x4a7: 0x28
*/
typedef struct KFBH
{
uc1 endian;
uc1 hard;
uc1 type;
uc1 datfmt;
uc4 block_blk;
uc4 block_obj;
uc4 check;
uc4 fcn_base;
uc4 fcn_wrap;
uc4 spare1;
uc4 spare2;
}KFBH;
/*
对应磁盘头的的0x000~0x01c内容
[grid@rac1]$kfed read /dev/asm-diske |more
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: 3440795174 ; 0x00c: 0xcd165e26
kfbh.fcn.base: 0 ; 0x010: 0x00000000
kfbh.fcn.wrap: 0 ; 0x014: 0x00000000
kfbh.spare1: 0 ; 0x018: 0x00000000
kfbh.spare2: 0 ; 0x01c: 0x00000000
*/
typedef struct KFDHDB
{
uc1 driver[32];
uc4 compat;
uc2 dsknum;
uc1 grptyp;
uc1 hdrsts;
uc1 dskname[32];
uc1 grpname[32];
uc1 fgname[32];
uc1 capname[32];
uc4 crestmp_hi;
uc4 crestmp_lo;
uc4 mntstmp_hi;
uc4 mntstmp_lo;
uc2 secsize;
uc2 blksize;
uc4 ausize;
uc4 mfact;
uc4 dsksize;
uc4 pmcnt;
uc4 fstlocn;
uc4 altlocn;
uc4 f1b1locn;
uc2 redomirrors[4];
uc4 dbcompat;
uc4 grpstmp_hi;
uc4 grpstmp_lo;
}KFDHDB;
/*
对应磁盘头的信息
kfdhdb.driver.provstr: ORCLDISK ; 0x000: length=8
kfdhdb.driver.reserved[0]: 0 ; 0x008: 0x00000000
kfdhdb.driver.reserved[1]: 0 ; 0x00c: 0x00000000
kfdhdb.driver.reserved[2]: 0 ; 0x010: 0x00000000
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: TEST_0000 ; 0x028: length=9
kfdhdb.grpname: TEST ; 0x048: length=4
kfdhdb.fgname: TEST_0000 ; 0x068: length=9
kfdhdb.capname: ; 0x088: length=0
kfdhdb.crestmp.hi: 33075987 ; 0x0a8: HOUR=0x13 DAYS=0x18 MNTH=0xc YEAR=0x7e2
kfdhdb.crestmp.lo: 218028032 ; 0x0ac: USEC=0x0 MSEC=0x3b6 SECS=0xf MINS=0x3
kfdhdb.mntstmp.hi: 33075987 ; 0x0b0: HOUR=0x13 DAYS=0x18 MNTH=0xc YEAR=0x7e2
kfdhdb.mntstmp.lo: 230266880 ; 0x0b4: USEC=0x0 MSEC=0x266 SECS=0x1b MINS=0x3
kfdhdb.secsize: 512 ; 0x0b8: 0x0200
kfdhdb.blksize: 4096 ; 0x0ba: 0x1000
kfdhdb.ausize: 1048576 ; 0x0bc: 0x00100000
kfdhdb.mfact: 113792 ; 0x0c0: 0x0001bc80
kfdhdb.dsksize: 1000 ; 0x0c4: 0x000003e8
kfdhdb.pmcnt: 2 ; 0x0c8: 0x00000002
kfdhdb.fstlocn: 1 ; 0x0cc: 0x00000001
kfdhdb.altlocn: 2 ; 0x0d0: 0x00000002
kfdhdb.f1b1locn: 2 ; 0x0d4: 0x00000002
kfdhdb.redomirrors[0]: 0 ; 0x0d8: 0x0000
kfdhdb.redomirrors[1]: 0 ; 0x0da: 0x0000
kfdhdb.redomirrors[2]: 0 ; 0x0dc: 0x0000
kfdhdb.redomirrors[3]: 0 ; 0x0de: 0x0000
kfdhdb.dbcompat: 168820736 ; 0x0e0: 0x0a100000
kfdhdb.grpstmp.hi: 33075987 ; 0x0e4: HOUR=0x13 DAYS=0x18 MNTH=0xc YEAR=0x7e2
kfdhdb.grpstmp.lo: 217828352 ; 0x0e8: USEC=0x0 MSEC=0x2f3 SECS=0xf MINS=0x3
*/
typedef struct KFFFDB
{
uc4 node_incarn;
uc4 node_frlist_num;
uc4 node_frlist_inc;
uc4 hibytes;
uc4 lobytes;
uc4 xtntcnt;
uc4 xtnteof;
uc4 blkSize;
uc1 flags;
uc1 fileType;
uc1 dXrs;
uc1 iXrs;
uc4 dXsiz[3];
uc4 iXsiz[3];
uc2 xtntblk;
uc2 asm_break;
uc1 priZn;
uc1 secZn;
uc2 ub2spare;
uc4 alias[2];
uc1 strpwdth;
uc1 strpsz;
uc2 usmsz;
uc4 crets_hi;
uc4 crets_lo;
uc4 modts_hi;
uc4 modts_lo;
uc4 spare[16];
}KFFFDB;
/*
对应AU的信息
kfffdb.node.incarn: 1 ; 0x000: A=1 NUMM=0x0
kfffdb.node.frlist.number: 4294967295 ; 0x004: 0xffffffff
kfffdb.node.frlist.incarn: 0 ; 0x008: A=0 NUMM=0x0
kfffdb.hibytes: 0 ; 0x00c: 0x00000000
kfffdb.lobytes: 2097152 ; 0x010: 0x00200000
kfffdb.xtntcnt: 2 ; 0x014: 0x00000002
kfffdb.xtnteof: 2 ; 0x018: 0x00000002
kfffdb.blkSize: 4096 ; 0x01c: 0x00001000
kfffdb.flags: 1 ; 0x020: O=1 S=0 S=0 D=0 C=0 I=0 R=0 A=0
kfffdb.fileType: 15 ; 0x021: 0x0f
kfffdb.dXrs: 17 ; 0x022: SCHE=0x1 NUMB=0x1
kfffdb.iXrs: 17 ; 0x023: SCHE=0x1 NUMB=0x1
kfffdb.dXsiz[0]: 4294967295 ; 0x024: 0xffffffff
kfffdb.dXsiz[1]: 0 ; 0x028: 0x00000000
kfffdb.dXsiz[2]: 0 ; 0x02c: 0x00000000
kfffdb.iXsiz[0]: 4294967295 ; 0x030: 0xffffffff
kfffdb.iXsiz[1]: 0 ; 0x034: 0x00000000
kfffdb.iXsiz[2]: 0 ; 0x038: 0x00000000
kfffdb.xtntblk: 2 ; 0x03c: 0x0002
kfffdb.break: 60 ; 0x03e: 0x003c
kfffdb.priZn: 0 ; 0x040: KFDZN_COLD
kfffdb.secZn: 0 ; 0x041: KFDZN_COLD
kfffdb.ub2spare: 0 ; 0x042: 0x0000
kfffdb.alias[0]: 4294967295 ; 0x044: 0xffffffff
kfffdb.alias[1]: 4294967295 ; 0x048: 0xffffffff
kfffdb.strpwdth: 0 ; 0x04c: 0x00
kfffdb.strpsz: 0 ; 0x04d: 0x00
kfffdb.usmsz: 0 ; 0x04e: 0x0000
kfffdb.crets.hi: 33075987 ; 0x050: HOUR=0x13 DAYS=0x18 MNTH=0xc YEAR=0x7e2
kfffdb.crets.lo: 219266048 ; 0x054: USEC=0x0 MSEC=0x6f SECS=0x11 MINS=0x3
kfffdb.modts.hi: 33075987 ; 0x058: HOUR=0x13 DAYS=0x18 MNTH=0xc YEAR=0x7e2
kfffdb.modts.lo: 219266048 ; 0x05c: USEC=0x0 MSEC=0x6f SECS=0x11 MINS=0x3
kfffdb.dasz[0]: 0 ; 0x060: 0x00
kfffdb.dasz[1]: 0 ; 0x061: 0x00
kfffdb.dasz[2]: 0 ; 0x062: 0x00
kfffdb.dasz[3]: 0 ; 0x063: 0x00
*/
uc1 scandisk(struct disk_info *dkif)
{
int fd=0,i,l;
ssize_t ls;
uc1 bc[512];
uc1 sl;
char *disk[]={"/dev/asm-diske","/dev/asm-diskf"};
KFBH kfbh;
KFDHDB kfdhdb;
printf("path Disk number Group name Disk name Fgname \n");
printf("----------------- ----------- ---------- ------------- --------------\n");
for ( i=0 ,sl=0 ; i<=1 ; i++ )
{
/*打开磁盘,得到文件描述符,如果打开磁盘报错退出程序*/
if ( (fd=open(disk[i],O_RDWR))==-1 )
{
break;
}
/*读取磁盘的512字节存放到bc数组里面*/
ls=read(fd,bc,512);
close(fd);
/*把磁盘头信息的前32位(系统信息包含大小端等)赋值给结构体kfbh*/
memcpy(&kfbh,bc,KFBH_L);
/*把磁盘头的32位开始,长度236赋值给结构体kfdhdb*/
memcpy(&kfdhdb,bc+KFBH_L,KFDHDB_L);
l=strlen(disk[i]);
(dkif+i)->diskname=(char*)malloc(l);
memcpy((dkif+i)->diskname,disk[i],l);
/*赋值磁盘组的基本信息*/
(dkif+i)->diskname[l]='\0';
(dkif+i)->disknum=kfdhdb.dsknum;
(dkif+i)->ausize=kfdhdb.ausize;
(dkif+i)->blksize=kfdhdb.blksize;
/*打印扫描到的磁盘信息*/
printf("%s %6d %12s%15s%15s %s %d\n",kfdhdb.driver,kfdhdb.dsknum,kfdhdb.grpname,kfdhdb.dskname,kfdhdb.fgname,(dkif+i)->diskname,(dkif+i)->disknum);
sl++;
}
return sl;
}
int opendisk(struct disk_info *dkif,int *disk_fd,uc1 sl)
{
struct disk_info dkifm;
int i,j,k;
printf("sl=%d\n", sl);
for ( i=0;i<=1;i++ )
{
printf("diskname=%s disknum=%d in opendisk\n", (dkif+i)->diskname, (dkif+i)->disknum);
for ( ; (dkif+i)->disknum != i ; )
{
printf("%s\n", (dkif+i)->disknum);
memcpy(&dkifm,dkif+(dkif+i)->disknum,DKIF_L);
memcpy(dkif+(dkif+i)->disknum,dkif+i,DKIF_L);
memcpy(dkif+i,&dkifm,DKIF_L);
}
/*获取文件描述符,并把打开磁盘得到的描述符赋值给结构体dkif*/
if ( ((dkif+i)->disk_fd=open((dkif+i)->diskname,O_RDWR))==-1 )
{
printf("Open %s error2!\n",dkif->diskname);
return 0;
}
}
return 1;
}
/*该函数功能为把磁盘读到的AU数据copy到一个临时文件里面*/
int copyfile(struct disk_info *dkif,long int fn,uc1 sl,char *namecp)
{
long int au_num,au_pos;
int file1,fildes,filsur,filcp,blknum,au_sl,i,j,max_ausize;
char ext_indir=0;
uc1 *midbf;
XPTR xptr;
KFBH kfbh;
KFFFDB kfffdb;
KFFIXB kffixb;
au_pos=fn/256;
blknum=fn%256;
for ( i=0,max_ausize=0 ; i<=sl ; i++ )
if ( max_ausize<(dkif+i)->ausize )
max_ausize=(dkif+i)->ausize;
midbf=(uc1 *)malloc(max_ausize);
printf("dkif->diskname=%s\n", dkif->diskname);
/*打开磁盘,并得到文件描述符file1 */
if ( (file1=open(dkif->diskname,O_RDWR))==-1 )
{
printf("1 = Open %s error2!\n",(dkif)->diskname);
return 0;
}
/*namecp为临时数据文件名"/home/oracle/256.dbf",打开该文件并得到文件描述符*/
if ( (filcp=open(namecp,O_WRONLY|O_CREAT|O_TRUNC,F760))==-1 )
{
printf("2 = Open %s error2!\n",namecp);
return 0;
}
/*定位磁盘的位置,dkif->ausize*2的长度为0号2号AU,也就是2个长度的AU,dkif->blksize代表读取哪个块, */
/*KFBH_L代表块的前32位长度,也是系统信息。POS_AU=1184代表定位到首次出现kfffde[0].xptr.au位置,XPTR_L=8代表磁盘信息结构XPTR的长度,au_pos代表需要读多少个长度为8的AU */
/*
[grid@rac1]$kfed read /dev/asm-diske aun=2 blkn=1|more <====dkif->ausize*2+dkif->blksize定位第二个AU的第一个块
kfbh.endian: 1 ; 0x000: 0x01
kfbh.hard: 130 ; 0x001: 0x82
kfbh.type: 4 ; 0x002: KFBTYP_FILEDIR
kfbh.datfmt: 1 ; 0x003: 0x01
kfbh.block.blk: 1 ; 0x004: blk=1
kfbh.block.obj: 1 ; 0x008: file=1
kfbh.check: 4143342563 ; 0x00c: 0xf6f663e3
kfbh.fcn.base: 262 ; 0x010: 0x00000106
kfbh.fcn.wrap: 0 ; 0x014: 0x00000000
kfbh.spare1: 0 ; 0x018: 0x00000000
kfbh.spare2: 0 ; 0x01c: 0x00000000 <=====KFBH_L=32的位置
kfffdb.node.incarn: 1 ; 0x000: A=1 NUMM=0x0
kfffdb.node.frlist.number: 4294967295 ; 0x004: 0xffffffff
kfffdb.node.frlist.incarn: 0 ; 0x008: A=0 NUMM=0x0
kfffdb.hibytes: 0 ; 0x00c: 0x00000000
kfffdb.lobytes: 2097152 ; 0x010: 0x00200000
kfffdb.xtntcnt: 2 ; 0x014: 0x00000002
kfffdb.xtnteof: 2 ; 0x018: 0x00000002
kfffdb.blkSize: 4096 ; 0x01c: 0x00001000
kfffdb.flags: 1 ; 0x020: O=1 S=0 S=0 D=0 C=0 I=0 R=0 A=0
kfffdb.fileType: 15 ; 0x021: 0x0f
kfffdb.dXrs: 17 ; 0x022: SCHE=0x1 NUMB=0x1
kfffdb.iXrs: 17 ; 0x023: SCHE=0x1 NUMB=0x1
kfffdb.dXsiz[0]: 4294967295 ; 0x024: 0xffffffff
kfffdb.dXsiz[1]: 0 ; 0x028: 0x00000000
kfffdb.dXsiz[2]: 0 ; 0x02c: 0x00000000
kfffdb.iXsiz[0]: 4294967295 ; 0x030: 0xffffffff
kfffdb.iXsiz[1]: 0 ; 0x034: 0x00000000
kfffdb.iXsiz[2]: 0 ; 0x038: 0x00000000
kfffdb.xtntblk: 2 ; 0x03c: 0x0002
kfffdb.break: 60 ; 0x03e: 0x003c
kfffdb.priZn: 0 ; 0x040: KFDZN_COLD
kfffdb.secZn: 0 ; 0x041: KFDZN_COLD
kfffdb.ub2spare: 0 ; 0x042: 0x0000
kfffdb.alias[0]: 4294967295 ; 0x044: 0xffffffff
kfffdb.alias[1]: 4294967295 ; 0x048: 0xffffffff
kfffdb.strpwdth: 0 ; 0x04c: 0x00
kfffdb.strpsz: 0 ; 0x04d: 0x00
kfffdb.usmsz: 0 ; 0x04e: 0x0000
kfffdb.crets.hi: 33075987 ; 0x050: HOUR=0x13 DAYS=0x18 MNTH=0xc YEAR=0x7e2
kfffdb.crets.lo: 219266048 ; 0x054: USEC=0x0 MSEC=0x6f SECS=0x11 MINS=0x3
kfffdb.modts.hi: 33075987 ; 0x058: HOUR=0x13 DAYS=0x18 MNTH=0xc YEAR=0x7e2
kfffdb.modts.lo: 219266048 ; 0x05c: USEC=0x0 MSEC=0x6f SECS=0x11 MINS=0x3
kfffdb.dasz[0]: 0 ; 0x060: 0x00
kfffdb.dasz[1]: 0 ; 0x061: 0x00
kfffdb.dasz[2]: 0 ; 0x062: 0x00
kfffdb.dasz[3]: 0 ; 0x063: 0x00
kfffdb.permissn: 0 ; 0x064: 0x00
kfffdb.ub1spar1: 0 ; 0x065: 0x00
kfffdb.ub2spar2: 0 ; 0x066: 0x0000
kfffdb.user.entnum: 0 ; 0x068: 0x0000
kfffdb.user.entinc: 0 ; 0x06a: 0x0000
kfffdb.group.entnum: 0 ; 0x06c: 0x0000
kfffdb.group.entinc: 0 ; 0x06e: 0x0000
kfffdb.spare[0]: 0 ; 0x070: 0x00000000
kfffdb.spare[1]: 0 ; 0x074: 0x00000000
kfffdb.spare[2]: 0 ; 0x078: 0x00000000
kfffdb.spare[3]: 0 ; 0x07c: 0x00000000
kfffdb.spare[4]: 0 ; 0x080: 0x00000000
kfffdb.spare[5]: 0 ; 0x084: 0x00000000
kfffdb.spare[6]: 0 ; 0x088: 0x00000000
kfffdb.spare[7]: 0 ; 0x08c: 0x00000000
kfffdb.spare[8]: 0 ; 0x090: 0x00000000
kfffdb.spare[9]: 0 ; 0x094: 0x00000000
kfffdb.spare[10]: 0 ; 0x098: 0x00000000
kfffdb.spare[11]: 0 ; 0x09c: 0x00000000
kfffdb.usm: ; 0x0a0: length=0
kfffde[0].xptr.au: 2 ; 0x4a0: 0x00000002 <======POS_AU=1184的位置,4a0是16进制,转换成10进制为1184
kfffde[0].xptr.disk: 0 ; 0x4a4: 0x0000
kfffde[0].xptr.flags: 0 ; 0x4a6: L=0 E=0 D=0 S=0
kfffde[0].xptr.chk: 40 ; 0x4a7: 0x28
kfffde[1].xptr.au: 26 ; 0x4a8: 0x0000001a <======XPTR_L*au_pos=8*1 = 8, lseek之后此时位置在这里
kfffde[1].xptr.disk: 1 ; 0x4ac: 0x0001
kfffde[1].xptr.flags: 0 ; 0x4ae: L=0 E=0 D=0 S=0
kfffde[1].xptr.chk: 49 ; 0x4af: 0x31
kfffde[2].xptr.au: 4294967295 ; 0x4b0: 0xffffffff
kfffde[2].xptr.disk: 65535 ; 0x4b4: 0xffff
kfffde[2].xptr.flags: 0 ; 0x4b6: L=0 E=0 D=0 S=0
kfffde[2].xptr.chk: 42 ; 0x4b7: 0x2a
*/
printf("file1=%d ausize=%d blksize=%d KFBH_L=%d POS_AU=%d XPTR_L*au_pos=%d\n", file1, dkif->ausize*2,dkif->blksize,KFBH_L,POS_AU,XPTR_L*au_pos);
lseek(file1,dkif->ausize*2+dkif->blksize+KFBH_L+POS_AU+XPTR_L*au_pos,SEEK_SET);
/*
把一下信息读取出来
kfffde[1].xptr.au: 26 ; 0x4a8: 0x0000001a <======XPTR_L*au_pos=8*1 = 8, lseek之后此时位置在这里
kfffde[1].xptr.disk: 1 ; 0x4ac: 0x0001
kfffde[1].xptr.flags: 0 ; 0x4ae: L=0 E=0 D=0 S=0
kfffde[1].xptr.chk: 49 ; 0x4af: 0x31
*/
read(file1,&xptr,XPTR_L);
printf("copyfile ==== %d %d %d %d %s\n",xptr.au,xptr.disk,xptr.flags,xptr.chk,(dkif+xptr.disk)->diskname);
/*
打印结果如下
copyfile ==== 26 1 0 49 /dev/asm-diskf
*/
/*
打开磁盘/dev/asm-diskf并得到文件描述符为fildes
*/
if ( (fildes=open((dkif+xptr.disk)->diskname,O_RDWR))==-1 )
{
printf("3 = Open %s error2!\n",dkif->diskname);
return 0;
}
printf("(dkif+xptr.disk)->ausize=%d xptr.au=%d (dkif+xptr.disk)->blksize=%d blknum=%d\n", (dkif+xptr.disk)->ausize,xptr.au, (dkif+xptr.disk)->blksize,blknum);
/*
打印结构如下
(dkif+xptr.disk)->ausize=1048576 xptr.au=26 (dkif+xptr.disk)->blksize=4096 blknum=0
*/
/*下面的au_num就是读取/dev/asm-diskf的26号AU*/
au_num=(dkif+xptr.disk)->ausize*xptr.au+(dkif+xptr.disk)->blksize*blknum; // +KFBH_L;
/*定位到1号盘的26AU*/
lseek(fildes,au_num,SEEK_SET);
/*把磁盘头信息的前32位(系统信息包含大小端等)赋值给结构体kfbh*/
/*
[grid@rac1]$kfed read /dev/asm-diskf aun=26 blkn=0|more
kfbh.endian: 1 ; 0x000: 0x01
kfbh.hard: 130 ; 0x001: 0x82
kfbh.type: 4 ; 0x002: KFBTYP_FILEDIR
kfbh.datfmt: 1 ; 0x003: 0x01
kfbh.block.blk: 256 ; 0x004: blk=256
kfbh.block.obj: 1 ; 0x008: file=1
kfbh.check: 729566444 ; 0x00c: 0x2b7c4cec
kfbh.fcn.base: 289 ; 0x010: 0x00000121
kfbh.fcn.wrap: 0 ; 0x014: 0x00000000
kfbh.spare1: 0 ; 0x018: 0x00000000
kfbh.spare2: 0 ; 0x01c: 0x00000000
*/
read(fildes,&kfbh,KFBH_L);
/*紧接着把32位下面长160的内容赋值给结构体kfffdb*/
/*
kfffdb.node.incarn: 995742567 ; 0x000: A=1 NUMM=0x1dace9b3
kfffdb.node.frlist.number: 4294967295 ; 0x004: 0xffffffff
kfffdb.node.frlist.incarn: 0 ; 0x008: A=0 NUMM=0x0
kfffdb.hibytes: 0 ; 0x00c: 0x00000000
kfffdb.lobytes: 10493952 ; 0x010: 0x00a02000
kfffdb.xtntcnt: 11 ; 0x014: 0x0000000b
kfffdb.xtnteof: 11 ; 0x018: 0x0000000b
kfffdb.blkSize: 8192 ; 0x01c: 0x00002000
kfffdb.flags: 17 ; 0x020: O=1 S=0 S=0 D=0 C=1 I=0 R=0 A=0
kfffdb.fileType: 2 ; 0x021: 0x02
kfffdb.dXrs: 17 ; 0x022: SCHE=0x1 NUMB=0x1
kfffdb.iXrs: 17 ; 0x023: SCHE=0x1 NUMB=0x1
kfffdb.dXsiz[0]: 4294967295 ; 0x024: 0xffffffff
kfffdb.dXsiz[1]: 0 ; 0x028: 0x00000000
kfffdb.dXsiz[2]: 0 ; 0x02c: 0x00000000
kfffdb.iXsiz[0]: 4294967295 ; 0x030: 0xffffffff
kfffdb.iXsiz[1]: 0 ; 0x034: 0x00000000
kfffdb.iXsiz[2]: 0 ; 0x038: 0x00000000
kfffdb.xtntblk: 11 ; 0x03c: 0x000b
kfffdb.break: 60 ; 0x03e: 0x003c
kfffdb.priZn: 0 ; 0x040: KFDZN_COLD
kfffdb.secZn: 0 ; 0x041: KFDZN_COLD
kfffdb.ub2spare: 0 ; 0x042: 0x0000
kfffdb.alias[0]: 106 ; 0x044: 0x0000006a
kfffdb.alias[1]: 1 ; 0x048: 0x00000001
kfffdb.strpwdth: 1 ; 0x04c: 0x01
kfffdb.strpsz: 20 ; 0x04d: 0x14
kfffdb.usmsz: 0 ; 0x04e: 0x0000
kfffdb.crets.hi: 33075987 ; 0x050: HOUR=0x13 DAYS=0x18 MNTH=0xc YEAR=0x7e2
kfffdb.crets.lo: 632091648 ; 0x054: USEC=0x0 MSEC=0x33d SECS=0x1a MINS=0x9
kfffdb.modts.hi: 33075987 ; 0x058: HOUR=0x13 DAYS=0x18 MNTH=0xc YEAR=0x7e2
kfffdb.modts.lo: 0 ; 0x05c: USEC=0x0 MSEC=0x0 SECS=0x0 MINS=0x0
kfffdb.dasz[0]: 0 ; 0x060: 0x00
kfffdb.dasz[1]: 0 ; 0x061: 0x00
kfffdb.dasz[2]: 0 ; 0x062: 0x00
kfffdb.dasz[3]: 0 ; 0x063: 0x00
kfffdb.permissn: 0 ; 0x064: 0x00
kfffdb.ub1spar1: 0 ; 0x065: 0x00
kfffdb.ub2spar2: 0 ; 0x066: 0x0000
kfffdb.user.entnum: 0 ; 0x068: 0x0000
kfffdb.user.entinc: 0 ; 0x06a: 0x0000
kfffdb.group.entnum: 0 ; 0x06c: 0x0000
kfffdb.group.entinc: 0 ; 0x06e: 0x0000
kfffdb.spare[0]: 0 ; 0x070: 0x00000000
kfffdb.spare[1]: 0 ; 0x074: 0x00000000
kfffdb.spare[2]: 0 ; 0x078: 0x00000000
kfffdb.spare[3]: 0 ; 0x07c: 0x00000000
kfffdb.spare[4]: 0 ; 0x080: 0x00000000
kfffdb.spare[5]: 0 ; 0x084: 0x00000000
kfffdb.spare[6]: 0 ; 0x088: 0x00000000
kfffdb.spare[7]: 0 ; 0x08c: 0x00000000
kfffdb.spare[8]: 0 ; 0x090: 0x00000000
kfffdb.spare[9]: 0 ; 0x094: 0x00000000
kfffdb.spare[10]: 0 ; 0x098: 0x00000000
kfffdb.spare[11]: 0 ; 0x09c: 0x00000000
kfffdb.usm: ; 0x0a0: length=0
*/
read(fildes,&kfffdb,KFFFDB_L);
/*4a0-KFFFDB_L=1024 */
/*
kfffdb.usm: ; 0x0a0: length=0
kfffde[0].xptr.au: 27 ; 0x4a0: 0x0000001b <======0x4a0,lseek之后,当前位置在这里
kfffde[0].xptr.disk: 1 ; 0x4a4: 0x0001
kfffde[0].xptr.flags: 0 ; 0x4a6: L=0 E=0 D=0 S=0
kfffde[0].xptr.chk: 48 ; 0x4a7: 0x30
kfffde[1].xptr.au: 26 ; 0x4a8: 0x0000001a
kfffde[1].xptr.disk: 0 ; 0x4ac: 0x0000
kfffde[1].xptr.flags: 0 ; 0x4ae: L=0 E=0 D=0 S=0
kfffde[1].xptr.chk: 48 ; 0x4af: 0x30
kfffde[2].xptr.au: 28 ; 0x4b0: 0x0000001c
kfffde[2].xptr.disk: 1 ; 0x4b4: 0x0001
kfffde[2].xptr.flags: 0 ; 0x4b6: L=0 E=0 D=0 S=0
kfffde[2].xptr.chk: 55 ; 0x4b7: 0x37
kfffde[3].xptr.au: 27 ; 0x4b8: 0x0000001b
kfffde[3].xptr.disk: 0 ; 0x4bc: 0x0000
kfffde[3].xptr.flags: 0 ; 0x4be: L=0 E=0 D=0 S=0
kfffde[3].xptr.chk: 49 ; 0x4bf: 0x31
kfffde[4].xptr.au: 29 ; 0x4c0: 0x0000001d
kfffde[4].xptr.disk: 1 ; 0x4c4: 0x0001
kfffde[4].xptr.flags: 0 ; 0x4c6: L=0 E=0 D=0 S=0
kfffde[4].xptr.chk: 54 ; 0x4c7: 0x36
kfffde[5].xptr.au: 28 ; 0x4c8: 0x0000001c
kfffde[5].xptr.disk: 0 ; 0x4cc: 0x0000
kfffde[5].xptr.flags: 0 ; 0x4ce: L=0 E=0 D=0 S=0
kfffde[5].xptr.chk: 54 ; 0x4cf: 0x36
kfffde[6].xptr.au: 30 ; 0x4d0: 0x0000001e
kfffde[6].xptr.disk: 1 ; 0x4d4: 0x0001
kfffde[6].xptr.flags: 0 ; 0x4d6: L=0 E=0 D=0 S=0
kfffde[6].xptr.chk: 53 ; 0x4d7: 0x35
kfffde[7].xptr.au: 29 ; 0x4d8: 0x0000001d
kfffde[7].xptr.disk: 0 ; 0x4dc: 0x0000
kfffde[7].xptr.flags: 0 ; 0x4de: L=0 E=0 D=0 S=0
kfffde[7].xptr.chk: 55 ; 0x4df: 0x37
kfffde[8].xptr.au: 31 ; 0x4e0: 0x0000001f
kfffde[8].xptr.disk: 1 ; 0x4e4: 0x0001
kfffde[8].xptr.flags: 0 ; 0x4e6: L=0 E=0 D=0 S=0
kfffde[8].xptr.chk: 52 ; 0x4e7: 0x34
kfffde[9].xptr.au: 30 ; 0x4e8: 0x0000001e
kfffde[9].xptr.disk: 0 ; 0x4ec: 0x0000
kfffde[9].xptr.flags: 0 ; 0x4ee: L=0 E=0 D=0 S=0
kfffde[9].xptr.chk: 52 ; 0x4ef: 0x34
kfffde[10].xptr.au: 32 ; 0x4f0: 0x00000020
kfffde[10].xptr.disk: 1 ; 0x4f4: 0x0001
kfffde[10].xptr.flags: 0 ; 0x4f6: L=0 E=0 D=0 S=0
kfffde[10].xptr.chk: 11 ; 0x4f7: 0x0b
kfffde[11].xptr.au: 4294967295 ; 0x4f8: 0xffffffff
kfffde[11].xptr.disk: 65535 ; 0x4fc: 0xffff
kfffde[11].xptr.flags: 0 ; 0x4fe: L=0 E=0 D=0 S=0
kfffde[11].xptr.chk: 42 ; 0x4ff: 0x2a
*/
lseek(fildes,POS_AU_OFFS,SEEK_CUR);
au_sl=kfffdb.lobytes/(dkif+xptr.disk)->ausize;
/*kfffdb.xtntcnt=11,也就是一共有11个AU需要读取*/
for ( i=0 ; i<kfffdb.xtntcnt ; i++ )
{
if ( i==Diretc_Ext )
{
close(fildes);
if ( (fildes=open((dkif+xptr.disk)->diskname,O_RDWR))==-1 )
{
printf("Open %s error2!\n",dkif->diskname);
return 0;
}
au_num=(dkif+xptr.disk)->ausize*xptr.au;
lseek(fildes,au_num,SEEK_SET);
read(fildes,&kfbh,KFBH_L);
read(fildes,&kffixb,KFFIXB_L);
printf("%d %d\n",kfbh.block_obj,kffixb.xtntblk);
continue;
}
/*循环11次,把AU的信息复制到结构体xptr里面*/
read(fildes,&xptr,XPTR_L);
/*打印结果
diske= 0 27 1 0 48 1024 /dev/asm-diskf
diske= 1 26 0 0 48 1024 /dev/asm-diske
diske= 2 28 1 0 55 1024 /dev/asm-diskf
diske= 3 27 0 0 49 1024 /dev/asm-diske
diske= 4 29 1 0 54 1024 /dev/asm-diskf
diske= 5 28 0 0 54 1024 /dev/asm-diske
diske= 6 30 1 0 53 1024 /dev/asm-diskf
diske= 7 29 0 0 55 1024 /dev/asm-diske
diske= 8 31 1 0 52 1024 /dev/asm-diskf
diske= 9 30 0 0 52 1024 /dev/asm-diske
diske= 10 32 1 0 11 1024 /dev/asm-diskf
*/
printf("diske=%5d %6d %5d %6d %6d %10d %s\n",i,xptr.au,xptr.disk,xptr.flags,xptr.chk,(dkif+xptr.disk)->ausize/1024,(dkif+xptr.disk)->diskname);
/*需要读取的AU位置,就是AU的长度,比如1号盘的27号AU,那么au_num=1048576*27 */
au_num=(dkif+xptr.disk)->ausize*xptr.au;
/*使用lseek函数定位到AU的位置,比如定位到1号盘的27号AU,因为跳过了au_num,au_num代表27个AU的长度*/
lseek((dkif+xptr.disk)->disk_fd,au_num,SEEK_SET);
/*disk_fd是打开磁盘的文件描述符,比如第一次循环,dkif+xptr.disk就是dkif+1,dkif是传入的参数,dkif已经在调用opendisk时打开了磁盘
所以(dkif+xptr.disk)->disk_fd就是/dev/asm-diskf的文件描述符,midbf是一个uc1指针,代码前面已经在内存中分配了一个AU大小的空间
读函数read
ssize_t read(int fd,void *buf,size_t nbyte)
read函数是负责从fd中读取内容.成功时,read返回实际所读的字节数,如果返回的值是0,表示已经读到文件的结束了.
小于0表示出现了错误.如果错误为EINTR说明读是由中断引起的, 如果是ECONNREST表示网络连接出了问题.
第一次循环相当于把1号盘的27号AU读到了midbf里面*/
read((dkif+xptr.disk)->disk_fd,midbf,(dkif+xptr.disk)->ausize);
/*把缓冲区midbf的内容读取到filcp里面, filcp代表需要写入文件的文件描述符,这里代表"/home/oracle/256.dbf"文件*/
write(filcp,midbf,(dkif+xptr.disk)->ausize);
}
/*把所有AU遍历之后,把缓冲区midbf的内容初始化为0*/
memset(midbf,0,8192);
write(filcp,midbf,8192);
/*关闭打开的文件*/
close(filcp);
close(fildes);
close(file1);
return 1;
}
int main(void)
{
long int fn;
int fd=0;
ssize_t ls;
uc1 bc[512];
uc1 sl;
int i = 0;
KFBH kfbh;
KFDHDB kfdhdb;
KFFFDB kfffdb;
struct disk_info dkif[1000];
int disk_fd[1000];
/*调用扫描磁盘组对应的磁盘函数*/
sl=scandisk(dkif);
for(i = 0; i< sl; i++)
{
printf("++++++%s %d %d %d %d\n",dkif[i].diskname,dkif[i].disknum,dkif[i].ausize,dkif[i].ausize/1024/1024,dkif[i].blksize);
}
/*调用opendisk函数获取磁盘组对应磁盘的文件描述符*/
opendisk(dkif,disk_fd,sl);
printf("opendisk return\n");
fn=256;
/*调用copyfile函数把磁盘组中的AU数据读取到临时文件"/home/oracle/256.dbf"*/
copyfile(dkif,fn,sl,"/home/oracle/256.dbf");
return 0;
}
C语言程序运行打印日志结果如下:
[root@rac1 scripts]# ./1
path Disk number Group name Disk name Fgname
----------------- ----------- ---------- ------------- --------------
ORCLDISK 0 TEST TEST_0000 TEST_0000 /dev/asm-diske 0
ORCLDISK 1 TEST TEST_0001 TEST_0001 /dev/asm-diskf 1
++++++/dev/asm-diske 0 1048576 1 4096
++++++/dev/asm-diskf 1 1048576 1 4096
sl=2
diskname=/dev/asm-diske disknum=0 in opendisk
diskname=/dev/asm-diskf disknum=1 in opendisk
opendisk return
dkif->diskname=/dev/asm-diske
file1=5 ausize=2097152 blksize=4096 KFBH_L=32 POS_AU=1184 XPTR_L*au_pos=8
copyfile ==== 26 1 0 49 /dev/asm-diskf
(dkif+xptr.disk)->ausize=1048576 xptr.au=26 (dkif+xptr.disk)->blksize=4096 blknum=0
diske= 0 27 1 0 48 1024 /dev/asm-diskf
diske= 1 26 0 0 48 1024 /dev/asm-diske
diske= 2 28 1 0 55 1024 /dev/asm-diskf
diske= 3 27 0 0 49 1024 /dev/asm-diske
diske= 4 29 1 0 54 1024 /dev/asm-diskf
diske= 5 28 0 0 54 1024 /dev/asm-diske
diske= 6 30 1 0 53 1024 /dev/asm-diskf
diske= 7 29 0 0 55 1024 /dev/asm-diske
diske= 8 31 1 0 52 1024 /dev/asm-diskf
diske= 9 30 0 0 52 1024 /dev/asm-diske
diske= 10 32 1 0 11 1024 /dev/asm-diskf
[root@rac1 scripts]#