前提知识回顾
数据库
数据库是一组文件,位于磁盘,用于存储数据。 这些文件可以独立于数据库实例存在。
数据库实例
实例是管理数据库文件的一组内存结构。 该实例包含一个叫做系统全局区 (SGA) 的共享内存区和一组后台进程。 实例可以独立于数据库文件而存在。
实例管理和维护数据库,为数据库用户提供服务。
本文从以下9个维度来对Oracle数据库实例进行概述
1、另一个角度(生存周期)看实例和数据库的关系
2、Oracle 实例结构
3、实例与数据库的关系
4、实例的生存时间
5、实例与Oracle 系统标识符 (SID)的关系
6、实例启动和关闭概述
7、实例关闭概述
8、实例恢复概述
9、实例和参数文件的概述
一、另一个角度(生存周期)看实例和数据库的关系
每个正在运行的 Oracle 数据库至少与一个 Oracle 数据库实例相关联。因为实例存在于内存中,而数据库存在于磁盘上,所以实例可以在没有数据库时而存在,数据库也可以在没有实例时存在。
二、Oracle 实例结构
当实例启动时, Oracle 数据库软件分配一个叫做系统全局区(SGA) 的内存区域,并启动多个后台进程。
SGA内存的主要作用:
1、维护由很多进程同时访问的内部数据结构
2、缓存从磁盘中读取的数据块
3、缓冲重做数据,等待后续将其写入联机重做日志文件
4、存储 SQL 语句和SQL语句的执行计划
备注:实例的内存和进程相关的详细知识,后续会以文章的方式单独来讲述。
三、实例与数据库的关系
1、非CDB模式
单实例环境:
一个实例对应一个数据库(一对一关系)。
这是传统的Oracle数据库架构。
RAC集群环境:
多个实例对应一个数据库(多对一关系)。
多个实例共享同一个数据库,提供高可用性和负载均衡。
备注:21c版本以后, 不支持非CDB模式 了
非CDB模式下实例与数据库的架构图:

2、 CDB(Container Database)模式
单实例环境 :
一个实例对应一个CDB,一个CDB可以管理多个PDB数据库
一个实例对应多个PDB (一对多关系)。
一个CDB实例可以管理多个PDB(Pluggable Database),每个PDB是一个独立的数据库。
你可以简单理解为:一个实例对应一个CDB,一个CDB可以管理多个PDB数据库。
RAC集群环境 :
多个实例共享同一个CDB,一个CDB实例可以管理多个PDB,所以同时可以管理多个PDB。
多个实例对应多个PDB(多对多关系)。
CDB模式单实例环境下实例与数据库的架构图:

四、 实例的生存时间
1、实例在startup命令时开始创建,直到shutdown时结束。
2、实例只能与一个数据库相关联。
3、实例只能装载数据库一次,关闭数据库一次、打开数据库一次。
4、在数据库已关闭后,必须启动一个不同实例来装载并打开此数据库。
备注:如果是容器数据库类型,则数据库表示的是CDB,而非PDB。
其它
1、STARTUP ; 创建(启动)一个实例,它会装载并打开数据库
2、ALTER DATABASE CLOSE; 实例关闭数据库,将其置于已装载状态。实例可以读写控制文件,但不能读写数据文件。
3、如果实例尝试重新打开之前已关闭的数据库。Oracle 数据库发出一个错误,因为同一实例不能打开数据库两次。
4、这个阶段,唯一选择的是关闭实例(shutdown immediate),结束此实例的生命周期。
5、查询当前实例的启动时间的语句
SELECT TO_CHAR(STARTUP_TIME,'MON-DD-RR HH24:MI:SS') AS "Inst Start Time" FROM V$INSTANCE;
五、 实例与Oracle系统标识符(SID)的关系
1、系统标识符 (SID) 是数据库服务器主机上的某个 Oracle 数据库实例的唯一名称。
2、在UNIX 及 Linux 上,Oracle 数据库使用 SID 和 Oracle Home 的值来创建一个指向共享内存的键。(可以通过ipcs查看)
3、SID 在默认情况下用于定位参数文件,并使用参数文件来进一步定位其它相关文件,如数据库控制文件等
4、在大多数的平台上, 由 ORACLE_SID 环境变量设置 SID,而ORACLE_HOME 变量设置 Oracle Home。
5、当客户端要连接到实例时,可以在 Oracle Net 连接中指定 SID,或使用网络服务名称。Oracle 数据库将服务名称转换为一个 ORACLE_HOME 和 ORACLE_SID
六、 实例启动概述
startup命令执行后,数据库从关闭状态推进到打开状态时,会经历以下几个阶段:
1、启动实例,但未装载数据库。实例已启动,但尚未与某个数据库相关联。
2、装载数据库,实例已启动,并且通过读取控制文件,来与数据库相关联,数据库对用户来说是关闭的。
3、打开数据库,实例已启动,并与一个打开的数据库相关联。业务程序可以通过授权的业务用户访问数据文件中的业务数据。
实例是如何启动的
当 Oracle 数据库启动一个实例时,它执行以下基本步骤:
1、在特定于平台的默认位置搜索服务器参数文件,如果未找到 ,则搜索一个初始化参数文本文件(当STARTUP 指定 SPFILE 或 PFILE 参数时,则覆盖该默认行为)
2、读取参数文件,以确定初始化参数值
3、基于初始化参数设置,分配 SGA
4、启动 Oracle 后台进程
4、打开警报日志和跟踪文件,并以有效的参数语法将所有显式参数设置写入警报日志中
这一阶段还没有数据库与该实例相关联。需要 NOMOUNT 状态的场景包括创建数据库和某些备份与恢复操作
数据库是如何装载的
1、由实例装载数据库,以将数据库与该实例相关联。
2、为装载数据库,该实例获取由 CONTROL_FILES 初始化参数指定的数据库控制文件名称,并打开文件。
3、Oracle 数据库读取控制文件,以查找数据文件和联机重做日志文件的名称,当打开数据库时,它会尝试访问这些文件
4、在一个已装载的数据库中,该数据库是关闭的,且只有数据库管理员可以访问。管理员可以在完成某些特定的维护操作时保持数据库关闭。但是,数据库此时还不可用于常规操作。
如果 Oracle 数据库允许多个实例同时装载同一数据库,则CLUSTER_DATABASE 初始化参数设置可以使数据库可用于多个实例。
1、如果装入数据库的第一个实例的 CLUSTER_DATABASE 为 false (默认),则只有自己这一个实例可以装载这个数据库。
2、如果第一个实例的 CLUSTER_DATABASE 为 true,则其他实例在其CLUSTER_DATABASE 参数也设置为 true 时可以装载这个数据库。可以装载数据库的实例数量决定于在创建数据库时指定的预定最大值。
数据库是如何打开的
打开一个已装载的数据库,使其可用于常规的数据库操作。业务程序可以连接到打开的数据库,访问业务数据。
在打开数据库时, Oracle 数据库执行下列操作:
1、打开除撤消(undo)表空间之外的其他的表空间中的联机数据文件
2、获取一个撤消表空间
3、如果存在多个撤消表空间,则由 UNDO_TABLESPACE 初始化参数指定要使用的撤消表空间。如果尚未设置此参数,则会选择第一个可用的撤消表空间。
4、打开联机重做日志文件
七、 实例关闭概述
数据库和实例关闭概述
当一致地关闭打开的数据库时,Oracle 数据库自动执行以下步骤:
1、数据库关闭:数据库仍处于装载状态,但数据文件和联机重做日志文件已被关闭。
2、数据库卸载:实例仍处于启动状态,但已不再与数据库的控制文件相关联。
3、数据库实例关闭:数据库实例不再处于启动状态(内存和进程都释放,被操作系统回收)。
当实例失败或执行 SHUTDOWN ABORT方式关闭数据库时,Oracle 数据库不会经历上面这些所有步骤,而只是立即关闭该实例。
实例启动和关闭概述
1、SHUTDOWN ABORT
可以简单理解为, 服务器断电方式关闭数据库,可想而知,此时会立即释放内存、进程、立马关闭整个数据库 。
此模式用于紧急情况,如其他形式的关闭方式都未能成功时。这种模式的关闭是最快的。但是,随后打开该数据库可能时间会显著增加,
因为必须执行实例恢复使数据文件保持一致。
2、SHUTDON IMMEDIATE
这种模式通常是除 SHUTDOWN ABORT 之外最快的关闭模式了。Oracle 数据库终止任何正在执行的 SQL 语句,并断开用户连接。所
有活动事务都将终止,并回滚所有未提交的更改。
3、SHUTDOWN TRANSACTIONAL
这种模式可以防止用户启动新事务,但在关闭之前会等待所有的当前事务完成。这种模式可能会花费相当长的时间,这取决于当前事务的特征。
4、SHUTDOWN NORMAL
这是默认的关闭模式。在关闭之前数据库会等待所有连接的用户断开连接。
实际生产环境中,我们尽量首先使用SHUTDOWN IMMEDIATE干净、尽可能快的关闭数据库。实在迫不得已,才会使用shutdown abort方式来关闭数据库。其它两种关闭模式则很少很少使用 。
数据库是如何关闭的
正常停机过程中是如何关闭数据库的
当数据库作为 SHUTDOWN 的一部分(不使用 ABORT 选项)而关闭时,Oracle 数据库将 SGA 中的数据写入数据文件和联机重做日志文件。然后数据库关闭联机数据文件和联机重做日志文件。脱机表空间中的任何脱机数据文件是本来就是已关闭的。当重新打开数据库时,任何本来脱机的空间仍然保持脱机状态。
这一阶段中,该数据库是关闭的,且无法进行正常操作访问。在数据库关闭后,控制文件仍保持打开状态。
非正常关机过程中是如何关闭数据库
如果执行了 SHUTDOWN ABORT,或出现异常终止,则打开数据库的实例会关闭,并在瞬间将数据库停机。Oracle 数据库不会将 SGA 缓冲区中的数据写入数据文件和重做日志文件。随后重新打开数据库需要实例恢复,这将由 Oracle 数据库自动执行。
数据库是如何卸载的
数据库关闭之后,Oracle 将数据库卸载,并解除与实例的关联。数据库卸载后 ,Oracle 数据库关闭数据库的控制文件。这个时候,实例仍将保留在内存中。
实例是如何关闭的
关闭数据库的最后一步是关闭实例。当数据库实例关闭时,SGA 被从内存中移除,且后台进程都将被终止。
在异常情况下,实例可能并未干净地关闭。内存结构可能未从内存中删除,或某个后台进程可能未被终止。当之前的实例存在残留物时,后续的实例启动可能会失败。在这样的情况下,可以强制启动一个新实例(startup force);或者通过删除之前实例的残留物(SHUTDOWN ABORT)在启动新实例;或者ipcs从操作角度删除残余内存信息;最后,也可通过重启操作系统彻底释放所有残留内容;
八、 实例恢复概述
实例恢复 是将联机重做日志中的记录应用到数据文件,以重建最近检查点之后所做更改的过程。
当尝试打开一个不一致的数据库时,在实例启动过程中会自动执行实例恢复。
备注:检查点,可以简单理解为SGA缓存中的数据块,写入磁盘文件的时刻,会记录此时联机日志的一个重做点结构,这个重做点结构会写入控制文件和数据文件头部。
实例恢复的目的
实例恢复可确保数据库在一个实例失败后仍能回到一个数据一致的状态(例如一则银行转账,转账后的数据,只能要么成功要么失败,而不能出现其它任何不一致的数据)。
重做线程
重做线程是对实例生成的所有更改的记录。单实例数据库拥有一个重做线程,而一个 Oracle RAC 数据库拥有多个重做线程——每个数据库实例有一个。
补充知识
重做日志,我前面说过,可以理解为记录所有对数据库更改的视频,当我们需要的时候,完全可以按照记录的视频,将这些对数据库的更改,重新在数据库中再来执行一次,这样就保证和实现了数据库恢复。
事务提交和数据写入磁盘
当事务提交时,日志写入进程(LGWR) 将内存中的重做条目和事务 SCN 同时写入联机重做日志。但是,数据库写入进程 (DBWn) 进程只在最有利的时机将已修改的数据块写入数据文件。由于这个原因,未提交的更改可能会暂时存在于数据文件中,而已提交的更改也可能还不在数据文件中
如果某个打开的数据库的实例失败,或者由于 SHUTDOWN ABORT 语句或异常终止,则可能会导致下列情况:
1、由某事务已提交的数据块更新还未写入数据文件,而仅写入了联机重做日志中。这些更改必须重新应用到数据库
2、数据文件包含实例失败时尚未提交的更改。这些更改必须回滚,以确保事务一致性。
Oracle 数据库何时执行实例恢复
是否需要实例恢复取决于重做线程的状态。在数据库实例被打开为读/写模式时,重做线程在控制文件中被标记为打开,而当实例被一致关闭时,重做线程被标记为关闭。如果重做线程在控制文件中被标记为打开,但没有活动的实例持有对应于这些线程的线程队列,则数据库将需要实例恢复。
Oracle 数据库自动执行实例恢复的情况
单实例数据库或 Oracle RAC 数据库的所有实例失败后第一次打开数据库。这种形式的实例恢复也称为 崩溃恢复 。Oracle 数据库一起恢
复所有已终止实例的联机重做线程。
只是 Oracle RAC 数据库中的某些、但不是所有实例失败。实例恢复将由配置中的某个存活实例自动进行。
SMON 后台进程自动执行实例恢复并应用联机重做记录。而不需要任何用户干预。
实例恢复阶段
实例恢复的第一阶段称为缓存恢复或 前滚 ,这涉及将联机重做日志中记录的所有更改重新应用到数据文件。因为回滚数据记录在联机重做日志中,前滚也会重新生成相应的撤消段。
前滚阶段:
前滚会遍历各个必要的联机重做日志,以将数据库推进到一个更前的一致时间点。前滚之后,数据块包含记录在联机重做日志文件中的所有已提交更改。这些文件可能还包含未提交的更改,要么是在实例失败前保存到数据文件中的,或者是在缓存恢复过程中引入的
回滚阶段:
前滚之后,任何未提交的更改必须被撤消。Oracle 数据库使用检查点位置,保证每个低于其 SCN 的已提交更改都已保存到磁盘。Oracle 数据库应用撤消块,以回滚数据块中在实例失败前写入的或缓存恢复过程中引入的未提交更改。这一阶段称为 回滚 或事务恢复。
Oracle 数据库可以根据需要同时回滚多个事务。实例失败时的所有活动事务被标记为终止。新事务可以自己回滚个别块以获取所需的数据,而不必等待 SMON 进程来回滚这些已终止的事务。
九、实例和参数文件的概述
要启动数据库实例,Oracle 数据库必须读取一个(推荐的) 服务器参数文 件 或一个(传统的) 文本初始化参数文件。这些文件包含配置参数的列表。
初始化参数
初始化参数 是会影响实例基本操作的配置参数。实例在启动时从一个文件读取初始化参数。
Oracle 数据库提供了许多 初始化参数 ,以优化其在不同环境中的操作。只需要显式设置几个参数,因为其默认值对大多数情况已经足够。
初始化参数的功能分组
1、名字参数,如文件或目录
2、限制设置参数,如进程、 数据库资源、或数据库本身等
3、影响容量的参数,如 SGA 的大小(这些参数也称为 可变参数 )
服务器参数文件
服务器参数文件 是 Oracle 数据库用来管理初始化参数的一个参数文件。具有以下主要特征:
1、对于一个数据库,只存在一个服务器参数文件。此文件必须驻留在数据库主机上。
2、服务器参数文件只由 Oracle 数据库读取和写入,而不能由客户端应用程序读取和写入。
3、服务器参数文件是二进制的,且不能使用文本编辑器修改。
4、存储在服务器参数文件中的初始化参数是yongjiu性的。数据库实例正在运行时对参数所做的任何更改,可以跨实例关闭和启动而存在
5、服务器参数文件消除了为多个客户端应用程序维护多个文本初始化参数文件的需要。服务器参数文件最初可以从一个文本初始化参数文件,使用CREATE SPFILE 语句来生成。也可以直接由数据库配置助手创建。
文本初始化参数文件
文本初始化参数文件 是一个文本文件,其中包含初始化参数的列表。这是一种旧式参数文件,具有以下关键特征:
1、文本初始化参数文件是基于文本的,而非二进制。
2、linux操作系统中数据库服务器ORACLE_HOME/dbs目录下的有默认的
init
3、Oracle 数据库可以读取,但不能写入文本初始化参数文件。若要更改参数值,必须使用文本编辑器手动更改文件。
4、通过 ALTER SYSTEM 对初始化参数值所做的更改,仅在当前实例中有效。
5、必须手动更新文本初始化参数文件,重新启动实例才可以是参数修改生效。
备注:基本很少使用这类参数文件,除非在某些特定的数据库管理场景下,作为过渡使用。
修改初始化参数的值
这里默认实例是用服务器参数文件启动的,使用 ALTER SYSTEM SET 语句更改系统级参数的值
参数更改的 范围 取决于更改何时生效,如下所示:
SCOPE=MEMORY
更改只应用于数据库实例(只修改内存值)。如果数据库关闭并重新启动,更改将不会保留。
SCOPE=SPFILE
更改被写入服务器参数文件,但不会影响当前实例(只修改文件,内存值不影响)。因此,所做的更改不会生效,下次重启实例生效。
SCOPE=BOTH
将更改同时写入内存和服务器参数文件。当数据库使用服务器参数文件时,这是默认的范围
本文参考官方文档: