Oracle 数据库关闭是启动过程的反向操作。
启动过程:
SHUTDOWN
|
v
NOMOUNT
|
v
MOUNT
|
v
OPEN
关闭过程:
OPEN
|
v
CLOSE
|
v
NOMOUNT
|
v
SHUTDOWN
注意:图中的 CLOSE 是数据库关闭后的阶段描述,不是普通 DBA 使用的 SHUTDOWN CLOSE 命令。
在 Oracle 中,数据库关闭不仅是停止进程,还涉及:
需要特别注意:Oracle 正常关闭并不是先把所有缓存逐个清空,再关闭数据库。
不同缓存和缓冲区的处理方式不同:
此阶段主要完成数据库文件关闭前的处理。
对于一致关闭模式:
数据库 OPEN
|
v
阻止新的普通业务连接
|
v
根据关闭模式处理现有会话
|
v
等待事务完成或回滚未提交事务
|
v
执行一致关闭所需检查点
|
v
DBWn 写出必要的脏数据块
|
v
LGWR 保证必要 Redo 已持久化
|
v
更新控制文件及数据文件检查点信息
|
v
关闭数据文件和联机重做日志
|
v
数据库 CLOSE
此时 Oracle 实例尚未完全终止。
数据库文件已经关闭,但实例仍可能保留部分内存结构和后台进程。
数据库关闭后,Oracle 继续解除实例与数据库的关联。
主要过程:
此时进入类似 NOMOUNT 的实例状态。
需要注意,普通的 SHUTDOWN 命令会连续完成这些步骤,通常不会停下来让 DBA 在中间操作。
最后终止 Oracle 实例。
主要过程:
最终:
SGA 已释放
后台进程已停止
数据库文件已关闭
Oracle Instance 已终止
SGA 是 Oracle 实例的核心共享内存区域。
主要包括:
SGA
|
+-- Database Buffer Cache
|
+-- Shared Pool
| |
| +-- Library Cache
| |
| +-- Data Dictionary Cache
|
+-- Redo Log Buffer
|
+-- Large Pool
|
+-- Java Pool
|
+-- Streams Pool
不同内存区域的关闭处理方式不同。
Database Buffer Cache 主要缓存数据文件中的数据块。
缓存中的数据块通常分为:
干净缓冲区中的数据与磁盘上的相应数据已经一致,不需要为了关闭数据库而重新写盘。
实例终止时,其内存直接释放。
脏缓冲区包含尚未全部写入数据文件的修改。
一致关闭时:
Dirty Buffer
|
v
DBWn 写入数据文件
|
v
完成必要的检查点处理
|
v
数据文件达到一致关闭要求
注意:DBWn 负责写数据块,CKPT 负责检查点协调和相关元数据更新。
Oracle 不要求每个数据块在关闭时都从缓存中删除。
真正需要保证的是数据库文件达到一致关闭所要求的状态。
Redo Log Buffer 保存尚未全部写入联机重做日志文件的重做记录。
其写盘由 LGWR 负责。
正常运行时,LGWR 会在提交及其他触发条件下写入 Redo。
一致关闭时,Oracle 需要保证必要的重做记录已经持久化,以配合数据文件完成一致关闭。
流程:
Redo Log Buffer
|
v
LGWR
|
v
Online Redo Log
|
v
必要 Redo 已持久化
需要区分:
关闭数据库不会清空或删除磁盘上的联机重做日志文件。
Shared Pool 主要包括:
正常关闭时,Shared Pool 不需要像脏数据块那样逐项写回数据文件。
例如:
Shared Pool
|
+-- SQL 解析结果
|
+-- SQL 执行计划
|
+-- 数据字典缓存
|
v
实例终止
|
v
释放共享内存
这里需要明确:
SQL 执行计划缓存和数据字典缓存不是需要逐项写盘保存的业务数据文件。
数据库重新启动后,Oracle 会根据运行需要重新建立相关缓存。
这些内存区域根据数据库功能和配置使用。
关闭时主要进行相关任务、进程和内存资源清理。
实例终止后,相关内存释放。
不需要将这些内存池全部写入磁盘。
PGA 是进程私有内存,可能包含:
当相应进程退出时,PGA 内存释放。
PGA 不属于 SGA,也不是需要整体写入数据库文件的持久化缓存。
Oracle 在正常运行期间,并不是每次提交事务都立即将对应数据块写入数据文件。
例如:
UPDATE employees
SET salary = 20000
WHERE employee_id = 100;
COMMIT;
事务提交时:
因此,提交成功不代表对应数据块已经全部写入数据文件。
一致关闭时,需要通过检查点机制使数据库文件达到一致关闭要求。
开始一致关闭
|
v
停止接收新的普通业务连接
|
v
处理当前事务
|
v
回滚需要撤销的事务
|
v
执行一致关闭检查点
|
+----------------------+
| |
v v
DBWn 写脏块 LGWR 写必要 Redo
| |
v v
数据文件更新 Redo 文件更新
| |
+-----------+----------+
|
v
更新必要的检查点元数据
|
v
数据库一致关闭
实际执行过程中,Redo 写入、脏块写出、事务回滚和检查点操作存在协调与并发关系,并不是完全严格的单线程顺序。
| 组件 | 主要作用 |
|---|---|
| CKPT | 检查点协调,更新控制文件及必要的数据文件头信息 |
| DBWn | 写出脏数据块 |
| LGWR | 持久化重做记录 |
| Undo | 支持未提交事务回滚 |
一致关闭完成后,数据库再次正常启动时通常不需要进行实例恢复。
Oracle 数据库提供四种主要关闭模式:
SHUTDOWN NORMAL;
SHUTDOWN TRANSACTIONAL;
SHUTDOWN IMMEDIATE;
SHUTDOWN ABORT;
四种模式的核心区别:
| 行为 | NORMAL | TRANSACTIONAL | IMMEDIATE | ABORT |
|---|---|---|---|---|
| 允许新普通连接 | 否 | 否 | 否 | 否 |
| 等待当前会话主动结束 | 是 | 否 | 否 | 否 |
| 等待当前事务正常结束 | 是 | 是 | 否 | 否 |
| 回滚未提交事务 | 会话正常结束时处理 | 不主动中断现有事务 | 是 | 不在关闭时执行 |
| 执行一致关闭检查点 | 是 | 是 | 是 | 否 |
| 下次启动通常需要实例恢复 | 否 | 否 | 否 | 是 |
命令:
SHUTDOWN NORMAL;
这是 Oracle 的默认关闭模式。
主要特点:
流程:
SHUTDOWN NORMAL
|
v
禁止新连接
|
v
等待所有当前用户会话退出
|
v
处理事务
|
v
执行一致关闭检查点
|
v
关闭数据库文件
|
v
释放 SGA 和后台进程
|
v
SHUTDOWN
缺点:
如果某个用户一直不退出,关闭过程可能一直等待。
命令:
SHUTDOWN TRANSACTIONAL;
主要特点:
流程:
SHUTDOWN TRANSACTIONAL
|
v
禁止新连接和新事务
|
v
等待现有事务完成
|
v
结束相关会话
|
v
执行一致关闭检查点
|
v
关闭数据库
|
v
释放实例资源
适合:
缺点:
如果存在长事务,关闭过程可能等待较长时间。
命令:
SHUTDOWN IMMEDIATE;
这是数据库日常维护中最常用的关闭方式之一。
主要特点:
流程:
SHUTDOWN IMMEDIATE
|
v
禁止新连接
|
v
终止正在执行的 SQL
|
v
回滚未提交事务
|
v
断开用户会话
|
v
执行 Checkpoint
|
v
DBWn 写出必要脏块
|
v
关闭数据文件和 Redo
|
v
关闭控制文件
|
v
释放 SGA / PGA 等资源
|
v
SHUTDOWN
优点:
缺点:
如果存在大量未提交事务,回滚可能需要较长时间。
日常维护推荐优先使用 SHUTDOWN IMMEDIATE。
命令:
SHUTDOWN ABORT;
这是强制关闭模式。
主要特点:
流程:
SHUTDOWN ABORT
|
v
立即终止实例
|
v
不执行一致关闭检查点
|
v
不等待未提交事务回滚
|
v
释放实例资源
|
v
数据库处于非一致关闭状态
|
v
下次 STARTUP
|
v
自动实例恢复
|
+---- 前滚 Redo
|
+---- 回滚未提交事务
|
v
数据库恢复正常
特别注意:
SHUTDOWN ABORT 并不等于直接删除数据库文件,也不代表已提交事务一定丢失。
在存储和 Redo 文件正常、恢复所需日志完整的前提下,Oracle 可以在下一次启动时通过实例恢复恢复已提交事务的持久化修改。
| 对比项 | IMMEDIATE | ABORT |
|---|---|---|
| 关闭时回滚事务 | 是 | 否 |
| 一致关闭检查点 | 是 | 否 |
| 写出必要脏块 | 是 | 不保证 |
| 关闭速度 | 取决于回滚和检查点 | 通常较快 |
| 下次启动实例恢复 | 通常不需要 | 通常需要 |
| 适用场景 | 日常维护 | 紧急终止实例 |
假设存在两个事务:
事务 A:
UPDATE accounts
SET balance = balance + 100
WHERE id = 1;
COMMIT;
事务 B:
UPDATE accounts
SET balance = balance - 200
WHERE id = 2;
-- 没有提交
此时执行:
SHUTDOWN IMMEDIATE;
Oracle 需要:
最终:
事务 A:已提交,修改保留
事务 B:未提交,修改回滚
Buffer Cache:实例终止时释放
Redo Log Buffer:必要记录已写盘,内存释放
Shared Pool:内存释放
SGA:释放
PGA:随相关进程退出释放
Oracle Instance:关闭
如果执行:
SHUTDOWN ABORT;
Oracle 不会等待事务 B 在关闭时完成回滚,也不执行一致关闭检查点。
下次启动时,需要通过 Redo 和 Undo 完成实例恢复。
| 组件 | 一致关闭时的处理 | 最终状态 |
|---|---|---|
| Database Buffer Cache | 必要脏块写盘 | 内存释放 |
| Redo Log Buffer | 必要 Redo 持久化 | 内存释放 |
| Shared Pool | 不需要逐项写盘 | 内存释放 |
| Library Cache | 不需要保存 SQL 缓存 | 内存释放 |
| Data Dictionary Cache | 不需要逐项保存缓存 | 内存释放 |
| Large Pool | 释放相关资源 | 内存释放 |
| Java Pool | 释放相关资源 | 内存释放 |
| Streams Pool | 释放相关资源 | 内存释放 |
| PGA | 随进程退出释放 | 内存释放 |
| 数据文件 | 一致关闭检查点完成后关闭 | 保留在磁盘 |
| 联机重做日志 | 完成必要写入后关闭 | 保留在磁盘 |
| Undo 数据文件 | 完成必要事务处理后关闭 | 保留在磁盘 |
| 控制文件 | 更新必要元数据后关闭 | 保留在磁盘 |
| 后台进程 | 正常终止 | 停止 |
注意:上表针对一致关闭。SHUTDOWN ABORT 不保证完成这些写盘和检查点操作。
使用 Oracle 用户登录:
su - oracle
sqlplus / as sysdba
正常关闭:
SHUTDOWN IMMEDIATE;
强制关闭:
SHUTDOWN ABORT;
重新启动:
STARTUP;
查看实例状态:
SELECT instance_name, status
FROM v$instance;
查看数据库状态:
SELECT name, open_mode
FROM v$database;
查看检查点相关信息:
SELECT file#, checkpoint_change#
FROM v$datafile_header
ORDER BY file#;
查看 Redo 状态:
SELECT group#, thread#, sequence#,
bytes/1024/1024 AS size_mb,
status
FROM v$log
ORDER BY group#;
注意:实例完全关闭后,无法继续通过该实例查询这些动态性能视图,需要重新启动实例后查询。
原因:
仍有用户连接数据库。
处理:
SELECT sid, serial#, username, status
FROM v$session
WHERE username IS NOT NULL;
可等待用户退出,或者在确认业务允许后改用:
SHUTDOWN IMMEDIATE;
原因:
存在长时间运行的事务。
检查:
SELECT s.sid, s.serial#, s.username,
t.start_time
FROM v$session s
JOIN v$transaction t
ON s.taddr = t.addr;
处理:
可能原因:
检查 Alert Log:
tail -n 100 /u01/app/oracle/diag/rdbms/ORCL/orcl/trace/alert_orcl.log
实际路径以 V$DIAG_INFO 为准。
不建议因为关闭缓慢就立即使用 ABORT,应先确认回滚和 I/O 是否仍在正常推进。
可能原因:
应根据 Alert Log 和具体 ORA 错误进行处理。
不要直接删除 Redo、Undo 或控制文件,也不要在不了解后果的情况下使用 OPEN RESETLOGS。
Oracle 数据库正常关闭的过程:
OPEN
|
v
禁止新普通连接
|
v
处理用户会话和事务
|
v
回滚需要撤销的事务
|
v
一致关闭 Checkpoint
|
+---- LGWR:保证必要 Redo 持久化
|
+---- DBWn:写出必要脏数据块
|
+---- CKPT:协调并更新检查点信息
|
v
关闭数据文件和联机重做日志
|
v
CLOSE
|
v
关闭控制文件
|
v
解除数据库装载状态
|
v
终止后台进程
|
v
释放 SGA / PGA 等实例内存
|
v
SHUTDOWN
四种关闭模式记忆:
最终记住三句话:
第一,Oracle 正常关闭不是清空所有缓存,而是保证必要的数据库修改持久化,然后释放实例内存。
第二,SHUTDOWN IMMEDIATE 会回滚未提交事务并完成一致关闭检查点,通常是日常维护的首选。
第三,SHUTDOWN ABORT 不执行一致关闭检查点,下一次启动通常依靠 Redo 前滚和 Undo 回滚完成实例恢复。