《Oracle内核技术揭秘》(笔记)--第一章 存储结构

1.区(Extent):表空间的基本单位

 

Extent的基本概念

Extent逻辑上连续空间。是表空间中空间分配基本单位

10g:创建表,则至少分配一个Extent。

11.2以上:创建表,不分配Extent。只有插入第一行数据,才分配第一个Extent。避免创建大量表(比如分区表),但不用而浪费时间。是一种延迟分配机制。

 

Extent的分配信息,可在DBA_EXTENTS视图中。描述Extent_id,所属File,起始Block_id,包含多少个blocks,所属表(segment_name)

 

select extent_id, file_id, block_id, blocks
from dba_extents where
segment_name='TABLE1' order by extent_id;

Extent如何定义大小?

统一区大小

Extent大小为固定值,可以在创建表空间时指定,如下是1M的Extent大小

create tablespace tbs_ts1 datafile '/u01/Disk1/tbs_ts_01.dbf' size 50m uniform size 1m;

建表,插入一条记录后,从DBA_EXTENTS中查看,能看到Extent信息:

table1包含1个Extent(0),从4号文件128号块开始,大小128(块大小8K,*128,正好1MB)。

文件头

从上面看,新申请的第一个extent是从128号块开始的,那前面的0~127,就是预留的文件头

其中:0,1时候真正文件头。

2~127是位图块记录区的分配情况。每个位图块中的一个二进制位,表示对应的一个区是否被分配

其中第一个位图块(2号)是位图段头:记录区使用情况。

 

真正的位图信息从3号块开始。

新分配起始标记位:为加快检索可用的位(代表区),有一个标记位记录已经分配到哪里。新分配区时,从这个标志位开始查

如果开启闪回,Drop只是改名,标记位不会下降

系统管理区大小

系统管理区大小:区大小不固定,根据表大小自动配置。随着表的大小变化,区大小也发生变化,持续怎增大。

0~15号区,Blocks大小为8

从16号开始,大小变为128个

继续增大表,区大小还会继续扩大。

 

小的区省空间。对于随机访问,小、大区没有影响;对于全表扫描,大区更合适(空间连续,机械硬盘效率高)。

通常建议使用系统管理区,找平衡;除非知道表 很大,直接建统一区大小,且区比较大的表空间。段超过64MB,区大小可以建议为8MB。

即使IO操作最大读都是1MB,但8MB区比1MB区有效,因为两个1MB可能是连续的。

 

位图标记方式,针对两种区是一样的方式,只是一次用的位数量不一样而已。例如:以64KB为准,每个二进制位代表64KB。对于1MB的区,就用16个来管理。

 

碎片,可忽略的问题:统一区大小,不会出现碎片。系统管理区中,会出现碎片,但情况较少。一个表创建后,很少Drop、Truncatre操作。在表空间层,碎片可忽略;在表、索引层,还是存在的

 

2.中块的使用

 

段是描述存储空间,段(segment)由一组数据扩展(extent)构成,其中存储了表空间内各种逻辑存储结构的数据。一个段至少包含一个区。例如,Oracle能为每个表的数据段(data segment)分配数据扩展,还能为每个索引的索引段(index segment)分配数据扩展。

在DBA_OBJECTS视图中,object_id列是表ID,data_object_id列是段ID。

表ID创建就不变,段ID会变化。truncate会导致段ID变化(删除旧的、新建新的)。

 

dbms_rowid包,可以把对象ID、文件号、块号、行号和ROWID进行转换。

删除某行,只是在行上加删除标志,表明空间可被覆盖。在未提交时,锁并没有释放。做回滚后,不会重新寻找空间,所以行号不变删除后提交再插入,行号会变化

 

关于堆表的顺序问题

堆表的特点就是无序、插入快速

插入时,在块中空间查找过程:

1、块中有一个标记,记录空间使用到哪里。空间是从下往上分配的,比如8192块,插入5行*100字节,标记位就是(8192-500) = 7692(示意),标记位就是7692

2、如果删除一行,标记位不变。再插入数据时,会从7692向上查找。删除行释放空间不会被使用。

只在一个页里面,看上去是顺序的。但不同页面,就不适合了。因为插入时根据PID计算随机过的。

 

ASSM(自动段空间管理):目的就是大并发插入,实际就是针对不同Session在分配块时,做了2次hash,减少冲突(buffer busy wait)

1、三级位图块结构

2个L3就很罕见

2、插入时选择块的步骤

1)先查数据字典,dba_segments的基表,确定段头位置

2)在段头中找到第一个L2块位置信息。注意,这里是按顺序选,只有第一个L2下面所有块都满了,才会选择下一个L2

3)到L2块中根据执行插入操作进程的PID号,做HASH运算,得到一个随机数N,在L2中,找到第N个L1块的位置信息。

4)在确定L1块中,根据插入操作进程的PID,做HASH运算,得到随机数M,在L1中找到第M号数据块。

即:在具体分配在哪个块插入时,是根据插入进程的PID做了两次HASH,以提高并发能力(不同进程尽量找不同的块)。

 

新创建一个表时,它的L1-L3是倒过来的:

比如:128是L1,129是L1,130时候L2,131是L3

 

一个案例:

高水点影响ASSM计算L1块的范围,导致数据并发在小范围内选择,增加冲突。高水点向后移动是以L1中数据块量为单位

如果块大小8KB,区大小1MB,L1中有64个块,高水位点就是以64位单位。如果不突破高水位,并发插入都在这64个块上插入。

会出现2个块同时修改一个块,则出现buffer busy waits。

 

L1的块数量不是定的,随着表增大会增大

段头与Extent Map

查段头

select header_file, header_block from dba_segments 
where segment_name = 'TABLE1';

seg$是基表。

 

段头包含第一个L3块,还包含区地图。每行描述一个区的的位置和长度。

 

01000080转为二进制为:

0000 ‭0001 0000 0000 0000 0000 1000 0000‬

前10位代表文件号:0000 ‭0001 00,代表4号文件

080是十进制128,起始块号。

继续往下 辅助地图

L1 dba:0x1000080 此区内第一个L1块开始的地方(即4号文件,128号块)

Data dba:0x1000084:用户数据开始的地方,即132号块

全表扫描时,按照Data dba扫。但这里没有长度,还得读全面的分区地图信息。

 

89、90的L1 dba相同。在1MB分区,当段大小超过64MB,一个L1存放256个数据块。这样,多个分区会使用同一个L1(因为256,能包含2个分区的信息)

索引范围扫描

按照根、枝、页的顺序。根块永远在索引段头的下一个块处。可以直接在数据字典找到段头,段头+1就能读出根块。

关于具体怎么读取,还需要后面再细化一下

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值