10g Data block Structure(Dump+BBED)

Environment:

Oracle 10.0.2.1.0

Linux kernal 2.6.18-92.el5PAE

 ASSM Tablespace

Block type: 0x06=trans data

 

clip_image002

上边这幅图虽然是Concept上的但是实际上并不完整,但是还是有一定的参考价值所以就放上来了

首先复习下数据块的结构,一个0x06block包含4layer

---------------------

1- Cache Layer       - kcbh 20byte 该层主要包含block format, type(index, table or cluster and so on)block中使用kcbh struct来描述

---------------------

2- Transaction Layer - ktbbh 48byte(包含ktbbhktbit就是一个ITL的容器单个ITL结构为ktbbhitl大小为24byte)

--------------------- ---------------------

3- Data Layer  包含  - - Data Header         - kdbh

--------------------- ---------------------

                          - Table Directory    - 包含offset

                          ---------------------

                          - Row Directory      -

                          ---------------------

                          - Free Space          -

                          ---------------------

                          - Row Data            -

                          ---------------------

---------------------

4- Tailchk            -

---------------------

BBED中查看Data Block的结构

node1-> bbed parfile=bbed.par

BBED> map

 File: /u02/oradata/ETMCDB.dbf (6)

 Block: 71                                    Dba:0x01800047

------------------------------------------------------------

 KTB Data Block (Table/Cluster)

 struct kcbh, 20 bytes             @0     1 Cache Layer(kcbh) 20bytes: block format, type(index, table or cluster and so on)

struct ktbbh, 72 bytes            @20   2 Transaction Layer(ktbbh+ ktbit) 72bytes: ITL(each ITL is 24byte),including 2 strcs (ktbbh 24bytes & ktbit 48bytes)

struct kdbh, 14 bytes             @100  3 Data Header 

 struct kdbt[1], 4 bytes           @114  4 Table Directory

 sb2 kdbr[733]                      @118   5 Row Directory

 ub1 freespace[1579]               @1584  6 Free Space

 ub1 rowdata[5025]                 @3163  7 Row Data

 ub4 tailchk                        @8188  8 Tailchk

kc~kernel cache, kt~kernel transaction, kd~kernel data


 

 

BBED> map /v

File: /u02/oradata/ETMCDB.dbf (6)

 Block: 71                                    Dba:0x01800047

------------------------------------------------------------

 KTB Data Block (Table/Cluster)

 struct kcbh, 20 bytes                      @0  1 Block Header Structure(kcbh) Cache Layer 20bytes: block format, type(index, table or cluster and so on)

    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, 72 bytes                     @20 2 Transaction Layer 72bytes: 包含两个struct (ktbbh_ 24bytes & ktbit_ 48bytes(每个ITL占用24bytes)) 之所以是这两个struct是因为ktbbh里边的结构都是以这两个strct开头的


 

10201 struct ktbbh block header

    ub1 ktbbhtyp                            @20 --block type

    union ktbbhsid, 4 bytes                 @24

    struct ktbbhcsc, 8 bytes                @28 --effective time of last cleanout

    b2 ktbbhict                             @36 --number of itl entries mask 0x00ff

    ub1 ktbbhflg                            @38 --flags

    ub1 ktbbhfsl                            @39 --free space lock

    ub4 ktbbhfnx                            @40 --next block in free list

    struct ktbbhitl[2], 48 bytes            @44

 

 struct kdbh, 14 bytes                      @100 3 Data Header   

    ub1 kdbhflag                            @100 --flags

    b1 kdbhntab                             @101 --Number of TABles in the table index

    b2 kdbhnrow                             @102 --Number of ROWs in the row index

    sb2 kdbhfrre                            @104 --first FRee Row index Entry

    sb2 kdbhfsbo                            @106 --Free Space Beginning Offset

    sb2 kdbhfseo                            @108 --Free Space Ending Offset

    b2 kdbhavsp                             @110 --AVailable SPace in the block

    b2 kdbhtosp                             @112 --TOtal Space that will be available

 

 struct kdbt[1], 4 bytes                    @114 4 Table Directory

    b2 kdbtoffs                             @114 --OFFSet in the block from kdbpri

    b2 kdbtnrow                             @116 --Number of Rows in the table

 

 sb2 kdbr[15]                               @118 5 Row Directory

 ub1 freespace[7064]                        @148 6 Free Space

 ub1 rowdata[976]                           @7212 7 Row Data

 ub4 tailchk                                @8188 8 Tailchk

使用BBED 方法查看Data Block 的内部信息


 

BBED> set dba 6,71

BBED> dump

clip_image004

使用Dump 方法查看Data Block 的逻辑信息


 

SQL> alter system dump datafile 6 block 71;

System altered.

Start dump data blocks tsn: 7 file#: 6 minblk 71 maxblk 71

1 Cache Layer


 

buffer tsn: 7 rdba: 0×01800047 (6/71)

scn: 0×0000.0032cd71 seq: 0×01 flg: 0×02 tail: 0xcd710601

frmt: 0×02 chkval: 0×0000 type: 0×06=trans data

Hex dump of block: st=0, typ_found=1

<—-more—->


 

Block header dump:  0×01800047

Object id on Block? Y

seg/obj: 0xda30  csc: 0×00.32cd5a  itc: 2  flg: E  typ: 1 – DATA

brn: 0  bdba: 0×1800041 ver: 0×01 opc: 0

inc: 0  exflg: 0

Itl           Xid                  Uba            Flag  Lck        Scn/Fsc

0×01   0x000a.019.000005b4  0×00800226.0347.1a  –U-  733  fsc 0×0000.0032cd71

0×02   0×0000.000.00000000  0×00000000.0000.00   —-    0  fsc 0×0000.00000000

 


 

data_block_dump,data header at 0xd071464

===============

tsiz: 0x1f98

hsiz: 0x5cc

pbl: 0x0d071464

bdba: 0×01800047

76543210

flag=——–

ntab=1   -- One table, if it’s a Cluster this num will be > 1;

nrow=733 –- Num of Rows in Table

frre=-1

fsbo=0x5cc –-free space start block: 44+NO_OF_ITLS*24+0x5cc)

fseo=0xbf7 –-free space end block: 44+NO_OF_ITLS*24+0x5cc)

 ?why the free space of current block is that much?0xbf7-0x5cc= 3063-1484 , therefore the PCTFREE is 0?

avsp=0×7

tosp=0×7

0xe:pti[0]      nrow=733        offs=0

0×12:pri[0]     offs=0x1f92 –- first row address 0x1f92 + (44+NO_OF_ITLS*24)

0×14:pri[1]     offs=0x1f8c -- second row address 0x1f8c + (44+NO_OF_ITLS*24)

0×16:pri[2]     offs=0x1f86

<—-more—->


 

0x5c8:pri[731]  offs=0xbfe

0x5ca:pri[732]  offs=0xbf7

block_row_dump:


 

tab 0, row 0, @0x1f92 –- first row

tl: 6 fb: –H-FL– lb: 0×1  cc: 1

col  0: [ 2]  c1 02

tab 0, row 1, @0x1f8c -- second row

tl: 6 fb: –H-FL– lb: 0×1  cc: 1

col  0: [ 2]  c1 03

tab 0, row 2, @0x1f86

tl: 6 fb: –H-FL– lb: 0×1  cc: 1

<—-more—->


 

tl: 7 fb: –H-FL– lb: 0×1  cc: 1

col  0: [ 3]  c2 08 21

tab 0, row 732, @0xbf7

tl: 7 fb: –H-FL– lb: 0×1  cc: 1

col  0: [ 3]  c2 08 22

end_of_block_dump

End dump data blocks tsn: 7 file#: 6 minblk 71 maxblk 71

在随后的内容里将会一一对比这4layerBBEDDump中的结果,进而更深一步的了解Data Block

---------------------------------1 Block Header / Cache Layer [struct kcbh]-----------------------------------


 

Let’s have a look on the first section [struct kcbh] which is 20 bytes:
typedef struct kcbh_ {
ub1 type_kcbh;
ub1 frmt_kcbh;
ub1 spare1_kcbh;
ub1 spare2_kcbh;
krdba rdba_kcbh;
ub4 bas_kcbh; /* base of SCN */
ub2 wrp_kcbh; /* wrap of SCN */
ub1 seq_kcbh; /* seq# of changes at same scn, KCBH_NLCSEQ */
ub1 flg_kcbh; /* see KCBHFNEW etc below */
ub2 chkval_kcbh;
ub2 spare3_kcbh;
} kcbh;

使用print 来更清晰地看出每个字节对应的意义:
BBED> p kcbh

struct kcbh, 20 bytes                       @0       
   ub1 type_kcbh                            @0        0x06
   ub1 frmt_kcbh                            @1        0xa2
   ub1 spare1_kcbh                          @2        0x00
   ub1 spare2_kcbh                          @3        0x00
   ub4 rdba_kcbh                            @4        0x004000aa
   ub4 bas_kcbh                             @8        0x001bf37e //base scn
   ub2 wrp_kcbh                             @12       0x0000
   ub1 seq_kcbh                             @14       0x01
   ub1 flg_kcbh                             @15       0x06 (KCBHFDLC, KCBHFCKV)
   ub2 chkval_kcbh                          @16       0xb42a
   ub2 spare3_kcbh                          @18       0x0000

clip_image005

File: /u02/oradata/ETMCDB.dbf (6)

 Block: 71               Offsets:    0 to  511           Dba:0x01800047

------------------------------------------------------------------------

 0ba20000 47008001 a3d23200 00000100 00000000 01000000 30da0000 a1d03200

 00000000 02003200 41008001 0a001900 b4050000 26028000 47031a00 00800000

 71cd3200 00000000 00000000 00000000 00000000 00000000 00000000 00000000

00000000 0001dd02 ffffcc05 f70b0700 07000000 dd02921f 8c1f861f 801f7a1f

 ……………

 <32 bytes per line>

clip_image007

0 byte is type06 means data block
1 byte is FRMT
commonly it’s 0X02
4-7 byte is RDBA
47 00 80 01 =  0X01800047(6/71) 
8-13 byte is SCN(First 4 byte is BASE the 2 byte left is WRAP
):a3 d2 32 00 00 00 : 0×0000.0032cd71
14 byte is SEQ
01 , SEQ=0x01
15 byte is FLAG: 02, FLAG=0x02 BBED
结果是0
16-17 byte is CHECKSUM:00 00 :0x0000  -- when db_block_checksum = FALSE, CheckSum=00 00

① select dbms_utility.DATA_BLOCK_ADDRESS_FILE(to_number('01800047','xxxxxxxxxx')) file#,
         dbms_utility.DATA_BLOCK_ADDRESS_BLOCK(to_number('01800047','xxxxxxxxxx')) block# from dual;
     FILE#     BLOCK#
---------- ----------
         6         71

---------------------------------2 Transaction Layer [struct ktbbh]---------------------------------------

记录数据块身份信息包含:ITL事务表,这个是行锁和读一致性的基础,记录本数据块中参与到某个事物的一条记录包括UBA,Transaction ID,SCN. oracle对每一次用户查询都要记录查询开始时当前的SCN并和数据块中的SCN对比,如果当前SCN>数据块中的SCN说明这个数据块被修改过,Oracle就会利用UNDO内容制造一个新版本的数据块叫CR数据块(Constant Block)它是利用ITL中的记录UBA信息完成的,CR构造完再继续对比SCN直到数据块的SCN<=查询SCN这个构造才结束,如果无法获得符合要求的CR块就会抛出ORA-0155


 

分成两部分:


 

第一部分为固定长度20字节开始是24字节长度的ktbbh,包含事务相关的一些基本信息

typedef struct ktbbh_ { /* 10201 struct ktbbh block header */

ub1 ktbbhtyp; /* block type */

ub4 ktbbhsid;

kscn ktbbhcsc; /* effective time of last cleanout */

b2 ktbbhict; /* number of itl entries mask 0x00ff*/

 

ub1 ktbbhflg; /* flags */

 

ub1 ktbbhfsl; /* free space lock */

 

krdba ktbbhfnx; /* next block in free list */

}

使用print 来更清晰地看出每个字节对应的意义:
BBED> p ktbbh

 

 File: /u02/oradata/ETMCDB.dbf (6)

 Block: 71               Offsets:    0 to  511           Dba:0x01800047

------------------------------------------------------------------------

 0ba20000 47008001 a3d23200 00000100 00000000 01000000 30da0000 a1d03200

 00000000 02003200 41008001 0a001900 b4050000 26028000 47031a00 00800000

 71cd3200 00000000 00000000 00000000 00000000 00000000 00000000 00000000

00000000 0001dd02 ffffcc05 f70b0700 07000000 dd02921f 8c1f861f 801f7a1f  

 ……………

 <32 bytes per line>

 

seg/obj: 0xda30  csc: 0x00.32d0a1  itc: 2  flg: E  typ: 1 - DATA

     brn: 0  bdba: 0x1800041 ver: 0x01 opc: 0

     inc: 0  exflg: 0

 

20 byte01 typ=01
24-27 byte is OBJECT ID: 30 da 00 00 :0xda30(
注意,这里有UB4的字节对齐问题,所以中间空了3个字节) a3 d2 32 00 00 00 : 0×0000.0032cd71
28-35 byte is SCN: a1 d0 32 00 00 00,SCN:
36-37 byte is Num of ITL
:用0x00ff掩码:02 00 :有2ITL
38 byte is FLAG: 32
39 byte is FSL:00
40-43 KDBA is the address of the next free block
41 00 80 01, 0x1800041

第二部分为可变长度44开始是ITL表,每个ITL记录的长度为24,从1可以看到这个块有2ITL槽,因此ITL48字节,ITL内部结构名ktbbhitl.这里共占用了48bytes 的空间


 

struct ktbit {

kxid ktbitxid; /* transaction id */

kuba ktbituba; /* undo address for last change */

b2 ktbitflg;   /* num of locks in block */

ktbitun_t _ktbitun;

ub4 ktbitbas;  /* sys commit num base */

}

File: /u02/oradata/ETMCDB.dbf (6)

 Block: 71               Offsets:    0 to  511           Dba:0x01800047

------------------------------------------------------------------------

 0ba20000 47008001 a3d23200 00000100 00000000 01000000 30da0000 a1d03200

 00000000 02003200 41008001 0a001900 b4050000 26028000 47031a00 00800000

 71cd3200 00000000 00000000 00000000 00000000 00000000 00000000 00000000

00000000 0001dd02 ffffcc05 f70b0700 07000000 dd02921f 8c1f861f 801f7a1f

 ……………

 <32 bytes per line>

 

Itl           Xid                  Uba                Flag  Lck        Scn/Fsc

0x01   0x000a.019.000005b4  0x00800226.0347.1a  C---    0  scn 0x0000.0032cd71

0x02   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000

KXID UB2 UNDO SEGMENT NUMBER
UB2
SLOT NUMBER
UB4
WRAP
44-51 byte is XID(8)0a 00 19 00 b4 05 00 00 0x0a00.1900.b4050000
52-59 byte is UBA(8)
26 02 80 00 47 03 1a 00 0x00800226.0347.1a 那么最后这个00?
60-61 byte is FLAG(2):00 80,0X0800, c--- LOCK 0
62-67 byte is SCN(6): 00 00 71 cd 32 00,0x0000.71cd3200
原文中 62-67(6):scn:00 00 6D 48 25 00 ,0x00254864.00这里是如何换算的

data_block_dump,data header at 0xd071464

===============

tsiz: 0x1f98 total data area size 除了上面的部分和block尾部的个字节剩下的空间0x1fb8就是字节

hsiz: 0x5cc  data header size 数据块头个字节+数据块尾个字节=24字节(0x14)

pbl: 0x0d071464 point to buffer holding the block   

bdba: 0×01800047 rdba Header 中的 rdba 相同

76543210

--------------3 Data Layer包括Data HeaderTable DirectoryRow DirectoryFree SpaceRow Data ---------
包含5部分


 

3.1 Data Header长度14字节内部数据结构名kdbh


 

这个块有2ITL槽,今后计算所有的位置都要根据这个来计算。下面一个重要的结构就是KDBH
struct kdbh {
ub1 kdbhflag;  /* FLAGs */
ktno kdbhntab; /* Number of TABles in the table index */
ub2 kdbhnrow;  /* Number of ROWs in the row index */
sb2 kdbhfrre;  /* first FRee Row index Entry */
sb2 kdbhfsbo;  /* Free Space Beginning Offset */
sb2 kdbhfseo;  /* Free Space Ending Offset */
b2 kdbhavsp;   /* AVailable SPace in the block */
b2 kdbhtosp;   /* TOtal Space that will be available */
}

使用print 来更清晰地看出每个字节对应的意义:

BBED> p kdbh

struct kdbh, 14 bytes                       @124    

   ub1 kdbhflag                             @124      0x00 (NONE)

   b1 kdbhntab                              @125      1

   b2 kdbhnrow                              @126      733 <--733行数据

   sb2 kdbhfrre                             @128     -1

   sb2 kdbhfsbo                             @130      1484

   sb2 kdbhfseo                             @132      2943

   b2 kdbhavsp                              @134      7

   b2 kdbhtosp                              @136      7

File: /u02/oradata/ETMCDB.dbf (6)

 Block: 71               Offsets:    0 to  511           Dba:0x01800047

------------------------------------------------------------------------

 0ba20000 47008001 a3d23200 00000100 00000000 01000000 30da0000 a1d03200

 00000000 02003200 41008001 0a001900 b4050000 26028000 47031a00 00800000

 71cd3200 00000000 00000000 00000000 00000000 00000000 00000000 00000000

00000000 0001dd02 ffffcc05 f70b0700 07000000 dd02921f 8c1f861f 801f7a1f

 ……………

 <32 bytes per line>

 

flag=——–  N=pctfree hit(clusters), F=don't put on free list K=flushable cluster keys. 当然还有别的标记: A ...

ntab=1    1 byte     表示这个block中有几个table的数据  cluster这个就可能大于1

nrow=733  2 bytes    block 中有多少行数据

frre=-1   2 bytes    First free row index entry. -1=you have to add one.

fsbo=0x5cc  2 bytes    Free Space Begin offset 空闲空间从哪里开始

fseo=0xbf7 ?why the free space of current block is that much?0xbf7-0x5cc= 3063-1484 , therefore the PCTFREE is 0? 2 bytes    Free Space End offset 空闲空间到哪里结束

avsp=0×7    2 bytes    Available space in the block  

tosp=0×7     2 bytes    Total available space when all TXs commit 所有事物都提交后可使用的空间

0xe:pti[0]      nrow=733        offs=0

0×12:pri[0]     offs=0x1f92

100 byte is: FLAG 0(--------------)
101 byte is: NTAB 1
102-103 byte is: NROW dd 02, 0x2dd (nrow=733) select to_number('2dd','xxxxxxxx') from dual; = 733
104-105 byte is: free ff ff, (free space=-1)
106-107 byte is: fsbo cc 05, 0x5cc = 1484
108-109 byte is: fseo f7 0b, 0xb7f = 2943
110-111 byte is: avsp 07 00, 0x007 = 7
112-113 byte is: tosp 07 00, 0x007 = 7

KDBH的位置的计算方法如下:
对于ASSM76+itls-1)*24
对于MSSM68+itls-1)*24
本例是使用ASSM的,并且有2ITL槽,因此是76+24=100
offset 可使用 p kdbr[n] 获得
itl      
可通过p ktbbh.ktbbhitc 获得

3.2 Table Directory: 一般table只有一个条目cluster则有一个或多个条目。每个条目长4字节内部数据结构名kdbt


 

struct kdbt {

b2 kdbtoffs; /* OFFSet in the block from kdbpri */

b2 kdbtnrow; /* Number of Rows in the table */

}


 

BBED> p kdbt

struct kdbt[0], 4 bytes                     @138    

   b2 kdbtoffs                              @138      0

b2 kdbtnrow                              @140      733

114-115: 00 00:0x0000
116-117: dd 02, 0x2dd (
这个块有733行数据)

下面紧接着是KDBR结构,KDBR结构是一个数组,是sb2类型的,指向每一行的头,这里只有1行,指向0x1f92


 

3.3 Row Directory数目由块中数据的行数决定每个条目长2字节内部数据结构名kdbr

BBED> p kdbr 从这里,我们可以观察到这个块一共有733行数据,每一行指针需要2bytes说明row# 1 的行的offset的十进制值为7856他们从偏移量142开始到1606存储在这个数据块中

sb2 kdbr[0]                                 @142      8082

sb2 kdbr[1]                                 @144      8076

..................

sb2 kdbr[731]                                @1604      1240

sb2 kdbr[732]                                @1606      1035

BBED>  p kdbr[0]

sb2 kdbr[0]                                 @142      8082

BBED>  p *kdbr[0]

rowdata[529]

------------

ub1 rowdata[529]                            @8182     0x2c

我们从以上的个结果可以看出第0行的offset8082对于ASSM需要+76+24就得到了8182,对照一下dump结果0x1f92这个值也是8082,就一致了。select to_number('1f92','xxxxxxxx') from dual;

block_row_dump:

tab 0, row 0, @0x1f92

tl: 6 fb: –H-FL– lb: 0×1  cc: 1

col  0: [ 2]  c1 02

<----more---->

end_of_block_dump

End dump data blocks tsn: 7 file#: 6 minblk 71 maxblk 71

clip_image009

2c 00 01 02 c1 02 01 06 a3 d2

2c是记录头的flag
00:ITL
曹的索引(锁所在的)
01
:这个记录有1个字段
后面是第一个字段的数据 02 c1 02
02
表示字段长度,后面c1 02就是字符串' '
最后四个字节是
01: SEQ
06: TYPE
最后两个字节是 scn base的低4个字节:0xd2a3 这个块的SCN是:0x????d2a3
注意的是:这个例子是最简单的,如果有字段的长度超过253字节,那么8位是表示不了的,这个时候,会使用前导字符FE
比如FE 03 06表示该字段的长度是0x603,就是1539字节
要注意的是在数据块里面是没有字段类型的,因此如果SYSTEM表空间损坏,需要导出数据,就必须了解表的结构,否则需要根据扫描的结果进行猜测

3.4 Free Space表示数据块中可用空间内部数据结构名freespace

BBED> p freespace[4]

ub1 freespace[4]                            @1588      0x00

所有的freespace'n' 的值都是0x00

3.5 Row Data表示实际的数据内部数据结构名rowdata

BBED> p rowdata[5019]

ub1 rowdata[5019]                           @8182     0x2c

表示放置第5019个数据的字节的位置为8182,值为0x2c

4 Tailchk: 保存在块结尾用于校验的数据长度4个字节内部结构名tailchk

BBED>p tailchk

ub4 tailchk                                 @8188     0xd37a0602

注意到tailchk=bas_kcbh2字节(d37a)+type_kcbh(06)+seq_kcbh(02)

tailchk 的值为last 2 bytes of base scn +type+ seq

--EOF--

posted @ 2011-02-15 10:11  xxd  阅读(1829)  评论(0编辑  收藏  举报