跳过正文

记一次 Oracle RAC Level 0 备份连续失败:从 NetBackup Status 6 到 datafile 264 恢复

Greatfinish
作者
Greatfinish
记录 Oracle、PostgreSQL、达梦、Linux、存储与生产环境故障处理经验。

故障背景
#

某套 Oracle 11.2.0.4 双节点 RAC 的每周 Level 0 备份连续失败。NetBackup 只给出 User backup failed (6),RMAN 客户端日志却每次停在同一个数据文件、同一个块号。现场先处理索引,使该位置成为空闲 extent,再把 datafile 264 恢复成新的 ASM 文件。

数据库端恢复、DISK 验证和 datafile 264 的 NetBackup SBT Level 0 写入均已完成。RMAN 目录中的备份集状态为 AVAILABLE,NetBackup 作业 10485387 以状态 0 结束。备份流程还需修正脚本退出码,并对 SBT 备份集做一次 RMAN 读回验证。下一次整库 Level 0 也尚未验证。

环境和故障位置
#

项目现场值
数据库Oracle Database 11.2.0.4
架构双节点 RAC
存储ASM,数据在 +DATA,归档在 +ARCH
备份Veritas NetBackup,RMAN Level 0
数据文件file# 264,表空间 GYGD_BI
原文件+DATA/orclpd/datafile/gygd_bi.530.1070638017
固定故障点block 1586176,block size 8192

故障证据链
#

本次故障最终形成了下面这条证据链:

NetBackup Status 6
dbclient 返回失败
RMAN-03009
ORA-19501
ORA-15081
datafile 264 / block 1586176
DISK VALIDATE 仍在相同块失败
排除 NetBackup SBT 作为直接根因
故障块对应索引 extent
迁移对象后 extent 释放
生成 DISK Level 0 救援 backupset
恢复到新的 ASM 文件
VALIDATE / CHECK LOGICAL 通过
NetBackup SBT Level 0 单文件备份成功

状态 6 只给出了失败结果
#

NetBackup 作业日志中的顺序很有用。

Info dbclient (...) wrote first buffer(size=262144)
Info dbclient (...) done. status: 6
Error bptm (...) media manager terminated by parent process
User backup failed (6)

dbclient 先返回失败,随后 bptm 被父进程终止。Veritas 对状态 6 的解释是用户备份因错误而失败,并要求继续检查客户端进度日志和数据库扩展日志。这里的 media manager terminated by parent process 出现在客户端失败之后,根因仍要从客户端日志找。

Media Server 当时还有 57 TB 可用空间,MSDP 也已经接收数据并输出去重统计。

Filesystem                       Size  Used Avail Use% Mounted on
/dev/mapper/vg_backup-lv_backup  117T   61T   57T  52% /kn_nbu_backup

StorageServer=PureDisk:media-kn-new
scanned: 12727413 KB
dedup: 61.1%
compression space saving: 61.0%

接下来检查 Oracle 客户端。RMAN 的 ch00 和 ch01 先后在同一位置失败。

RMAN-03009: failure of backup command on ch00 channel
ORA-19501: read error on file
"+DATA/orclpd/datafile/gygd_bi.530.1070638017",
block number 1586176 (block size=8192)
ORA-15081: failed to submit an I/O operation to a disk

channel ch00 disabled, job failed on it will be run on another channel

RMAN-03009: failure of backup command on ch01 channel
ORA-19501: read error on file
"+DATA/orclpd/datafile/gygd_bi.530.1070638017",
block number 1586176 (block size=8192)
ORA-15081: failed to submit an I/O operation to a disk

错误按下面的顺序向上返回。

file# 264 的 block 1586176 读取失败
→ ORA-15081
→ ORA-19501
→ RMAN-03009
→ dbclient status 6
→ NetBackup status 6

用 DISK validate 切断 NetBackup 变量
#

直接使用 RMAN 的 DISK channel 验证原文件。

VALIDATE DATAFILE 264;

2026 年 8 月 4 日的现场结果仍指向原位置。

input datafile file number=00264
name=+DATA/orclpd/datafile/gygd_bi.530.1070638017
RMAN-03009: failure of validate command on ORA_DISK_1 channel
ORA-19501: read error on file
"+DATA/orclpd/datafile/gygd_bi.530.1070638017",
block number 1586176 (block size=8192)
ORA-15081: failed to submit an I/O operation to a disk

这次验证没有经过 NetBackup SBT 库,仍然复现相同文件和块号。排查范围缩到 Oracle 数据文件及 ASM 或底层存储 I/O 路径。

同时查询 Oracle 的坏块视图。

select file#, block#, blocks, corruption_type, corruption_change#
from v$database_block_corruption
where file# = 264;
no rows selected

这个空结果不能覆盖 RMAN 的直接读错误。V$DATABASE_BLOCK_CORRUPTION 记录 Oracle 已标记的物理或逻辑块损坏,本次错误栈给出的是底层 I/O 提交失败。排查时应把视图结果和 VALIDATE 的错误栈一起看。

块号先落到对象,再落到物理文件
#

块 1586176 距文件头约 12.10 GiB。

1586176 × 8192 bytes ≈ 12.10 GiB

先查它当时属于哪个 extent。

select owner,
       segment_name,
       partition_name,
       segment_type,
       tablespace_name,
       block_id,
       blocks,
       block_id + blocks - 1 end_block
from dba_extents
where file_id = 264
  and 1586176 between block_id and block_id + blocks - 1;
OWNER         GYGD_BI
SEGMENT_NAME  SYS_C00390447
SEGMENT_TYPE  INDEX
TABLESPACE    GYGD_BI
BLOCK_ID      1585664
BLOCKS        8192
END_BLOCK     1593855

SYS_C00390447GYGD_BI.FACT_STOCK_SHOP_2021 的主键唯一索引。现场完成对象迁移后,同一条 DBA_EXTENTS 查询已经没有记录,DBA_FREE_SPACE 显示原位置落在一个 64 MB 的空闲 extent 中。

select tablespace_name,
       file_id,
       block_id,
       blocks,
       block_id + blocks - 1 end_block,
       round(bytes/1024/1024, 2) size_mb
from dba_free_space
where file_id = 264
  and 1586176 between block_id and block_id + blocks - 1;
TABLESPACE_NAME  GYGD_BI
FILE_ID          264
BLOCK_ID         1585664
BLOCKS           8192
END_BLOCK        1593855
SIZE_MB          64

对象迁走以后,VALIDATE DATAFILE 264 仍在 block 1586176 报 ORA-19501ORA-15081。索引层已经避开故障点,原数据文件的物理读取问题仍在。

缩小文件也走不通。现场查询得到高水位约 21.76 GiB,故障块之后还有 746 个 extent。

select file_id,
       max(block_id + blocks - 1) hwm_block,
       round(max(block_id + blocks - 1) * 8192 / 1024 / 1024 / 1024, 2) hwm_gb
from dba_extents
where file_id = 264
group by file_id;

select count(*) extents_after_bad_block
from dba_extents
where file_id = 264
  and block_id + blocks - 1 >= 1586176;
FILE_ID  HWM_BLOCK  HWM_GB
264      2851839    21.76

EXTENTS_AFTER_BAD_BLOCK
746

12 GiB 附近做 RESIZE 会碰到文件后部仍在使用的 extent。这条路在执行前就被 SQL 结果排除了。

空闲 extent 让救援 backupset 成为可能
#

原 extent 释放后,对 file# 264 单独生成 DISK Level 0 backupset。

RUN {
    ALLOCATE CHANNEL d1 DEVICE TYPE DISK;

    BACKUP AS BACKUPSET
        INCREMENTAL LEVEL 0
        DATAFILE 264
        FORMAT '+ARCH'
        TAG 'DF264_RESCUE_L0_20260805';

    RELEASE CHANNEL d1;
}

最新一份备份在 2026 年 8 月 5 日生成。

BS Key      230561
BP Key      230924
Type        Incr 0
Size        16.66G
Device Type DISK
Status      AVAILABLE
Tag         DF264_RESCUE_L0_20260805
Checkpoint SCN 24582312976013
Piece Name  +ARCH/orclpd/backupset/2026_08_05/
            nnndn0_df264_rescue_l0_20260805_0.388.1240511237

channel d1: backup set complete, elapsed time: 00:01:05
Finished backup

随后读取整份备份集做验证。

VALIDATE BACKUPSET 230561;
channel ORA_DISK_1: validation complete, elapsed time: 00:00:35
Finished validate

Oracle 11g 文档说明,满足未使用块压缩条件时,DISK 上的 full 或 Level 0 backupset 只读取当前分配给数据库段的块。文档同时说明,VALIDATE 也会跳过从未使用的块;在 COMPATIBLE >= 10.2 的本地管理表空间中,它还会跳过当前未分配块。现场结果不足以推导出 backupset 跳过而 validate 必读的规则。

这里能够确认两件事。NetBackup 失败时,该位置仍属于索引 extent;extent 释放后,DISK Level 0 完成并通过 VALIDATE BACKUPSET。原文件在现场复测中仍报告同一 I/O 错误,本文只记录结果,不借此推断 RMAN 内部对该块的读取细节。

这条救援路径依赖具体环境。COMPATIBLE、guaranteed restore point、表空间管理方式、备份类型和目标设备都会影响未使用块压缩。Oracle 11g 文档列出的目标设备是 DISK 或 Oracle Secure Backup,NetBackup SBT 不属于 Oracle Secure Backup。生产操作前要逐项核对,备份生成后还要执行 VALIDATE BACKUPSET

恢复到新的 ASM 文件
#

生产窗口内先停止 GYGD_BI 相关写入,备份控制文件和 SPFILE,再将 file# 264 正常 offline。恢复脚本最终使用了明确的 tag 和单文件 switch。

RUN {
    ALLOCATE CHANNEL d1 DEVICE TYPE DISK;

    SET NEWNAME FOR DATAFILE 264 TO '+DATA';

    RESTORE DATAFILE 264
        FROM TAG 'DF264_RESCUE_L0_20260805';

    SWITCH DATAFILE 264;

    RECOVER DATAFILE 264;

    RELEASE CHANNEL d1;
}

第一次使用 RESTORE DATAFILE 264 FROM BACKUPSET 时,RMAN 在现场解析阶段报错。

RMAN-01009: syntax error: found "backupset": expecting one of:
"autobackup, tag, double-quoted-string, single-quoted-string"

Oracle 11g 的命令参考中列有 FROM BACKUPSET 选项,因此这次报错不应扩大成版本限制。现场改用 FROM TAG 后,restore、switch 和 recover 均完成,同时明确锁定了已经验证的救援备份。

channel d1: restore complete, elapsed time: 00:01:05
Finished restore
datafile 264 switched to datafile copy
media recovery complete, elapsed time: 00:00:00
Finished recover

控制文件中的文件名已经改变。

旧文件  +DATA/orclpd/datafile/gygd_bi.530.1070638017
新文件  +DATA/orclpd/datafile/gygd_bi.1153.1240512549

Oracle 的标准流程要求 SET NEWNAME 后先 restore,再用 SWITCH 更新控制文件指向,随后 recover。现场修正后的命令与这个顺序一致。

验收看新文件,也看备份能力
#

recover 完成后,现场先确认 RECOVER=NOV$RECOVER_FILE 没有记录,再将文件 online。下面是 online 后保存的综合验收查询。

select df.file#,
       df.name,
       df.status,
       df.enabled,
       dh.recover,
       dh.fuzzy,
       dh.checkpoint_change#
from v$datafile df
join v$datafile_header dh on dh.file# = df.file#
where df.file# = 264;

select * from v$recover_file
where file# = 264;

select * from v$database_block_corruption
where file# = 264;
FILE#    264
NAME     +DATA/orclpd/datafile/gygd_bi.1153.1240512549
STATUS   ONLINE
ENABLED  READ WRITE
RECOVER  NO

V$RECOVER_FILE
no rows selected

V$DATABASE_BLOCK_CORRUPTION
no rows selected

物理验证和块内逻辑验证各执行一次。

VALIDATE DATAFILE 264;
VALIDATE CHECK LOGICAL DATAFILE 264;
channel ORA_DISK_1: validation complete, elapsed time: 00:00:35
Finished validate at 05-AUG-26

channel ORA_DISK_1: validation complete, elapsed time: 00:00:55
Finished validate at 05-AUG-26

CHECK LOGICAL 检查通过物理校验的数据块内部是否逻辑一致。它不校验块间关系,也不能代替表与索引一致性检查或业务查询。

恢复后的新文件又执行了一次 DISK Level 0,错误关键字检查没有返回内容。这个输出只证明已展示的日志中没有这些错误,正式记录仍应补存 LIST BACKUPVALIDATE BACKUPSET 的结果。

egrep -i 'ORA-|RMAN-[0-9]|error|fail' \
/tmp/df264_after_restore_backup_20260805_*.log

NetBackup 单文件 264 复测
#

复测使用了 hot_datafile_264_backup.sh,脚本变量和 RMAN 输入都指向 file# 264。

Script: /usr/openv/rman/hot_datafile_264_backup.sh
DATAFILE_NO: 264
input datafile file number=00264
piece handle=df264_230875_1_1240565773
tag=DF264_LEVEL0

RMAN 日志确认,这次读取的是恢复后的新 ASM 文件,而不是 file# 246 或原来的故障文件。

DATAFILE_NO: 264
channel ch00: Veritas NetBackup for Oracle - Release 8.0 (2016110921)

input datafile file number=00264
name=+DATA/orclpd/datafile/gygd_bi.1153.1240512549
piece handle=df264_230875_1_1240565773
tag=DF264_LEVEL0
channel ch00: backup set complete, elapsed time: 00:04:38
Finished backup at 06-AUG-26
Recovery Manager complete.

数据库动态视图、RMAN 目录和 NetBackup Job Details 的记录也与备份日志一致。

select session_key,
       input_type,
       status,
       start_time,
       end_time,
       output_bytes_display,
       time_taken_display
from v$rman_backup_job_details
where start_time > sysdate - 0.5
order by start_time desc;
SESSION_KEY  INPUT_TYPE     STATUS     OUTPUT_BYTES_DISPLAY  TIME_TAKEN_DISPLAY
-----------  -------------  ---------  --------------------  ------------------
14069        DATAFILE INCR  COMPLETED  16.70G                00:04:44
RMAN> LIST BACKUP OF DATAFILE 264 TAG 'DF264_LEVEL0';

BS Key          230594
BP Key          230957
Type            Incr 0
Size            16.70G
Device Type     SBT_TAPE
Elapsed Time    00:04:31
Completion Time 06-AUG-26
Status          AVAILABLE
Tag             DF264_LEVEL0
Handle          df264_230875_1_1240565773
Media           @aaaa9
File            264
Name            +DATA/orclpd/datafile/gygd_bi.1153.1240512549
NetBackup Job Details

Job ID:          10485387
Job State:       Done (Successful)
Client:          vbiracdb1
Policy:          bidbm_oracle
Storage Unit:    msdp-kn-pool-stu
Media Server:    media-kn-new
Current Kilobytes Written: 17515296
Percent Complete: 100%

dbclient ... done. status: 0
bptm ... EXITING with status 0
The requested operation was successfully completed. (0)

下表按四层记录这次复测的证据。

检查层现场证据能确认什么
目标文件file number=00264 和新 ASM 文件名实际备份对象是恢复后的 datafile 264
RMAN 写入backup set completeFinished backupLevel 0 备份片已通过 SBT 写完
数据库记录session 14069 为 COMPLETED;BS Key 230594 为 AVAILABLERMAN 任务完成,控制文件已登记备份集和备份片
NetBackupJob 10485387、status 0NetBackup 应用备份作业成功结束

AVAILABLE 不等于读回验证
#

目前证据足以确认 datafile 264 的 SBT 备份写入完成、NetBackup 作业状态为 0。LIST BACKUP 中的 AVAILABLE 表示 RMAN 目录认为备份片可用,不代表 RMAN 已从 NetBackup 读回并检查整套备份。Job Details 里的 validating image for client 也不能替代 RMAN 的 VALIDATE BACKUPSET

如需把结论写成“备份集读回验证通过”,还要使用本次 BS Key 和相同的 NetBackup 参数执行以下命令。

RUN {
    ALLOCATE CHANNEL ch00 TYPE 'SBT_TAPE';
    SEND 'NB_ORA_POLICY=bidbm_oracle,NB_ORA_CLIENT=vbiracdb1';

    VALIDATE BACKUPSET 230594;

    RELEASE CHANNEL ch00;
}

验收日志应出现读取备份片、validation completeFinished validate,同时不含 RMAN 或 ORA 错误。

到这里,数据库恢复、恢复后物理与块内逻辑检查,以及 datafile 264 的 NetBackup SBT 单文件备份写入都已完成。旧 ASM 文件 .530.1070638017 继续保留,等脚本以退出码 0 结束、SBT 备份集读回验证和下一次整库 Level 0 都通过后,再走清理变更。

参考资料
#