oracle的块

Oracle的块

概念:Oracle  数据块是  Oracle 能够读或写的最小存储单元,但不是最小分配单元

一个数据块对应一个或多个( 被分配了数据文件的 ) 操作系统块组成,数据块大小应当是 操作系统块大小的整数倍,以避免不必要的 I/O Oracle 是以块为单位读取数据。  Oracle 每次请求数据的时候,都是以块为单位。也就是说, Oracle 每次请求的数据是块的整数倍。如果 Oracle 请求的数据量不到一块, Oracle 也会读取整个块。所以说,“块”是 Oracle 读写数据的最小单位或者最基本的单位。

块中存放表的数据和索引的数据,无论存放哪种类型的数据,块的格式都是相同的,块由块头(header/Common and Variable), 表目录 (Table Directory), 行目录 (Row Directory), 空余空间 (Free Space) 和行数据 (Row Data) 五部分组成 ,如下图所示:

 

<!-- [if gte mso 9]><xml><w:WordDocument><w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel><w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery><w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery><w:DocumentKind>DocumentNotSpecified</w:DocumentKind><w:DrawingGridVerticalSpacing>7.8</w:DrawingGridVerticalSpacing><w:View>Normal</w:View><w:Compatibility></w:Compatibility><w:Zoom>0</w:Zoom></w:WordDocument></xml><![endif]-->

 

1 块头(header/Common and Variable) :存放块的基本信息,如:块的物理地址,块所属的段的类型 ( 是数据段还是索引段 ) 。 

2 表目录(Table Directory) :存放表的信息,即:如果一些表的数据被存放在这个块中,那么,这些表的相关信息将被存放在“表目录”中。

   3 行目录(Row Directory) :如果块中有行数据存在,则,这些行的信息将被记录在行目录中。这些信息包括行的地址等。

   4 行数据(Row Data) :是真正存放表数据和索引数据的地方。这部分空间是已被数据行占用的空间。

   5 空余空间(Free Space) :空余空间是一个块中未使用的区域,这片区域用于新行的插入和已经存在的行的更新。

6 头部信息区(Overhead) :我们把块头 (header/Common and Variable), 表目录 (Table Directory), 行目录 (Row Directory) 这三部分合称为头部信息区 (Overhead) 。头部信息区不存放数据,它存放的整个块的信息。头部信息区的大小是可变的。一般来说,头部信息区的大小介于 84 字节 (bytes) 107 字节 (bytes) 之间。

7 数据块中自由空间的使用

  当往数据库中插入(INSERT) 数据的时候,块中的自由空间会减少 ; 当对块中已经存在的行进行修改 (UPDATE)的时候 ( 使记录长度增加 ) ,块中的自由空间也会减少。

  DELETE 语句和 UPDATE 语句会使块中的自由空间增加。当使用 DELETE 语句删除块中的记录或者使用 UPDATE 语句把列的值更改成一个更小值的时候, Oracle 会释放出一部分自由空间。释放出的自由空间并不一定是连续的。通常情况下, Oracle 不会对块中不连续的自由空间进行合并。因为合并数 据块中不连续的自由空间会影响数据库的性能。只有当用户进行数据插入(INSERT) 或者更新 (UPDATE) 操作,却找不到连续的自由空间的时候, Oracle 才会合并数据块中不连续的自由空间。

 

Pct_free:空闲百分比,默认为 10% ;会保持 10% 的空间不适用。

Pct_used:使用百分比,默认为 40% ;如果向某个块里插入数据,当超过该块的 40% 时就不会再往这个快插入了。

那为什么要这样设计呢?为了防止行连接和行迁移;

行链接(Row Chaining) :如果我们往数据库中插入 (INSERT) 一行数据,这行数据很大,以至于一个数据块存不下一整行, Oracle 就会把一行数据分作几段存在几个数据块中,这个过程叫行链接 (Row Chaining) 。如下图所示:

 

行迁移(Row Migrating) :数据块中存在一条记录,用户执行 UPDATE 更新这条记录,这个 UPDATE 操作使这条记录变长,这时候, Oracle 在这个数据块中进行查找,但是找不到能够容纳下这条记录的空间,无奈之下, Oracle 只能把整行数据移到一个新的数据块。原来的数据块中保留一个“指针”,这个“指针”指向新的数据块。被移动的这条记录的 ROWID 保持不变。行迁移的原理如下图所示:

 

 

无论是行链接还是行迁移,都会影响数据库的性能。Oracle 在读取这样的记录的时候, Oracle 会扫描多个数据块,执行更多的 I/O

故会留一定的空间由 update等操作,对已存在的数据的扩展提供空间。提高 oracle 的性能。还有为 头部信息区(Overhead) 的扩展提空预留空间,因为头部信息区里会存储事务信息,事务信息会增加的。

 

 

 

 

 

 

 

块的管理方式:

1、链表管理:

在生成段的时候,会同时分配初始区(initial extents) , 初始区的第一个块就格式化为 segment header , 并被用来记录 free list 描述信息、 extents 信息, HWM 信息等。 

段头就是初始区的第一个块,free list 是一种单向链表用于定位可以接收数据的块,在字典管理方式的表空间中或 MSSM Oracle 使用 free list 来管理未分配的存储块。

Oracle记录了有空闲空间的块用于 insert Update 。空闲空间来源于两种方式:

1.段中所有超过高水位( HWM )的块,这些块已经分配给段了,但是还未被使用。

2.段中所有在 HWM 下的且链入了 free list 的块,可以被重用。

     HWM HIGH WATER MARK 代表一个表使用的最大的 (top limit) 块 。简单点说  HWM  就是一口井曾经达到的最高水位 , 也就是历史最高水位点,比如一个杯子能装 100 升水 装到 80, 倒出 20 .  高水位就是 80;

 

空闲的块怎么来的?

1.段中所有超过 HWM 的块,这些块已经分配给段了,但是还未被使用。

注意限定词:这些块已经分配给段了

2.段中所有在 HWM 下的且链入了 free list 的块,可以被重用。

FREE LIST就是一个链入了空闲块的单向链表

高水位上的肯定是空闲的, 想用高水位以上的空闲之前 , 必须将高水位延伸 .

 

具体操作:

Insert发生了什么:

1、 freelist ,如果有空闲的就插入

2、 如果空闲列表中没有可以使用的快,就挪动高水位

3、 如果插入到该块的10% 时则会把该块从 freelist 列表中移除

 

Delete发生了什么:

当删除数据时,该块的剩余空间到pct_used 的时侯,就会把该块假如到空闲列表中。

就是当删除一个已经超过到40% 的块时并不是马上就会用该块的剩余的空间,只有当该块的的剩余空间到 pct_used 的时侯才会把它纳入到可使用的范围。

 

 

 

 

2、 位图管理:

 

L3 ROOT 层,放在段头, L2 是分支层,而 L1 就是实际的位图块。

 

 

 

 

里面4 个图,从左到右看。 

ASSM将采用把数据块拆分成4个水位:

0-25%,26%-50%,51%-75%,76%-100% 

根据实际数据在4 个水位的相对位置及 PCTFREE 来决定该块的空闲状况 

注意ASSM PCTUSED 参数将无效 只用这四个水位来决定块被使用情况

上图我们看到设置的PCTFREE 40%( 表示块得保留 40% 的块空闲空间,用作以后增大的 UPDATE)

我们从左到右把上图分解为4 个小图 A B C D 

A图的水位在 PCTFREE 规定的范围内,所以块当前的状态为 FULL=NO 

然后进行了INSERT  操作,有数据插入了块,水位升高了,达到 PCTFREE 线以上 

这时,数据块状态直接变为了FULL=YES  B 图) 

FULL=YES代表什么呢? 

代表你以后再执行INSERT 语句时候,就不会将数据插入这个块中了,会找其他 FULL=NO 的块。

B 图后,执行 DELETE C 图,这里要注意的是 :

DELETE后水位仍然在 50% 以上, C 图块的状态改变还是 YES.

C图块的状态改变了没有?

因为块被分成了4 个水位  0-25%,26%-50%,51%-75%,76%-100%

C这里虽然减少了,但是还没有跨越水平线

这样的好处是,减少频繁的改变块状态。防止系统颠簸

D DELETE 操作后,水位下降到了 26%-50% ,这时候块状态发现改变了 又可以插入数据了。

 

 

操作时的变化:

当增加extent 时,会增加一级位图,一般 2 8 块一个一级位图,一级位图被现在的二级位图管理,如果一次分配的过多就会出现一次出现多个一级位图。

segment 过大时会出现多个二级位图,因为块能存储的空间有限当一级位图过多时二级位图就无法存储了。就要在分配二级位图,他们分别管理自己一级位图,而二

 级位图只被头管理。

位图管理效率比较高,故在9i 以后默认情况下建的表就是位图管理。

猜你喜欢

转载自997004049-qq-com.iteye.com/blog/1717827