昨天在家里的Linux服务器上,尝试用C 写一个抽取data block 的例子,用到的system_call()
简单得很就是标准的文件读写.
块 头的读取比较顺利,block_type种类大多我不熟悉,那是应用见的少了,只见过表,索引;IOT,cluster则从没见过。不过其实国内用这类高 级特性的恐怕也是极少,加了一个Oracle 的mail-list,看外国人对DB层的研究确实不懈的,而且人家只要这技术有优势就有本事和胆量拿来用,这份精神实在不殆。
块头之后是事务 槽,同行字典一样多少不定,是以行数据是倒过来存储的,即由尾而头,这番道理估计现下的DB上都是一般的。然而Oracle 之所以精妙与这事务槽同回滚段实现的读一致大有关系,然而反过来说Oracle本身也是背了一个极大的包袱在行走能有如今的效用真是不易之极,无怪乎 latch之类要用到汇编指令,但这又加大了改换平台的难度.
行字典中最末是每行的绝对距离. offsets=sizeof(head)+phead->itc*ITL_SIZE
相对地址为: pri[j]+offsets
完成之后,抽取多行却格式总是层次不齐,前前后后迂回了几个小时,最后蓦然回首发现自己参考的格式居然是9i的,怪不得读了读取行总是不工整.
回过头来说oracle的文件格式在今天来说基本是一点悬念也没有了,然而对于shared_pool的管理理论,sql的机器optimizer,以及架构等等都无愧为龙头老大,说要超越确实千难万难,何况即便超越了,其势本身极大要,谗食也不容易.
datablock的格式,都是前辈高人一个字节一个字节试出来的,其志诚嘉.
Offset | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | f | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
00014000 | 06 | A2 | 00 | 00 | 0A | 00 | 40 | 01 | 0E | 89 | 43 | 00 | 00 | 00 | 05 | 02 | ||||||||||||||||||
type | frmt | spare1/2_kcbh | rdba | scn | seq | flg | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
00014010 | 00 | 00 | 00 | 00 | 01 | 00 | 17 | 00 | 54 | D2 | 00 | 00 | 0A | 89 | 43 | 00 | ||||||||||||||||||
chkval | spare3_kcbh | typ | ? | seg/obj | csc | |||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
00014020 | 00 | 00 | E8 | 1F | 02 | 00 | 03 | 00 | 00 | 00 | 00 | 00 | 04 | 00 | 0C | 00 | ||||||||||||||||||
csc | ? | itc | ? | flg | fsl | fnx | xid | |||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
00014030 | 50 | 18 | 00 | 00 | 96 | 14 | 80 | 00 | B9 | 07 | 01 | 00 | 01 | 20 | 00 | 00 | ||||||||||||||||||
xid | uba | Lck Flag | Scn/Fsc | |||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
00014040 | 0E | 89 | 43 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | ||||||||||||||||||
Scn/Fsc | 第2条itl 这里没使用 | |||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
00014050 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 01 | 01 | 00 | ||||||||||||||||||
第2条itl 这里没使用 | flag | ntab | nrow | |||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
00014060 | FF | FF | 14 | 00 | 9B | 1F | 83 | 1F | 83 | 1F | 00 | 00 | 01 | 00 | 9B | 1F | ||||||||||||||||||
frre | fsbo | fseo | avsp | tosp | offs | nrow | row offs | |||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
00015FF0 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 2C | 01 | 01 | 01 | 61 | 05 | 06 | 0E | 89 | ||||||||||||||||||
fb | lb | cc | length | data | block tail | |||||||||||||||||||||||||||||
|
10.1.0~lgone@ONE.LG.OK> create table a(v varchar2(4000)) TABLESPACE t; Table created. 10.1.0~lgone@ONE.LG.OK> insert into a values('a'); 1 row created. Start dump data blocks tsn: 17 file#: 5 minblk 10 maxblk 10 buffer tsn: 17 rdba: 0x0140000a (5/10) //// buffer tsn: 数据文件对应的 tablespace 的 number 这只是dump文件中记录的数据而已 block 中是没有记录 tablespace 的 number 的 scn: 0x0000.0043890e seq: 0x05 flg: 0x02 tail: 0x890e0605 frmt: 0x02 chkval: 0x0000 type: 0x06=trans data Block header dump: 0x0140000a Object id on Block? Y seg/obj: 0xd254 csc: 0x00.43890a itc: 2 flg: O typ: 1 - DATA fsl: 0 fnx: 0x0 ver: 0x01 Itl Xid Uba Flag Lck Scn/Fsc 0x01 0x0004.00c.00001850 0x00801496.07b9.01 --U- 1 fsc 0x0000.0043890e 0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000 data_block_dump,data header at 0x87e125c //// data_block_dump,data header at 0x87e125c 其实这个block不是直接从 data buffer 中 dump 出来的这个表示真正dump时 block 的数据区的起始位置 也就是下面这部分开始的位置 =============== //// tsiz: hsiz: pbl: bdba: 在数据文件都是没有存储的 tsiz: 0x1fa0 //// Total data area size 8k的block: 8192-20(block head)-24(Transaction Header)-24*2(一个事务条)-4(block tail)=8096(0x1fa0) hsiz: 0x14 //// Data header size 数据块头20个字节+数据块尾4个字节=24字节(0x14) pbl: 0x087e125c //// Pointer to buffer holding the block bdba: 0x0140000a 76543210 flag=-------- ntab=1 nrow=1 frre=-1 fsbo=0x14 fseo=0x1f9b avsp=0x1f83 tosp=0x1f83 0xe:pti[0] nrow=1 offs=0 0x12:pri[0] offs=0x1f9b block_row_dump: tab 0, row 0, @0x1f9b tl: 5 fb: --H-FL-- lb: 0x1 cc: 1 col 0: [ 1] 61 end_of_block_dump End dump data blocks tsn: 17 file#: 5 minblk 10 maxblk 10
block 坏掉了还可以报: ORA-600 (4519) Cache layer block type is incorrect ORA-600 (4393) Check for Type for Segment header with free list ORA-600 (4136) Check Rollback segment block ORA-600 (4154) Check Rollback segment block Ora-600[kcbzpb_1],[d],[kind],[chk] gets signaled when the block got corrupted in memory. The only way it should be bad is if a stray store into memory destroyed the header or tail. d = blocknumber, kind= kind of corruption detected,chk = checksum flag ora-600[3398] and ora-600[3339] ora-600[3398] is not in oracle 8. ora-600[3398] means it failed a verification check before writing back to disk, so it must be an in-memory corruption. ora-600[3339] comes with ora-1578 and means either disk corruption or in memory corruption after read. ora-600 [3339] has been removed from 7.2+ From 7.2+ ora-600 [3398] has become ora-600 [3374] with some checks added. 2进制存储格式 ALTER SESSION SET EVENTS '10289 trace name context forever, level 1'; ALTER SESSION SET EVENTS '10289 trace name context off';