深入解析Oracle数据块的内部结构

访问www.tomcoding.com网站,学习Oracle内部数据结构,详细文档说明,下载Oracle的exp/imp,DUL,logminer,ASM工具的源代码,学习高技术含量的内容。

在Oracle数据库的存储体系中,数据块是整个体系的最小逻辑单元,也是I/O操作的基本单位。理解数据块的内部结构,不仅能够帮助DBA排查数据损坏、空间分配异常等底层问题,更能让开发者从根本上优化数据库的存储与访问性能。

Oracle数据块是分层结构,从上到下依次是块头,事务固定层,事务可变层,数据头层,表目录层,行目录层,空闲空间,行数据层和块尾。我们从上到下来分析各个层的结构。

1. 块头(Block Header)

块头是数据块最外层的元数据区域,存储整个块的基础控制信息,主要用于在SGA的缓存中识别不同的数据块。包含数据块的类型,数据块的地址(RDBA),块的系统改变号(SCN)和块的校验和等内容。一个块头的dump信息如下。

buffer tsn: 9 rdba: 0x02000087 (8/135)
scn: 0x0000.003f2481 seq: 0x01 flg: 0x06 tail: 0x24810601
frmt: 0x02 chkval: 0x70f9 type: 0x06=trans data

2. 事务固定层(Tansaction Layer Fixed)

这一次包含了块的事务信息中的固定部分,包含了段内的对象ID(segment object id),事务槽的个数,管理这个块的块地址(BDBA),块内的数据类型等。这部分的dump信息如下。

Block header dump:  0x02000087
 Object id on Block? Y
 seg/obj: 0x1338d  csc: 0x00.3f2480  itc: 2  flg: E  typ: 1 - DATA
     brn: 0  bdba: 0x2000080 ver: 0x01 opc: 0
     inc: 0  exflg: 0
其中事务槽的个数叫做itc,在这里是2,这个值决定了事务可变层中ITL的个数。

3. 事务可变层(Transaction Layer Variable)

这一层就是ITL(Interested Transaction List):也叫事务槽,每个槽位占用24字节,记录当前块上所有未提交事务的信息,用于实现多版本并发控制与行锁管理,ITL的个数在上一次中,由itc变量控制。事务槽的dump信息如下。

 Itl           Xid                                  Uba                       Flag  Lck        Scn/Fsc
0x01   0x0009.01c.00000d6b  0x00c010d0.0309.2c  --U-    1  fsc 0x0000.003f2481
0x02   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000

4. 数据头层(Data Header Layer)

数据头是定义块中数据信息的结构,比如块中包含了多少个表的数据(ntab),块中一共包含了多少条数据(nrow),数据空闲空间的偏移量(fsbo),总共的空闲空间大小(tosp)等等。数据头的dump信息如下。

data_block_dump,data header at 0x2b57aace6a64
===============
tsiz: 0x1f98
hsiz: 0x14
pbl: 0x2b57aace6a64
     76543210
flag=--------
ntab=1
nrow=1
frre=-1
fsbo=0x14
fseo=0x1f4c
avsp=0x1f38
tosp=0x1f38
 

5. 表目录层(Table Directory Layer)

这是一个数组结构,数据块中包含了几个表的数据,这个数组就有几个元素,普通表的数据块中只包含一个表,所有这里只有一个数组元素,Cluster表的数据块中可能包含几个表的数据,所以就会有好几个数组元素,数组的下标就是表的编号。这个结构有两个字段,分别叫做nrow和offs,表示表在块中包含的数据条数和表数据在下面的行目录中开始的位置。它的dump信息如下。

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

表示块中只有一个表的数据,数据条数是1,从行目录的第0个元素开始计算。

6. 行目录(Row Directory Layer)

行目录的结构比较简单,其实就是一个2字节的数组,每个数组元素中存放着一条记录的偏移量,叫做row offset,这个偏移量就是这行数据开始的位置,有多少条数据就有多少个数组元素。这个偏移量有一个相对地址,这个相对地址是数据头的基地址,这一点一定要搞清楚,因为很容易会把这个偏移量看做是相对于块头的地址。所以这个偏移量加上数据头的偏移量才是数据相对于块头的位置。行目录的dump信息如下。

0x1a:pri[0]     offs=0x1f80
0x1c:pri[1]     offs=0x1f74
0x1e:pri[2]     offs=0x1f64
0x20:pri[3]     offs=0x1f54
 

7. 空闲空间(Free Space)

行目录是从块头的方向往块尾增长的,每增加一行数据,行目录就增加一个元素。块中的数据是从块尾向块头的方向增长的,每增加一行数据,就向块头方向移动一段位置,所以在行目录和最后的数据行之间就有一段空间,这就是空闲空间,PCTFREE参数决定了空闲空间的大小。

8. 行数据层(Row Data Layer)

行数据位于块的底部,自下而上增长,是真正存储表中实际业务数据的区域。通常情况下一行数据在一个块中由一个数据片组成,在行链接的情况下单行数据可以跨多个数据块存储,由多个数据片组成,每个数据片在一个块中。每一个数据片的存储结构分为:行头(Row Header)和列数据。行头一般有三个字节,分别是fb,lb和cc。fb是数据片的标志,决定数据行由怎样的数据片组成。lb是锁标志,如果不为0,则表示这行数据对应着块中ITL的哪个槽位。cc则表示数据片中包含几列数据。列数据由数据长度和数据值组成,不同类型的列有不同格式的数据表示形式。数据行的dump信息如下。

tab 0, row 0, @0x1f4c
tl: 76 fb: --H-FL-- lb: 0x1  cc: 5
col  0: [ 2]  c1 02
col  1: [30]
 31 61 61 61 61 61 61 61 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
 20 20 20 20 20
col  2: [10]  31 62 62 62 62 62 62 62 62 62
col  3: [12]  31 63 63 63 63 63 63 63 63 63 63 63
col  4: [14]  31 64 64 64 64 64 64 64 64 64 64 64 64 64
 

9. 块尾(Block Tail)

数据块的块尾由4个字节组成,用于块的校验。在前面的块头dump信息中其实包含了块尾的信息。

buffer tsn: 9 rdba: 0x02000087 (8/135)
scn: 0x0000.003f2481 seq: 0x01 flg: 0x06 tail: 0x24810601
frmt: 0x02 chkval: 0x70f9 type: 0x06=trans data
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值