微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

oracle block internalblock 内部结构分解

Oracle block的详细物理结构图:

 

oracle block internal(block 内部结构分解)

本文主要说明oracle block的物理结构,它是oracle的最小存储单元,由多个os数据块组成。主要由三个逻辑层组成(通过c语言描绘的结构,如下图一所示):the cache layer,the transaction layer,data layer。如果再细化,data layer又分为很多结构,如table directory,row directory,free space,row data等

oracle block internal(block 内部结构分解)

Oracle的block被映射到SGA kcbh(kernel cache block header)的对应的block上 。

 

the cache layer:它是block header的第一部分,占用20个bytes。用于检查数据的正确性,即被读的block是否断裂或损坏。它包含如下结构

 

1.       the data block address(DBA)

2.       the block type (例如Table/Index, Rollback Segment, Temporary)

3.       the block format (8i~9i 都是0x02 10.1.0 2k: 0x62 4k:0x82 8k:0xa2 16k:0xc2 (logfile 0x22 512  bytes))

 

4.       a system change number(SCN)used for ordering purposes during recovery

 

 

the transaction layer: 用户存储数据块里transaction信息的,包含两部分信息

1.       一个a fixed component ,KTBBH(TRANSACTION FIXED HEADER),包含关于数据块的类型,数据块的最 新cleanout时间,ITL(Interested Transcation List)的数量,空闲列表的链接,还有空闲空间lock。

2.       另一个 a variable portion,KTBIT(TRANSACTION VARIABLE HEADER),包含一个进程在一个block里要编辑行所需要的ITLs。认的包含一个表的数据块只有一个ITL,ITL的多少是通过存储参数INITRANS来设置的,设置较大的值会减少row data的可用空间,这个参数是可以动态修改的,但只影响新的block,对已经存在的block没有作用(可以用imp/exp,move等方法可以让其对存在的block起作用)

 

The data layer:包含data header 结构,KDBH(kernel data block header,是DATA HEADER,占用14bytes),和row data。其中data header包含表的数量(在表索引中,即table directory),数据行的数量,第一个空闲行的条目(在行索引中,即row directory),指向空闲区域的开始和结束的偏移量,可用的空闲空间。数据行是从block的底部开始insert的,伴随insert和delete操作,行数据是随机存储的。

如下图所示:

oracle block internal(block 内部结构分解)

假设初始化5行数据,每行10bytes大小,按offsets排序是5,4,3,2,1。现在删除2,4行,再insert一行20bytes的数据,在row directory 中slot2被使用,但实际的row data存储在row5之上。这个时候再按offsets排序就是2,5,3,1 。随着你在数据块上的DML操作的越频繁,这种行的随机性就更强。

 

 

 

下面说下data block的设计,如下图所示

 

oracle block internal(block 内部结构分解)

 

下面是oracle block的dump文件,结合上面这个图片来验证下oracle block的存储情况

 

 

 

Dump file e:/oracle/product/10.2.0/admin/test/udump/test_ora_4820.trc

Thu Aug 19 13:01:36 2010

ORACLE V10.2.0.4.0 - Production vsnsta=0

vsnsql=14 vsnxtr=3

Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production

With the Partitioning, OLAP, Data Mining and Real Application Testing options

Windows XP Version V5.1 Service Pack 3, v.3300

cpu                 : 2 - type 586, 2 Physical Cores

Process Affinity    : 0x00000000

Memory (Avail/Total): Ph:313M/1918M, Ph+PgF:2399M/3812M, VA:1289M/2047M

Instance name: test

 

Redo thread mounted by this instance: 1

 

Oracle process number: 21

 

Windows thread id: 4820, image: ORACLE.EXE (SHAD)

 

 

*** 2010-08-19 13:01:36.593

*** ACTION NAME:() 2010-08-19 13:01:36.578

*** MODULE NAME:(sql*Plus) 2010-08-19 13:01:36.578

*** SERVICE NAME:(test) 2010-08-19 13:01:36.578

*** SESSION ID:(201.21830) 2010-08-19 13:01:36.578

Error: alter system dump datafile/tempfile: invalid input file # 0

*** 2010-08-19 13:02:41.375

Error: alter system dump datafile/tempfile: invalid input file # 0

*** 2010-08-19 13:03:17.296

Start dump data blocks tsn: 4 file#: 4 minblk 29347 maxblk 29347

buffer tsn: 4 rdba: 0x010072a3 (4/29347)

scn: 0x0000.009b876f seq: 0x01 flg: 0x04 tail: 0x876f2301

frmt: 0x02 chkval: 0x4671 type: 0x23=PAGETABLE SEGMENT HEADER

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

Dump of memory from 0x0A2A8400 to 0x0A2AA400

A2A8400 0000A223 010072A3 009B876F 04010000  [#....r..o.......]

A2A8410 00004671 00000000 00000000 00000000  [qF..............]

A2A8420 00000000 00000001 00000008 00000A9C  [................]

A2A8430 00000000 00000004 00000008 010072A5  [.............r..]

..r......

..r......

 

A2A9850 00000000 00000000 00000000 00000000  [................]

        Repeat 185 times

A2AA3F0 00000000 00000000 00000000 876F2301  [.............#o.]

 

这里说明下TAIL用于验证block的完整性的,它是由SCNBase,block type,SCN seq number组成。

876F2301=876Flast two bytes of SCN Base)+ 23(type)+ 01(seq)

 

红色的字是offset(偏移量)

 

首先来看前20个bytes,也就是the cache layer,16进制的数据如下:

0000A223 010072A3 009B876F 04010000 00004671

 

 

 

第一和第二个字节是filler,也就是未被使用(

ub1 spare1_kcbh this field is no longer used (old inc#, Now always 0) 
ub1 spare2_kcbh this field is no longer used (old ts#, Now always 0)

),未被定义(和前面的图有点出入)

第三个字节是frmt,一般是0x02,这里是0xa2,用掩码0x0f与运算可以取出0x02(掩码是为了保护敏感信息)

第四个字节是type,这里是23,代表PAGETABLE SEGMENT HEADER

第五个到第八个字节是rdba,这里是0x010072a3

第九个到第十二字节是SCNBase ,这里是 0x009B876F

第十三个字节是flg,这里是0x04

as defined in kcbh.h 
#define KCBHFNEW 0x01 /* new block - zeroed data area */
#define KCBHFDLC 0x02 /* Delayed Logging Change advance SCN/seq */
#define KCBHFCKV 0x04 /* ChecK Value saved-block xor's to zero */
#define KCBHFTMP 0x08 /* Temporary block */
这是一个可以组合的值 也就是说有为 6 的时候是 2,4 两种情况的组合

第十四个字节seq,这里是 0x01。

 

A sequence number incremented for each change to a block at the same SCN 
A new SCN is allocated if the sequence number wraps. 
一个SCN影响这个block中的行数大于 254 行就会为这个事务分配一个新的SCN 
如下面的操作就可能引起同一个SCN但影响的同一个block 中的行超过254行 
"delete from table_name" 
影响的行数(最大254) 是用从 0x01 到 0xfe 表示的
当这个byte 的数据为 0xff 的时候标志这个 block 坏调了---> ora-01578
Sequence number:
SEQ -> 0 /* non-logged changes - do not advance seq# */
SEQ -> (UB1MAXVAL-1)/* maximum possible sequence number */
SEQ -> (UB1MAXVAL) /* seq# to indicate a block is corrupt,equal to FF. soft corrupt*/ 
0xff : When present it indicates that the block has been marked as corrupt by Oracle. either by the db_block_checking functionality or the equivalent events (10210 for data blocks, 10211 for index blocks, and 10212 for cluster blocks) when making a database change, or by the DBMS_REPAIR.FIX_CORRUPT_BLOCKS procedure, or by PMON after an unsuccessful online block recovery attempt while recovering a Failed process, or by RMAN during a BACKUP, copY or VALIDATE command with the CHECK LOGICAL option. Logical corruptions are normally due to either recovery through a NOLOGGING operation, or an Oracle software bug.)

 

第十五和第十六字节是SCNWrap ,这里是0x0000

第十七和第十八字节是spare3_kcbh,这里未使用

第十九和第二十字节是checksum,这里是0x4671

 

 

正好和dump的内容一样

buffer tsn: 4 rdba: 0x010072a3 (4/29347)

scn: 0x0000.009b876f seq: 0x01 flg: 0x04 tail: 0x876f2301

frmt: 0x02 chkval: 0x4671 type: 0x23=PAGETABLE SEGMENT HEADER

 

 

相关说明:

Rdba:block的相对地址(DBA)

Scn: SCN number

Seq:sequence number incremented for each change made to the block at the same SCN

Flg:flag

Tail:验证block的完整性,通过检查block的开始和结束是否是同一版本

Frmt:block format 通常是0x02

Chkval:如果db_block_checksum=true时,block的核查值

Type:block的类型,如data,index等

 

 

到此block的前20bytes都已经解读了,然后再看看紧跟其后的kttbh 的24bytes内容解读

 

Bbed> p ktbbh

struct ktbbh, 48 bytes                      @20     

   ub1 ktbbhtyp                             @20       0x01 (KDDBTDATA)

   union ktbbhsid, 4 bytes                  @24     

      ub4 ktbbhsg1                          @24       0x0000001c

      ub4 ktbbhod1                          @24       0x0000001c

   struct ktbbhcsc, 8 bytes                 @28     

      ub4 kscnbas                           @28       0x805c12df

      ub2 kscnwrp                           @32       0x0000

   b2 ktbbhict                              @36       1

   ub1 ktbbhflg                             @38       0x02 (NONE)

   ub1 ktbbhfsl                             @39       0x00

   ub4 ktbbhfnx                             @40       0x00000000

   struct ktbbhitl[0], 24 bytes             @44      

      struct ktbitxid, 8 bytes              @44     

         ub2 kxidusn                        @44       0x0002

         ub2 kxidslt                        @46       0x0025

         ub4 kxidsqn                        @48       0x0006e714

      struct ktbituba, 8 bytes              @52     

         ub4 kubadba                        @52       0x00801ba0

         ub2 kubaseq                        @56       0xaa14

         ub1 kubarec                        @58       0x10

      ub2 ktbitflg                          @60       0x2001 (KTBFUPB)

      union _ktbitun, 2 bytes               @62     

         b2 _ktbitfsc                       @62       0

         ub2 _ktbitwrp                      @62       0x0000

      ub4 ktbitbas                          @64       0x805c12e0

 

以下是16进制文件内容

 

Start dump data blocks tsn: 4 file#: 4 minblk 29348 maxblk 29348

buffer tsn: 4 rdba: 0x010072a4 (4/29348)

scn: 0x0000.00e66a1e seq: 0x02 flg: 0x06 tail: 0x6a1e0602

frmt: 0x02 chkval: 0x4590 type: 0x06=trans data

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

Dump of memory from 0x061E8400 to 0x061EA400

61E8400 0000A206 010072A4 00E66A1E 06020000  [.....r...j......]

61E8410 00004590 00000001 0000ED65 009B8769  [.E......e...i...]

61E8420 00000000 00320003 010072A1 0000FFFF  [......2..r......]

61E8430 00000000 00000000 00000000 00008000  [................]

61E8440 009B8769 00190001 00001B03 0080027B  [i...........{...]

61E8450 002C0E55 00002001 00E66A1E 00000000  [U.,.. ...j......]

61E8460 00000000 00000000 00000000 00000000  [................]

61E8470 00000000 00000000 00000000 00090100  [................]

61E8480 0024FFFF 1C291C4D 00001C29 1F1E0009  [..$.M.).).......]

61E8490 1E6C1EC3 1DB71E13 1D021D5B 1C4D1CA7  [..l.....[.....M.]

61E84A0 00000000 00000000 00000000 00000000  [

.

.

.

61EA3E0 38302D35 3A30332D 353A3331 30333A30  [5-08-30:13:50:30]

61EA3F0 4C415605 4E014449 4E014E01 6A1E0602  [.VALID.N.N.N...j]

 

 

其中buffer tsn: 数据文件对应的 tablespace 的 number ,这只是dump文件中记录的数据而已,block 中是没有记录 tablespace 的number 的

 

 

21-24字节,即0x00000001,表示typ ,占4个bytes

1 : DATA , 2: index 
改成3了在10.1.0 上引起了ora-600[2032]然后ORA-27101: shared memory realm does not exist
oracle进行查询的时候是根据 obj$表中的情况来判断对象的类型的,不是根据这个typ
也就是说如果有一个表但改变表中block的这个标志位,一样可以查询出数据来,
dump block 时会出错,ORA-00600: 内部错误代码,自变量: [4555], [0], [], [], [], [], [], []
错误中的 [0] 就是typ对应的数据
10G中改变它后update这个block的数据commit可以但rollback的报错)

 

25-28字节,即0x0000ED65,表示seg/obj,占4个字节

 

29-36字节,即 0x009B8769.00000000,表示csc ,占6个字节(The SCN at which the last full cleanout was performed on the block)   

 

37字节,即0x00 表示 fsl (Index to the first slot on the ITL freelist. ITL TX freelist slot)

38字节,即0x32 表示flg

indicates that the block is on a freelist. Otherwise the flag is -
9i 的ASSM 的情况下这个值为 E
ixora 上说他占用 2 bytes 但我下面的试验和他的结果有一定的出入
我观察到的情况是 : Object id on Block? Y flg: O ver: 0x01 
上面的3项是用同一个 byte 来表示的

flg: O ver: 0x01 Object id on Block? Y 
从我的观察中 dump 出来的文件 flg ver Object id on Block
他们共同占用的这个一个字节 他的规律可以从下面的情况看出
2进制数据 flg ver Object id on Block?
0x00 - 0x00 N
0x01 0 0x00 N
0x02 - 0x01 Y
0x03 0 0x01 Y
0x04 - 0x02 Y
0x05 0 0x02 Y
0x06 - 0x03 Y
0x07 0 0x03 Y
0x08 - 0x04 N
0x09 0 0x04 N
0x0a - 0x05 Y
0x0b 0 0x05 Y
0x0c - 0x06 Y
0x0d 0 0x06 Y
0x0e - 0x07 Y
0x0f 0 0x07 Y
0x10 ... 类似上面的循环了 这种情况在9i上已经改变因为ASSM的出现

 

39-40字节,即0x0003 表示 itc ,占2个字节。用0x00ff掩码取值,值为3(ITL 条目的个数 max 255超过会报ORA-02207 ORA-00060 ORA-00054 可能是没空间分配itl条目了或它的争用引起的,在8i中 INITRANS default为1 , 9.2.0中 INITRANS default为2)

 

41-44字节,即0x010072A1 表示 (自由列表中下一块的地址 Null if this block is not on a freelist)

 

 

44字节以后就是ITL的记录,每个itl所占24bytes

 

 

45-52字节,即0x0000.FFFF.00000000,表示xid

Transaction ID (UndoSeg.Slot.Wrap)
值可以用select XIDUSN, XIDSLOT,XIDSQN from v$transaction;查到 
This is comprised of the rollback segment number (2 bytes), the slot number
in the transaction table of that rollback segment (2 bytes), and the number
of times use of that transaction table has wrapped (4 bytes).

53-60字节,即0x00000000.000000.00,表示uba

Undo address (UndoDBA.SeqNo.RecordNo)
The location of the undo for the most recent change to this block by this transaction. This is comprised of the DBA of the rollback segment block (4 bytes), the sequence number (2 bytes), and the record number for the change in that undo block (1 byte), plus 1 unused byte.

 

63-64字节,即0x8000 ,表示lck flag

Lck 锁定的row数 这里还用到了下一个 byte 的数据
2 对应的二进制表示为 0010 正好和dump文件中的 --U- 吻合
flag 1 nibble 
C = Committed; U = Commit Upper Bound; T = Active at CSC; B = Rollback of this UBA gives before image of the ITL.
---- = transaction is active, or committed pending cleanout
C--- = transaction has been committed and locks cleaned out
-B-- = this undo record contains the undo for this ITL entry
--U- = transaction committed (maybe long ago); SCN is an upper bound
---T = transaction was still active at block cleanout SCN
Lck 3 nibbles 
The number of row-level locks held in the block by this transaction.)

 

 

61-62和65-68字节,即 0x0000.009B8769 表示Scn/Fsc:

If the transaction has been cleaned out, this is the commit SCN or an upper bound thereof. Otherwise the leading two bytes contain the free space credit for the transaction - that is, the number of bytes freed in the block by the transaction 
Scn = SCN of commited TX; Fsc = Free space credit (bytes)

 

 

 

再往下分析, 

 

 

 

Block header dump:  0x010072a4

 Object id on Block? Y

 seg/obj: 0xed65  csc: 0x00.9b8769  itc: 3  flg: E  typ: 1 - DATA

     brn: 0  bdba: 0x10072a1 ver: 0x01 opc: 0

     inc: 0  exflg: 0

 

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc

0x01   0xffff.000.00000000  0x00000000.0000.00  C---    0  scn 0x0000.009b8769

0x02   0x0001.019.00001b03  0x0080027b.0e55.2c  --U-    1  fsc 0x0000.00e66a1e

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

 

 

因为这里有三个itls,所有共占用24×3=72bytes空间,再加上20+24+8(这个可能是保留的,具体做什么,不是很清楚?),总124字节

 

16进制文件如下:

 

61E8470 00000000 00000000 00000000 00090100  [................]

61E8480 0024FFFF 1C291C4D 00001C29 1F1E0009  [..$.M.).).......]

61E8490 1E6C1EC3 1DB71E13 1D021D5B 1C4D1CA7  [..l.....[.....M.]

 

 

125字节,即0x00 表示flag

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

 

126字节,即0x09,表示nrow (block 有多少行数据)

127字节,即0x01,表示ntab (这block中有几个table的数据 cluster这个就可能大于1)

128-129字节,即0x0000,表示frre (First free row index entry. -1=you have to add one.)

 

130字节,即0x24,表示fsbo

Free Space Begin offset 出去row dict 后面的可以放数据的空间的起始位置
也可以看成是从这个区域的开始"flag"到最后一个 "row offs"占用的空间)

 

135-136字节,即 0x1C4D,表示fSEO

Free Space End offset ( 9.2.0 )参与db_block_checking的计算剩余空间
select 的时候oracle不是简单的根据offset定位row.这个值也是参与了定位row的

 

139-140字节,即0x1C29,表示tosp(Total available space when all TXs commit ( 9.2.0 )参与db_block_checking)

 

133-134字节,即0x1C29,表示avsp(Available space in the block (pctfree and pctused) ORA-01578)

 

Oracledsi文档里和bbed查看block的结构,都表明kdbh占14字节,但我的这个测试和其有些出入,希望高人指出

 

其中第141-142字节,即0x1F1E,表示offsets (偏移量 用 cluster 的时候可以看出值)

143-144字节,即0x0009,表示nrow(这个table有多少行数据)

 

和下面的Block的dump文件是对应符合的

 

data_block_dump,data header at 0x61e847c

//data_block_dump,data header at 0x61e847c
         //其实这个block不是直接从 data buffer 中 dump 出来的这个表示真正dump时 block 的数//据区的起始位置
         //也就是下面这部分开始的位置

 ===============  ////  tsiz:    hsiz:   pbl:   bdba: 在数据文件都是没有存储的

 tsiz: 0x1f80       //// Total data area size   ---8k的block: 8192-20(block head)-24(Transaction Header)-24*2(一个事务条)-8(我不太清楚的8个字节)-4(block tail)=8072(0x1f80)

 

hsiz: 0x24    //// Data header size  数据块头20个字节+数据块尾4个字节=24字节(0x14)

pbl: 0x061e847c  //// Pointer to buffer holding the block

 

bdba: 0x010072a4

     76543210

flag=--------

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

nrow=9   ---block 有多少行数据

frre=-1

fsbo=0x24

fSEO=0x1c4d

avsp=0x1c29

tosp=0x1c29

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

0x12:pri[0] offs=0x1f1e

0x14:pri[1] offs=0x1ec3

0x16:pri[2] offs=0x1e6c

0x18:pri[3] offs=0x1e13

0x1a:pri[4] offs=0x1db7

0x1c:pri[5] offs=0x1d5b

0x1e:pri[6] offs=0x1d02

0x20:pri[7] offs=0x1ca7

0x22:pri[8] offs=0x1c4d

block_row_dump:

tab 0, row 0, @0x1f1e

tl: 98 fb: --H-FL-- lb: 0x2  cc: 15

col  0: [ 5]  c4 02 07 4c 0c

col  1: [ 4]  32 30 30 31

col  2: [ 3]  53 59 53

col  3: [16]  53 4e 41 50 5f 4c 4f 41 44 45 52 54 49 4d 45 24

col  4: *NULL*

col  5: [ 3]  c2 02 3f

col  6: [ 3]  c2 02 3e

col  7: [ 5]  54 41 42 4c 45

col  8: [ 7]  78 69 08 1e 0e 33 1f

col  9: [ 7]  78 69 08 1e 0e 33 1f

col 10: [19]  32 30 30 35 2d 30 38 2d 33 30 3a 31 33 3a 35 30 3a 33 30

col 11: [ 5]  56 41 4c 49 44

col 12: [ 1]  4e

col 13: [ 1]  4e

col 14: [ 1]  4e


1.gif

2.gif

3.gif

4.gif

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐