当前位置: 代码迷 >> 综合 >> Oracle 19c Concepts(12):Logical Storage Structures
  详细解决方案

Oracle 19c Concepts(12):Logical Storage Structures

热度:75   发布时间:2024-01-06 06:13:11.0

逻辑存储结构简介

Oracle 数据库为数据库中的所有数据分配逻辑空间。

数据库空间分配的逻辑单元是数据块、 扩展区、 段、 和表空间。 而在物理级,数据被存储在磁盘上的数据文件中 。数据文件中的数据存储在操作系统块中。

下图是一个物理和逻辑存储的实体关系图。 乌鸦脚表示法表示一对多关系。

图 12-1 逻辑和物理存储


Description of "Figure 12-1 Logical and Physical Storage"

另见:

"Physical Storage Structures"

逻辑存储层次结构

段包含一个或多个区,每个区包含多个数据块

下图显示了在表空间中的数据块、 扩展区、 和段之间的关系。在此示例中, 一个段具有分别存储在不同数据文件中的两个扩展区。

图 12-2 表空间中的段、 扩展盘区、 和数据块


Description of "Figure 12-2 Segments, Extents, and Data Blocks Within a Tablespace"

从最低粒度到最高粒度,Oracle数据库存储数据

  • 数据块是Oracle数据库中最小的数据存储逻辑单元。

    一个逻辑数据块对应于特定字节数的物理磁盘空间,比如 2 KB。数据块是 Oracle 数据库可以使用或分配的最小存储单位。

  • 区是为存储特定类型的信息而分配的一组逻辑上相邻的数据块

    在上图中,这个 24 KB 的扩展区有 12 个数据块,而这个 72 KB 的扩展区有 36 个数据块。

  • 段是为特定数据库对象(如表)分配的一组区段。

    例如,employees 表的数据存储在其自己的数据段中,而该表的每个索引存储在其自己的索引段中。 会消耗存储空间的每个数据库对象都由单个段组成。

  • 表空间是一个包含一个或多个段的数据库存储单元。

    每个段属于且仅属于一个表空间。因此,一个段的所有扩展区存储在相同的表空间中。在一个表空间中, 一个段可以包括多个数据文件中的扩展区,如上图所示。例如, 段的一个扩展区可能存储在 users01.dbf 中,而另一个存储在 users02.dbf 中。 单个扩展区绝不会跨越多个数据文件。

另见:

"Overview of Data Files"

逻辑空间管理

Oracle 数据库必须使用逻辑空间管理来在表空间中跟踪并分配扩展区。

当数据库对象需要扩展区时,该数据库必须有查找和分配扩展区的方法。同样,当对象不再需要扩展区时,数据库必须提供一种方法来重用可用空间。

Oracle 数据库基于您创建的表空间的类型来管理其中的空间。您可以创建下列类型的表空间之一:

  • 本地管理表空间(默认值)

    数据库使用表空间本身中的位图来管理扩展区。 因此, 本地管理表空间需要预留表空间的一部分用于位图。 在一个表空间中, 数据库可以使用自动段空间管理 (ASSM) 或手动段空间管理 (MSSM) 来管理段 。

  • 字典管理表空间

    数据库使用数据字典来管理扩展区

图 12-3 显示了一个表空间中的逻辑空间管理方法的可选方案。

图 12-3 逻辑空间管理


Description of "Figure 12-3 Logical Space Management"

另见:

"Overview of the Data Dictionary"

本地管理表空间

本地管理表空间在数据文件头中维护一个位图,以跟踪数据文件体中的可用空间和已用空间。

每一位对应一组块。当空间被分配或释放时, Oracle 数据库更改位图值, 以反映数据块的新状态。

下面的图形是位图管理存储的概念表示。标头中的 1 是指已用空间,而 0 指可用空间。

图 12-4 位图管理存储


Description of "Figure 12-4 Bitmap-Managed Storage"

本地管理表空间具有如下优势:

  • 避免使用数据字典来管理扩展区

    如果消耗或释放一个扩展区会导致在数据字典表或撤消段中消耗或释放空间,则在字典管理的表空间中会发生递归操作。

  • 自动跟踪相邻的可用空间

    通过这种方式,数据库消除了合并空闲扩展区的需要。

  • 自动确定本地管理扩展区的大小

    或者, 在本地管理表空间中所有的扩展区可以具有相同的大小,并覆盖对象存储选项。

段空间管理是一个从包含该段的表空间继承来的属性。在一个本地管理表空间中, 数据库可以自动地或手动地管理段。 例如, users 表空间中的段使用自动管理,而 tools 表空间中的段使用手动管理。

自动段空间管理

自动段空间管理(ASSM)方法在表空间中使用位图管理空间。

位图提供了以下优点:

  • 简化管理

    ASSM 可以避免手动确定许多存储参数的正确设置的需要。只有一个很关键的控制空间分配的 SQL 参数: PCTFREE。此参数指定要为块 中保留用于将来的更新的空间百分比(请参阅"Percentage of Free Space in Data Blocks") 。
  • 增强并发性

    多个事务可以搜索多个相互独立的空闲数据块列表,从而减少争用和等待。 对很多标准工作负载,使用 ASSM 的应用程序性能比使用优化得很好的使用 MSSM 的应用程序性能更好。

  • 对 Oracle 真正应用集群 (Oracle RAC) 环境中实例的空间动态亲合性

ASSM 更有效,并且是永久性本地管理表空间的默认值。

手动段空间管理

旧式的手动段空间管理(MSSM)方法使用称为空闲列表的链表来管理段中的可用空间。

对一个具有可用空间的数据库对象, 有一个空闲列表会跟踪位于高水位线(HWM) 之下的数据块,所谓高水位, 即已使用段空间和未使用段空间之间的分界线。当块被使用时,数据库根据需要将块放入空闲列表,或将块从空闲列表中删除

除了 PCTFREE, MSSM 需要您使用额外的几个 SQL 参数(如 PCTUSED、FREELISTS、和 FREELIST GROUPS)来控制空间分配。 PCTUSED 设置在当前使用块中必须存在的可用空间百分比, 当使用率低于该百分比时,数据库会将其放入空闲列表中。例如, 如果 CREATE TABLE 语句中设置 PCTUSED 为 40,则只有当块空间使用少于 40%的情况下, 您才能往段中的块插入新行。

例如,假设向一个表中插入行。数据库检查该表的空闲列表,以查找第一个可用的块。如果行无法容纳进该块中,并在块中已使用空间大于或等于 PCTUSED,则数据库将该块从空闲列表中移除,并搜索另一个块。如果从块中删除行,则数据库检查块中的已使用空间现在是否小于 PCTUSED。如果是, 则数据库将该块置于空闲列表的开头。

一个对象可能有多个空闲列表。 通过这种方式,在表上执行 DML 的多个会话可以使用不同列表,以减少争用。每个数据库会话在其会话持续时间只使用一个空闲列表。

如图 12-5 所示,你也可以创建具有一个或多个空闲列表组的对象, 空闲列表组是空闲列表的集合。每个组有一个主空闲列表,用于管理组中的各个的处理空闲列表。 空闲列表、 尤其是空闲列表组的空间开销,可能非常显著。

图 12-5 空闲列表组


Description of "Figure 12-5 Free List Groups"

手动管理段空间可能会很复杂。您必须调整 PCTFREE 和 PCTUSED,以减少行迁移和避免空间浪费。 例如,如果段中的每个使用的块是半满,并且 PCTUSED 是 40, 则数据库不允许向这些块插入新行。由于微调空间分配参数很困难, Oracle 强烈建议使用 ASSM。在ASSM 中, 由 PCTFREE 确定是否可以将新行插入一个块中,但它不使用空闲列表,并忽略 PCTUSED。

另见:

  • "Chained and Migrated Rows"

  • 《Oracle Database Administrator’s Guide》了解本地管理表空间

  • 《Oracle Database Administrator’s Guide》了解自动段空间管理

  • 《Oracle Database SQL Language Reference》了解存储参数, 如 PCTFREE 和 PCTUSED

字典管理表空间

字典管理表空间使用数据字典来管理其扩展区。

每当分配或释放了一个扩展区时, Oracle 数据库更新数据字典中的表。 例如, 当表需要扩展区时,数据库查询数据字典表,并搜索空闲扩展区。如果数据库找到了空间,则修改一个数据字典表, 并插入一行。 按这种方式,数据库通过修改和移动数据来管理空间。

数据库在后台为数据库对象获取空间而执行的 SQL 是递归 SQL。频繁使用递归 SQL 可能会对性能有负面影响,因为必须串行化对数据字典的更新。而默认的本地管理表空间避免了这种性能问题。

另见:

《Oracle Database Administrator’s Guide》了解如何从字典管理表空间迁移到本地管理表空间

数据块概述

Oracle 数据库以数据块(也称为 Oracle 块或页) 为单位,来管理数据库数据文件中的逻辑存储空间。数据块是数据库 I/O 的最小单位。

数据块和操作系统块

在物理级别, 存储在磁盘文件中的数据库数据由操作系统块组成。

操作系统块是操作系统可以读取或写入的最小数据单位。 相比之下, Oracle 块是一个逻辑存储结构, 其大小和结构对操作系统是透明的。

下图显示操作系统块与数据块的大小可能有所不同。数据库按数据块(而不是按操作系统块) 的倍数来请求数据。

图 12-6 数据块和操作系统块


Description of "Figure 12-6 Data Blocks and Operating System Blocks"

当数据库请求一个数据块时,操作系统将此操作转换为对永久存储数据的多个请求。数据块与操作系统块的逻辑分离具有以下含义:

  • 应用程序不需要确定磁盘上的数据的物理地址。

  • 数据库数据可以在多个物理磁盘上进行条带化或镜像。

数据库块大小

每个数据库都有一个数据库块大小。

DB_BLOCK_SIZE 初始化参数在数据库被创建时设置其数据块大小。 此大小是 SYSTEM 和 SYSAUX 表空间的大小, 并且是其它表空间的默认大小。 不能更改数据库的块大小, 除非重新创建数据库。

如果尚未设置 DB_BLOCK_SIZE,则默认数据块大小特定于操作系统。 数据库的标准数据块大小为 4 KB 或 8 KB。如果数据块和操作系统块的大小不同, 则数据块大小必须是操作系统块大小的整数倍。

另见:

  • 《Oracle Database Reference》了解 DB_BLOCK_SIZE 初始化参数

  • 《Oracle Database Administrator’s Guide》《Oracle Database Performance Tuning Guide》了解如何选择块大小

表空间块大小

你可以创建其块大小不同于 DB_BLOCK_SIZE 设定值的表空间。

当你需要将一个可移动表空间移动到一个不同的平台时,非标准的块大小非常有用。

另见:

《Oracle Database Administrator’s Guide》了解如何为表空间指定非标准的块大小

数据块格式

每个数据块有一个格式或内部结构,使得数据库能够跟踪块中的数据和可用空间。 各种数据块的格式是类似的,无论其包含的是表、 索引、 或表簇数据。

下图显示了一个未压缩的数据块的格式

图 12-7 数据块格式


Description of "Figure 12-7 Data Block Format"

另见:

"Data Block Compression"了解压缩块

数据块开销

Oracle 数据库使用块开销来管理块本身。块开销不能用来存储用户数据。

如"Data Block Format"展示,块开销将包括以下部分:

  • 块头

    此部分包含关于块的一般信息,包括磁盘地址和段类型。对于事务管理块,其块头包含活动的和历史的事务信息。

    每个更新块的事务都需要一个事务条目。 Oracle 数据库预先在块头中为事务条目保留空间。 在分配给段用于支持事务性更改的数据块中,当块头空间耗尽时, 可用空间也可以容纳事务条目。 事务条目所需的的空间取决于操作系统。但是, 绝大多数操作系统中的事务条目需要大约 23 个字节。

  • 表目录

    对于堆组织表,此目录包含有关其行存储在该块中的表的元数据。多个表可以将行存储在相同的块中。

  • 行目录

    对于堆组织表, 此目录描述该块的数据部分中的行的位置。数据库可以在块底部的任何位置放置一行。行地址记录在行目录向量的一个槽中。

    rowid指向特定的文件、块和行号。例如,在rowid AAAPecAAFAAAABSAAA中,最后的 AAA 表示行号。行号是行目录中某个条目的索引。行目录条目包含指向数据块上该行位置的指针。如果数据库在一个块中移动一行,那么数据库将更新行目录条目来修改指针。rowid保持不变。

    当已在行目录中分配空间后, 即使在行被删除后, 数据库也不会回收此空间。因此, 就算某块现在是空的,但若之前曾经达到 50 行,则在行目录仍会保留已分配的 100 字节。仅在块中插入新行时,数据库才会重用此空间。

块开销的某些部分是大小固定的,但总的大小是可变的。 平均起来, 块开销总计在 84 到 107 字节左右。

行格式

块的行数据部分包含实际数据,如表行或索引键条目等。正如每个数据块具有一个内部的格式,每一行也有一个行格式,使得数据库能够跟踪行中的数据。

Oracle 数据库以可变长度记录形式来存储行。行包含在一个或多个行片断中。每个行片断有一个行头和列数据。

下图显示了行格式。

图 12-8 行片断格式


Description of "Figure 12-8 The Format of a Row Piece"
行头

Oracle 数据库使用行头来管理存储在块中的行片断。

行头包含以下信息:

  • 行片断中的各列

  • 位于其他数据块中的各个行片断

    如果整个行可以插入到一个数据块中, 则 Oracle 数据库将该行存储为一个行片断。但是,如果所有行数据不能插入一个单一的块,或者一个更新导致现有的行不能容纳在原来的块中,则数据库将该行存储为多个行片断。数据块中通常每行只包含一个行片断。

  • 表簇的簇键

包含在一个块中的完全行至少有 3 个字节的行头。

另见:

  • "Chained and Migrated Rows"

  • "Overview of Table Clusters"

列数据

在行头之后的列数据部分存储行中的实际数据。行片断通常按 CREATE TABLE 语句中列出的顺序来存储列,但这个顺序并不总是能保证的。 例如, LONG 类型列总是在最后。

如图"Row Format"所示,对行片断中的每一列, Oracle 数据库独立地存储列长度和列数据。所需的空间取决于数据类型。 如果列的数据类型是可变长度的,则用于容纳一个值所需的空间可能在其数据被更新时会增长和收缩。

每一行都在数据块标头的行目录中有一个槽位。 槽位指向行的开始部分。

另见:

"Table Storage""Index Storage"

Rowid 格式

Oracle 数据库使用一个 rowid 唯一地标识一行。 在内部, rowid 是一个结构, 用于保存数据库访问行所需要的信息。一个 rowid 并不物理地存储在数据库中, 而是从存储数据的文件和块推导而来的。

扩展的 rowid 包括数据对象号。这种 rowid 类型使用每个行的物理地址的 64 进位编码。编码的字符为 A-Z、 a-z、 0-9、 +、和/。

例 12-1 ROWID 伪列

如下示例查询 ROWID 伪列来显示 employees 表中雇员 100 的所在行的扩展 rowid。

SQL> SELECT ROWID FROM employees WHERE employee_id = 100;ROWID
------------------
AAAPecAAFAAAABSAAA

下图说明了一个扩展的 rowid 的格式。

Figure 12-9 ROWID Format


Description of "Figure 12-9 ROWID Format"

一个扩展 rowid 以一个四段式格式显示, OOOOOOFFFBBBBBBRRR, 此格式分为以下几个组件:

  • OOOOOO

    数据对象号标识段(如示例查询的数据对象 AAAPec)。 数据库中的每个段都被分配了一个数据对象号。同一段中的模式对象(如一个表簇) 具有相同的数据对象号。

  • FFF

    表空间相对数据文件号, 标识包含行的数据文件 (如示例查询的文件 AAF)。

  • BBBBBB

    数据块号标识包含行的块(如示例查询的块 AAAABS) 。块号是相对于他们的数据文件的,而不是其表空间。因此, 具有相同块号的两行,可以驻留在同一表空间的不同数据文件中。

  • RRR

    行号标识块中的行(示例查询的行 AAA)。

在一个 rowid 被分配给一个行片断后, 该 rowid 在特殊情况下可以更改。例如, 如果启用了行移动,则 rowid 可能会因为分区键更新、 闪回表操作、收缩表操作等而发生变化。如果禁用了行移动,则如果使用 Oracle 数据库实用程序导出和导入了行,其 rowid 可能会发生变化。

另见:

  • "Rowid Data Types"

  • 《Oracle Database SQL Language Reference》了解 rowid

数据块压缩

数据库可以使用表压缩来消除在数据块中的重复值。本节介绍使用压缩的数据块格式。

使用基本表压缩和 OLTP 表压缩的数据块,其格式与一个未压缩的块实质上是相同的。 区别是使用位于块开头的符号表来存储行和列的重复值。数据库使用一个到符号表的短引用来替换这些重复出现的值。

例 12-2 数据块压缩格式

假定下面的行存储在具有七个列的 sales 表的某个数据块中:

2190,13770,25-NOV-00,S,9999,23,161
2225,15720,28-NOV-00,S,9999,25,1450
34005,120760,29-NOV-00,P,9999,44,2376
9425,4750,29-NOV-00,I,9999,11,979
1675,46750,29-NOV-00,S,9999,19,1121
当在此表上应用基本或 OLTP 表压缩时,数据库会将重复值替换为一个符号引用。下面是是压缩的一个概念性展示,使用符号*替换了 29-NOV-00, 而使用%替换了 9999:
2190,13770,25-NOV-00,S,%,23,161
2225,15720,28-NOV-00,S,%,25,1450
34005,120760,*,P,%,44,2376
9425,4750,*,I,%,11,979
1675,46750,*,S,%,19,1121

表 12-1 从概念上展示了从符号映射到值的符号表。

表 12-1  符号表

Symbol Value Column Rows

*

29-NOV-00

3

958-960

%

9999

5

956-960

另见:

"Table Compression"

数据块的空间管理

随着数据库从底向上不断填充数据块, 在行数据和块头之间的可用空间就会逐渐减少。 

当将一个尾部空值更改为非空值时,在更新期间,数据块中的可用空间也会变少。数据库会管理数据块中的可用空间, 以优化性能并避免空间浪费。

数据块中的可用空间百分比

PCTFREE SQL参数对于数据库如何管理其可用空间非常重要。此 SQL 参数设置为更新现有的行而保留的可用空间最小百分比。因此, PCTFREE 对于防止行迁移并避免空间浪费非常重要。

例如,假设您创建了一个只是偶尔需要更新的表,其中大多数更新都不会增加现有数据的大小。 你可以在 CREATE TABLE 语句中指定 PCTFREE 参数,如下所示:

CREATE TABLE test_table (n NUMBER) PCTFREE 20;

图 12-10 显示了将 PCTFREE 设置为 20 是如何影响空间管理的。数据库不断将行添加到块, 这将导致行数据朝着块头方向向上不断增长,而块头本身又朝行数据方向向下不断扩大。 该 PCTFREE 设置确保至少 20%的数据块是空闲的。 例如, 数据库可以防止一个 INSERT 语句填充该块, 使行数据和标头一共占据块总空间的 90%, 而只剩 10%可用空间。

图 12-10 PCTFREE


Description of "Figure 12-10 PCTFREE"

另见:

  • "Overview of LOBs"

  • 《Oracle Database SQL Language Reference》关于 PCTFREE 参数的语法和语义

优化数据块中的可用空间

虽然可用空间的百分比不能小于 PCTFREE,但其可用空间量可以更大。例如,将PCTFREE设置为20%可以防止空闲空间总量下降到块的 5%,但是允许块的 50% 是空闲的。

通过增加自由空间进行优化

一些DML语句可以增加数据块中的空闲空间。

下列语句可以增加空间:

  • DELETE 语句

  • UPDATE 语句,要么将现有值更新为更小的值,或者增大现有值并被强制迁移到另一个行

  • 在使用了行压缩的表上的 INSERT 语句

    如果插入操作往块中填充了数据, 则数据库会调用块压缩,结果可能会导致在块中有更多的可用空间。

在下列条件下, 释放的空间可供 INSERT 语句使用:

  • 如果 INSERT 语句是位于释放空间的语句之后,且处于相同的事务中,则该语句可以使用已释放的空间。

  • 如果 INSERT 语句与释放空间的语句位于各自单独的事务中(也许是由另一个用户运行的),且空间允许,则该语句可以在需要此空间时使用它,但是只有在另一个事务提交之后。

另见:

《Oracle Database Administrator’s Guide》了解行压缩的优点

通过合并碎片空间进行优化

被释放的空间与数据块可用空间的主要区域可能是连续的。不连续的可用空间称为碎片空间。

下图显示具有非连续空闲空间的数据块。

图 12-11 具有碎片空间的数据块


Description of "Figure 12-11 Data Block with Fragmented Space"

只有在满足以下条件时, Oracle 数据库才会自动且透明地合并数据块中的可用空间:

  • INSERT 或 UPDATE 语句试图使用的块, 包含足够的可用空间来容纳新的行片断。

  • 可用空间已被碎片化, 以至于该行片断不能插入到块中的某一个连续区域。

合并后, 可用空间量与操作之前是相同的,只不过该空间现在已成为连续的。图 12-12 显示一个数据块的空间被合并了之后的情况。

图 12-12  数据块合并后的可用空间


Description of "Figure 12-12 Data Block After Coalescing Free Space"

Oracle 数据库仅在上述情况下执行合并, 否则会因为连续地合并数据块中的可用空间反而降低性能。

链接和迁移的行

Oracle 数据库必须管理太大而不能放入一个单一块的行。

可能存在下列情况:

  • 该行太大, 在它第一次插入时,无法放入一个数据块。

    在行链接中, Oracle 数据库将数据存储在为段保留的一个或多个被链接的数据块中。 行链接最经常出现在大行中。示例包括包含 LONG 或 LONG RAW 数据类型列的行、 或在 2 KB 块中的 VARCHAR2(4000) 列、 或具有大量列的行。在这些情况下链接行是不可避免的。

  • 本来可以放入一个数据块的行,在更新后整体行长增加了,但没有足够的可用空间来容纳更新的行。

    在行迁移中, 假设行可以容纳在一个新块中, Oracle 数据库将整个行移动到一个新的数据块。 已迁移行的原始行片断,包含一个指针或“转发地址”到包含已迁移行的新块。 已迁移行的 rowid 不会更改。

  • 超过 255 个列的行。

    Oracle 数据库在一个行片断中只能存储 255 的列。因此,如果你在具有 1000 个列的表中插入行,则数据库将创建 4 个行片断,通常会链接多个块。

图 12-13 描述了向数据块中插入大行的情形。行对于左边的块太大, 所以数据库通过将第一个行片断放入在左边的块, 将第二个行片断放入右边的块中,形成行链接。

图 12-13 行链接


Description of "Figure 12-13 Row Chaining"

在图 12-14 中, 左边的块包含的行被更新, 致使该行现在太大而不能放入块中。数据库将整个行移动到右边的块中, 并在左边的块中保留一个指向被迁移行的指针。

图 12-14 行迁移


Description of "Figure 12-14 Row Migration"

当行被链接或迁移时, 检索数据所需的 I/O 会增加。会导致这种情况是因为 Oracle 数据库必须扫描多个块以检索行信息。 例如, 如果数据库执行一个 I/O 读取索引和一个 I/O 读取一个未迁移的表行,则对于一个迁移行需要一个额外的 I/O 才能获得数据。

段顾问是一个 Oracle 数据库组件,可以手动或自动执行, 使用此工具可以标识有空间可回收的段。 这个顾问工具可以对具有很多可用空间的对象,或有太多行链接的对象,提供建议。

另见:

  • "Row Storage""Rowids of Row Pieces"

  • 《Oracle Database Administrator’s Guide》了解如何回收浪费的空间

  • 《Oracle Database Performance Tuning Guide》了解如何减少行链接和行迁移

索引块概述

索引块是一种特殊类型的数据块,它以不同于表块的方式管理空间。Oracle数据库使用索引块管理索引中的逻辑存储空间。

索引块类型

索引包含根块、分支块和叶块。

块类型定义如下:

  • 根块

    此块标识索引的入口点。

  • 分支块

    当搜索索引键时,数据库在分支块中导航。

  • 叶块

    这些块包含指向相关行的索引键值行id。叶块按顺序存储键值,以便数据库能够有效地搜索键值范围内的所有行。

索引项的存储

索引项存储在索引块中的方式与数据块中的表行相同,块部分中的索引项不是按二进制顺序存储的,而是堆中存储的。

数据库管理索引块中的行目录与数据块中的目录是不同的。行目录中的条目(而不是索引块主体中的条目)是按键值排序的。例如,在行目录中,索引键000000的目录条目在索引键111111的目录条目之前,以此类推。

行目录中条目的顺序提高了索引扫描的效率。在范围扫描中,数据库必须读取范围中指定的所有索引键。数据库遍历分支块,以标识包含第一个键的叶块。因为行目录中的条目是排序的,所以数据库可以使用二分查找查找范围内的第一个索引键,然后按顺序遍历行目录中的条目,直到找到最后一个键。这样,数据库就避免读取叶块体中的所有键。

另见:

"Data Block Overhead"

重用索引块中的槽

数据库可以重复使用一个索引块内的空间。

例如,应用往列中插入了一个值, 又将其删除。当一行需要空间时,数据库可以重用被删除值以前占用的索引槽。

索引块通常比堆组织的表块具有更多的行。在一个索引块中存储多行使数据库更容易维护索引,因为它避免了存储新数据时频繁的块分割。

索引本身不能合并,尽管您可以使用一个 ALTER INDEX 语句和 REBUILD 或 COALESCE 选项手动合并索引。例如,如果用值1到500,000填充列,然后删除包含偶数的行,那么索引将包含250,000个空槽。只有当数据库能够插入适合于包含空槽的索引块的数据时,才会重用槽。

合并索引块

索引合并压缩现有的索引数据,如果重新组织释放了块,则在索引结构中保留空闲块。因此,合并不会为其他用途释放索引块,也不会导致索引重新分配块。

Oracle 数据库不会自动压缩索引:需要使用 ALTER INDEX REBUILD 或 COALESCE 语句。

图 12-15 代表在 employees.department_id 列上的一个索引在其合并之前的情况。前面三个叶块只是部分填满的,如灰色填充线所示。

图 12-15 索引合并之前


Description of "Figure 12-15 Index Before Coalescing"

图 12-16 显示图 12-15 中的索引在合并后的情况。前两个叶块现在已充满,如灰色填充线所示, 而第三个叶块已被释放了。

图 12-16 索引合并后


Description of "Figure 12-16 Index After Coalescing"

另见:

  • 《Oracle Database Administrator’s Guide》了解如何合并和重新生成索引

  • 《Oracle Database SQL Language Reference》了解 COALESCE 语句

扩展区概述

扩展区是数据库存储空间分配的逻辑单位,由多个连续数据块组成。在一个扩展区中的数据块在逻辑上是连续的,但在物理上可能由于 RAID 条带化和文件系统的实施方式而在磁盘上分散分布。

分配扩展区

在默认情况下, 在数据段被创建时, 数据库会为数据段分配一个初始扩展区。 一个扩展区总是包含在一个数据文件中。

虽然还没有数据被添加到段中,在初始扩展区中的数据块被专门为段保留起来。每个段的第一个数据块包含该段中的扩展区目录。图 12-17 显示了一个数据文件中某个段中的初始扩展区,它之前还没有包含任何数据

图 12-17 段的初始扩展区


Description of "Figure 12-17 Initial Extent of a Segment"

如果初始扩展区满了,并需要更多空间时,则数据库自动为该段分配一个增量扩展区。一个增量扩展区是为该段创建的后续扩展区。

分配算法取决于表空间是本地管理的还是字典管理的。 对于本地管理表空间, 数据库搜索一个数据文件的位图,以查找相邻的可用数据块。如果该数据文件中没有足够的空间,则数据库到另一个数据文件中查找。一个段的扩展区始终位于同一表空间中,但可能在不同的数据文件中。

图 12-18 显示,数据库可能为一个段,在表空间中的任意数据文件中分配扩展区。 例如,段可能在 users01.dbf 中分配初始扩展区, 在 users02.dbf 中分配第一个增量扩展区, 并在 users01.dbf 中分配下一个扩展区。

图 12-18 段的增量扩展区


Description of "Figure 12-18 Incremental Extent of a Segment"

在新分配扩展区中的块, 虽然他们是可用的,但可能并未清空旧数据。在 ASSM 中,对新分配扩展区中的块,只有当 Oracle 数据库开始使用它们时,才会根据需要将其格式化

另见:

  • "Segment Space and the High Water Mark"

  • 《Oracle Database Administrator’s Guide》了解如何手动分配扩展区

释放扩展区

通常,用户段的扩展区不会返回给表空间,除非您使用 DROP 命令删除该对象。

例如, 如果你删除了表中的所有行,但数据库不会回收数据块以供表空间中的其他对象使用。也可以使用 DBMS_SPACE_ADMIN 软件包删除段。

在某些情况下,可以手动释放空间。 基于对象中的碎片级别, Oracle 数据段顾问工具可帮助确定一个对象是否有空间可回收。以下技术可以释放扩展区:

  • 你可以使用在线段收缩来回收在段中的零碎空间。段收缩是一种在线、 就地的操作。 通常, 紧凑的数据会获得更好的缓存利用率, 且在全表扫描中只需读取更少的块。

  • 将非分区表或表分区的数据移动到一个新的段,或可选地移入另一个你在其中具有配额的表空间。

  • 您可以重建或合并索引。

  • 您可以截断表或表簇, 这将删除所有行。默认情况下, 除了留下由 MINEXTENTS 存储参数所指定的扩展区数之外, Oracle 数据库将释放已删除行所使用的所有空间。 在数据库 11g 第 2 版 (11.2.0.2)中, 您还可以用带有 DROP ALL STORAGE 选项的 TRUNCATE 语句来删除整个段。

  • 您可以释放未使用的空间, 即释放数据库段的高水位端的未使用空间, 以便供表空间中的其他段使用。

当扩展区被释放时, Oracle 数据库将修改本地管理表空间的数据文件中的位图, 以反映重新获得作为可用空间的扩展区。 被释放扩展区的数据块中的任何数据变得不可访问。

另见:

  • "Coalescing an Index Block"

  • "Undo Tablespaces"

  • "Segment Space and the High Water Mark"

  • 《Oracle Database Administrator’s Guide》了解如何回收段空间

扩展区的存储参数

每一个段是由扩展区表示的存储参数来定义的。这些参数控制 Oracle 数据库如何为段分配可用空间。

存储设置按如下的优先级顺序确定, 列表中较高的设置会覆盖较低的设置:

  1. 段存储子句

  2. 表空间存储子句

  3. Oracle 数据库缺省值

本地管理表空间可以具有统一的扩展区大小, 或由系统自动确定可变的扩展区大小:

  • 对统一的扩展区,可以指定扩展区的大小,或使用默认的大小 1 MB。 表空间中的所有扩展区都是一样大小。本地管理的临时表空间只能使用这种分配类型。

  • 对于自动分配的扩展区由 Oracle 数据库确定新分配扩展区的最佳大小。

对本地管理表空间, 其某些存储参数不能在表空间级指定。但是,您可以在段级指定这些参数。在这种情况下,数据库使用所有参数一起计算段的初始大小。 由内部算法确定每个后续扩展区的大小。

另见:

  • 《Oracle Database Administrator’s Guide》了解当创建本地管理表空间时的扩展区管理注意事项

  • 《Oracle Database SQL Language Reference》了解存储子句中的选项

段概述

段是一个表空间内包含某个逻辑存储结构的所有数据的扩展区集合。

例如,Oracle 数据库分配一个或多个扩展区,形成一个表的数据段。数据库还分配了一个或多个扩展区, 形成一个表的索引段。

Oracle 数据库可以自动或手动地管理段空间。本节假定使用 ASSM 。

另见:

"Logical Space Management"了解更多关于 ASSM

用户段

在数据库中的单个数据段用于存储一个用户对象的数据。

段有不同的类型。用户段的示例包括:

  • 表、 表分区、 或表簇

  • 大对象或大对象分区

  • 索引或索引分区

每个未分区对象和对象分区存储在其自己的段中。 例如,如果索引有五个分区,则有五个段包含该索引的数据。

创建用户段

默认情况下,数据库使用延迟的段创建, 当创建表、索引和分区时,仅更新数据库元数据。

在用户向表或分区中插入第一行时,数据库才创建表或分区、 及其 LOB 列、 和索引段等。延迟的段创建使您能够避免不必要地使用数据库资源。 例如, 某个应用程序在安装过程中可能会创建成千上万个占用大量磁盘空间的对象。许多这些对象可能从未使用。

可以使用 DBMS_SPACE_ADMIN 包管理空对象的段。你可以使用该 PL/SQL 包执行下列操作:

  • 为没有创建段的空表或分区手动实例化段

  • 从空表或当前分配了空段的分区中删除段

为了更好地说明对象创建和段创建之间的关系, 假设延迟段创建已被禁用。你创建一个表,如下所示:

CREATE TABLE test_table (my_column NUMBER);

如图 12-19 所示, 数据库为该表创建一个段。

图 12-19 创建用户段


Description of "Figure 12-19 Creation of a User Segment"

当创建具有主键或唯一键的表时, Oracle 数据库将自动为此键创建一个索引。再假设延迟的段创建被禁用。 你创建一个表,如下所示:

CREATE TABLE lob_table (my_column NUMBER PRIMARY KEY, clob_column CLOB);
图 12-20 显示 lob_table 表的数据存储在一个段中, 而隐式创建的索引在另一个不同的段中。此外, CLOB 数据及其关联的 CLOB 索引也分别存储在其自己的段中。因此, 这个 CREATE TABLE 语句会创建四个不同的段。

图 12-20 多个网段


Description of "Figure 12-20 Multiple Segments"

当创建一个段时,数据库将分配一个或多个扩展区。由对象的存储参数确定每个段的扩展区如何分配。这些参数影响数据检索的效率, 和与该对象关联的数据段的存储。

另见:

  • "Internal LOBs"

  • "Storage Parameters for Extents"

  • 《Oracle Database Administrator’s Guide》了解如何管理延迟段创建

  • 《Oracle Database SQL Language Reference》关于 CREATE TABLE 的语法

临时段

当处理查询时, Oracle 数据库通常在 SQL 语句执行的中间阶段需要临时工作区。

可能需要临时段的典型操作包括排序、哈希、和合并位图。当创建索引时,Oracle 数据库将索引段置于临时段,然后当索引创建完成时将其转换成永久段。

如果一个操作可以在内存中执行,则 Oracle 数据库不会创建一个临时段。不过,如果不能使用内存, 则数据库自动在磁盘上为其分配临时段。

为查询分配临时段

Oracle 数据库在用户会话期间, 根据需要为查询分配临时段,并在查询完成后将其删除。 除了会记录在临时段上的空间管理操作, 临时段的更改不会记录在联机redo日志中。

数据库在分配给用户的临时表空间中创建临时段。表空间的默认存储特性决定了临时段中的扩展区特征。由于分配和释放临时段会频繁发生,最佳做法就是为临时段创建至少一个特别的表空间。数据库将 I/O 分布到多个磁盘,并避免在 SYSTEM 和其他表空间使用临时段,以防碎片化。

另见:

  • "Overview of the Online Redo Log"
  • 《Oracle Database Administrator's Guide》了解如何创建临时表空间

  • 《Oracle Database SQL Language Reference》关于 CREATE TEMPORARY TABLESPACE 的语法和语义

为临时表及其索引分配临时段

Oracle 数据库也可以为临时表及其索引分配临时段。

临时表仅保存一个事务或会话的持续期间的数据。每个会话只能访问分配给该会话的扩展区, 而不能访问分配给其他会话扩展区。

Oracle 数据库在第一次插入表时,会为临时表分配段。 插入操作可能会显式发生, 或者在运行 CREATE TABLE AS SELECT 时发生。 在向一个临时表第一次插入数据时,会为表及其索引分配临时段、 为索引创建根页、 并分配 LOB 段。

临时表的段在当前用户的临时表空间中分配。假定为 user1 指派的临时表空间是 temp1, 分配给 user2 的临时表空间是 temp2。在这种情况下, user1 将临时数据存储在 temp1 内的段中, 而 user2 将其临时数据存储在 temp2内的段中。

另见:

  • "Overview of Temporary Tables"

  • 《Oracle Database Administrator’s Guide》了解如何创建临时表

Undo 段

Oracle 数据库维护事务的操作记录, 统称为 undo 数据。

Oracle 数据库使用 undo 来执行下列操作:

  • 回滚一个活动事务

  • 恢复一个已终止的事务

  • 提供读取一致性

  • 执行一些逻辑闪回操作

Oracle 数据库将撤消数据存储在数据库内,而不是在外部日志中。 存储撤消数据的块与数据块类似,对这些块的更改将生成 redo 数据。 通过这种方式, Oracle 数据库可以高效地访问撤消数据, 而无需读取外部日志。

永久对象的 undo 数据存储在一个 undo 表空间中。Oracle 数据库提供了一个称为自动 undo 管理模式的完全自动化机制,来管理 undo 表空间中的 undo 段和空间。

数据库将 undo 数据分成两个流。临时 undo 流只封装由对临时对象的更改生成的 undo 记录,而永久撤消流只封装永久对象的 undo 记录。数据库独立地管理临时和永久 undo。撤销分离通过以下操作减少存储并提高性能:

  • 使您能够配置最适合永久表和临时表的工作负载的永久表空间大小和 undo 表空间大小

  • 减少写入在线 redo 日志的redo的大小

  • 避免备份临时 undo 数据

在活动数据保护实例中,全局临时表上的DML需要在临时 undo 段中生成 undo。

另见:

  • "Use of the Online Redo Log"

  • "Temporary Undo Segments"

  • 《Oracle Database Administrator’s Guide》了解临时 undo 段

  • 《Oracle Database Reference》了解TEMP_UNDO_ENABLED初始化参数

Undo 段和事务

当事务启动时,数据库将此事务绑定到(分配给)一个撤消段,并因此也绑定到当前撤消表空间中的一个事务表。在极少数的情况下,如果数据库实例没有一个指定的撤消表空间,则该事务被绑定到系统撤消段。

多个活动事务可以同时写入同一个撤消段或不同的撤消段。 例如,事务 T1 和 T2 可以同时写入撤消段 U1,或 T1 写入 U1 而 T2 写入 U2。

从概念上讲,一个撤消段中的扩展区形成一个环。 事务先写到一个撤消扩展区,然后写到环中的下一个扩展区,如此等等, 循环往复。图 12-21 显示两个事务 T1 和 T2, 从一个撤消段的第三个扩展区开始写入,然后继续往第四个扩展区 (E4) 写入。

图 12-21 Undo 段中的扩展区分配环


Description of "Figure 12-21 Ring of Allocated Extents in an Undo Segment "

在任何给定时间,一个事务仅在一个撤消段上的某个扩展区上顺序写入,该扩展区称为事务的当前扩展区。多个活动事务可以同时写入同一个当前扩展区或不同的当前扩展区。图 12-21 显示事务 T1 和 T2 同时写入扩展区E3。在一个撤消扩展区内某个数据块仅包含一个事务的数据。

当前撤消扩展区被填充后, 第一个需要空间的事务将检查环中分配的下一个扩展区的可用性。如果下一个扩展区不包含活动事务数据, 则该扩展区将成为当前扩展区。现在,需要空间的所有事务都可以写入新的当前扩展区内。在图 12-22 中, 当 E4 填满时, T1 和 T2 继续写入 E1,覆盖在 E1 中的非活动撤消数据。

图 12-22 Undo 段中已分配扩展区的周期性使用


Description of "Figure 12-22 Cyclical Use of Allocated Extents in an Undo Segment"

如果下一个扩展区确实包含某个活动事务的数据, 则数据库必须分配一个新的扩展区。图 12-23 显示 T1 和 T2 同时写入 E4 的场景。 当 E4 填满时, 这两个事务无法继续写入 E1,因为 E1 包含活动的撤消条目。因此,数据库为该 undo 段分配新的扩展区 (E5)。 事务继续写入 E5。

图 12-23 为 Undo 段分配新的扩展区


Description of "Figure 12-23 Allocation of a New Extent for an Undo Segment"

另见:

《Oracle Database Administrator’s Guide》了解如何管理 undo 段

事务回滚

当发出了一个 ROLLBACK 语句时, 数据库将使用撤消记录, 来回滚未提交事务对数据库所做的更改。

在恢复期间, 数据库将回滚从联机redo日志应用到数据文件的任何未提交更改。 当数据正在被其它用户更改时, 撤消记录通过维护数据前像, 为在同一时间访问数据的用户提供读取一致性。

临时 Undo 段

临时 undo 段是只用于临时 undo 数据的可选空间管理容器。

对临时表的更改的 undo 记录是特定于会话的,并且仅对读取一致性和事务回滚有用。在Oracle Database 12c之前,数据库总是将这些记录存储在联机redo日志中。由于对临时对象的更改没有记录在在线redo日志中,因此将临时对象的 undo 写入临时 undo 段可以节省在线redo日志和存档redo日志文件中的空间。数据库不记录对undo 的更改或对临时表的更改,这会提高性能。

您可以设置 TEMP_UNDO_ENABLED 初始化参数,以便临时表将 undo 数据存储在临时 undo 段中。当该参数为 TRUE 时,数据库从临时表空间分配临时 undo 段。

另见:

  • 《Oracle Database Administrator’s Guide》了解临时 undo 段

  • 《Oracle Database Reference》要了解 TEMP_UNDO_ENABLED 初始化参数

段空间和高水位标记

Oracle 数据库通过跟踪段中的块状态来管理空间。 高水位标记 (HWM) 是段中的一个点,超过该点的数据块是未格式化和未使用过的。

MSSM 使用空闲列表来管理段空间。在创建表时, 段中的块并未被格式化。当一个会话初次向表中插入行时,数据库将搜索空闲列表来查找可用的块。如果数据库未找到可用的块,则它会预格式化一组块,并将它们放置在空闲列表中,并开始将数据插入到块中。在 MSSM 中,全表扫描会读取 HWM之下的所有块。

ASSM 不使用空闲列表,所以必须以不同的方式管理空间。当会话初次向表中插入数据时,数据库只格式化一个单一位图块,而不像在 MSSM 中那样预格式化一组块。位图取代了空闲列表,用于跟踪在段中的块的状态。数据库使用位图来查找可用的块,然后在往块写入数据之前将其格式化。 ASSM 将插入操作分散到多个块, 以避免并发问题。

在一个 ASSM 段中的每个数据块处于以下状态之一:

  • 在 HWM 之上

    这些块是未格式化的, 且从未使用过。

  • 在 HWM 之下

    这些块处于以下状态之一:

    • 已分配, 但当前未格式化且未使用

    • 已格式化且包含数据

    • 已格式化且为空,因为数据已被删除

图 12-24 将一个 ASSM 段描述为一系列水平的块。在创建表时, HWM 在左侧段的开头。因为还未插入数据, 段中的所有块都还是未格式化且从未使用过。

图 12-24 在创建表时的 HWM


Description of "Figure 12-24 HWM at Table Creation"

假设一个事务将行插入到段中。数据库必须分配一组块来容纳这些行。 已分配的块在 HWM 之下。数据库格式化该组中的一个位图块来容纳元数据,但不会预格式化组中其余的块。

在图 12-25 中, HWM 之下的块是已分配的,而 HWM 之上的块是既未分配也未格式化的。插入发生时,数据库可以写入到任何具有可用空间的块。 由低位高水位标记 (低 HWM) 标记一个点,该点之下的所有块都已知是已格式化的, 要么包含数据, 或以前曾包含数据。

图 12-25 HWM 和低 HWM


Description of "Figure 12-25 HWM and Low HWM"

在图 12-26 中,数据库选定了 HWM 和低 HWM 之间的一个块,并往其中写入数据。 数据库也可能会随意选择 HWM 和低 HWM 之间的任何其他块, 或低 HWM 之下任何有可用空间的块。 图 12-25 中,在新填充块两边的块都还是未格式化的。

图 12-26 HWM 和低 HWM


Description of "Figure 12-26 HWM and Low HWM"

低 HWM 在全表扫描中非常重要。因为 HWM 之下的块只在被使用时才格式化, 所以可能还有一些块是未被格式化的, 如图 12-26 所示。 鉴于此, 数据库读取位图块,以获取低 HWM 的位置。数据库读取低 HWM 之下的所有块,因为已知它们是已格式化的,然后仅仔细读取位于低 HWM 和 HWM 之间的已格式化块。

假定一个新事务将行插入到该表,但位图指示在 HWM 之下没有足够的可用空间。在图 12-27 中, 数据库向右推进 HWM, 分配一组新的未格式化块。

图 12-27 推进 HWM 和低 HWM


Description of "Figure 12-27 Advancing HWM and Low HWM"

当 HWM 与低 HWM 之间的块填满时, HWM 向右推进,而低 HWM 相应推进到旧的 HWM 的位置。数据库不断插入数据,随着时间的推移, HWM 继续向右推进,而低 HWM 总尾随其后。除非您手动重建、 截断、 或缩小该对象, 否则 HWM 从不倒退。

另见:

  • 《Oracle Database Administrator’s Guide》了解如何在线收缩段

  • 《Oracle Database SQL Language Reference》关于 TRUNCATE TABLE 的语法和语义

表空间概述

表空间是段的逻辑存储容器。段是占用存储空间的数据库对象, 如表和索引。在物理级别, 表空间将数据存储在一个或多个数据文件或临时文件中。

数据库必须有 SYSTEM 和 SYSAUX 表空间。下图显示了一个典型的数据库中的表空间。以下各节描述表空间类型。

图 12-28 表空间


Description of "Figure 12-28 Tablespaces"
永久表空间

永久表空间对持久性模式对象进行分组。表空间中的对象的段物理上存储在数据文件中。

每个数据库用户被分配了一个默认的永久表空间。 一个非常小的数据库可能只需要默认的 SYSTEM 和 SYSAUX 表空间。 Oracle 建议您创建至少一个表空间来存储用户和应用程序数据。可以使用表空间实现以下目标:

  • 控制数据库数据的磁盘空间分配

  • 为数据库用户分配配额 (空间限额或限制)

  • 将单个表空间联机或脱机,而不影响整个数据库的可用性

  • 执行单个表空间的备份和恢复

  • 使用 Oracle 数据泵实用程序导入或导出应用程序数据

  • 通过创建一个可传输表空间,可以将其从一个数据库复制或移动到另一个数据库,甚至跨平台

    通过传输表空间来移动数据,可能比导出/导入或卸载/装载相同的数据要快几个数量级,因为传输表空间只涉及复制数据文件并集成表空间元数据。当您传输表空间时,还可以移动索引数据。

另见:

  • "Oracle Data Pump Export and Import"

  • 《Oracle Database Administrator’s Guide》了解如何传输表空间

  • 《Oracle Database Utilities》了解 Oracle 数据泵

SYSTEM 表空间

SYSTEM 表空间是在数据库被创建时就包括的一个必要的管理性表空间。Oracle 数据库使用 SYSTEM 来管理数据库。

SYSTEM 表空间包括以下信息,全部都由 SYS 用户所拥有:

  • 数据字典

  • 包含数据库管理信息的表和视图

  • 已编译的存储对象,如触发器、 过程、 和包等

SYSTEM 表空间的管理与其他表空间几乎一样,但需要较高的特权, 且在某些方面有所限制。 例如,您不能重命名或删除 SYSTEM 表空间。

默认情况下, Oracle 数据库将所有新创建的用户表空间设置为本地管理表空间。在 SYSTEM 为本地管理表空间的数据库中,不能创建字典管理表空间 (这已经过时)。但是,如果手动执行 CREATE DATABASE 语句并接受默认值,则 SYSTEM 表空间是字典管理的。您可以将一个现有字典管理SYSTEM 表空间迁移到本地管理格式。

另见:

  • "Online and Offline Tablespaces"有关 SYSTEM 表空间永久在线状态的信息

  • "Tools for Database Installation and Configuration"了解 DBCA

  • 《Oracle Database Administrator’s Guide》了解如何创建或迁移到本地管理的SYSTEM 表空间

  • 《Oracle Database SQL Language Reference》有关 CREATE DATABASE 的语法和语义

SYSAUX 表空间

SYSAUX 表空间是 SYSTEM 表空间的一个辅助表空间。 

因为 SYSAUX 是许多 Oracle 数据库特性和产品的默认表空间,这些特性和产品以前都需要自己的表空间,SYSAUX 减少了数据库所需的表空间数量。它还减少了系统表空间的负载。

SYSAUX 表空间在数据库创建或升级过程中自动创建。在正常的数据库操作中,数据库不允许删除或重命名 SYSAUX 表空间。如果 SYSAUX 表空间变得不可用, 则数据库的核心功能仍是可用的。使用 SYSAUX 表空间的数据库特性可能会失败,或只能发挥有限功能。

另见:

《Oracle Database Administrator’s Guide》了解 SYSAUX 表空间

Undo 表空间

undo 表空间是为系统管理的 undo 数据而保留的一个本地管理表空间。

与其他永久表空间类似,undo 表空间也包含数据文件。在这些文件中的 undo 块被分组为一些扩展区。

另见:

"Undo Segments"

自动 Undo 管理模式

Undo 表空间要求数据库处于默认的自动 undo 管理模式。

自动模式消除了手动管理 undo 段的复杂性。数据库自动对其进行优化,提供 undo 数据最佳可能的保留期,以满足可能需要此数据的长时间查询。

新安装的 Oracle 数据库会自动创建一个撤消表空间。早期版本的 Oracle 数据库可能不包含撤消表空间, 而是使用在手动撤消管理模式下的传统的回滚段。在升级到 Oracle 数据库 11 g 以上版本时。可以启用自动撤消管理模式,并创建一个撤消表空间。Oracle 数据库包含一个撤消顾问,可提供有助于你自动化您的撤消环境的建议。

数据库可以包含多个撤消表空间,但一次只能使用其中的某一个。当实例尝试打开数据库时, Oracle 数据库将自动选择第一个可用的撤消表空间。 若没有撤消表空间可用,则实例以不带撤消表空间的方式启动,并将撤消数据存储在 SYSTEM 表空间中。建议不要在 SYSTEM 表空间中存储撤消数据。

另见:

  • 《Oracle Database Administrator’s Guide》了解自动 undo 管理

  • 《Oracle Database Upgrade Guide》了解如何迁移到自动撤消管理模式

自动 Undo 保留

撤消保留期是 Oracle 数据库在覆盖旧的撤消数据之前尝试对其保留的最小时间量。

撤消保留很重要, 因为长时间运行的查询可能需要旧数据块前像以提供读取一致性。此外,某些 Oracle 闪回功能也可能会依赖于撤消数据的可用性。

通常,应该尽可能保留旧的撤消数据。事务提交后,撤消数据对于回滚或恢复事务不再是必需的。 如果撤消表空间还有足够空间用于新事务, 数据库可能会保留旧的撤消数据。 当可用空间偏低时, 数据库开始覆盖已提交事务的旧撤消数据。

Oracle 数据库自动为当前的撤消表空间提供最佳可能的撤消保留。数据库会收集使用情况统计信息,并基于这些统计信息和撤消表空间大小来调整保留期。如果撤消表空间配置了 AUTOEXTEND 选项, 而且也未指定最大大小,则撤消保留调整会有所不同。在这种情况下, 如果空间允许, 数据库将撤消保留期调整为比最长运行的查询稍长。

另见:

《Oracle Database Administrator’s Guide》有关自动调整的撤消保留的更多详细信息

shadow 表空间

shadow 表空间是一个大文件表空间,用于 shadow 丢失的写保护。

shadow 表空间的用途

shadow 丢失写保护提供快速检测和立即响应丢失的写。

当I/O子系统确认块写已经完成时(即使没有发生写操作)或当块的前映像覆盖了当前映像时,数据块丢失的写操作就会发生。

未检测到的写丢失可能导致数据损坏,因为不正确的数据可以用于其他DML事务。例如,事务可以从一个表读取旧的和不正确的数据,然后根据这些数据更新数百个其他表。这样,数据损坏就会蔓延到整个数据库。

shadow 丢失写保护提供以下好处:

  • 它在标准DML、SQL*Loader常规路径加载、直接路径加载和RMAN备份使用之前检测丢失的写。

  • 不需要备用数据库,如Oracle数据库11g中引入的写丢失保护。

  • 您可以为特定的表空间和数据文件启用 shadow 丢失写保护。您不需要跟踪所有数据。

  • 您可以用另一个 shadow 表空间替换一个 shadow 表空间,以更改其配置或位置。

  • 可以挂起并恢复表空间或数据文件的 shadow 丢失写保护。

  • 您可以使用 ALTER DATABASE ... LOST WRITE TRACKING 语句为整个非cdb或PDB启用或禁用它。注意,PROP$表指示是否为PDB启用跟踪。

另见:

《Oracle Database SQL Language Reference》要了解更多关于丢失写入跟踪子句的信息

shadow 表空间如何工作

丢失写保护需要两个表空间:一个 shadow 表空间和一个非 shadow 表空间,shadow 表空间的块由 shadow 表空间跟踪。

下图提供了一个示例场景。表空间 TBS1 和 TBS2 中的数据文件由 shadow 表空间跟踪。只有表空间 TBS3 中的数据文件 DBF6 被 shadow 表空间跟踪。


Description of the illustration cncpt390.eps

一个跟踪数据文件映射到 shadow 表空间中的一个 shadow 区。跟踪数据文件中的每个数据块在 shadow 块中都有对应的条目。这个条目包含被跟踪数据块的SCN。当从磁盘读取被跟踪的数据块时,shadow 丢失写保护将 shadow 表空间中该块的SCN与被跟踪数据块中最近一次写入的SCN进行比较。如果 shadow 条目的 SCN 大于正在读取的数据块,则会发生写操作丢失,从而提示错误。

shadow 区的大小具有显著的额外空间,以防止自动调整数据文件的大小导致 shadow 区过大。如果手动或自动调整跟踪数据文件的大小,并且需要增加 shadow 区,那么数据库将尝试调整跟踪数据的大小。如果 shadow 表空间中没有足够的空间,那么数据库将向警报日志写入警告,并跟踪尽可能多的数据块。

另见:

《Oracle Database Administrator’s Guide》学习如何管理影子丢失写保护

shadow 表空间的用户接口

使用 ALTER DATABASE 命令启用和禁用 shadow 丢失写保护。

为了保护特定的表空间或数据文件,必须满足以下条件:

  • 您必须使用 ALTER DATABASE ENABLE LOST WRITE PROTECTION 语句为整个非cdb或PDB启用了影子丢失写保护。

  • 必须使用 ENABLE LOST WRITE PROTECTION 子句启用表空间或数据文件的 shadow 丢失写保护。

    当启用表空间的 shadow 丢失写保护时,表空间的所有数据文件都受到保护,添加到表空间的任何数据文件也受到保护。注意,不能在临时表空间或另一个丢失的写表空间上启用丢失的写保护。

  • 必须使用带 LOST WRITE PROTECTION 子句的 CREATE BIGFILE TABLESPACE 语句创建一个或多个 shadow 表空间。

Oracle 数据库自动将跟踪到的数据文件分配给特定的 shadow 表空间。您不能指定哪个 shadow 表空间用于特定的数据文件。

下面的数据字典视图监控 shadow 表空间:

  • DBA_TABLESPACES

    通过查询显示哪些表空间是影子表空间。

  • DBA_DATA_FILES.LOST_WRITE_PROTECT

    显示是否为数据文件启用了丢失的写保护

  • USER_TABLESPACES.LOST_WRITE_PROTECT

    显示是否为特定表空间打开了丢失的写保护。DBA_DATA_FILES 不指示是否打开了表空间的写操作:您必须查看 USER_TABLESPACES。

另见:

  • "Data Corruption"

  • 《Oracle Database Administrator’s Guide》学习如何管理 shadow 表空间

  • 《Oracle Database SQL Language Reference》要了解CREATE TABLESPACE语句

  • 《Oracle Database Reference》了解 DBA_TABLESPACES

例:配置丢失写保护

这个例子支持一组表空间的 shadow 丢失写跟踪。

在本例中,您的目标是在非cdb中保护 salestb 和 hrtbs 表空间。您还需要保护oetbs01.dbf 数据文件,并且只有这个数据文件位于oetbs表空间中。你要做的是:

  1. 用 SYSTEM 登录数据库。

  2. 创建一个 shadow 表空间如下:

    CREATE BIGFILE TABLESPACE shadow_lwp1 DATAFILE 'shadow_lwp1_df' SIZE 10M LOST WRITE PROTECTION;
    
  3. 为整个数据库启用丢失的写保护,如下:

    ALTER DATABASE ENABLE LOST WRITE PROTECTION;
  4. 为 salestb 和 hrtbs 表空间启用影子丢失写保护,如下所示:

    ALTER TABLESPACE salestbs ENABLE LOST WRITE PROTECTION;
    ALTER TABLESPACE hrtbs ENABLE LOST WRITE PROTECTION;
  5. 为 oetbs01.dbf 数据文件启用 shadow 丢失写保护,如下所示:

    ALTER DATABASE DATAFILE 'oetbs01.dbf' ENABLE LOST WRITE PROTECTION;

另见:

  • 《Oracle Database Administrator’s Guide》学习如何管理 shadow 表空间

  • 《Oracle Database SQL Language Reference》要了解 CREATE TABLESPACE 语句

临时表空间

临时表空间仅包含在会话期间存在的瞬态数据。永久模式对象不能驻留在临时表空间中。临时文件存储临时表空间数据。

临时表空间可以提高不适合在内存中进行的多个排序操作的并发性。这些表空间也提高了在排序过程中空间管理的效率。

共享和本地临时表空间

临时表空间要么是共享的,要么是本地的。

共享临时表空间将临时文件存储在共享磁盘上,以便所有数据库实例都可以访问临时空间。相反,本地临时表空间为每个数据库实例存储单独的、非共享的临时文件。本地临时表空间对于Oracle实际应用程序集群或Oracle Flex集群非常有用。

您可以为只读和读/写数据库实例创建本地临时表空间。当许多只读实例访问单个数据库时,本地临时表空间可以提高涉及排序、散列聚合和连接的查询的性能。优点是:

  • 通过使用本地磁盘存储而不是共享磁盘存储来改进I/O性能

  • 避免昂贵的跨实例临时空间管理

  • 通过消除磁盘空间元数据管理来提高实例启动性能

下表比较了共享表空间和本地临时表空间的特征。

表 12-2 共享和本地临时表空间

共享临时表空间 本地临时表空间
CREATE TEMPORARY TABLESPACE 语句创建 CREATE LOCAL TEMPORARY TABLESPACE 语句创建
为数据库创建单独的临时表空间。 为每个数据库实例创建单独的临时表空间。FOR LEAF选项仅为只读实例创建表空间。FOR ALL选项为所有实例创建表空间,包括只读和读/写。
支持表空间组。 不支持表空间组。
在控制文件中存储临时文件元数据。 在SGA中存储与控制文件中的所有实例通用的临时文件元数据,以及特定于实例的元数据(例如,用于分配的位图、当前临时文件大小和文件状态)。

另见:

"Introduction to the Oracle Database Instance"

默认临时表空间

每个数据库用户帐户都分配一个默认的共享临时表空间。如果数据库包含本地临时表空间,则还为每个用户帐户分配默认的本地临时存储。

可以使用 CREATE USER 或 ALTER USER 语句为用户帐户指定不同的临时表空间。对于没有指定不同临时表空间的用户,Oracle数据库使用系统级默认临时表空间。

另见:

《Oracle Database SQL Language Reference》要了解更多关于CREATE USER语句的信息

创建默认临时表空间

创建数据库时,默认的临时存储取决于 SYSTEM 表空间是否是本地管理。

下表显示了Oracle数据库在创建数据库时如何选择默认的临时表空间。

表 12-3 创建默认临时表空间

SYSTEM 表空间是本地管理的吗? CREATE DATABASE语句是否指定了默认的临时表空间? 然后数据库…
使用指定的表空间作为默认值。
创建临时表空间。
使用指定的表空间作为默认值。
使用 SYSTEM 作为默认临时存储。数据库在告警日志中写入警告,建议使用默认的临时表空间。

创建数据库之后,可以使用 ALTER DATABASE DEFAULT TEMPORARY TABLESPACE 语句更改数据库的默认临时表空间。

另见:

  • "Permanent and Temporary Data Files"

  • 《Oracle Database Administrator's Guide》了解如何创建默认临时表空间

  • 《Oracle Database SQL Language Reference》用于 CREATE DATABASE 和 ALTER DATABASE 的 DEFAULT TEMPORARY TABLESPACE 子句的语法

访问临时存储

如果用户分配了一个临时表空间,那么数据库首先访问它;否则,数据库将访问默认的临时表空间。在数据库为查询访问临时表空间之后,它不会切换到其他表空间。

用户查询可以访问共享存储或本地临时存储。此外,用户可以为只读实例分配一个默认的本地临时表空间,为读/写实例分配另一个默认的本地临时表空间。

对于读/写实例,数据库给予共享临时表空间更高的优先级。对于只读实例,数据库给予本地临时表空间更高的优先级。如果数据库实例是读/写的,则数据库按以下顺序搜索空间:

  1. 是否为用户分配了共享临时表空间?

  2. 是否为用户分配了本地临时表空间?

  3. 数据库默认临时表空间有空间吗?

如果前面任何问题的答案是yes,那么数据库将停止搜索并从指定的表空间分配空间;否则,将从数据库默认的本地临时表空间分配空间。

如果数据库实例是只读的,则数据库按以下顺序搜索空间:

  1. 是否为用户分配了本地临时表空间?

  2. 指定的数据库默认本地临时表空间是否有空间?

  3. 是否为用户分配了共享临时表空间?

如果前面任何问题的答案是yes,那么数据库将停止搜索并从指定的表空间分配空间;否则,将从数据库默认共享临时表空间分配空间。

表空间模式

由表空间模式确定表空间的可访问性。

读/写和只读表空间

每个表空间都处于某种写入模式,以指定是否可以对其进行写入操作。

互斥模式如下:

  • 读/写模式

    用户可以读取和写入表空间。所有表空间最初都被创建为可读/写的。 SYSTEM、SYSAUX 表空间、和临时表空间总是可读/写的,也就是不能将它们置为只读。

  • 只读模式

    对表空间中数据文件的写操作被禁止。只读表空间可以驻留在只读介质上,如 DVD 或 WORM 驱动器。

    只读表空间消除了对数据库中大型的静态部分执行备份和恢复的需要。只读表空间不会变更,因此不需要重复的备份。如果在介质故障后恢复一个数据库, 则不需要恢复只读表空间。

另见:

  • 《Oracle Database Administrator’s Guide》了解如何将表空间更改为只读或读/写模式

  • 《Oracle Database SQL Language Reference》关于 ALTER TABLESPACE 的语法和语义

  • 《Oracle Database Backup and Recovery User’s Guide》关于恢复的详细信息

联机和脱机表空间

当数据库处于打开状态时, 表空间可以处于联机状态 (可访问) 或脱机状态 (不能访问)。

表空间通常是联机的,以便其数据可供用户使用。SYSTEM 表空间和临时表空间不能脱机。

表空间可以自动或手动脱机。 例如,您可以将表空间脱机,以进行维护或备份与恢复。数据库在遇到某些错误时会自动将一个表空间脱机,比如数据库写进程 (DBWn)多次试图写入数据文件但遭遇失败时。当用户试图访问一个脱机表空间中的表时, 将收到一个错误。

当一个表空间进入脱机状态时,数据库执行以下任务:

  • 数据库不允许后续 DML 语句引用脱机表空间中的对象。脱机的表空间无法被除 Oracle 数据库之外的任何其它实用程序读取或编辑。

  • 活动事务中的某些已完成的语句,曾引用了脱机表空间中的数据,这些事务在事务级别不受影响。

  • 数据库将那些已完成语句相应的撤消数据, 保存在 SYSTEM 表空间中的延迟撤消段中。 当表空间被联机时, 数据库在必要时将撤消数据应用到该表空间。

另见:

  • "Online and Offline Data Files"

  • "Database Writer Process (DBW)"

  • 《Oracle Database Administrator’s Guide》了解如何更改表空间的可用性

表空间文件大小

表空间可以是一个大文件表空间或小文件表空间。这些表空间的区别在于 SQL 语句的执行是否需要显式引用数据文件或临时文件。 

区别如下:

  • 小文件表空间可以包含多个数据文件或临时文件,但其文件不能像大文件表空间中的文件那么大。这是默认的表空间类型。

  • 大文件表空间仅包含一个非常大的数据文件或临时文件。这种类型的表空间可以:

    • 提高数据库的存储容量

      数据库中的数据文件的最大数量有限,所以增加每个数据文件的大小也就增加了总的存储量。

    • 减轻管理过多数据文件和临时文件的负担

      大文件表空间使用 Oracle 管理的文件和自动存储管理 (Oracle ASM),通过消除添加新文件和处理多个文件的需要, 简化了文件管理。

    • 在表空间上(而不是在单个文件上) 执行操作

      大文件表空间将表空间作为磁盘空间管理、 备份和恢复等的主要单位。

    大文件表空间只支持使用 ASSM 的本地管理表空间。然而,本地管理的撤消和临时表空间, 即便在手动段管理模式下,仍然可以是大文件表空间。

另见:

  • "Backup and Recovery"

  • 《Oracle Database Administrator’s Guide》了解如何管理大文件表空间        

  相关解决方案