ora-01578与ora-26040组合报错表明物理备库存在nologging导致的soft corruption,应优先用rman blockrecover修复;若失败,则需主库基于first_nonlogged_scn执行增量备份并在备库noredo恢复,修复后须验证v$datafile中first_nonlogged_scn是否归零并刷新缓冲区。

备库报ORA-01578 + ORA-26040,基本就是NOLOGGING导致的坏块
物理备库遇到 ORA-01578 并伴随 ORA-26040(“Data block was loaded using the NOLOGGING option”),不用查日志也能断定:主库执行了 NOLOGGING 操作(比如 INSERT /*+ APPEND */、CREATE TABLE ... NOLOGGING 或 impdp DISABLE_ARCHIVE_LOGGING:Y),且主库未开启 FORCE LOGGING。这类坏块属于 soft corruption,不破坏文件结构,但访问对应块时直接报错,无法用常规 DML 绕过。
别急着停库或拷文件,先确认坏块范围和影响对象
在备库执行以下查询,明确是哪个数据文件、哪些块出问题:
-
SELECT * FROM V$DATABASE_BLOCK_CORRUPTION;—— 查看当前标记的坏块 -
SELECT FILE#, FIRST_NONLOGGED_SCN FROM V$DATAFILE WHERE FIRST_NONLOGGED_SCN > 0;—— 找出受 NOLOGGING 影响的数据文件及其起点 SCN -
SELECT owner, segment_name, segment_type FROM dba_extents WHERE file_id = &file_id AND &block_id BETWEEN block_id AND block_id + blocks - 1;—— 定位坏块归属的表或索引(避免盲目修复整库)
注意:不要只看 V$DATABASE_BLOCK_CORRUPTION,它可能只反映已触发访问的块;而 V$DATAFILE.FIRST_NONLOGGED_SCN 才是真正受影响文件的“污染起点”,更可靠。
RMAN BLOCK RECOVER 是最快最安全的修复方式
只要主库完好、归档完整、备库处于 MOUNT 或 OPEN READ ONLY 状态,RMAN 可直接从主库拉取日志块修复,无需传输整个数据文件,也不用中断太久。操作顺序不能乱:
- 停日志应用:
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL; - 执行块恢复:
RMAN> RECOVER DATAFILE &file_id BLOCK &block_id;(支持多块,如BLOCK 100, 101, 102) - 重启日志应用:
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT;
这个过程依赖主库的归档日志和在线日志,RMAN 会自动选择所需日志流,不需要提前备份。但如果坏块太多(比如整个分区被 NOLOGGING 插入),RMAN 可能因找不到连续日志而失败——这时才考虑增量备份方案。
增量备份修复要严格按 SCN 切片,跳步必失败
当 RMAN BLOCK RECOVER 失败或坏块分散在多个文件时,必须走基于 SCN 的增量备份路径。关键点在于:主库备份必须从 FIRST_NONLOGGED_SCN 开始,而不是从当前 SCN 或任意时间点:
- 主库执行:
RMAN> BACKUP INCREMENTAL FROM SCN &scn_value DATAFILE &file_id FORMAT '/tmp/inc_%U' TAG 'FOR_STANDBY'; - 备库注册备份:
RMAN> CATALOG START WITH '/tmp/inc_'; - 备库恢复:
RMAN> RECOVER DATAFILE &file_id NOREDO;(注意是NOREDO,因为日志已在主库生成并应用过)
漏掉 OFFLINE/ONLINE 数据文件步骤、或在 RECOVER 前没停止日志应用,都会导致控制文件状态不一致,后续 OPEN 报 ORA-10567。修复后务必再查一遍 V$DATAFILE,确保 FIRST_NONLOGGED_SCN 回归为 0。
最易被忽略的是:修复完成后,如果立即查询刚修好的表,仍可能报错。因为 buffer cache 里还缓存着旧的 corrupt branch 块,需执行 ALTER SYSTEM CHECKPOINT; 等 DBWR 刷盘,或极谨慎地用 ALTER SYSTEM FLUSH BUFFER_CACHE;(仅限测试环境)。











