• 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--

  • 相关阅读:
    简单的登录验证小程序_python
    远程执行命令_python
    远程执行本地脚本_linux
    反射_python
    ssh oa项目介绍
    返回上一级过程
    ssh框架开发crm(客户关系系统总结)
    struct相对路径,绝对路径
    <s:textfield>标签回显
    ssh框架整合
  • 原文地址:https://www.cnblogs.com/buro79xxd/p/1954875.html
Copyright © 2020-2023  润新知