文章翻译源于 Oracle Database Database Concepts, 18c

本章介绍 Oracle 数据库实例的原理,实例的参数文件和诊断文件,以及实例创建和数据库的打开与关闭的过程。

本章包含以下内容:

  • 数据库实例介绍
  • 实例启动与关闭
  • 检查点
  • 实例恢复
  • 参数文件
  • 诊断文件

数据库实例介绍

数据库实例(instance)是一组用于管理数据库文件的内存结构。

数据库是一组位于磁盘上的物理文件,通过 CREATE DATABASE 语句创建。实例管理相关的数据,并且为数据库用户提供服务。

每个正在运行的 Oracle 数据库至少与一个实例相关联。因为实例存在于内存中,而数据库存在磁盘上,所以实例可以独立于数据库存在,数据库也可以独立于实例存在。

实例结构

当一个实例启动时,Oracle 数据库分配一个称为系统全局区(SGA)的内存区域,并启动一个或多个后台进程。

SGA 的作用包括:

  • 维护多个进程和线程并发访问的内部数据结构
  • 缓存从磁盘读取的数据块
  • 在写入在线重做日志文件之前缓冲重做数据
  • 存储 SQL 执行计划

同一个服务器上的 Oracle 进程之间共享 SGA。Oracle 进程与 SGA 的交互方式取决于操作系统。

一个数据库实例包括多个后台进程(background process)。服务器进程(server process),以及分配给它们的内存,也位于实例之中。实例在服务器进程结束后仍然继续存在。

下图显示了 Oracle 数据库实例中的主要组件。
Database Instance
图 13- 1 数据库实例

实例配置

Oracle 数据库支持单实例配置和真正应用集群(Oracle RAC)配置。这两种配置只能二选其一。

在单实例配置中,数据库和实例之间一一对应。在 Oracle RAC 中,数据库和实例存在一对多的关系。

下图显示了两种可能的数据库实例配置。
Database Instance Configurations
图 13-2 数据库实例配置

无论是单实例还是 Oracle RAC 配置,一个实例每次只能与一个数据库关联。管理员可以启动一个实例,然后加载(关联)一个数据库,但是不能同时加载两个数据库。

注意:除非特别指出,本章讨论单实例数据库配置。

一台服务器上可以同时运行多个实例,每个实例管理各自的数据库。例如,某台服务器上拥有两个不同的数据库:prod1 和 prod2。一个实例管理 prod1另一个实例管理 prod2。

读写实例与只读实例

实例支持两种模式:读写实例与只读实例。

对于读写实例,可以处理 DML 操作,支持客户端的直接连接请求。这是默认方式。与此相反,只读实例能够运行查询,但是不能支持 DML修改操作(UPDATE、DELETE、INSERT 以及 MERGE),也不能从客户端直接进行连接。

注意:除非另外指明,本文档中的实例都是指读写实例。

在之前的版本中,所有的实例(除非管理一个 standby 数据库)都是读写实例。从 Oracle 数据库 12c (12.2) 开始, 一个数据库可以同时存在只读实例和读写实例。这种配置对于即查询数据又修改数据库的并行 SQL 语句非常有用,因为读写实例和只读实例都能够查询数据,而读写实例能够修改数据。

与读写实例相比,只读实例具有以下特点:

  • 只能打开一个已经被读写实例打开的数据库
  • 禁用了许多不必要的后台进程,包检查点进程和归档进程
  • 可以加载一个被禁用的重做线程或者没有任何在线重做日期的线程

要想将实例设置为只读模式,可以将初始化参数 INSTANCE_MODE 设置为 READ_ONLY。该参数的默认值为 READ_WRITE。

实例生命周期

数据库实例从 STARTUP 命令创建开始,直到被终止时结束。

在此期间,一个实例能且只能与一个数据库相关联。进一步而言,该实例只能加载数据库一次、打开数据库一次,并且关闭数据库一次。在数据库关闭之后,必须重新启动一个实例,然后加载并打开数据库。

下表演示了一个实例尝试重新打开之前关闭的数据库的过程。

表 13- 1 实例生命周期

语句注释
SQL> STARTUP
ORACLE instance started.
Total System Global Area 468729856 bytes
Fixed Size 1333556 bytes
Variable Size 440403660 bytes
Database Buffers 16777216 bytes
Redo Buffers 10215424 bytes
Database mounted.
Database opened.
STARTUP 命令创建一个实例,然后加载并打开数据库。
SQL> SELECT
TO_CHAR(STARTUP_TIME,‘MON-DD-RR HH24:MI:SS’)
AS “Inst Start Time” FROM V$INSTANCE;

Inst Start Time
------------------
JUN-18-14 13:14:48
该查询显示了当前实例的启动时间。
SQL> SHUTDOWN IMMEDIATE关闭数据库和实例,结束实例的生命周期。
SQL> STARTUP
Oracle instance started… . .
STARTUP 命令创建一个新的实例,然后加载并打开数据库。
SQL> SELECT
TO_CHAR(STARTUP_TIME,‘MON-DD-RR HH24:MI:SS’)
AS “Inst Start Time” FROM V$INSTANCE;

Inst Start Time
------------------
JUN-18-14 13:16:40
该查询显示了当前实例的启动时间。不同的启动时间表明了这是一个新的实例。

实例标识

一个主机上可以运行多个数据库实例。因此,访问时需要指定访问哪个实例。

Oracle 最优灵活体系结构(OFA)规则是一组配置指南,可以确保组织良好的 Oracle 软件安装。本节中的示例使用 OFA 体系结构。

本节包含以下主题:

  • Oracle 根目录
  • Oracle 主目录
  • Oracle 系统标识符(SID)
Oracle 根目录

Oracle 根目录(Oracle Base directory)存储 Oracle 产品的二进制文件。

Oracle 根目录是 Oracle 数据库安装拥有者的数据库主目录。一个主机上可以按照多个 Oracle 数据库,以及多个 Oracle 数据库软件安装的拥有者。

以下示例显示了操作系统用户 oracle 的 Oracle 根目录:

/u01/app/oracle

在路径的前缀中, /u01/ 是存储的挂载点, /u01/app/ 是安装应用软件的分支目录。

Oracle 主目录

Oracle 主目录(Oracle home directory)是 Oracle 数据库软件的安装位置。

每个新的 Oracle 数据库软件安装都需要指定一个新的 Oracle 主目录。默认情况下,Oracle 主目录是 Oracle 根目录(ORACLE_BASE)下的一个子目录。

在同一个主机上,相同的 Oracle 根目录下,可以安装不同版本的数据库软件。归属于不同系统用户的不同版本的多个数据库可以并存。

以下示例显示了三个不同的 Oracle 主目录的完整路径名称,它们都位于相同的 Oracle 根目录(/u01/app/oracle/)下:

/u01/app/oracle/product/12.1.0/dbhome_1
/u01/app/oracle/product/12.1.0/dbhome_2
/u01/app/oracle/product/18.0.0/dbhome_1

路径名称中, Oracle 根目录(/u01/app/oracle/)之后的部分包含了产品版本编号(例如 12.1.0)和 Oracle 主目录的相对路径(例如 dbhome_1)目录 /u01/app/oracle/product/12.1.0/ 中包含了两个不同的 Oracle 主目录: dbhome_1 和 dbhome_2。

从 Oracle Database 18c 开始,支持创建只读的 Oracle 主目录,将其作为一个软件的映像。只读 Oracle 主目录存储静态文件,例如二进制程序。Oracle 根主目录(ORACLE_BASE_HOME)位于 ORACLE_BASE/homes/home_name,存储与特定 Oracle 主目录相关的动态文件。Oracle 根配置目录(ORACLE_BASE_CONFIG)由 Oracle 根目录中的所有 Oracle 主目录共享,用于存储实例相关的动态文件。

以下示例中,第一个路径是一个只读 Oracle 主目录,第二个路径是其对应的 根主目录:

/u01/app/oracle/product/18.0.0/ro_dbhome_1
/u01/app/oracle/homes/ro_dbhome_1
Oracle SID

系统标识符(SID) 是一个主机上的 Oracle 数据库实例的唯一名称。

在 UNIX 和 Linux 系统上,Oracle 数据库使用 SID 和 Oracle 主目录的路径名称作为共享内存的键值。 另外,Oracle 数据库默认使用 SID 查找初始化参数文件,通过初始化文件查找其他相关文件,例如数据库控制文件。

在大多数平台上,使用 ORACLE_SID 环境变量设置 SID,使用 ORACLE_HOME 变量设置 Oracle 主目录。客户端连接数据库实例时,可以在 Oracle Net 连接中指定 SID,或者使用一个网络服务名(service name)。 Oracle 数据库将服务名转换为 ORACLE_HOME 和 ORACLE_SID。

传统的可读写 Oracle 主目录包含了实例相关的文件。但是,如果 Oracle 主目录改为只读,实例相关的文件单独存储在 Oracle 根目录中。无论哪种情况,名称中包含 SID 的文件存储在 Oracle 主配置目录(ORACLE_BASE_CONFIG)的 dbs 子目录中。有了这种文件分离,用户可以使用只读 Oracle 主目录中的软件创建数据库,然后使用另一个只读 Oracle 主目录中的软件启动一个实例,管理该数据库。

实例启动与关闭

数据库实例(database instance)为用户提供数据库访问。实例和数据库存在各种不同的状态。

启动实例与数据库

通常来说,管理员手动启动一个实例,然后加载并打开数据库,接受客户端连接。这些操作可以通过 SQL*Plus 的 STARTUP 命令、 Oracle 企业管理器(Enterprise Manager)或者 SRVCTL 工具完成。

如果使用 Oracle Net 启动一个数据库实例,需要满足以下条件:

  • 数据库通过静态方式注册到 Oracle Net 监听器中。
  • 使用 SYSDBA 权限进行连接。

监听器启动一个专用的服务器进程,用于启动数据库实例。

下图显示了数据库从关闭到打开的处理过程。
Instance and Database Startup Sequence
图 13-3 实例与数据库启动顺序

数据库从关闭状态到打开状态需要经历以下几个阶段。

表 13-2 实例启动阶段

阶段加载状态描述更多内容
1启动实例,未加载数据库启动一个实例,但没有与数据库关联。启动实例
2加载数据库实例已经启动,并且读取数据库的控制文件。数据库对用户不可用。加载数据库
3打开数据库实例已经启动,并且打开数据库。授权用户可以访问数据文件中的数据。打开数据库
管理员登录

数据库的启动和关闭是非常强大的管理功能,只能由具有管理员权限的用户执行。

普通用户无法控制数据库的当前状态。根据操作系统的不同,用户可以通过以下方式获得管理员权限

  • 用户的操作系统权限允许他/她已管理员权限连接到数据库。
  • 用户被授予特殊的系统权限,数据库使用口令文件认证通过网络连接的管理员

以下特殊的系统权限能够在数据库未打开时访问实例:

  • SYSDBA
  • SYSOPER
  • SYSBACKUP
  • SYSDG
  • SYSKM

以上权限的管理不在数据库的自身范围之内。使用 SYSDBA 系统权限连接时,用户位于 SYS 模式中。使用 SYSOPER 连接时,用户位于公共模式中。SYSOPER 权限是 SYSDBA 权限的一个子集。

启动实例

当 Oracle 数据库启动一个实例时,需要经过几个阶段。

实例启动阶段包括:

  1. 查找不同平台下默认位置中的服务器参数文件,如果没有找到该文件,查找文本形式的初始化参数文件(在 STARTUP 命令中指定 SPFILE 或 PFILE 参数将会覆盖默认行为)
  2. 读取参数文件,获取初始化参数的值
  3. 基于初始化参数设置分配 SGA
  4. 启动 Oracle 后台进程
  5. 打开告警日志(alert log)文件和跟踪文件(trace file),按照参数设置的语法在告警日志中写入所有显式指定的参数设置

在这一阶段,实例还没有关联到数据库。NOMOUNT 状态的使用场景包括数据库创建以及备份与恢复操作。

加载数据库

实例通过加载数据库与其进行关联。

加载数据库时,实例通过初始化参数 CONTROL_FILES 获取数据库控制文件 的名称并打开这些文件。Oracle 数据库读取控制文件,获取数据文件和在线重做日志文件的名称,在打开数据库时需要访问这些文件。

加载之后,数据库处于关闭状态,只允许管理员访问。管理员可以在保持数据库关闭的同时执行一些特定的维护操作。但是,此时数据库还不能执行一些常规操作。

如果 Oracle 数据库允许多个实例同时加载相同的数据库,初始化参数 CLUSTER_DATABASE 可以设置多个实例访问该数据库。具体的行为取决于该参数的值:

  • 如果第一个加载数据库的实例的 CLUSTER_DATABASE 设置为 false(默认值),只有该实例能够加载数据库。
  • 如果第一个加载数据库的实例的 CLUSTER_DATABASE 设置为 true,其他实例在 CLUSTER_DATABASE 也设置为 true 时可以加载该数据库。可以同时加载同一个数据库的实例数量由创建数据库时的预定义值决定。
打开数据库

打开一个已加载的数据库意味着可以对其执行常规的操作。

任何有效的用户都可以连接到一个打开的数据库,并且访问其中的信息。通常来说,数据库管理员负责打开数据库。

打开数据库时, Oracle 数据库将会执行以下操作:

  • 打开撤销表空间(undo tablespace)之外的其他表空间的在线数据文件

    如果一个表空间在数据库关闭之前处于离线(offline)状态,重新打开数据库时,该表空间和相应的数据文件仍然处于离线状态。

  • 获取一个撤销表空间

    如果存在多个撤销表空间,由初始化参数 UNDO_TABLESPACE 决定使用哪个表空间。如果没有设置该参数,使用第一个可用的撤销表空间。

  • 打开在线重做日志文件

只读模式

默认情况下,数据库以读/写模式打开。在这种模式下,用户可以修改数据,产生重做日志项。另外,数据库可以以只读模式打开,防止用户事务修改数据。

注意:默认情况下,物理备用数据库以只读模式打开。

只读模式下的数据库只能执行只读事务,不能写入数据文件或者在线重做日志文件。不过,数据库仍然能够执行恢复操作或者不产生重做日志的操作。例如,只读模式支持以下操作:

  • 将数据文件离线或者在线。但是,不能将永久表空间离线。
  • 恢复离线的数据文件和表空间。
  • 修改控制文件中关于数据库状态的信息。
  • 使用 CREATE TEMPORARY TABLESPACE 语句创建的临时表空间允许读写操作。
  • 写入操作系统的审计文件、跟踪文件以及告警日志。
数据库文件检查

如果打开数据库时,任何数据文件或重做日志文件不存在,或者它们存在但是一致性检测失败,数据库将会返回一个错误。此时需要执行介质恢复。

关闭数据库与实例

通常来说,管理员在执行维护操作或其他管理任务时手动关闭数据库。可以使用 SQL*Plus 的 SHUTDOWN 命令或者 Enterprise Manager 执行这些操作。

下图演示了数据库从打开状态到一致性关闭的过程。
Instance and Database Shutdown Sequence
图 13-4 实例与数据库关闭顺序

Oracle 数据库从打开到一致性关闭时自动执行以下操作。
表 13-3 一致性关闭的步骤

阶段加载状态描述更多内容
1关闭数据库数据库处于加载状态,但是在线数据文件和重做日志文件被关闭。关闭数据库
2卸载数据库实例处于启动状态,但是不再关联数据库的控制文件。卸载数据库
3关闭实例实例被关闭,不再处于启动状态。关闭实例

Oracle 数据库在出现实例失败或者执行 SHUTDOWN ABORT (立即终止实例)命令时,不会执行以上操作。

关闭模式

具有 SYSDBA 或者 SYSOPER 权限的数据库管理员可以使用 SQL*Plus 的 SHUTDOWN 命令或 Enterprise Manager 关闭数据库。SHUTDOWN 命令包含了不同的关闭选项。

下表总结了不同的关闭模式。
表 13-4 数据库关闭模式

数据库行为ABORTIMMEDIATETRANSACTIONALNORMAL
运行新用户连接
等待当前会话结束
等待当前事务结束
执行检查点并关闭打开的文件

不同的 SHUTDOWN 语句包括:

  • SHUTDOWN ABORT

    这种关闭模式用于紧急情况,例如其他模式无法关闭实例时。这种模式速度最快。但是,随后再打开数据库时需要更长的时间,因此需要执行实例恢复以确保数据文件的一致性。

    由于 SHUTDOWN ABORT 命令不对打开的数据文件执行检查点操作,重新打开数据库时必须执行实例恢复。其他的关闭模式在重新打开数据库时不需要执行实例的恢复。

    注意:在 CDB 中,针对 PDB 执行的 SHUTDOWN ABORT 命令等价于非 CDB 上的 SHUTDOWN IMMEDIATE 命令。

  • SHUTDOWN IMMEDIATE

    这种关闭模式是除了 SHUTDOWN ABORT 之外的最快方式。Oracle 数据库立即终止任何正在执行的 SQL 语句并且断开用户的连接。系统终止所有正在进行的事务,并且回滚未提交的更改。

  • SHUTDOWN TRANSACTIONAL

这种关闭模式不允许用户开始新的事务,但会等待所有当前正在执行的事务结束,然后关闭数据库。这种模式可能需要等待很长的时间才能完成。

  • SHUTDOWN NORMAL

这是默认的关闭模式。数据库在关闭之前等待所有连接的用户断开连接。

关闭数据库

关闭数据库的操作分为正常关闭和异常关闭。

正常关闭

当数据库使用非 ABORT 模式关闭时,会将 SGA 中的数据写入数据文件和在线重做日志文件。

然后,数据库关闭在线数据文件和重做日志文件。离线表空间中的离线数据文件已经处于关闭状态。当数据库重新打开时,原来的离线表空间仍然处于离线状态。

此时,数据库已经关闭,不接受正常访问。但是控制文件仍然处于打开状态。

异常关闭

如果使用 SHUTDOWN ABORT 命令关闭数据库或者数据库异常终止时,实例瞬间停止并关闭数据库。

异常关闭时,Oracle 数据库不会将 SGA 缓存中的数据写入数据文件和重做日志文件。随后重新打开数据库时需要执行实例恢复,Oracle 自动执行实例的恢复操作。

卸载数据库

在关闭数据库之后,Oracle 将会卸载数据库,将其与实例分离。

卸载数据库之后,Oracle 关闭数据库的控制文件。此时,实例仍然存在于内存之中。

关闭实例

关闭数据库的最后一步就是关闭实例。关闭实例时,系统释放 SGA 内存,并停止后台进程。

在异常情况下,实例可能没有关闭干净。内存中仍然存在一些内存结构,或者某个后台进程仍未终止。如果之前的实例仍然部分存在,后续的实例可能会启动失败。此时,可以通过删除之前实例的残余并重新启动一个新实例,或者使用 SHUTDOWN ABORT 语句关闭之前的实例,强制启动一个新的实例。

某些情况下,进程的清除可能会遇到错误,导致进程监控进程(PMON)或者实例的终止。动态初始化参数 INSTANCE_ABORT_DELAY_TIME 用于指定发生内部实例失败时延迟关闭的时间(秒)。延迟时间之内,管理员可以介入处理。当发生延迟的实例终止时,数据库在告警日志中写入一条消息。某些情况下,通过允许隔离某些数据库资源,可以避免实例被终止。

检查点

检查点(checkpoint)对于一致性数据库关闭、实例恢复以及常规数据库操作都至关重要。

检查点操作具有以下含义:

  • 检查点位置(checkpoint position),它表示重做日志流中的系统更改号(SCN),实例恢复必须从该检查点位置开始

    检查点位置由数据库缓冲区高速缓存中最早的脏块决定。检查点位置相当于一个指向重做流的指针,它的信息存储在控制文件以及每个数据文件的头部。

  • 将数据库缓冲区高速缓存中被修改过的缓存数据写入磁盘

检查点的作用

Oracle 数据库使用检查点实现多个功能,包括:

  • 减少实例或介质失败时的恢复时间
  • 确保数据库定期将缓冲区高速缓存中的脏数据写入磁盘
  • 确保数据库在一致性关闭时将所有已提交的数据写入磁盘

检查点触发时机

检查点进程(CKPT)负责将检查点写入数据文件头部以及控制文件中。

许多场景都会导致检查点发生。例如,Oracle 数据库包含以下检查点类型:

  • 线程检查点

    数据库在完成特定操作之前将某个重做线程修改的缓存数据写入磁盘。一个数据库的所有实例上的线程检查点集合组成数据库检查点。线程检查点在以下情况下触发:

    • 一致性数据库关闭
    • 执行 ALTER SYSTEM CHECKPOINT 语句
    • 在线重做日志切换
    • 执行 ALTER DATABASE BEGIN BACKUP 语句
  • 表空间和数据文件检查点

数据库在完成特定操作之前将所有重做线程修改的缓存数据写入磁盘。表空间检查点包含一组数据文件检查点,每个数据文件一个检查点。这些检查点的触发事件包括:将表空间设置为只读或者正常离线,收缩数据文件,或者执行 ALTER TABLESPACE BEGIN BACKUP 命令。

  • 增量检查点

增量检查点是一种线程检查点,作用包括避免在线重做日志切换时的大量数据块写入。DBW 至少每三秒执行一次检查,判断是否需要写入数据。当 DBW 将脏缓存写磁盘时,同时推进检查点位置,使得 CKPT 将检查点位置写入控制文件,但不会写入数据文件头部。

其他类型的检查点包括实例与介质恢复检查点,以及删除或截断模式对象时的检查点。

实例恢复

实例恢复(Instance recovery)是将在线重做日志文件中的记录应用到数据文件的过程,用于重建最近的检查点之后的数据变更。

当管理员尝试打开一个之前未能一致性关闭的数据库时,系统自动执行实例的恢复。

实例恢复的作用

实例恢复可以确保数据库在发生实例失败之后能够恢复到一致性的状态。数据对于变更的管理方式,导致数据库文件可能会处于一个非一致性的状态。

日志线程(redo thread)是一个实例产生的所有变更记录。单实例数据库只有一个日志线程,而 Oracle RAC 数据库包含多个日志线程,每个实例一个日志线程。

当事务被提交时,日志写入进程(LGWR)将内存中的重做日志项和该事务的 SCN 同时写入在线重做日志。但是,数据写入(DBW)进程以系统认为的高效方式将修改后的数据块写入数据文件。因此,未提交的更改可能会临时存在数据文件中,同时已提交的修改有可能未写入数据文件。

如果数据库位于打开状态时发生实例失败(可能是由于 SHUTDOWN ABORT 语句或异常终止),将会导致以下状况:

  • 已提交的数据块还没有写入数据文件,只记录在在线重做日志中。这些变更必须重新应用到数据文件中。
  • 数据文件中包含一些实例失败时未提交的变更。这些变更必须进行回滚,以确保事务的一致性。

实例恢复只利用在线重做日志文件和当前在线数据文件执行数据文件的同步,确保它们的一致性。

实例恢复的时间

是否需要执行实例恢复取决于日志线程的状态。

当数据库实例以读写模式打开时,对应的日志线程被标记为打开状态,当实例一致性关闭时,日志线程被标记为关闭。如果日志线程在控制文件中是打开状态,但是没有对应的活动实例,数据库需要执行实例恢复。

Oracle 数据库在以下情况下自动执行实例恢复:

  • 单实例数据库失败后,或者 Oracle RAC 数据库的所有实例失败后,首次打开数据库。这种形式的实例恢复也称为崩溃恢复。Oracle 数据库同时恢复所有失败实例的在线重做日志线程。
  • Oracle RAC 数据库的部分(非全部)实例失败 。集群中某个存活实例自动执行实例恢复操作。

后台进程 SMON 负责执行实例恢复,自动应用在线重做日志。整个过程不需要管理员介入。

检查点的重要性

实例恢复时,使用检查点决定需要应用到数据文件中的变更。检查点位置确保了所有 SCN 小于检查点 SCN 的已提交变更都已保存到数据文件中。

下图描绘了在线重做日志中的日志线程。
Checkpoint Position in Online Redo Log
图 13-5 在线重做日志中的检查点位置

在执行实例恢复时,数据库必须应用检查点位置和日志线程终点之间的所有变更。如图 13-5 所示,某些变更可能已经写入了数据文件。但是,只有 SCN 小于检查点位置的变更确认已经写入磁盘之中。

实例恢复步骤

实例恢复的第一步称为缓存恢复(cache recovery)或前滚(rolling forward),将在线重做日志中的所有变更重新应用到数据文件中。

由于在线重做日志中包含了撤销数据(undo data),前滚操作也会重建相应的撤销段(undo segment)。前滚操作应用在线重做日志文件将数据库恢复到实例失败之前的状态。完成前滚操作之后,数据块中包含了在线重做日志文件中的所有已提交变更。这些数据文件中可能还包含一些实例失败之前写入的未提交变更,或者缓存恢复时从在线重做日志中引入的未提交变更。

前滚之后,未提交的变更需要回滚。Oracle 数据库使用检查点位置确保所有 SCN 小于检查点 SCN 的已提交变更已经写入磁盘。Oracle 数据库应用撤销块 回滚未提交的变更(包括实例失败之前写入的变更和缓存恢复时引入的变更)。这个阶段称为回滚(rolling back)或者事务恢复(transaction recovery)。

下图演示了数据库实例恢复的两个必要步骤:前滚和回滚。
Basic Instance Recovery Steps: Rolling Forward and Rolling Back
图 13-6 基本实例恢复操作:前滚和回滚

Oracle 数据库可以根据需要同时回滚多个事务。实例失败时的所有活动事务都被标记为终止。新的事务可以回滚各自的数据块以获取所需的数据,而不需要等待 SMON 进程回滚被终止的事务。

参数文件

启动数据库实例时,Oracle 数据库必须读取一个服务器参数文件(推荐方式)或者一个文本初始化参数文件(传统遗留方式)。这些文件中包含了一个配置参数的列表。

手动创建一个数据库时,必须使用一个参数文件启动实例,然后执行 CREATE DATABASE 语句。实例和参数文件可以独立于数据库而存在。

初始化参数

初始化参数(Initialization parameter)是一些可以影响实例操作的配置参数。实例在启动时读取参数文件中的初始化参数。

Oracle 数据库提供了许多初始化参数,用于优化不同环境下的操作。只有少数参数需要显式设置,通常只需要使用默认值即可。

初始化参数分组

初始化参数可以按照功能分为不同的组。

大部分初始化参数属于以下分组之一:

  • 设置实体项目(例如文件或目录)的参数
  • 设置进程限制、数据库资源限制、或者数据库自身限制的参数
  • 影响容量的参数,例如 SGA 的大小(这些参数被称为可变参数)

数据库管理员特别关注可变参数,因为他们可以通过这些参数优化数据库的性能。

基本参数与高级参数

初始化参数可以分为两类:基本参数和高级参数。

通常来说,管理员需要设置并优化大约 30 个基本的参数,以达到合理的性能。基本参数用于设置一些特性,例如数据库名称、控制文件的位置、数据库块大小以及撤销表空间。

在极少数情况下,管理员需要修改高级参数,以便获得最佳性能。DBA 专家通过可以高级参数调整数据库的行为,以满足特定的需求。

Oracle 数据库在安装软件的启动初始化参数文件中提供了参数值,或者可以通过数据库配置助手(DBCA)创建这些参数。管理员可以根据自己的配置需求或者调优方案,修改 Oracle 提供的这些初始化参数,也可以增加其他参数。对于参数文件中没有涉及的相关初始化参数,Oracle 数据库提供默认值。

服务器参数文件

服务参数文件(server parameter file)是初始化参数的一个存储库。

服务器参数文件具有以下主要特征:

  • 只能由 Oracle 数据库读写服务器参数文件。
  • 一个数据库只能有一个服务器参数文件。该文件必须存放在数据库服务器主机中。
  • 服务器参数文件是一个二进制文件,不能使用文本编辑器进行修改。
  • 服务器参数文件中的初始化参数是永久存储的。在数据库实例运行时对参数所做的任何更改在实例关闭和启动后仍然生效。

服务器参数文件使得客户端应用不再需要维护多个文本初始化参数文件。服务器参数文件通过 CREATE SPFILE 语句从文本初始化参数文件创建。它可以通过数据库配置助手直接创建。

文本初始化参数文件

文本初始化参数文件(text initialization parameter file)是一个文本文件,内容是一个初始化参数的列表。

这种参数文件是历史遗留的实现方式,它具有以下主要特点:

  • 当启动或者关闭数据库时,文本初始化参数文件必须位于连接到数据库的客户端主机中。
  • 文本初始化参数文件时一个文本文件,而不是二进制文件。
  • Oracle 数据库可以读取文本初始化参数文件,但是不能写入该文件。要想修改参数的值,必须通过文本编辑器手动进行修改。
  • 使用 ALTER SYSTEM 语句修改的初始化参数值只在当前实例中生效。必须手动更新文件初始化参数文件并重启实例才能永久生效。

文本初始化参数文件中包含一系列 key=value 配置,每行一个配置。例如,以下是某个参数文件中的部分内容:

db_name=sample
control_files=/disk1/oradata/sample_cf.dbf
db_block_size=8192
open_cursors=52
undo_management=auto
shared_pool_size=280M
pga_aggregate_target=29M
.
.
.

为了说明文本参数文件可能带来的管理问题,假设你使用了计算机 clienta 和 clientb,并且需要能够从任意一个计算机上启动数据库。此时,每个计算机上都需要一个单独的文本初始化参数文件,如图 13-7 所示。 服务参数文件可以解决参数文件的分散存储问题。
Multiple Initialization Parameter Files
图 13-7 多个初始化参数文件

修改初始化参数

管理员可以通过修改初始化参数来调整数据库的行为。参数按照修改方式分为静态(static)参数和动态(dynamic)参数。

下列表格总结了它们的不同之处。

表 13-5 静态初始化参数和动态初始化参数

特性静态参数动态参数
需要修改参数文件
需要重启实例才能生效
Oracle Database Reference 中显示为“Modifiable”
只能修改数据库或实例相关的参数

静态参数包括 DB_BLOCK_SIZE、DB_NAME 以及 COMPATIBLE。动态参数分为会话级别的参数(只影响当前会话)和系统级别的参数(影响数据库和所有会话)。例如,MEMORY_TARGET 是一个系统级参数,而 NLS_DATE_FORMAT 是一个会话级参数。

参数变更的范围取决于变更何时生效。当实例使用服务器参数文件启动时,可以使用 ALTER SYSTEM SET 语句选择以下方式修改系统级参数:

  • SCOPE=MEMORY

    参数的变更只针对当前数据库实例生效。数据库关闭并重启后变更不会持久化。

  • SCOPE=SPFILE

    参数的变更只应用于服务器参数文件,不会影响当前实例。因此,变更只在实例重启之后生效。

    注意:对于那些在 Oracle Database Reference 中标识为不可更改的参数,修改时必须指定 SPFILE 。

  • SCOPE=BOTH

    Oracle 数据库同时将变更写入内存和服务器参数文件。这是数据库使用服务器参数文件时的默认修改范围。

诊断文件

Oracle 数据库提供了一个故障诊断基础架构(fault diagnosability infrastructure),用于防止、检测、诊断和解决数据库问题。这些问题包括代码错误、元数据损坏以及客户数据丢失等严重错误。

这个高级的故障诊断基础架构的作用包括:

  • 主动发现问题
  • 检测到问题后控制损失和系统中断
  • 减少故障诊断和解决时间
  • 通过拆分跟踪文件提高可管理性,允许用户指定每个文件的大小,以及保留的最大文件数量,并且在占用的存储到达用户指定的磁盘空间后关闭跟踪
  • 方便客户与 Oracle 支持人员的交流

多租户容器数据库(CDB)与非 CDB 的诊断架构不同。本节内容针对非 CDB,除非另有说明。

自动诊断库

自动诊断库(ADR)是一个基于文件的资料库,用于存储数据库的诊断数据,例如跟踪文件、告警日志、DDL 日志以及健康健康报告。

ADR 具有以下主要特点:

  • 统一的目录结构
  • 一致的诊断数据格式
  • 统一的工具套件

以上特性使得客户和 Oracle 支持人员能够关联和分析多个实例、组件和产品的诊断数据。

ADR 存储在数据库之外,Oracle 数据库在物理库不可用时仍然能够访问和管理 ADR。数据库实例在创建数据库之前创建 ADR。

问题和事件

ADR 可以主动发现问题(problems), 它们是数据库中的一些关键错误。

关键错误显示为内部错误,例如 ORA-600,或者其他严重错误。每个问题拥有一个问题键(problem key),它是描述该问题的文本字符串。

当一个问题多次发生时,ADR 为每次的错误创建一个包含时间戳的事件(incident)。事件由一个数字的事件 ID 唯一确定。当一个事件发生时, ADR 将会发送一个事件告警(incident alert)到 Enterprise Manager。一个关键错误的诊断和解决通常从一个事件告警开始。

由于一个问题可能在短时间内产生多次事件,当该事件的次数到达一个特定阈值之后,ADR 将会采用防洪控制措施。防洪控制事件只会产生一个告警日志项,而不会产生事件转储信息。ADR 通过这种方式通知用户正在发生一个严重的错误,而不会因为产生大量的诊断数据给系统带来压力。

ADR 目录结构

ADR base 是 ADR 的根目录。

ADR 根目录下可以存在多个 ADR 主目录(ADR home),每个 ADR 主目录是一个 Oracle 产品或组件的实例的诊断数据所在的根目录,包括跟踪文件、转储文件以及告警日志等等。例如, 在一个使用了共享存储和 Oracle ASM 的 Oracle RAC 环境中,每个数据库实例和 Oracle ASM 实例都拥有各自的 ADR 主目录。

图 13-8 显示了一个数据库实例的 ADR 目录层次结构。在相同的 ADR 根目录下,还可以存在其他 Oracle 产品或组件的其他 ADR 主目录,例如 Oracle ASM 或者 Oracle Net Services。
ADR Directory Structure for an Oracle Database Instance
图 13-8 Oracle 数据库实例的 ADR 目录结构

以下是一个 Linux 环境的示例,当你在创建数据库之前使用一个唯一的 SID 和数据库名称启动实例时,Oracle 数据库默认在文件系统中创建一个 ADR 目录结构。SID 和数据库名称成为了 ADR 主目录中的文件路径的一部分。

示例 13-1 创建 ADR

% setenv ORACLE_SID osi
% echo "DB_NAME=dbn" > init.ora
% sqlplus / as sysdba
.
.
. 
Connected to an idle instance.
 
SQL> STARTUP NOMOUNT PFILE="./init.ora"
ORACLE instance started.
 
Total System Global Area  146472960 bytes
Fixed Size                  1317424 bytes
Variable Size              92276176 bytes
Database Buffers           50331648 bytes
Redo Buffers                2547712 bytes
 
SQL> COL NAME FORMAT a21
SQL> COL VALUE FORMAT a60
SQL> SELECT NAME, VALUE FROM V$DIAG_INFO;
 
NAME                  VALUE
--------------------- --------------------------------------------------------
Diag Enabled          TRUE
ADR Base              /d1/3910926111/oracle/log
ADR Home              /d1/3910926111/oracle/log/diag/rdbms/dbn/osi
Diag Trace            /d1/3910926111/oracle/log/diag/rdbms/dbn/osi/trace
Diag Alert            /d1/3910926111/oracle/log/diag/rdbms/dbn/osi/alert
Diag Incident         /d1/3910926111/oracle/log/diag/rdbms/dbn/osi/incident
Diag Cdump            /d1/3910926111/oracle/log/diag/rdbms/dbn/osi/cdump
Health Monitor        /d1/3910926111/oracle/log/diag/rdbms/dbn/osi/hm
Default Trace File    /d1/3910926111/oracle/log ... osi/trace/osi_ora_6825.trc
Active Problem Count  0
Active Incident Count 0

告警日志

每个数据库都有一个告警日志,它是一个 XML 文件,其中包含了数据库消息和错误的时间日志。

告警日志包含以下内容:

  • 所有内部错误(ORA-600),块损坏错误(ORA-1578)以及死锁错误(ORA-60)
  • 数据库管理操作,例如 SQL*Plus 的 STARTUP、
    SHUTDOWN、ARCHIVE LOG 以及 RECOVER 命令
  • 与共享服务器和调度进程功能相关的一些消息和错误
  • 物化视图自动刷新错误

Oracle 数据库使用告警日志作为在 Enterprise Manager GUI 中显示信息的替代方案。如果成功执行一个管理操作,Oracle 数据库将会在告警日志中写入一个带时间戳的“已完成”的消息。

首次启动一个实例时,Oracle 数据库在图 13-8 所示的 alert 子目录中创建一个告警日志文件,即使还没有创建数据库。该文件使用 XML 格式。在 trace 子目录中存在一个纯文本的告警日志,以下是某个告警日志的一部分:

Fri Nov 02 12:41:58 2014
SMP system found. enable_NUMA_support disabled (FALSE)
Starting ORACLE instance (normal)
CLI notifier numLatches:3 maxDescs:189
LICENSE_MAX_SESSION = 0
LICENSE_SESSIONS_WARNING = 0
Initial number of CPU is 2
Number of processor cores in the system is 2
Number of processor sockets in the system is 2
Shared memory segment for instance monitoring created
Picked latch-free SCN scheme 3
Using LOG_ARCHIVE_DEST_1 parameter default value as /disk1/oracle/dbs/arch
Autotune of undo retention is turned on.
IMODE=BR
ILAT =10
LICENSE_MAX_USERS = 0
SYS auditing is disabled
NOTE: remote asm mode is local (mode 0x1; from cluster type)
Starting up:
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
With the Partitioning, Advanced Analytics and Real Application Testing options.
.
.
.
Using parameter settings in client-side pfile 
System parameters with nondefault values:
  processes                = 100
  sessions                 = 172

正如示例 13-1所示,可以查询 V$DIAG_INFO 找到告警日志文件的位置。

DDL 日志

DDL 日志(DDL log)的格式及基本特性和告警日志相同,但是只包含了 DDL 语句和相关细节信息。数据库将 DDL 的信息写入单独的文件,以便减少告警日志的复杂性。

DDL 日志记录 DDL 文本,或者一些额外的信息。每个 DDL 语句记录一条日志。DDL 存储在 ADR 主目录下的 log/ddl 子目录中。

跟踪文件

跟踪文件(trace file)存储了用于调查问题的诊断数据。同时,跟踪文件还可以为应用程序或实例优化的提供指导。

跟踪文件的类型

每个服务器进程或后台进程都可以定期写入一个关联的跟踪文件。该文件中包含了进程环境、状态、活动以及错误的信息。

SQL 跟踪工具也可以创建跟踪文件,为特定 SQL 语句提供性能相关的信息。可以以不同的方式为指定客户端标识、服务、模块、操作、会话、实例或者数据库启用跟踪。例如,可以通过执行 DBMS_MONITOR 包中的相应过程或者设置事件的方式启动跟踪。

跟踪文件的位置

ADR 在 trace 子目录中存储跟踪文件。跟踪文件名称取决于不同的系统,并且使用 .trc 扩展名。

通常来说数据库后台进程的跟踪文件名称包含 Oracle SID、后台进程名以及操作系统进程编号。mytest_reco_10355.trc 是 一个 RECO 进程跟踪文件的示例。

服务器进程的跟踪文件名称包含 Oracle SID、字符串“ora”以及操作系统进程编号。mytest_ora_10304.trc 是一个服务器进程跟踪文件的示例。

有时候跟踪文件还拥有一个跟踪元数据文件,使用扩展名 .trm。这些文件中包含了称为跟踪映射(trace maps)的结构信息,数据库利用这些信息进行搜索和导航。

跟踪文件的拆分

如果设置了跟踪文件的大小限制,数据库自动将其拆分成最多五个分段。每个分段都是独立的文件,名称和活动的跟踪文件一致,只是加上了一个编号,例如 ora_1234_2.trc。

每个分段通常是 MAX_DUMP_FILE_SIZE 参数的 20% 大小。每当所有分段的总大小超过了限制,数据库将会删除最早的分段(永远不会删除第一个分段,因为它包含了进程初始状态的相关信息),然后创建一个新的空分段文件。

诊断转储文件

诊断转储文件(diagnostic dump file)是一种特殊的跟踪文件,包含了关于某个状态或结构的详细时间点信息。

跟踪往往是连续的诊断数据。与此相反,转储通常是针对某一事件的一次性诊断数据。

跟踪转储与事件

大多数跟踪转储由事件触发。

当一个事件发生时,数据库在该事件的事件目录中写入一个或多个转储文件。事件转储文件的名称中还包含了事件编号。

创建事件时,应用可能会为某个操作产生一个堆转储或者系统状态转储。这种情况下,数据库将转储名称添加到事件文件名之后,而不是默认的跟踪文件名之后。例如,由于一个进程的产生事件时,数据库创建 prod_ora_90348.trc 文件。该事件的转储操作产生 prod_ora_90348_incident_id.trc 文件,其中 incident_id 是该事件的数字 ID。随着该事件创建的堆转储操作产生一个堆转储文件 prod_ora_90348_incident_id_dump_id.trc,其中 dump_id 是跟踪转储的数字 ID。

Logo

Authing 是一款以开发者为中心的全场景身份云产品,集成了所有主流身份认证协议,为企业和开发者提供完善安全的用户认证和访问管理服务

更多推荐