
好的,我们来深入解析 Oracle 19c 中一个非常重要但常被忽视的动态性能视图:V$BACKUP_NONLOGGED。这个视图直接关系到备份的可靠性和可恢复性。
1. 视图作用
V$BACKUP_NONLOGGED 用于标识和跟踪在 NOLOGGING 或 UNRECOVERABLE 模式下操作后,因此可能包含“不可恢复”数据块的数据文件。
其核心作用是:
- 风险暴露: 暴露由于
NOLOGGING操作导致的潜在数据不一致风险,这些操作会绕过重做日志机制。 - 备份验证: 帮助 DBA 验证一个已有的备份集是否包含这些在备份时处于“无效”状态的数据块。
- 恢复预警: 提前警告 DBA,如果基于某个备份进行恢复,某些数据文件中的特定数据块可能已经损坏,因为它们的更改从未被记录到归档日志中。
- 补救指导: 指示需要采取哪些行动(如执行新的备份)来使数据库回到一个完全可恢复的状态。
⚠️ 核心价值: 它是备份有效性和可恢复性的“守门人”。一个成功的备份不代表它一定能成功恢复,这个视图揭示了那些可能导致恢复失败的关键隐患。
2. 使用场景
- 备份后检查: 在执行大型
NOLOGGING操作(如SQL*Loader direct path,CREATE TABLE ... AS SELECT ... NOLOGGING)后,立即检查此视图,确认操作对备份状态的影响。 - 恢复准备: 在执行恢复之前,查询目标备份集的
RECID/STAMP,确认该备份是否受到NOLOGGING操作的影响。 - 监控与审计: 定期检查,确保没有未知的或意外的
NOLOGGING操作破坏了备份的完整性。 - 制定备份策略: 根据
NOLOGGING操作的频率和影响,决定是否需要更频繁的增量备份。
3. 字段详解 (Oracle 19c)
该视图的字段直接关联到受影响的备份和文件。
| 字段名 | 数据类型 | 描述 |
|---|---|---|
RECID | NUMBER | 备份记录的唯一标识符。与 STAMP 一起,唯一标识一个受 NOLOGGING 操作影响的备份集。 |
STAMP | NUMBER | 备份记录的时间戳标识符。与 RECID 共同构成主键。 |
BS_RECID | NUMBER | (可能已废弃)备份集记录 ID。 |
BS_STAMP | NUMBER | (可能已废弃)备份集时间戳。 |
FILE# | NUMBER | 关键:受 NOLOGGING 操作影响的数据文件编号。 |
CREATE_TIME | DATE | 关键:记录此 NOLOGGING 信息的时间(即 Oracle 发现此问题的时间)。 |
NONLOGGED_START_SCN | NUMBER | 关键:NOLOGGING 操作开始的 SCN(系统变更号)。 |
NONLOGGED_START_TIME | DATE | 关键:NOLOGGING 操作开始的时间。 |
NONLOGGED_END_SCN | NUMBER | 关键:NOLOGGING 操作结束的 SCN。 |
NONLOGGED_END_TIME | DATE | 关键:NOLOGGING 操作结束的时间。 |
BLOCK_ID | NUMBER | 受影响的起始数据块ID。 |
BLOCKS | NUMBER | 受影响的连续数据块数量。 |
AUX_NAME | VARCHAR2(256) | 辅助名称。 |
CON_ID | NUMBER | 容器ID(在多租户环境中使用)。 |
📌 核心字段解读:
FILE#,NONLOGGED_START_SCN,NONLOGGED_END_SCN定义了“问题窗口”。任何备份,如果其检查点 SCN 落在这个窗口内,那么它包含的该数据文件就是不可靠的。CREATE_TIME表示 Oracle 何时感知到这个NOLOGGING操作。这通常发生在操作之后的下一次检查点或文件头写入时。
4. 相关视图与基表
关联视图
| 视图名称 | 描述 | 关系 |
|---|---|---|
V$BACKUP_SET | 备份集元数据。 | 通过 RECID 和 STAMP 与 V$BACKUP_NONLOGGED 关联,可以获取受影响备份集的详细信息(如完成时间、标签)。 |
V$DATAFILE | 当前数据文件信息。 | 通过 FILE# 关联,可以获取受影响的数据文件名称和所属表空间,使信息更具可读性。 |
V$DATAFILE_HEADER | 数据文件头信息。 | 包含 UNRECOVERABLE_CHANGE# 和 UNRECOVERABLE_TIME 字段,这些字段与 V$BACKUP_NONLOGGED 中的 SCN 和时间直接对应,是同一事件在不同层面的表现。 |
V$BACKUP_DATAFILE | 数据文件备份详情。 | 用于查找备份的 CHECKPOINT_CHANGE#,以验证其是否落在 NOLOGGING 时间窗口内。 |
底层基表
X$KRCBL或X$KRBNL:存储非日志记录块的内部动态性能表(内存结构)。V$BACKUP_NONLOGGED的数据来源于此。X$KCVFH:文件头信息表,其中包含UNRECOVERABLE相关的 SCN 和时间戳。
⚠️ 警告: 这些
X$表是Oracle内部的、未文档化的结构,严禁直接查询。
5. 底层详细原理
NOLOGGING 操作如何破坏备份
flowchart TD
A[NOLOGGING 操作<br>e.g., Direct Path Load] --> B[数据直接写入数据文件<br>绕过重做日志机制]
B --> C[操作完成后的检查点]
C --> D[文件头更新<br>记录UNRECOVERABLE_SCN和时间]
D --> E[Oracle 在内存中<br>X$KRCBL 表记录此事件]
E --> F[V$BACKUP_NONLOGGED<br>视图可见]
F --> G{RMAN 执行备份}
G --> H{备份检查点SCN<br>晚于 NONLOGGED_START_SCN?}
H -- 是 --> I[备份包含“空洞”块<br>恢复时将损坏]
H -- 否 --> J[备份安全]
- 操作执行: 用户执行
NOLOGGING操作(如INSERT /*+ APPEND */)。为了性能,Oracle 直接修改数据块,而不将更改向量记录到重做日志中。 - 标记文件头: 操作完成后,在下一个检查点,Oracle 会更新受影响数据文件的文件头,将
UNRECOVERABLE_CHANGE#和UNRECOVERABLE_TIME设置为操作结束时的 SCN 和时间。这是一个永久性标记。 - 内存记录: Oracle 在内存中的内部结构(
X$KRCBL)记录这一事件,包括文件号、开始和结束 SCN。 - 视图可见:
V$BACKUP_NONLOGGED视图从此内存结构中读取数据,使其对 DBA 可见。 - 备份影响: 任何在该
NOLOGGING操作之后、但下一次备份之前进行的备份,都会包含这些数据块。但由于更改没有重做记录,恢复时无法前滚这些块,导致它们永久损坏。
“修复”机制
唯一的“修复”方法是执行一个新的全量备份或增量备份(Level 0)。新的备份会在 NOLOGGING 操作之后进行,因此其检查点 SCN 晚于 NONLOGGED_END_SCN,备份集将包含数据块的最新有效状态,从而“覆盖”掉之前无效的备份记录。
6. 关键知识点介绍
1. 哪些操作会产生 NOLOGGING 影响?
CREATE TABLE ... AS SELECT ... NOLOGGINGALTER TABLE ... MOVE ... NOLOGGINGALTER TABLE ... ADD COLUMN ... <default value>ALTER INDEX ... REBUILD ... NOLOGGINGSQL*Loader使用DIRECT=TRUE参数INSERT /*+ APPEND */ INTO ... NOLOGGING(Direct Path Insert)
2. 数据文件头中的标记
即使 V$BACKUP_NONLOGGED 中的记录因为实例重启而消失(因为它在内存中),数据文件头中的 UNRECOVERABLE_CHANGE# 标记也会一直存在,直到该文件被再次备份。你可以通过以下查询看到这个永久标记:
SELECT file#, unrecoverable_change#, unrecoverable_time
FROM v$datafile_header
WHERE unrecoverable_change# IS NOT NULL;
3. 与增量备份的关系
这是 NOLOGGING 操作的一个特例。如果启用了块更改跟踪 (Block Change Tracking),并且执行的是增量备份,Oracle 可以智能地避免备份那些在 NOLOGGING 操作中修改的块,因为它知道这些块无法被恢复。这可以防止增量备份被污染。
7. 常用查询 SQL
① 检查当前是否存在影响备份完整性的 NOLOGGING 操作
SELECT n.file#,
d.name AS datafile_name,
n.nonlogged_start_scn,
TO_CHAR(n.nonlogged_start_time, 'YYYY-MM-DD HH24:MI:SS') AS start_time,
n.nonlogged_end_scn,
TO_CHAR(n.nonlogged_end_time, 'YYYY-MM-DD HH24:MI:SS') AS end_time,
TO_CHAR(n.create_time, 'YYYY-MM-DD HH24:MI:SS') AS detected_time
FROM v$backup_nonlogged n
JOIN v$datafile d ON n.file# = d.file#
ORDER BY n.create_time DESC;
② 验证特定备份集是否受 NOLOGGING 操作影响
-- 首先找到你想检查的备份集 BS_KEY 或 TAG
SELECT bs.recid, bs.stamp, bs.bs_key, bs.tag, bs.completion_time
FROM v$backup_set bs
WHERE bs.tag = 'MY_WEEKLY_FULL_BACKUP'; -- 替换为你的备份标签
-- 然后使用 RECID 和 STAMP 检查
SELECT n.*, d.name
FROM v$backup_nonlogged n
JOIN v$datafile d ON n.file# = d.file#
WHERE n.recid = &your_recid
AND n.stamp = &your_stamp;
③ 查找所有需要新备份的数据文件(补救措施指南)
SELECT DISTINCT n.file#,
d.name AS datafile_name
FROM v$backup_nonlogged n
JOIN v$datafile d ON n.file# = d.file#
WHERE NOT EXISTS (
-- 查找在该NOLOGGING操作之后的新备份
SELECT 1
FROM v$backup_datafile bd
WHERE bd.file# = n.file#
AND bd.checkpoint_change# > n.nonlogged_end_scn -- 关键:备份SCN晚于NOLOGGING结束SCN
AND bd.incremental_level = 0 -- 通常需要0级备份来修复
);
④ 结合数据文件头信息进行综合评估
SELECT d.file#,
d.name,
TO_CHAR(dh.unrecoverable_time, 'YYYY-MM-DD HH24:MI:SS') AS unrecoverable_time,
dh.unrecoverable_change#,
TO_CHAR(n.nonlogged_start_time, 'YYYY-MM-DD HH24:MI:SS') AS nonlogged_start,
n.nonlogged_start_scn
FROM v$datafile d
JOIN v$datafile_header dh ON d.file# = dh.file#
LEFT JOIN v$backup_nonlogged n ON d.file# = n.file#
WHERE dh.unrecoverable_change# IS NOT NULL;
总结
- 核心价值:
V$BACKUP_NONLOGGED是一个关键的风险预警系统。它揭示了高性能NOLOGGING操作所带来的隐藏代价:备份不可恢复的风险。 - 最佳实践:
- 监控: 将检查此视图的脚本纳入日常备份检查流程。
- 补救: 一旦发现记录,立即对受影响的数据文件执行新的备份(最好是 Level 0)。
- 设计: 在应用设计阶段就评估
NOLOGGING操作的必要性,并规划好后续的备份窗口。
- 关键注意:
- 视图记录存储在内存中,实例重启后会丢失。但数据文件头上的
UNRECOVERABLE标记是持久的。 - 即使视图是空的,也不能百分百保证备份有效,因为记录可能已被重启清除。最可靠的方法是检查
V$DATAFILE_HEADER.UNRECOVERABLE_CHANGE#并与备份的CHECKPOINT_CHANGE#进行比较。 - 在使用增量备份且启用了块更改跟踪时,情况会稍微复杂,但风险依然存在。
- 视图记录存储在内存中,实例重启后会丢失。但数据文件头上的
🔧 最终建议: 在执行任何已知的
NOLOGGING操作后,有计划地安排一次备份。 这是消除风险最彻底的方法。
欢迎关注我的公众号《IT小Chen》
582

被折叠的 条评论
为什么被折叠?



