MSSM和ASSM block内部offset的base的计算方法区别
转载自Eygle
http://www.eygle.com/rss/20100209.html
我曾经在"利用BBED修改block内数据的一个例子"这篇文章里提到了一个计算block内部offset的base的计算方法,即:
BASE的计算方法为:
对于ASSM:76+(itc-1)*24
对于MSSM:68+(itc-1)*24
有朋友在MSN上问我说:为什么这里ASSM要比MSSM多了8个byte?
正好也有朋友在MSN上问我为啥不写一些关于block存储格式的文章,我这里就一并回答了吧。
首先,我觉得没有必要写block存储格式了,因为用BBED的map和print就可以精准的了解一个block的结构了,除了ASSM的segment header、L1、L2、L3用不了map和print之外,其他的基本上都可以。所以,除了写那些用BBED看不了的block的结构之外,写其他的意义并不大。
接着我们来回答一下第一个朋友的问题,即为什么这里ASSM要比MSSM多了8个byte?
要回答上述问题,我们先来看一下一个data block必然会有的三个component的大小:
SQL> select * from v$type_size where component in ('KCB','KTB');
COMPONENT TYPE DESCRIPTION TYPE_SIZE
--------- -------- -------------------------------- ----------
KCB KCBH BLOCK COMMON HEADER 20
KTB KTBIT TRANSACTION VARIABLE HEADER 24
KTB KTBBH TRANSACTION FIXED HEADER 48
从结果里我们可以看到,一个data block的cache layer的大小是20个byte,其transaction layer的固定部分的大小是48个byte(因为必然会有一个ITL),所以这里对于MSSM而言,其base的计算方法就是:20+48+(itc-1)*24,即上文中提到的68+(itc-1)*24。
那么对于ASSM而言,为什么会多了8个byte呢?我们继续往下看:
我们随便看一个MSSM的block:
BBED> map /v
File: /dras21/astca/system02.dbf (125)
Block: 1426 Dba:0x1f400592
------------------------------------------------------------
KTB Data Block (Table/Cluster)
struct kcbh, 20 bytes @0
ub1 type_kcbh @0
ub1 frmt_kcbh @1
ub1 spare1_kcbh @2
ub1 spare2_kcbh @3
ub4 rdba_kcbh @4
ub4 bas_kcbh @8
ub2 wrp_kcbh @12
ub1 seq_kcbh @14
ub1 flg_kcbh @15
ub2 chkval_kcbh @16
ub2 spare3_kcbh @18
struct ktbbh, 96 bytes @20
ub1 ktbbhtyp @20
union ktbbhsid, 4 bytes @24
struct ktbbhcsc, 8 bytes @28
b2 ktbbhict @36
ub1 ktbbhflg @38
ub1 ktbbhfsl @39
ub4 ktbbhfnx @40
struct ktbbhitl[3], 72 bytes @44
struct kdbh, 14 bytes @116
ub1 kdbhflag @116
b1 kdbhntab @117
b2 kdbhnrow @118
sb2 kdbhfrre @120
sb2 kdbhfsbo @122
sb2 kdbhfseo @124
b2 kdbhavsp @126
b2 kdbhtosp @128
struct kdbt[1], 4 bytes @130
b2 kdbtoffs @130
b2 kdbtnrow @132
sb2 kdbr[32] @134
ub1 freespace[4966] @198
ub1 rowdata[3024] @5164
ub4 tailchk @8188
注意看这里kdbh的offset是116。
我们再来看一个ASSM的block:
BBED> map /v
File: /dras21/astca/armshistemptbs_03.dbf (121)
Block: 274445 Dba:0x1e44300d
------------------------------------------------------------
KTB Data Block (Table/Cluster)
struct kcbh, 20 bytes @0
ub1 type_kcbh @0
ub1 frmt_kcbh @1
ub1 spare1_kcbh @2
ub1 spare2_kcbh @3
ub4 rdba_kcbh @4
ub4 bas_kcbh @8
ub2 wrp_kcbh @12
ub1 seq_kcbh @14
ub1 flg_kcbh @15
ub2 chkval_kcbh @16
ub2 spare3_kcbh @18
struct ktbbh, 96 bytes @20
ub1 ktbbhtyp @20
union ktbbhsid, 4 bytes @24
struct ktbbhcsc, 8 bytes @28
b2 ktbbhict @36
ub1 ktbbhflg @38
ub1 ktbbhfsl @39
ub4 ktbbhfnx @40
struct ktbbhitl[3], 72 bytes @44
struct kdbh, 14 bytes @124
ub1 kdbhflag @124
b1 kdbhntab @125
b2 kdbhnrow @126
sb2 kdbhfrre @128
sb2 kdbhfsbo @130
sb2 kdbhfseo @132
b2 kdbhavsp @134
b2 kdbhtosp @136
struct kdbt[1], 4 bytes @138
b2 kdbtoffs @138
b2 kdbtnrow @140
sb2 kdbr[32] @142
ub1 freespace[4958] @206
ub1 rowdata[3024] @5164
ub4 tailchk @8188
注意看这里kdbh的offset是124,比MSSM多了8个byte。
所以上述问题的答案就是:在ASSM下,oracle改变了block内部table directory和row directory的位置,oracle把它们顺延了8个byte,所以对于ASSM而言,其base的计算方法就是:20+48+8+(itc-1)*24,即上文中提到的76+(itc-1)*24。