block 内部结构分解

Oracle block 的详细物理结构图:

 

 

 

 

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

 

 

 

 

          

                                (图一)

 

 

Oracle block 被映射到SGA kcbhkernel cache block header )的对应的block 上 。

 

the cache layer :它是block header 的第一部分,占用20bytes 。用于检查数据的正确性,即被读的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 SCNused for ordering purposes during recovery

 

 

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

 

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

 

2.        另一个是 a variable portionKTBITTRANSACTION VARIABLE HEADER ),包含一个进程在一个block 里要编辑行所需要的ITLs 。默认的包含一个表的数据块只有一个ITLITL 的多少是通过存储参数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 操作,行数据是随机存储的。

如下图所示:

 

 

 

 

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

 

 

 

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

 

 

 

 

 

下面是oracle blockdump 文件,结合上面这个图片来验证下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 0000A 223 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 的完整性的,它是由SCNBaseblock typeSCN seq number 组成。

876F 2301=876F last two bytes of SCN Base+ 23type+ 01seq

 

红色的字是offset (偏移量)

 

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

 

0000A 223 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 的类型,如dataindex

 

 

到此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 ,占4bytes

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 default1 , 9.2.0 INITRANS default2

 

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

 

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

 

其中第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

------续----

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Block design 是一种设计思想,用于将复杂系统分解为多个模blocks),每个模负责特定的功能或任务。以下是 Block design 的一般使用流程: 1. 确定系统需求:首先,明确系统的功能和需求。这包括确定系统的输入、输出、约束条件以及期望的性能指标。 2. 模划分:根据系统需求,将系统分解为多个模。每个模应该具有清晰的功能和责任,并且可以独立地实现和测试。 3. 定义接口:确定各个模之间的接口,包括输入、输出和通信方式。确保接口定义清晰、一致,并且能够满足模之间的数据交换和通信需求。 4. 设计每个模:对于每个模,进行详细设计。这包括确定模内部的算法、数据结构、状态机等。确保每个模的设计能够满足其功能需求,并且能够与其他模进行协同工作。 5. 实现和测试:根据设计,实现每个模,并进行单元测试。确保每个模的功能正确性和稳定性。 6. 集成和验证:将所有模进行集成,并进行系统级测试和验证。确保系统在各种情况下能够正确地工作,并满足系统需求和性能指标。 7. 优化和调试:在集成和验证过程中,可能会发现问题或需要对系统进行优化。根据具体情况,进行调试和优化,确保系统达到最佳性能和稳定性。 总的来说,Block design 的流程包括需求分析、模划分、接口定义、详细设计、实现和测试、集成和验证以及优化和调试。通过这个流程,可以有效地分解和组合复杂系统,提高系统的可维护性和可扩展性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值