Oracle 检查点(Checkpoint)机制详解
Oracle 检查点(Checkpoint)机制详解
适用版本:Oracle Database 11g / 12c / 19c / 23ai 阅读基础:了解 Buffer Cache、Redo Log、LGWR/DBWn/CKPT 进程的工作机制 文档版本:v1.0 / 2026-07
目录
- 1. 概述:检查点的作用与本质
- 2. 检查点的核心概念
- 3. 检查点的类型
- 4. 检查点队列(Checkpoint Queue)
- 5. CKPT 进程的职责
- 6. DBWn 与检查点的关系
- 7. 检查点相关参数
- 8. 实例恢复与 MTTR
- 9. 检查点相关视图
- 10. 常见坑与排错
- 11. 最佳实践
- 12. 参考资料
1. 概述:检查点的作用与本质
检查点(Checkpoint)是 Oracle 数据库中保证数据一致性和缩短实例恢复时间的核心机制[1][2]。
核心定义:检查点是数据库将**内存中已修改的数据(脏块)**写入数据文件,并同步控制文件和数据文件头部的 SCN 的过程。
作用:
- 缩短实例恢复时间:检查点之前的修改已落盘,崩溃恢复时只需重做检查点之后的 Redo
- 保证数据一致性:将数据文件头部 SCN 与控制文件同步
- 释放 Redo Log 空间:检查点推进后,旧的 Redo Log 才能被覆盖
- 触发条件:日志切换、关闭数据库、
FAST_START_MTTR_TARGET触发等
核心流程:
应用层 内存层 磁盘层
+----------+ +------------+ +------------+
| DML | ──修改──> | Buffer | ──脏块──> | Data File |
| | | Cache | (DBWn) | |
| | | | +------------+
| | ──记录──> | Redo Log | ──落盘──> | Redo Log |
| | | Buffer | (LGWR) | File |
+----------+ +------------+ +------------+
| |
| Checkpoint |
+─── 同步 SCN ─────────+
|
+----------------+
| Control File |
| (CKPT 更新) |
+----------------+
2. 检查点的核心概念
2.1 SCN(System Change Number)
SCN 是 Oracle 数据库内部的逻辑时钟,标志着数据库的某个一致状态[2]:
-- 查询当前 SCN
SELECT current_scn FROM v$database;
-- 查询数据文件头 SCN
SELECT name, checkpoint_change#, status
FROM v$datafile_header;
-- 查询控制文件中数据文件 SCN
SELECT name, checkpoint_change#, status
FROM v$datafile;
关键 SCN 类型:
| SCN 类型 | 含义 |
|---|---|
| System Commit SCN | 最新 commit 的 SCN |
| Checkpoint SCN | 检查点推进到的 SCN |
| Datafile Checkpoint SCN | 数据文件头的 SCN |
| Stop SCN | 控制文件中数据文件的”停止 SCN”(数据库正常关闭时与 Checkpoint SCN 一致) |
| Thread Checkpoint SCN | Redo Thread 的检查点 SCN |
2.2 RBA(Redo Block Address)
RBA 是 Redo Log 中每一条记录的物理位置,由三部分组成:
RBA = (Log Sequence#, Block Number within log, Byte Offset within block)
= (日志序列号, 块号, 字节偏移)
例如:RBA = (0x245, 0x400, 0x10) 表示序列号 0x245 的日志中第 0x400 块的第 0x10 字节。
2.3 Checkpoint RBA
Checkpoint RBA 是检查点推进到的 RBA 位置:
- 该 RBA 之前的所有 Redo 记录对应的脏块都已被 DBWn 写入数据文件
- 实例恢复只需从 Checkpoint RBA 开始重做 Redo
- Checkpoint RBA 越接近当前 Redo 位置,实例恢复越快
2.4 On-Disk RBA
On-Disk RBA 是 Redo Log 中已被 LGWR 写入磁盘的最新位置:
- 比 Checkpoint RBA 更靠前
- 是实例恢复的”上限”
Redo Log 时间轴:
0x000 ──────────────────────────────────────> 0xFFF
│ │ │
│ │ │
▼ ▼ ▼
Checkpoint RBA On-Disk RBA Current RBA
│ │ │
│ │ │
└── 实例恢复需要重做的范围 ─┘ │
│
LGWR 还未写入
3. 检查点的类型
3.1 完全检查点(Full Checkpoint)
触发条件:
SHUTDOWN NORMAL/TRANSACTIONAL/IMMEDIATE- 手工执行:
ALTER SYSTEM CHECKPOINT; - 日志切换(部分场景)
行为:
- 将 Buffer Cache 中所有脏块写入数据文件
- 更新所有数据文件头 SCN
- 更新控制文件中的检查点信息
特点:
- 一次写完所有脏块,可能产生大量 I/O
- 完成后实例恢复时间最短
- 通常不会频繁触发
-- 手动触发完全检查点
ALTER SYSTEM CHECKPOINT;
-- 全局检查点(RAC 所有节点)
ALTER SYSTEM CHECKPOINT GLOBAL;
3.2 增量检查点(Incremental Checkpoint)
触发条件:
- 每 3 秒 CKPT 自动触发
FAST_START_MTTR_TARGET设置后持续触发- Redo Log 切换时
- 检查点队列过长时
行为:
- 只更新控制文件中的 Checkpoint RBA
- 不更新数据文件头 SCN
- 不强制 DBWn 立即写入所有脏块
- DBWn 在后台按 Checkpoint Queue 顺序写入脏块
特点:
- 频繁但开销小
- 是 Oracle 8i 之后主要的检查点机制
- 主要为了控制实例恢复时间
3.3 局部检查点(Partial Checkpoint)
触发条件:
- 将表空间设为 OFFLINE:
ALTER TABLESPACE users OFFLINE - 将数据文件设为 OFFLINE:
ALTER DATABASE DATAFILE ... OFFLINE - 删除表空间:
DROP TABLESPACE users - BEGIN BACKUP 模式:
ALTER TABLESPACE users BEGIN BACKUP - 执行 TRUNCATE:
TRUNCATE TABLE tab
行为:
- 只将特定表空间或对象的脏块写入数据文件
- 不影响其他表空间
3.4 对象检查点(Object Checkpoint)
触发条件:
DROP TABLE/TRUNCATE TABLE- 表的 SHRINK SPACE
- 索引重建
行为:
- 仅针对特定对象的脏块
- 释放该对象占用的空间
4. 检查点队列(Checkpoint Queue)
Checkpoint Queue 是 Buffer Cache 中脏块按 RBA 排序的链表[3]:
脏块链表(按 RBA 升序):
+--------+ +--------+ +--------+ +--------+
| RBA=100| -> | RBA=200| -> | RBA=350| -> | RBA=500|
+--------+ +--------+ +--------+ +--------+
▲
│
DBWn 从这里开始写入(最早变脏的脏块)
当 Checkpoint RBA 推进到 200 时:
+--------+ +--------+ +--------+
| RBA=350| -> | RBA=500|
+--------+ +--------+
▲
│
新加入的脏块(RBA 大于 500)
关键特性:
- FIFO 顺序:先变脏的块先被写出
- RBA 顺序:保证 Checkpoint RBA 可以稳定推进
- DBWn 写入目标:DBWn 优先写队列头部脏块
- LRU 队列独立:Checkpoint Queue 与 LRU 队列分开维护
查看 Checkpoint Queue:
-- 查看脏块数量
SELECT name, value
FROM v$sysstat
WHERE name IN ('DBWR checkpoint buffers written',
'DBWR checkpoints',
'physical writes');
-- 查看检查点进度
SELECT
ctid,
rdtyp,
rdbno,
boff,
drba, -- Checkpoint RBA
iorba -- On-Disk RBA
FROM x$kccrt; -- 内部视图(需 SYSDBA)
5. CKPT 进程的职责
CKPT(Checkpoint Process)后台进程主要负责:
- 更新控制文件:在检查点触发时更新控制文件中的检查点信息
- 更新数据文件头:完全检查点时更新数据文件头 SCN
- 通知 DBWn:触发 DBWn 写入脏块(实际写盘由 DBWn 完成)
- 每 3 秒唤醒:维持心跳,推进增量检查点
注意:
- CKPT 本身不写数据块到数据文件
- 写脏块的工作由 DBWn 完成
- CKPT 只是”信使”,记录检查点位置
警报日志中可见:
Sun Jul 21 10:23:15 2026
Beginning global checkpoint up to RBA [0x245.0x400.0x10], SCN: 1234567890
Completed checkpoint up to RBA [0x245.0x400.0x10], SCN: 1234567890
6. DBWn 与检查点的关系
DBWn(Database Writer)负责将脏块写入数据文件,与检查点紧密配合[3]:
6.1 DBWn 触发写脏块的场景
- 检查点触发:CKPT 通知 DBWn 写脏块
- LRU 链表扫描:扫描 LRU 寻找空闲块时,遇到脏块需要写出
- 空闲空间不足:Buffer Cache 空闲块少时
- 每 3 秒:DBWn 定时唤醒
- Ping 写:RAC 跨节点访问
- 表空间 OFFLINE/READ ONLY:写出该表空间脏块
- 关闭数据库(非 ABORT)
6.2 DBWn 写入策略
Checkpoint Queue(按 RBA 顺序)
头部 尾部
▼ ▼
+-------+--------+--------+--------+--------+
|RBA=100|RBA=200 |RBA=350 |RBA=500 |RBA=800 |
+-------+--------+--------+--------+--------+
│
│
DBWn 从头部开始写:
1. 找到队列头部脏块
2. 多块写(batch write)到数据文件
3. 从 Checkpoint Queue 移除
4. 移到 LRU 的 MRU 端(变为干净块)
5. 继续写下一个,直到满足 Checkpoint RBA 推进
6.3 DBWn 进程数量
SHOW PARAMETER db_writer_processes;
-- 默认为 1,最大可设为 CPU_COUNT / 8
何时增加 DBWn 进程数:
- 写等待事件显著:
free buffer waits、write complete waits - 多 CPU 服务器,写密集型负载
-- 增加 DBWn 进程
ALTER SYSTEM SET db_writer_processes=4 SCOPE=SPFILE;
-- 重启生效
SHUTDOWN IMMEDIATE;
STARTUP;
7. 检查点相关参数
7.1 FAST_START_MTTR_TARGET
作用:设置实例恢复目标时间(秒),Oracle 自动调整检查点频率以达成目标[1]:
SHOW PARAMETER fast_start_mttr_target;
-- 默认 0(关闭),范围 0-3600 秒
-- 设置目标恢复时间为 60 秒
ALTER SYSTEM SET fast_start_mttr_target=60 SCOPE=BOTH;
工作原理:
- Oracle 持续估算当前累积的 Redo 量
- 当估计恢复时间接近目标值时,触发 DBWn 写脏块
- 推进 Checkpoint RBA,降低待恢复 Redo
权衡:
| 设置 | 实例恢复时间 | 检查点开销 |
|---|---|---|
| 较小(如 30s) | 短 | 高(频繁 DBWn 写) |
| 较大(如 600s) | 长 | 低(DBWn 写入少) |
| 0(关闭) | 不保证 | 由其他参数控制 |
推荐:
- OLTP:60-120 秒
- 数据仓库:300-600 秒
- 关键业务:30-60 秒
7.2 LOG_CHECKPOINT_INTERVAL
作用:每写 N 个 Redo Block 触发一次检查点(已被 FAST_START_MTTR_TARGET 取代)
SHOW PARAMETER log_checkpoint_interval;
-- 默认 0(关闭)
7.3 LOG_CHECKPOINT_TIMEOUT
作用:每 N 秒触发一次检查点(已被 FAST_START_MTTR_TARGET 取代)
SHOW PARAMETER log_checkpoint_timeout;
-- 默认 0(关闭),单位秒
7.4 LOG_CHECKPOINTS_TO_ALERT
作用:将每次检查点信息写入警报日志,便于排错
SHOW PARAMETER log_checkpoints_to_alert;
-- 默认 FALSE
ALTER SYSTEM SET log_checkpoints_to_alert=TRUE SCOPE=BOTH;
7.5 参数优先级
Oracle 推荐使用 FAST_START_MTTR_TARGET,其他参数置为 0:
ALTER SYSTEM SET fast_start_mttr_target=60 SCOPE=BOTH;
ALTER SYSTEM SET log_checkpoint_interval=0 SCOPE=BOTH;
ALTER SYSTEM SET log_checkpoint_timeout=0 SCOPE=BOTH;
8. 实例恢复与 MTTR
8.1 MTTR 估算
MTTR(Mean Time To Recover) = 崩溃后重启数据库的时间,主要由实例恢复构成:
MTTR = Redo 重放时间 + Undo 回滚时间
Redo 重放时间 ∝ 待恢复的 Redo 量
∝ (On-Disk RBA - Checkpoint RBA)
Undo 回滚时间 ∝ 未提交事务的数量
8.2 MTTR 估算视图
-- 查看 MTTR 估算
SELECT
mttr_target_for_estimate, -- 推荐的 MTTR 目标
estd_cache_size, -- 对应的 cache 大小
estd_cache_hit_ratio, -- 缓存命中率
estd_total_writes -- 估计的写次数
FROM v$mttr_target_advice;
8.3 实例恢复过程
1. 实例崩溃(断电、SHUTDOWN ABORT)
2. STARTUP 启动:
┌─────────────────────────────────┐
│ NOMOUNT │
│ - 读参数文件,分配 SGA │
└─────────────────────────────────┘
│
▼
┌─────────────────────────────────┐
│ MOUNT │
│ - 读控制文件 │
└─────────────────────────────────┘
│
▼
┌─────────────────────────────────┐
│ OPEN │
│ - 实例恢复: │
│ a. 前滚:从 Checkpoint RBA │
│ 重做 Redo │
│ b. 打开数据库(用户可访问) │
│ c. 后台异步回滚未提交事务 │
└─────────────────────────────────┘
8.4 加速实例恢复
方法 1:设置合理的 FAST_START_MTTR_TARGET
ALTER SYSTEM SET fast_start_mttr_target=60 SCOPE=BOTH;
方法 2:增加 DBWn 进程
ALTER SYSTEM SET db_writer_processes=4 SCOPE=SPFILE;
方法 3:使用并行恢复
-- 设置恢复并行度
ALTER SYSTEM SET recovery_parallelism=4 SCOPE=SPFILE;
-- 或
ALTER SYSTEM SET parallel_recovery_stopat=600 SCOPE=SPFILE;
9. 检查点相关视图
9.1 V$DATABASE
SELECT
name,
log_mode,
checkpoint_change#, -- 当前检查点 SCN
current_scn -- 当前系统 SCN
FROM v$database;
9.2 V$THREAD
SELECT
thread#,
status,
sequence#,
checkpoint_change#,
checkpoint_time
FROM v$thread;
9.3 V$DATAFILE
SELECT
file#,
name,
status,
checkpoint_change#, -- 数据文件检查点 SCN
last_change#, -- 最后一次修改的 SCN
offline_change#
FROM v$datafile;
9.4 V$INSTANCE_RECOVERY
-- 查看实例恢复动态信息
SELECT
recovery_estimated_ios, -- 估计的恢复 I/O 数
actual_redo_blks, -- 当前需要恢复的 Redo 块数
target_redo_blks, -- 目标 Redo 块数
log_file_size_redo_blks, -- 受 Redo Log 大小限制
log_chkpt_timeout_redo_blks, -- 受超时限制
fast_start_io_target_redo_blks,
fast_start_mttr_target_redo_blks
FROM v$instance_recovery;
9.5 V$SYSSTAT
-- 查看检查点相关统计
SELECT name, value
FROM v$sysstat
WHERE name IN (
'DBWR checkpoints',
'DBWR checkpoint buffers written',
'background checkpoints',
'background checkpoints started',
'background checkpoints completed'
);
9.6 V$SYSTEM_EVENT
-- 查看检查点相关等待事件
SELECT event, total_waits, time_waited
FROM v$system_event
WHERE event LIKE '%checkpoint%'
OR event LIKE '%file sync%'
ORDER BY time_waited DESC;
10. 常见坑与排错
10.1 checkpoint not complete
现象:警报日志出现:
Sun Jul 21 10:23:15 2026
Thread 1 cannot allocate new log, sequence 246
Checkpoint not complete
原因:
- Redo Log 文件太小,切换过快
- DBWn 写脏块速度跟不上 Redo 生成速度
- 检查点未完成时 LGWR 需要覆盖未落盘的 Redo
修复:
-- 1. 增加 Redo Log 文件大小
ALTER DATABASE ADD LOGFILE GROUP 4
('/u01/oradata/orcl/redo04.log') SIZE 500M;
ALTER DATABASE ADD LOGFILE GROUP 5
('/u01/oradata/orcl/redo05.log') SIZE 500M;
-- 2. 增加日志组数量(至少 3 组,推荐 4-6 组)
-- 3. 调整 FAST_START_MTTR_TARGET
ALTER SYSTEM SET fast_start_mttr_target=300 SCOPE=BOTH;
-- 4. 增加 DBWn 进程
ALTER SYSTEM SET db_writer_processes=4 SCOPE=SPFILE;
10.2 “write complete waits” 等待严重
现象:等待事件 write complete waits、free buffer waits 频繁出现。
原因:DBWn 写入速度跟不上脏块产生速度。
修复:
-- 1. 增加 DBWn 进程
ALTER SYSTEM SET db_writer_processes=4 SCOPE=SPFILE;
-- 2. 增大 Buffer Cache
ALTER SYSTEM SET db_cache_size=4G SCOPE=BOTH;
-- 3. 检查 I/O 子系统性能
-- 例如 ASM disk 性能、SAN 配置
-- 4. 调整检查点参数
ALTER SYSTEM SET fast_start_mttr_target=300 SCOPE=BOTH;
10.3 实例恢复时间过长
现象:STARTUP 后实例恢复耗时几分钟,影响可用性。
排查:
-- 查看实际恢复时间
SELECT
recovery_estimated_ios,
actual_redo_blks,
fast_start_mttr_target_redo_blks
FROM v$instance_recovery;
-- 警报日志中查看:
-- Sun Jul 21 10:23:15 2026
-- Beginning crash recovery of 1 threads
-- Completed crash recovery at ...
-- (时间差 = 实际恢复时间)
修复:
-- 1. 调小 MTTR 目标
ALTER SYSTEM SET fast_start_mttr_target=60 SCOPE=BOTH;
-- 2. 增加 DBWn 进程
ALTER SYSTEM SET db_writer_processes=4 SCOPE=SPFILE;
-- 3. 启用并行恢复
ALTER SYSTEM SET recovery_parallelism=4 SCOPE=SPFILE;
10.4 Redo Log 切换过快
现象:每分钟切换多次 Redo Log,性能下降。
排查:
-- 查看日志切换历史
SELECT
to_char(first_time, 'YYYY-MM-DD HH24') AS hour,
count(*) AS switches
FROM v$log_history
WHERE first_time > SYSDATE-1
GROUP BY to_char(first_time, 'YYYY-MM-DD HH24')
ORDER BY hour DESC;
-- 健康标准:每小时 < 3 次切换
修复:
-- 1. 增加 Redo Log 大小
ALTER DATABASE ADD LOGFILE GROUP 4 ('/u01/redo04.log') SIZE 1G;
-- 2. 优化产生大量 Redo 的 SQL(批量操作改用 NOLOGGING)
ALTER TABLE large_tab NOLOGGING;
INSERT /*+ APPEND */ INTO large_tab SELECT * FROM source_tab;
ALTER TABLE large_tab LOGGING;
10.5 OFFLINE 表空间卡住
现象:执行 ALTER TABLESPACE users OFFLINE 长时间无响应。
原因:触发局部检查点,DBWn 写该表空间脏块速度慢。
修复:
-- 1. 监控 DBWn 进度
SELECT event, total_waits, time_waited
FROM v$system_event
WHERE event LIKE '%checkpoint%';
-- 2. 加快检查点完成(暂时调小 MTTR)
ALTER SYSTEM SET fast_start_mttr_target=30 SCOPE=BOTH;
-- 3. 或使用 OFFLINE TEMPORARY(不触发完全检查点)
ALTER TABLESPACE users OFFLINE TEMPORARY;
10.6 SHUTDOWN IMMEDIATE 缓慢
现象:SHUTDOWN IMMEDIATE 卡住几分钟才完成。
原因:触发完全检查点,DBWn 需要写所有脏块。
修复:
-- 1. 提前手动触发检查点
ALTER SYSTEM CHECKPOINT;
-- 2. 等几秒后再 shutdown
SHUTDOWN IMMEDIATE;
-- 3. 调整参数加快关闭
ALTER SYSTEM SET fast_start_mttr_target=30 SCOPE=BOTH;
11. 最佳实践
11.1 使用 FAST_START_MTTR_TARGET
-- 推荐设置(根据业务 SLA)
-- OLTP: 60-120 秒
-- OLAP: 300-600 秒
ALTER SYSTEM SET fast_start_mttr_target=120 SCOPE=BOTH;
-- 关闭旧参数
ALTER SYSTEM SET log_checkpoint_interval=0 SCOPE=BOTH;
ALTER SYSTEM SET log_checkpoint_timeout=0 SCOPE=BOTH;
11.2 合理规划 Redo Log
-- 查看当前 Redo Log 配置
SELECT group#, bytes/1024/1024 AS mb, members, status
FROM v$log;
-- 健康指标:
-- 1. 每组至少 1 个 member(推荐 2-3 个多路复用)
-- 2. 至少 3 个 group(推荐 4-6 个)
-- 3. 单组大小:每小时切换 3-5 次
-- 4. 大小估算:峰值 Redo 速率 × 30 分钟
估算 Redo 速率:
-- 查看每小时 Redo 生成量
SELECT
to_char(first_time, 'YYYY-MM-DD HH24') AS hour,
sum(blocks * block_size)/1024/1024/1024 AS redo_gb
FROM v$archived_log
WHERE first_time > SYSDATE-1
GROUP BY to_char(first_time, 'YYYY-MM-DD HH24')
ORDER BY hour DESC;
11.3 根据负载调整 DBWn 进程数
-- 监控 DBWn 等待
SELECT event, total_waits, time_waited
FROM v$system_event
WHERE event IN ('free buffer waits', 'write complete waits');
-- 如果等待明显,增加 DBWn
ALTER SYSTEM SET db_writer_processes=4 SCOPE=SPFILE;
-- 重启生效
-- 经验值:
-- 1-4 CPU: 1 个 DBWn
-- 8-16 CPU: 2-4 个 DBWn
-- 32+ CPU: 4-8 个 DBWn
11.4 监控检查点进度
-- 定期检查实例恢复进度
SELECT
recovery_estimated_ios,
actual_redo_blks,
target_redo_blks
FROM v$instance_recovery;
-- actual_redo_blks 应该接近 target_redo_blks 的 50% 以下
11.5 启用检查点日志
ALTER SYSTEM SET log_checkpoints_to_alert=TRUE SCOPE=BOTH;
-- 便于排错,开销很小
11.6 ASM + 多 DBWn
对于使用 ASM 的高负载系统:
-- 1. 增加 DBWn
ALTER SYSTEM SET db_writer_processes=8 SCOPE=SPFILE;
-- 2. ASM 配置多 disk group 分散 I/O
-- DATA: 数据文件
-- FRA: 闪回区
-- REDO: Redo Log(单独 disk group 性能最佳)
-- 3. ASM AU 大小 4M(大数据库)
-- CREATE DISKGROUP DATA EXTERNAL REDUNDANCY
-- DISK '/dev/asm*' ATTRIBUTE 'au_size'='4M';
11.7 关闭数据库前预 checkpoint
-- 维护窗口前
ALTER SYSTEM CHECKPOINT;
-- 等待几秒
ALTER SYSTEM SWITCH LOGFILE;
-- 再 SHUTDOWN
SHUTDOWN IMMEDIATE;
12. 参考资料
[1] Oracle Database Administrator’s Guide 19c, “Controlling Checkpoints” https://docs.oracle.com/en/database/oracle/oracle-database/19/admin/controlling-checkpoints.html
[2] Oracle Database Concepts 19c, “Checkpoints” https://docs.oracle.com/en/database/oracle/oracle-database/19/cncpt/checkpoints.html
[3] AskTOM, “Checkpoint Internals and FAST_START_MTTR_TARGET” https://asktom.oracle.com/pls/apex/f?p=100:1:0
[4] 墨天轮,“Oracle 检查点机制与实例恢复详解” https://www.modb.pro/db/1759656813559025664
[5] Oracle Support Note 147468.1, “Checkpoint Tuning and Troubleshooting Guide” https://support.oracle.com/epmos/faces/DocumentDisplay?id=147468.1
[6] Jonathan Lewis, “Oracle Core: Essential Internals for DBAs and Developers”(Apress, 2011)