作者: 何致億, 美商甲骨文公司台湾分公司特约顾问
上一期我为大家介绍了Oracle9i服务器架构,并探讨Oracle9i 执行个体之组成要素与其运作原理,本期将把重点放在Oracle9i数据库实体结构。
Oracle9i数据库结构
谈及Oracle数据库结构时,我们应该从两个角度来探讨:分别是数据库的「逻辑层面」与「实体组成」。简单的说,「逻辑层面」是由”数据库内部”观看其组成要素,包括:资料表空间(tablespaces)、区段(segments)、延伸区块(extents)、资料区块(data block)、以及纲要对象(Schema objects)(注[1])。而「实体组成」则是从”操作系统”角度来看 Oracle9i 数据库的实体构成项目,包括:数据文件(Data files)、重置日志文件(redo log files)、控制文件(control files)、密码文件(password)、起始参数档(initialization parameter files)…等等。如果您有心成为一个顶尖的 Oracle DBA,那么不仅要对以上各项如数家珍般熟悉,还要了解其内部运作与相互关系才行。首先我们就先从「逻辑层面」探访Oracle9i数据库!
数据库之逻辑组成
无论是任何规模的企业,在管理数据库系统时,DBA都应该依据实际系统需求或是未来可能的管理方式,规划出一个或多个资料储存区域。重点是希望将资料分门别类地妥善存放。譬如,您可能会希望将公司内会计系统的帐务资料与产品销售纪录分开存放。
Oracle9i数据库允许DBA自行规划各种用途的资料表空间(Tablespace),以便存放不同型态的资料与数据库对象。举例来说,存放Oracle系统信息的「资料辞典」(data dictionary)可放在 SYSTEM 资料表空间;应用系统资料可存放在 USER 资料表空间;而所有数据表的索引(Index)则可单独存放在INDX 数据表空间内(注[2])。
一般来说,Oracle9i数据库至少应规划出五个以上的资料表空间,如下图一所示:
图一:Oracle9i数据库之资料表空间。
那么,先从资料的最小储存单位 — 「资料区块」谈起。
何谓「资料区块」?
许多初次接触数据库的读者最好奇的一点是:” 资料究竟是如何存放在数据库呢?”。其实,Oracle9i 数据库有几种资料储存体,其中最小的储存单元就称为「数据区块」(data block)。资料区块大小是由起始参数档的 DB_BLOCK_SIZE 参数所决定,且在新建Oracle9i数据库之前就必须明确地定义。实际上,资料区块大小与”操作系统的磁盘读写区块”(O.S. blocks)也有关系,所以您必须将 DB_BLOCK_SIZE 设定为 O.S. blocks的整数倍。附带一提:Oracle9i在存取资料时是以data block为最小读取单位,而不是以OS block为单位。
从 Oracle9i 开始,数据库内可以设定多种资料区块大小。换句话说,Oracle9i数据库内分为「标准资料区块」与「非标准资料区块」;预设情况下 SYSTEM 资料表空间就是以「标准资料区块」建立而成。
何谓「延伸区块」?
除了资料区块之外,Oracle9i数据库还有所谓的「延伸区块」(extents)。虽然资料区块是Oracle9i最小的资料读写单位,但值得注意的是:Oracle9i 在”配置”储存空间时,并不是以资料区块为单位,而是改采「延伸区块」的方式来配置空间。那么,使用「延伸区块」究竟有何好处呢?当您执行DDL指令建立数据库对象时(例如CREATE TABLE 指令),Oracle9i会先配置出一连串的资料区块;直到这些资料区块全部存满资料后,下次再配置一连串的资料区块。这些连续的资料区块就统称为「延伸区块」。
举例来说,假定您准备在Oracle9i数据库内存放80 KB的资料,Oracle9i可以先配置一个「延伸区块」,其大小可为资料区块(8 KB)的5倍;然后视实际需要再配置第二个「延伸区块」(大小还是40 KB)。如此一来,只要两次的空间配置动作就可以存放80 KB的资料了!试想,如果Oracle9i每次只配置8 KB的「资料区块」让您存放资料,总共需要10次空间配置动作才能放满80 KB的资料,是不是比较没有效率呢?由此可见,「延伸区块」的确有其存在的必要性。
何谓「区段」?
依照不同的数据处理性质,您可能需要在资料表空间内划分出不同区域,以存放不同资料;我们将这些区域称之为「区段」(segment)。例如,存放数据的称为「数据区段」、存放数据的称为「索引区段」。而「区段」其实就是由许多「延伸区块」组合而成。除了上述两种「区段」以外,Oracle9i数据库内还有另外两种区段结构,分别是:「暂时性区段」(temporary segment)与「退回区段」(rollback segment)。下图二说明了Oracle9i数据库内各逻辑组成要件之间的阶层关系:
图二:Tablespace、Segment、Extent、Block之间的关系。
所以,从Oracle9i数据库的「逻辑层面」来看,我们知道:
n 资料是存放在每个「资料区块」内,资料读写动作也将以「资料区块」为单位。
n 空间配置的动作则是引用「延伸区块」的概念。一个「延伸区块」由一连串的「资料区块」所构成。
n 依实际资料量多寡,资料(或数据库对象)由多个「延伸区块」所组成。
n 「资料表空间」内可划分不同的「区段」;而每个「区段」内又包含许多「延伸区块」。
n 在每个Oracle9i数据库内可规划不同的「资料表空间」,用以存放不同型态的资料。
截至目前为止,无论是资料区块、延伸区块、区段、甚至数据表空间,都只是逻辑上的数据储存概念。实际上,Oracle9i数据库是藉由数个操作系统内实体档案来维系数据库系统之正常运作。接下来我们将从操作系统角度来探讨Oracle9i的实体组成要素。
数据库之实体组成
还记得上一期文章中我们曾经综览Oracle9i 服务器基本架构吗?如果从操作系统的观点来看,Oracle9i 数据库的实体组成要素就是操作系统内各式档案,最重要的有:数据文件、重置日志文件、控制文件、起始参数档…等。下图三描述了Oracle9i 数据库的基本架构。
图三:Oracle9i 数据库基本架构。
数据文件
每个 Oracle9i 数据库都包含为数不等的实体「数据文件」。数据库内所有逻辑数据库对象都是存放在数据文件内,如:数据表、索引….等。
一但数据文件被建立后,系统就会在磁盘上配置出适当空间给数据文件;但尚未存放任何使用者资料。等到未来使用者将资料存入数据库时,Oracle9i 才会在数据文件内配置出「数据区段」,以存放数据。而这些动作都是由 Oracle9i 自动完成的。
当然了,如果数据文件剩余空间不足,您就必须调整数据文件大小;或增加新的数据文件。所以在 Oracle9i 数据库内,一个数据库对象有可能横跨多个数据文件 (数据文件相关的管理与维护动作将在未来专栏内容中详细探讨) 。
如前所述,Oracle9i 数据库内可规划一个以上的「资料表空间」。但如果由操作系统角度来看,「资料表空间」其实是由一个或数个实体「数据文件」所组成。换句话说,数据库的所有资料就是位于操作系统的各「数据文件」内。
所以:
n 一个「数据文件」只能对应的一个「资料表空间」。
n 一个「资料表空间」可包含多个「数据文件」。
如下图四所示:SYSTEM 「资料表空间」对应到操作系统的 system01.ora 「数据文件」(注[3]);USER 「资料表空间」则是包含 user01.ora 与 user02.ora 两个「数据文件」。
图四:资料表空间与数据文件之对应。
重置日志文件
除了「数据文件」外,最重要的Oracle9i数据库实体档案就是「重置日志文件」(redo log files),也就是大家俗称的「交易日志」(transaction log)。虽然它与「数据文件」不同,但是彼此间却有密不可分的关系!简单的说,Oracle9i 重置日志文件会负责纪录数据库内任何数据处理情况(注[4])。当资料被异动时,所有异动纪录会先保留在内存的重置纪录缓冲区,并在适当时机由LGWR背景处理程序负责写入至硬盘上重置日志文件(注[5])。如此一来,所有资料异动情况都会完整地保留下来。万一您的 Oracle9i 数据库不小心当机或是遭遇毁损,Oracle9i 将凭借重置日志文件内相关纪录将资料复原至最完整的状态—这个动作我们又称为『Roll Forward』。
重置日志文件的配置方式
请注意,Oracle9i数据库正常运作的先决条件是至少配置两个(组)重置日志文件!
假定目前Oracle9i数据库拥有两个重置日志文件,分别是redo01.ora与redo02.ora。因为重置日志文件是以循环方式使用,所以当redo01.ora写满后就会轮到redo02.ora — 这个动作称为「日志切换」(log switch)。理论上,当redo02.ora写满后应该会立刻从redo01.ora重新开始写入动作。但实际上并非如此 — Oracle9i 会等到redo01.ora内纪录的资料异动情况真正反应在数据文件之后(记得我们曾经提过的CKPT处理程序吗?),才会覆写redo01.ora的资料。在一个大型线上交易(OLTP)系统下,如果资料交易量十分频繁,建议您不妨配置五个以上重置日志文件。以免Oracle9i进行「日志切换」时