Oracle 教程 Oracle Instance
1. 数据库实例介绍
数据库实例(instance)是一组用于管理数据库文件的内存结构。
数据库是一组位于磁盘上的物理文件,通过 CREATE DATABASE 语句创建。实例管理相关的数据,并且为数据库用户提供服务。
每个正在运行的 Oracle 数据库至少与一个实例相关联。因为实例存在于内存中,而数据库存在磁盘上,所以实例可以独立于数据库存在,数据库也可以独立于实例存在。
1.1. 实例结构
当一个实例启动时,Oracle 数据库分配一个称为系统全局区(SGA)的内存区域,并启动一个或多个后台进程。
SGA 的作用包括:
- 维护多个进程和线程并发访问的内部数据结构
- 缓存从磁盘读取的数据块
- 在写入在线重做日志文件之前缓冲重做数据
- 存储 SQL 执行计划
同一个服务器上的 Oracle 进程之间共享 SGA。Oracle 进程与 SGA 的交互方式取决于操作系统。
一个数据库实例包括多个后台进程(background process)。服务器进程(server process),以及分配给它们的内存,也位于实例之中。实例在服务器进程结束后仍然继续存在。
下图显示了 Oracle 数据库实例中的主要组件。
1.2. 实例配置
Oracle 数据库支持单实例配置和应用集群(Oracle RAC)配置。这两种配置只能二选其一。
在单实例配置中,数据库和实例之间一一对应。在 Oracle RAC 中,数据库和实例存在一对多的关系。
下图显示了两种可能的数据库实例配置。
无论是单实例还是 Oracle RAC 配置,一个实例每次只能与一个数据库关联。管理员可以启动一个实例,然后加载(关联)一个数据库,但是不能同时加载两个数据库。
一台服务器上可以同时运行多个实例,每个实例管理各自的数据库。例如,某台服务器上拥有两个不同的数据库:prod1 和 prod2。一个实例管理 prod1另一个实例管理 prod2。
1.3. 读写实例与只读实例
实例支持两种模式:读写实例与只读实例。
对于读写实例,可以处理 DML 操作,支持客户端的直接连接请求。这是默认方式。与此相反,只读实例能够运行查询,但是不能支持 DML修改操作(UPDATE、DELETE、INSERT 以及 MERGE),也不能从客户端直接进行连接。
在之前的版本中,所有的实例(除非管理一个 standby 数据库)都是读写实例。从 Oracle 数据库 12c (12.2) 开始, 一个数据库可以同时存在只读实例和读写实例。这种配置对于即查询数据又修改数据库的并行 SQL 语句非常有用,因为读写实例和只读实例都能够查询数据,而读写实例能够修改数据。
与读写实例相比,只读实例具有以下特点:
– 只能打开一个已经被读写实例打开的数据库
– 禁用了许多不必要的后台进程,包检查点进程和归档进程
– 可以加载一个被禁用的重做线程或者没有任何在线重做日期的线程
要想将实例设置为只读模式,可以将初始化参数 INSTANCE_MODE 设置为 READ_ONLY。该参数的默认值为 READ_WRITE。
1.4. 实例生命周期
数据库实例从 STARTUP 命令创建开始,直到被终止时结束。
在此期间,一个实例能且只能与一个数据库相关联。进一步而言,该实例只能加载数据库一次、打开数据库一次,并且关闭数据库一次。在数据库关闭之后,必须重新启动一个实例,然后加载并打开数据库。
下表演示了一个实例尝试重新打开之前关闭的数据库的过程。
1.5. 实例标识
一个主机上可以运行多个数据库实例。因此,访问时需要指定访问哪个实例。
Oracle 最优灵活体系结构(OFA)规则是一组配置指南,可以确保组织良好的 Oracle 软件安装。本节中的示例使用 OFA 体系结构。
1.5.1. Oracle 根目录
Oracle 根目录(Oracle Base directory)存储 Oracle 产品的二进制文件。
Oracle 根目录是 Oracle 数据库安装拥有者的数据库主目录。一个主机上可以按照多个 Oracle 数据库,以及多个 Oracle 数据库软件安装的拥有者。
以下示例显示了操作系统用户 oracle 的 Oracle 根目录:
/u01/app/oracle
在路径的前缀中, /u01/ 是存储的挂载点, /u01/app/ 是安装应用软件的分支目录。
1.5.2. 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
1.5.3. 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 主目录中的软件启动一个实例,管理该数据库。
2. 实例启动与关闭
数据库实例(database instance)为用户提供数据库访问。实例和数据库存在各种不同的状态。
2.1. 启动实例与数据库
通常来说,管理员手动启动一个实例,然后加载并打开数据库,接受客户端连接。这些操作可以通过 SQL*Plus 的 STARTUP 命令、 Oracle 企业管理器(Enterprise Manager)或者 SRVCTL 工具完成。
如果使用 Oracle Net 启动一个数据库实例,需要满足以下条件:
- 数据库通过静态方式注册到 Oracle Net 监听器中。
- 使用 SYSDBA 权限进行连接。
监听器启动一个专用的服务器进程,用于启动数据库实例。
下图显示了数据库从关闭到打开的处理过程。
通常来说,管理员手动启动一个实例,然后加载并打开数据库,接受客户端连接。这些操作可以通过 SQL*Plus 的 STARTUP 命令、 Oracle 企业管理器(Enterprise Manager)或者 SRVCTL 工具完成。
如果使用 Oracle Net 启动一个数据库实例,需要满足以下条件:
– 数据库通过静态方式注册到 Oracle Net 监听器中。
– 使用 SYSDBA 权限进行连接。
监听器启动一个专用的服务器进程,用于启动数据库实例。
下图显示了数据库从关闭到打开的处理过程。
数据库从关闭状态到打开状态需要经历以下几个阶段。
2.1.1. 管理员登录
数据库的启动和关闭是非常强大的管理功能,只能由具有管理员权限的用户执行。
普通用户无法控制数据库的当前状态。根据操作系统的不同,用户可以通过以下方式获得管理员权限:
- 用户的操作系统权限允许他/她已管理员权限连接到数据库。
- 用户被授予特殊的系统权限,数据库使用口令文件认证通过网络连接的管理员
以下特殊的系统权限能够在数据库未打开时访问实例:
- SYSDBA
- SYSOPER
- SYSBACKUP
- SYSDG
- SYSKM
以上权限的管理不在数据库的自身范围之内。使用 SYSDBA 系统权限连接时,用户位于 SYS 模式中。使用 SYSOPER 连接时,用户位于公共模式中。SYSOPER 权限是 SYSDBA 权限的一个子集。
2.1.2. 启动实例
当 Oracle 数据库启动一个实例时,需要经过几个阶段。
实例启动阶段包括:
- 查找不同平台下默认位置中的服务器参数文件,如果没有找到该文件,查找文本形式的初始化参数文件(在 STARTUP 命令中指定 SPFILE 或 PFILE 参数将会覆盖默认行为)
- 读取SPFILE或者PFILE指定参数文件中已定义好的初始参数值
- 基于初始化参数设置分配 SGA(共享内存区)
- 创建并启动 Oracle 后台进程
- 打开告警日志(alert log)文件和跟踪文件(trace file),按照参数设置的语法在告警日志中写入所有显式指定的参数设置
在这一阶段,实例还没有关联到数据库。NOMOUNT 状态的使用场景包括数据库创建以及备份与恢复操作。
可以使用RESTRICT和FORCE选项开启实例。在RESTRICT模式下,只允许DBA做以下工作:
– 执行结构维护,如重建索引;
– 执行数据库文件的导入导出;
– 执行数据库装载;
– 临时阻止用户使用数据。
2.1.3. 加载数据库
实例通过加载数据库与其进行关联。
加载数据库时,实例会根据初始化参数CONTROL_FILES指定的值找到并打开控制文件。Oracle 数据库读取控制文件,从控制文件中获取数据文件和重做日志文件的信息,在打开数据库时需要访问这些文件。
加载之后,数据库处于关闭状态,只允许管理员访问。管理员可以在保持数据库关闭的同时执行一些特定的维护操作。但是,此时数据库还不能执行一些常规操作。
只允许具有数据库管理权限的部分用户对数据库进行操作,例如:
– 重命名数据文件;
– 添加、撤销或重命名重做日志文件;
– 启动和禁止重做日志归档;
– 执行全部的数据库恢复。
装载RAC
如果 Oracle 数据库允许多个实例同时加载相同的数据库,初始化参数 CLUSTER_DATABASE 可以设置多个实例访问该数据库。具体的行为取决于该参数的值:
- 如果第一个加载数据库的实例的 CLUSTER_DATABASE 设置为 false(默认值),只有该实例能够加载数据库。
- 如果第一个加载数据库的实例的 CLUSTER_DATABASE 设置为 true,其他实例在 CLUSTER_DATABASE 也设置为 true 时可以加载该数据库。可以同时加载同一个数据库的实例数量由创建数据库时的预定义值决定。
装载备库(standby database)
standby数据库是主数据库的一个完全相同的副本,可以为灾难继续提供数据库的可用性。standby数据库永远都处于RECOVERY模式。只能使用ALTER DATABASE命令将数据库以standby模式装载,在standby模式下应用主数据库产生的归档重做日志。只能以READ ONLY打开(OPEN)standby数据库。
装载克隆数据库(clone database)
克隆数据库是专门用于表空间时间点恢复(point-in-time recovery)的数据库副本。在执行时间点恢复时,装载克隆数据库并将数据库恢复到预期的时间,则将从克隆数据库导入元数据(metadata)到主数据库、复制表空间中的数据文件到主数据库。
2.1.4. 打开数据库
打开一个已加载的数据库意味着可以对其执行常规的操作。以OPEN方式打开数据库,至此数据库才算完全打开。
任何有效的用户都可以连接到一个打开的数据库,并且访问其中的信息。通常来说,数据库管理员负责打开数据库。
- 打开数据库时, Oracle 数据库将会执行以下操作:
- 打开undo表空间(undo tablespace)之外的其他表空间的在线数据文件
如果一个表空间在数据库关闭之前处于离线(offline)状态,重新打开数据库时,该表空间和相应的数据文件仍然处于离线状态。 - 获取一个undo表空间
如果存在多个undo表空间,由初始化参数 UNDO_TABLESPACE 决定使用哪个表空间。如果没有设置该参数,使用第一个可用的undo表空间。如果初始化参数UNDO_MANAGEMENT值为AUTO,则实例自动管理UNDO。初始化参数UNDO_MANAGEMENT默认值为MANUAL。如果使用表空间管理UNDO,则会自动管理UNDO,此为推荐模式;如果使用回滚段(rollback segment)管理UNDO空间,则使用MANUAL方式管理。 - 打开在线重做日志文件
- 如果有数据文件或者重做日志文件存在异常,则ORACLE将返回错误。
- 如果数据库非正常关闭,并且存在分散的有疑议的事务,无论是已提交还是已回滚,当你重新打开数据库并完全恢复时,后台进程RECO能够自动地、立即地、永久地完成此工作。
只读模式
默认情况下,数据库以读/写模式打开。在这种模式下,用户可以修改数据,产生重做日志项。另外,数据库可以以只读模式打开,防止用户事务修改数据。
- 注意:默认情况下,物理备用数据库以只读模式打开。
只读模式下的数据库只能执行只读事务,不能写入数据文件或者在线重做日志文件。不过,数据库仍然能够执行恢复操作或者不产生重做日志的操作。例如,只读模式支持以下操作:
- 将数据文件离线或者在线。但是,不能将永久表空间离线。
- 恢复离线的数据文件和表空间。
- 修改控制文件中关于数据库状态的信息。
- 使用 CREATE TEMPORARY TABLESPACE 语句创建的临时表空间允许读写操作。
- 写入操作系统的审计文件、跟踪文件以及告警日志。
数据库文件检查
如果打开数据库时,任何数据文件或重做日志文件不存在,或者它们存在但是一致性检测失败,数据库将会返回一个错误。此时需要执行介质恢复。
2.1.5. STARTUP命令
STARTUP options | upgrade_options
options:[FORCE] [RESTRICT] [PFILE=filename] [QUIET] [ MOUNT [dbname] | [ OPEN [open_options] [dbname] ] | NOMOUNT ]
NOMOUNT、MOUNT、OPEN为startup的三个阶段,不能在命令中同时存在。
其中,open_options为:READ {ONLY | WRITE [RECOVER]} | RECOVER。
upgrade_options:[PFILE=filename] {UPGRADE | DOWNGRADE} [QUIET]
- FORCE解析:强制打开数据库,在open之前会先执行shutdown,相当于shutdown abort; startup open。在当前实例正在运行的情况下,如果不使用FORCE的话,startup时会报错。FORCE可以在调试环境或非生产环境中使用,需慎用。
- RESTRICT解析:以此模式打开的数据库只有拥有RESTRICTED SESSION系统权限的用户才能连接。打开后,可以使用ALTER SYSTEM命令将该状态设为disable,以关闭restricted将数据库正常打开。
- PFILE=filename解析:使用指定的文件中的参数打开实例。在未使用PFILE的情况下,startup以默认参数文件中的参数打开。在UNIX系统中,该文件默认为ORACLE_HOME/dbs/init\$ORACLE_SID.ora;在Windows系统中,该文件默认为%ORACLE_HOME%\database\initSID.ora。
- QUIET解析:使用该选项将致使实例在打开过程中不显示SGA的相关信息
- MOUNT dbname解析:以MOUNT方式打开实例,如果未指定dbname,则打开以参数文件中DB_NAME参数指定的数据库。
- OPEN解析:以OPEN方式打开实例
- NOMOUNT解析:以NOMOUNT方式打开实例
- RECOVER解析:该选项可以引导startup在打开实例之前进行完全恢复,与RECOVER DATABASE命令的功能相同。若要开启自动恢复,可将AUTORECOVERY参数值设为ON。如果redo日志文件未在指定位置,在根据提示指定备用的日志文件后,即使未开启自动恢复,recovery仍可继续进行。
- UPGRADE解析:以OPEN UPGRADE方式打开实例,并且设定特定参数值,使得能够运行upgrade脚本。只有在第一次打开一个新版本的数据库时才可使用UPGRADE选项。当使用该选项时,运行upgrade脚本可将当前安装的数据库版本升级为一个更新的版本。完成upgrade后,数据库需关闭和正常重启。
- DOWNGRADE解析:以OPEN DOWNGRADE方式打开实例,并且设定特定参数,似的能够运行downgrade脚本。当使用该选项时,运行downgrade脚本可将当前安装的数据库版本降为一个更旧的版本。完成downgrade后,数据库需关闭和正常重启。
说明
1. 必须以SYSOPER或SYSDBA身份连接才有权限执行startup
2. 未带任何参数的startup相当于 STARTUP OPEN
3. STARTUP OPEN RECOVER 即使在恢复失败的情况下,仍旧会加载并打开实例
2.2. 关闭数据库与实例
通常来说,管理员在执行维护操作或其他管理任务时手动关闭数据库。可以使用 SQL*Plus 的 SHUTDOWN 命令或者 Enterprise Manager 执行这些操作。
下图演示了数据库从打开状态到一致性关闭的过程。
Oracle 数据库从打开到一致性关闭时自动执行以下操作。
Oracle 数据库在出现实例失败或者执行 SHUTDOWN ABORT (立即终止实例)命令时,不会执行以上操作。
2.2.1. 关闭模式
具有 SYSDBA 或者 SYSOPER 权限的数据库管理员可以使用 SQL*Plus 的 SHUTDOWN 命令或 Enterprise Manager 关闭数据库。SHUTDOWN 命令包含了不同的关闭选项。
下表总结了不同的关闭模式。
hutdown有四个参数:normal、transactional、immediate、abort。缺省不带任何参数时表示是normal
- SHUTDOWN ABORT
这种关闭模式用于紧急情况,例如其他模式无法关闭实例时。这种模式速度最快。但是,随后再打开数据库时需要更长的时间,因此需要执行实例恢复以确保数据文件的一致性。
由于 SHUTDOWN ABORT 命令不对打开的数据文件执行检查点操作,重新打开数据库时必须执行实例恢复。其他的关闭模式在重新打开数据库时不需要执行实例的恢复。
当数据库出现故障时,可能以上三种方式都无法正常关闭数据库,则使用这种方法.强制结束当前正在执行的SQL语句;任何未递交的事务都不被回退! 这种方法基本上不会对控制文件或者参数文件造成破坏。这比强制关机要好一点(在无法正常关闭数据库的时候).启动时自动进行实例恢复。
注意:在 CDB 中,针对 PDB 执行的 SHUTDOWN ABORT 命令等价于非 CDB 上的 SHUTDOWN IMMEDIATE 命令。 -
SHUTDOWN IMMEDIATE
这种关闭模式是除了 SHUTDOWN ABORT 之外的最快方式。Oracle 数据库立即终止任何正在执行的 SQL 语句并且断开用户的连接。系统终止所有正在进行的事务,并且回滚未提交的更改。
阻止任何用户新的连接,同时限制当前连接用户开始新的事务。如果已连接用户有未完成的事务,则数据库系统不会等待他们完成,而是直接把当前未递交的事务回退。数据库系统不再等待用户主动断开连接,当未递交的事务回退成功后,系统会直接关闭、卸载数据库,并终止数据库进程。启动时不需要实例恢复。 -
SHUTDOWN NORMAL
这是默认的关闭模式。数据库在关闭之前等待所有连接的用户断开连接。
不断开现在连接的用户,阻止任何用户建立新的连接,包括管理员在内。已经连接的用户能够继续他们当前的工作,如递交新的更新事务,直到此用户自行断开连接。这样需要等待的时间长,可以查出现连用户,再通知其自行断开。
所有的用户都断开连接,数据库才进行关闭操作,即关闭数据库、卸载数据库、终止例程。在这种情况下关闭的数据库在重新启动后,不会出现问题。启动时不需要实例恢复。 -
SHUTDOWN TRANSACTIONAL
这种关闭模式不允许用户开始新的事务,但会等待所有当前正在执行的事务结束,然后关闭数据库。这种模式可能需要等待很长的时间才能完成。
阻止任何用户建立新的连接。等待所有当前连接用户的未递交的活动事务提交完毕,然后立即断开用户的连接。所有的用户都断开连接则立即关闭数据库,进行关闭数据库、卸载数据库、终止进程等操作。这种方式,用户有可能正在算账,做复杂报表!一次数据库操作做不完的,在刚做了一次数据库操作后,将被断开,这样对用户有一定影响.启动时不需要实例恢复。
对于normal、transactional、immediate,DB BUFFER CACHE的内容写入了数据文件,没有提交的事务被回滚,所有的资源被释放,数据库被“干净”的关闭。
对于abort,DB BUFFER CACHE的内容没有写入数据文件,没有提交的事务也没有回滚。数据库没有DISMOUNT和关闭,数据文件也没有关闭。当数据库启动时,需要通过REDO LOG恢复数据,通过回滚段对事务回滚,对资源进行释放。
2.2.2. 关闭数据库
关闭数据库的操作分为正常关闭和异常关闭。
正常关闭
当数据库使用非 ABORT 模式关闭时,会将 SGA 中的数据写入数据文件和在线重做日志文件。
然后,数据库关闭在线数据文件和重做日志文件。离线表空间中的离线数据文件已经处于关闭状态。当数据库重新打开时,原来的离线表空间仍然处于离线状态。
此时,数据库已经关闭,不接受正常访问。但是控制文件仍然处于打开状态。
异常关闭
如果使用 SHUTDOWN ABORT 命令关闭数据库或者数据库异常终止时,实例瞬间停止并关闭数据库。
异常关闭时,Oracle 数据库不会将 SGA 缓存中的数据写入数据文件和重做日志文件。随后重新打开数据库时需要执行实例恢复,Oracle 自动执行实例的恢复操作。
2.2.3. 卸载数据库
在关闭数据库之后,Oracle 将会卸载数据库,将其与实例分离。
卸载数据库之后,Oracle 关闭数据库的控制文件。此时,实例仍然存在于内存之中。
2.2.4. 关闭实例
关闭数据库的最后一步就是关闭实例。关闭实例时,系统释放 SGA 内存,并停止后台进程。
在异常情况下,实例可能没有关闭干净。内存中仍然存在一些内存结构,或者某个后台进程仍未终止。如果之前的实例仍然部分存在,后续的实例可能会启动失败。此时,可以通过删除之前实例的残余并重新启动一个新实例,或者使用 SHUTDOWN ABORT 语句关闭之前的实例,强制启动一个新的实例。
某些情况下,进程的清除可能会遇到错误,导致进程监控进程(PMON)或者实例的终止。动态初始化参数 INSTANCE_ABORT_DELAY_TIME 用于指定发生内部实例失败时延迟关闭的时间(秒)。延迟时间之内,管理员可以介入处理。当发生延迟的实例终止时,数据库在告警日志中写入一条消息。某些情况下,通过允许隔离某些数据库资源,可以避免实例被终止。
3. 检查点
检查点(checkpoint)对于一致性数据库关闭、实例恢复以及常规数据库操作都至关重要。
检查点操作具有以下含义:
– 检查点位置(checkpoint position),它表示重做日志流中的系统更改号(SCN),实例恢复必须从该检查点位置开始
– 检查点位置由数据库缓冲区高速缓存中最早的脏块决定。检查点位置相当于一个指向重做流的指针,它的信息存储在控制文件以及每个数据文件的头部。
– 将数据库缓冲区高速缓存中被修改过的缓存数据写入磁盘
3.1. 检查点的作用
Oracle 数据库使用检查点实现多个功能,包括:
– 减少实例或介质失败时的恢复时间
– 确保数据库定期将缓冲区高速缓存中的脏数据写入磁盘
– 确保数据库在一致性关闭时将所有已提交的数据写入磁盘
3.2. 检查点触发时机
检查点进程(CKPT)负责将检查点写入数据文件头部以及控制文件中。
许多场景都会导致检查点发生。例如,Oracle 数据库包含以下检查点类型:
- 线程检查点
数据库在完成特定操作之前将某个重做线程修改的缓存数据写入磁盘。一个数据库的所有实例上的线程检查点集合组成数据库检查点。线程检查点在以下情况下触发:- 一致性数据库关闭
- 执行 ALTER SYSTEM CHECKPOINT 语句
- 在线重做日志切换
- 执行 ALTER DATABASE BEGIN BACKUP 语句
- 表空间和数据文件检查点
数据库在完成特定操作之前将所有重做线程修改的缓存数据写入磁盘。表空间检查点包含一组数据文件检查点,每个数据文件一个检查点。这些检查点的触发事件包括:将表空间设置为只读或者正常离线,收缩数据文件,或者执行 ALTER TABLESPACE BEGIN BACKUP 命令。 - 增量检查点
增量检查点是一种线程检查点,作用包括避免在线重做日志切换时的大量数据块写入。DBW 至少每三秒执行一次检查,判断是否需要写入数据。当 DBW 将脏缓存写磁盘时,同时推进检查点位置,使得 CKPT 将检查点位置写入控制文件,但不会写入数据文件头部。
其他类型的检查点包括实例与介质恢复检查点,以及删除或截断模式对象时的检查点。
4. 实例恢复
实例恢复(Instance recovery)是将在线重做日志文件中的记录应用到数据文件的过程,用于重建最近的检查点之后的数据变更。
当管理员尝试打开一个之前未能一致性关闭的数据库时,系统自动执行实例的恢复。
4.1. 实例恢复的作用
实例恢复可以确保数据库在发生实例失败之后能够恢复到一致性的状态。数据对于变更的管理方式,导致数据库文件可能会处于一个非一致性的状态。
日志线程(redo thread)是一个实例产生的所有变更记录。单实例数据库只有一个日志线程,而 Oracle RAC 数据库包含多个日志线程,每个实例一个日志线程。
当事务被提交时,日志写入进程(LGWR)将内存中的重做日志项和该事务的 SCN 同时写入在线重做日志。但是,数据写入(DBW)进程以系统认为的高效方式将修改后的数据块写入数据文件。因此,未提交的更改可能会临时存在数据文件中,同时已提交的修改有可能未写入数据文件。
如果数据库位于打开状态时发生实例失败(可能是由于 SHUTDOWN ABORT 语句或异常终止),将会导致以下状况:
– 已提交的数据块还没有写入数据文件,只记录在在线重做日志中。这些变更必须重新应用到数据文件中。
– 数据文件中包含一些实例失败时未提交的变更。这些变更必须进行回滚,以确保事务的一致性。
实例恢复只利用在线重做日志文件和当前在线数据文件执行数据文件的同步,确保它们的一致性。
4.2. 实例恢复的时间
是否需要执行实例恢复取决于日志线程的状态。
当数据库实例以读写模式打开时,对应的日志线程被标记为打开状态,当实例一致性关闭时,日志线程被标记为关闭。如果日志线程在控制文件中是打开状态,但是没有对应的活动实例,数据库需要执行实例恢复。
Oracle 数据库在以下情况下自动执行实例恢复:
- 单实例数据库失败后,或者 Oracle RAC 数据库的所有实例失败后,首次打开数据库。这种形式的实例恢复也称为崩溃恢复。Oracle 数据库同时恢复所有失败实例的在线重做日志线程。
- Oracle RAC 数据库的部分(非全部)实例失败 。集群中某个存活实例自动执行实例恢复操作。
后台进程 SMON 负责执行实例恢复,自动应用在线重做日志。整个过程不需要管理员介入。
4.3. 检查点的重要性
实例恢复时,使用检查点决定需要应用到数据文件中的变更。检查点位置确保了所有 SCN 小于检查点 SCN 的已提交变更都已保存到数据文件中。
下图描绘了在线重做日志中的日志线程。
在线重做日志中的检查点位置
在执行实例恢复时,数据库必须应用检查点位置和日志线程终点之间的所有变更。如图 13-5 所示,某些变更可能已经写入了数据文件。但是,只有 SCN 小于检查点位置的变更确认已经写入磁盘之中。
4.4. 实例恢复步骤
实例恢复的第一步称为缓存恢复(cache recovery)或前滚(rolling forward),将在线重做日志中的所有变更重新应用到数据文件中。
由于在线重做日志中包含了撤销数据(undo data),前滚操作也会重建相应的撤销段(undo segment)。前滚操作应用在线重做日志文件将数据库恢复到实例失败之前的状态。完成前滚操作之后,数据块中包含了在线重做日志文件中的所有已提交变更。这些数据文件中可能还包含一些实例失败之前写入的未提交变更,或者缓存恢复时从在线重做日志中引入的未提交变更。
前滚之后,未提交的变更需要回滚。Oracle 数据库使用检查点位置确保所有 SCN 小于检查点 SCN 的已提交变更已经写入磁盘。Oracle 数据库应用撤销块 回滚未提交的变更(包括实例失败之前写入的变更和缓存恢复时引入的变更)。这个阶段称为回滚(rolling back)或者事务恢复(transaction recovery)。
下图演示了数据库实例恢复的两个必要步骤:前滚和回滚。
Oracle 数据库可以根据需要同时回滚多个事务。实例失败时的所有活动事务都被标记为终止。新的事务可以回滚各自的数据块以获取所需的数据,而不需要等待 SMON 进程回滚被终止的事务。
5. 实验
从alert.log看数据库启动3个阶段