Oracle 数据库为数据库中的所有数据分配逻辑空间。数据库空间分配的逻辑单元是数据块、 扩展区、 段、和表空间。而在物理级,数据被存储在磁盘上的数据文件中 。数据文件中的数据存储在操作系统块中。
图 12-1 是一个物理和逻辑存储的实体关系图。乌鸦脚表示法表示一对多关系。
逻辑存储层次结构
图 12-2 显示了在表空间中的数据块、 扩展区、和段之间的关系。在此示例中,一个段具有分别存储在不同数据文件中的两个扩展区。
在最细的粒度级别, Oracle 数据库将数据存储为数据块。一个逻辑数据块对应于特定字节数的物理磁盘空间,比如 2 KB。数据块是Oracle 数据库可以使用或分配的最小存储单位。
扩展区是一组逻辑上连续的数据块,被分配来用于存储特定类型的信息。在图12-2中,这个24 KB的扩展区有12 个数据块,而这个72 KB的扩展区有 36个数据块。
段是为一个特定数据库对象(如一个表)分配的一组扩展区。例如,employees表的数据存储在其自己的数据段中,而该表的每个索引存储在其自己的索引段中。会消耗存储空间的每个数据库对象都由单个段组成。
每个段属于且仅属于一个表空间。因此,一个段的所有扩展区存储在相同的表空间中。在一个表空间中,一个段可以包括多个数据文件中的扩展区,如图 12-2 所示。例如,段的一个扩展区可能存储在 users01.dbf中,而另一个存储在 users02.dbf 中。单个扩展区绝不会跨越多个数据文件。
逻辑空间管理
Oracle 数据库必须使用逻辑空间管理来在表空间中跟踪并分配扩展区。当数据库对象需要扩展区时,该数据库必须有查找和分配扩展区的方法。同样,当对象不再需要扩展区时,数据库必须提供一种方法来重用可用空间。
Oracle 数据库基于您创建的表空间的类型来管理其中的空间。您可以创建下列类型的表空间之一:
本地管理表空间 (默认值)
数据库使用表空间本身中的位图来管理扩展区。因此,本地管理表空间需要预留表空间的一部分用于位图。在一个表空间中,数据库可以使用自动段空间管理 (ASSM) 或手动段空间管理 (MSSM)来管理段 。
字典管理表空间
数据库使用数据字典来管理扩展区。
图 12-3 显示了一个表空间中的逻辑空间管理方法的可选方案。
本地管理表空间
本地管理表空间在数据文件头中维护一个位图,以跟踪数据文件体中的可用空间和已用空间。每一位对应一组块。当空间被分配或释放时,Oracle 数据库更改位图值,以反映数据块的新状态。
下面的图形是位图管理存储的概念表示。标头中的 1 是指已用空间,而 0 指可用空间。
本地管理表空间具有如下优势:
避免使用数据字典来管理扩展区
如果消耗或释放一个扩展区会导致在数据字典表或撤消段中消耗或释放空间,则在字典管理的表空间中会发生递归操作。
自动跟踪相邻的可用空间
通过这种方式,数据库消除了合并空闲扩展区的需要。
自动确定本地管理扩展区的大小
或者,在本地管理表空间中所有的扩展区可以具有相同的大小,并覆盖对象存储选项。
注意:
Oracle 强烈建议使用自动段空间管理的本地管理表空间。
段空间管理是一个从包含该段的表空间继承来的属性。在一个本地管理表空间中,数据库可以自动地或手动地管理段。例如,users表空间中的段使用自动管理,而tools表空间中的段使用手动管理。
自动段空间管理(ASSM)
ASSM方法使用位图管理空间。位图提供了以下优点:
简化管理
ASSM 可以避免手动确定许多存储参数的正确设置的需要。只有一个很关键的控制空间分配的 SQL 参数: PCTFREE。此参数指定要为块中保留用于将来的更新的空间百分比。
增强并发性
多个事务可以搜索多个相互独立的空闲数据块列表,从而减少争用和等待。对很多标准工作负载,使用ASSM的应用程序性能比使用优化得很好的使用MSSM的应用程序性能更好。
对Oracle 真正应用集群 (Oracle RAC) 环境中实例的空间动态亲合性
ASSM 更有效,并且是永久性本地管理表空间的默认值。
注意:
本章假定在逻辑存储空间的所有讨论中使用ASSM。
手动段空间管理(MSSM)
旧式的 MSSM 方法使用称为空闲列表的链表来管理段中的可用空间。对一个具有可用空间的数据库对象,有一个空闲列表会跟踪位于高水位线 (HWM) 之下的数据块,所谓高水位,即已使用段空间和未使用段空间之间的分界线。当块被使用时,数据库根据需要将块放入空闲列表,或将块从空闲列表中删除。
除了 PCTFREE,MSSM 需要您使用额外的几个SQL 参数(如PCTUSED、FREELISTS、和FREELIST GROUPS)来控制空间分配。PCTUSED 设置在当前使用块中必须存在的可用空间百分比,当使用率低于该百分比时,数据库会将其放入空闲列表中。例如,如果CREATE TABLE 语句中设置 PCTUSED为40,则只有当块空间使用少于 40%的情况下,您才能往段中的块插入新行。
作为一个说明,假设向一个表中插入行。数据库检查该表的空闲列表,以查找第一个可用的块。如果行无法容纳进该块中,并在块中已使用空间大于或等于 PCTUSED,则数据库将该块从空闲列表中移除,并搜索另一个块。如果从块中删除行,则数据库检查块中的已使用空间现在是否小于PCTUSED。如果是,则数据库将该块置于空闲列表的开头。
一个对象可能有多个空闲列表。通过这种方式,在表上执行 DML的多个会话可以使用不同列表,以减少争用。每个数据库会话在其会话持续时间只使用一个空闲列表。
如图12-4 所示,你也可以创建具有一个或多个空闲列表组的对象,空闲列表组是空闲列表的集合。每个组有一个主空闲列表,用于管理组中的各个的处理空闲列表。空闲列表、尤其是空闲列表组的空间开销,可能非常显著。
手动管理段空间可能会很复杂。您必须调整PCTFREE 和 PCTUSED,以减少行迁移 和避免空间浪费。例如,如果段中的每个使用的块是半满,并且 PCTUSED 是 40, 则数据库不允许向这些块插入新行。由于微调空间分配参数很困难, Oracle 强烈建议使用 ASSM。在 ASSM中,由PCTFREE 确定是否可以将新行插入一个块中,但它不使用空闲列表,并忽略 PCTUSED。
字典管理表空间
字典管理表空间使用数据字典来管理其扩展区。每当分配或释放了一个扩展区时, Oracle 数据库更新数据字典中的表。例如,当表需要扩展区时,数据库查询数据字典表,并搜索空闲扩展区。如果数据库找到了空间,则修改一个数据字典表,并插入一行。按这种方式,数据库通过修改和移动数据来管理空间。
数据库在后台为数据库对象获取空间而执行的SQL是递归 SQL。频繁使用递归 SQL 可能会对性能有负面影响,因为必须串行化对数据字典的更新。而默认的本地管理表空间避免了这种性能问题。