■ 概述
Oracle的所有数据都是以数据文件的形式存储的,Oracle使用和分配存储的最小逻辑单位是:数据块
在操作系统的物理层面上,也有数据块的概念,但跟Oracle的数据块不一样,操作系统是以字节为单位存储数据的
Oracle请求数据时,它请求的是Oracle的数据块,而不是物理层面上操作系统的数据块
数据块也有大小的,通过初始化参数DB_BLOCK_SIZE可以设定数据块的标准大小(standard block size),此外,也可指定5个非标准块大小
数据块的大小应为操作系统的块大小的倍数,但同时也要确保其不要超过最大限制,以确保出现不必要的I/O
■ 数据块格式(Data Block Format)
数据块内存储的内容可以是表,索引,簇等数据内容,但不管存储的是什么,它们的格式都是相似的
□ 头(Common and Variable Header)
包含了数据块的一般信息,例如数据块的地址和段的类型(例如,数据或索引)
□ 表目录(Table Directory)
包含了数据块中表的信息,这些表包含着行数据
□ 行目录(Row Directory)
包含了数据块中实际行的信息(包括行数据区域中每个行段的地址)
□ 块开销(Overhead)
数据块的头、表目录和行目录统称为块开销
一些块开销的大小是固定的,总的块开销大小是可变的
平均而言,数据块开销的固定和可变部分总计84到107字节
□ 行数据(Row Data)
包含了表或索引的数据
数据是可以跨块的,比如一个数据库表的数据量较大,它的数据在一个块内不能全部存储,剩下的部分可以存储在其他数据块里
□ 可用空间(Free Space)
可用空间用于插入新行和更新行数据时,所需要的额外空间(例如,当行中的null更新为非null值时)
在为表或簇的数据段或索引的索引段分配的数据块中,可用空间还可以保存事务条目(transaction entry)
当在块内对一条或多条记录进行增删改查操作时,是需要一个事务条目的
事务条目所需空间的大小取决于所在的操作系统,大多数操作系统中的事务条目大约需要23个字节
■ 可用空间管理
可用空间的管理方式即可以是自动的,也可以是手动的
可用空间可以在数据库段内被自动管理
段内可用/已用空间的使用是通过位图来追踪的,而不是空闲列表
段内空间通过以自动方式来管理,有以下好处:
1) 方便使用
2) 更好的空间利用率,特别是对于行大小变化很大的对象
3) 对并发访问中的变化进行更好的运行时调整
4) 在性能/空间利用率方面有更好的多实例行为
在创建的表空间是以本地管理的方式时,可以将段内空间管理方式为设为自动,这样在此表空间中创建的所有段都会使用该设置
□ 数据块中可用空间的可用性与优化
以下两种类型的语句可以增加数据块的可用空间
1) DELETE语句
2) UPDATE语句(将现有值更新为更小值)
在以下条件下,这些类型语句释放的空间可用于后续INSERT语句:
1) 如果INSERT语句与释放空间的语句在同一事务中,并且在释放空间的语句之后,则INSERT语句可以使用可用的空间
2) 如果INSERT语句与释放空间的语句不在同一事务中(可能由另一个用户运行),则INSERT语句只能在其他事务提交之后,并且只有在需要空间时才可以使用可用的空间
释放的空间未必是与数据块中的可用空间的主要区域相邻的
当满足以下两个条件时,Oracle才会对数据块的可用空间进行合并:
1) INSERT或UPDATE语句使用该数据块时,该数据块拥有足够的空闲空间来包含新的行片段
2) 数据块的可用空间被分段,以至于无法将新的行片段插入到块的连续部分中
Oracle只在以上情况下进行这种压缩,否则会因为数据块中的可用空间的不停压缩而降低数据库系统的性能
□ 行链接和行迁移
◆ 行链接(row chaining)
表中一行的数据可能太大,而无法放入单个数据块中
第一次插入行时,该行太大,无法放入一个数据块中
在这种情况下,Oracle将该行的数据存储在该段内保留的数据块中(一个或多个)
行链接通常发生在大行中,例如包含数据类型为LONG或LONG RAW的行
在这些情况下,行链接是不可避免的
◆ 行迁移(row migration)
原来适合于一个数据块的行被更新,使得整个行长度增加,并且块的可用空间已经被完全填满
在这种情况下,Oracle将整行的数据迁移到一个新的数据块中,假设整行可以放入一个新的块中
Oracle保留已迁移行的原始行片段,以指向包含已迁移行的新块
已迁移行的rowid不会更改
◆ 注意
当一行被链接或迁移时,与该行关联的I/O性能会降低,因为Oracle必须扫描多个数据块才能检索该行的信息
■ PCTFREE, PCTUSED和行链接
对于手动管理的表空间,通过以下两个参数管理可用空间,来控制指定段内的所有数据块中的行的插入和更新操作
PCTFREE
PCTUSED
在创建或更改表或集群(它有自己的数据段)时指定这些参数
还可以在创建或更改索引(索引有自己的索引段)时指定存储参数PCTFREE
□ PCTFREE
PCTFREE参数用于设置数据块内要保留为可用空间的最小百分比,以便对该块中已存在的行进行可能的更新时有足够的空间
例如,在createtable语句中指定以下参数
PCTFREE 20
这说明该表的数据段中每个数据块的20%是空闲的,并且可以对每个块中已有的行进行可能的更新
新行可以添加到行数据区,相应的信息可以添加到开销区域的可变部分,直到行数据和开销总计占总块大小的80%
□ PCTUSED
PCTUSED参数用于设置向数据块内添加新行之前,已使用空间(行数据加开销所占空间)的最小百分比
在将数据块填充到PCTFREE确定的限制后,Oracle将认为该块不可用于插入新行,直到该块的百分比低于参数PCTUSED
在获得该值之前,Oracle只使用数据块的可用空间来更新数据块中已经包含的行
例如,假设在CREATETABLE语句中指定以下参数
PCTUSED 40
表示只有当该表数据段的数据块的已用空间量降至39%或更低(假设该块的已用空间以前已达到PCTFREE),才可用于插入任何新行
□ PCTFREE和PCTUSED如何一起工作
通过同时使用PCTFREE和PCTUSED,可以达到优化使用数据段中的数据块中的空间的作用
在新分配的数据块中,可用于插入的空间是:块大小 - (块开销 + 可用空间(PCTFREE))
对现有数据的更新操作可以使用块中的任何可用空间
因此,更新可以将块的可用空间减少到小于PCTFREE,PCTFREE是为更新保留的空间,不可用于插入
Oracle针对每个数据段和索引段维护一个或多个空闲列表,这些空闲列表中包含着分配给该段对应的区的数据块,它们的可用空间都是大于PCTFREE的,因此这些块可用于插入
执行INSERT语句时,Oracle会检查空闲列表中的第一个可用数据块,并在可能的情况下使用它
如果该块中的可用空间不足以容纳插入的数据,并且该块至少已占用PCTUSED,则Oracle会将该块从空闲列表中移除
当并发插入发生时,每个段的多个空闲列表可以减少空闲列表的争用
当Oracle执行完DELETE或UPDATE语句后,将检查块中使用的空间现在是否小于PCTUSED
如果是,那么该块将转到事务空闲列表的开头,并且将其列为该事务中要使用的第一个可用块
当事务提交时,块中的可用空间可用于其他事务