1. Oracle 各版本处理不同类型坏块的方法总结

坏块类型Oracle 11gOracle 12cOracle 18cOracle 21cOracle 23ai
物理坏块 发现方法:
 
1. DBV FILE=<数据文件路径> BLOCKSIZE=<块大小>(检测物理损坏,输出Corrupt block
 
2. RMAN> VALIDATE DATAFILE <文件号>;(结果记录到V$DATABASE_BLOCK_CORRUPTION
 
3. 告警日志(alert.log)中搜索ORA-1578(物理坏块标识)
 
 
处理方法:
 
1. BLOCKRECOVER DATAFILE <文件号> BLOCK <块号> FROM BACKUP;
 
2. 离线数据文件后恢复:ALTER DATABASE DATAFILE <文件号> OFFLINE; + 恢复 + 上线
发现方法:
 
1. 继承 11g 方法,新增RMAN> VALIDATE DATAFILE <文件号> ONLINE;(在线检查,不阻塞业务)
 
2. V$DATABASE_BLOCK_CORRUPTION新增CORRUPTION_TYPE='PHYSICAL'过滤
 
 
处理方法:
 
1. 在线修复:BLOCKRECOVER DATAFILE <文件号> BLOCK <块号> ONLINE;
 
2. 混合检查修复:VALIDATE DATAFILE <文件号> CHECK LOGICAL;(同时检测逻辑坏块)
发现方法:
 
1. 自动检测:启用DB_BLOCK_CHECKING=TRUE后,数据库后台自动扫描物理坏块并记录到V$DIAG_ALERT_EXT(ADR 日志)
 
2. 并行检查:RMAN> VALIDATE DATABASE SECTION SIZE 1G;(按 1G 分片并行检测)
 
 
处理方法:
 
1. ADG 自动修复:备库物理坏块自动从主库同步好块(需配置LOG_ARCHIVE_CONFIG
 
2. 快速标记:ALTER DATABASE MARK BLOCK <块号> DATAFILE <文件号> AS CORRUPT;
发现方法:
 
1. 跨平台检查:RMAN> VALIDATE DATAFILE <文件号> FROM SERVICE <远程库TNS>;(检查异机备份的物理坏块)
 
2. V$DEGRADED_SEGMENTS(提前预警即将损坏的块,REASON='CORRUPT BLOCKS'
 
 
处理方法:
 
1. 跨平台修复:BLOCKRECOVER ... FROM SERVICE <主库TNS>;
 
2. 批量修复:BLOCKRECOVER CORRUPTION LIST;(修复V$视图中所有物理坏块)
发现方法:
 
1. AI 预测:DBMS_AI_REPAIR.PREDICT_BAD_BLOCKS(基于历史数据预测 7 天内可能损坏的块)
 
2. 实时监控:OCI 控制台自动展示物理坏块数量及位置(云环境)
 
 
处理方法:
 
1. 智能修复:DBMS_AI_REPAIR.AUTO_FIX_PHYSICAL(自动选择备份或主库同步修复)
 
2. 云备份联动:直接从 OCI 备份修复,无需指定备份集
逻辑坏块 发现方法:
 
1. ANALYZE TABLE <表名> VALIDATE STRUCTURE CASCADE;(检测逻辑坏块,输出ORA-1498
 
2. RMAN> VALIDATE DATAFILE <文件号> CHECK LOGICAL;(标记逻辑坏块到V$DATABASE_BLOCK_CORRUPTIONCORRUPTION_TYPE='LOGICAL'
 
3. 查询表时出现ORA-600 [kdsgrp1](逻辑坏块典型错误)
 
 
处理方法:
 
1. DBMS_REPAIR.SKIP_CORRUPT_BLOCKS(标记坏块,查询时跳过)
 
2. 导出重建:EXPDP + DROP + IMPDP
发现方法:
 
1. 在线分析:ANALYZE TABLE <表名> VALIDATE STRUCTURE ONLINE;(不阻塞 DML)
 
2. V$LOGICAL_BLOCK_CORRUPTION(单独记录逻辑坏块,12c 新增视图)
 
 
处理方法:
 
1. 在线标记:DBMS_REPAIR.ONLINE_SKIP_CORRUPT(业务不中断)
 
2. 从主库修复:BLOCKRECOVER ... FROM ACTIVE DATABASE;(直接同步好块)
发现方法:
 
1. ADR 自动记录:逻辑坏块信息同时写入alert.logADR$ORACLE_BASE/diag/.../trace
 
2. 批量检查:RMAN> VALIDATE DATABASE CHECK LOGICAL SECTION SIZE 512M;(并行检测逻辑坏块)
 
 
处理方法:
 
1. 批量标记:DBMS_REPAIR.BATCH_MARK_CORRUPT(一次标记多个逻辑坏块)
 
2. 日志追溯:DBMS_LOGMNR分析 redo,定位坏块产生时间点
发现方法:
 
1. 实时监控:V$LOGICAL_CORRUPTION_DETAILS(显示逻辑坏块的具体错误类型,如ROWID MISMATCH
 
2. 自动告警:OEM中配置逻辑坏块阈值告警(如超过 10 个触发通知)
 
 
处理方法:
 
1. 在线修复:ALTER SYSTEM REPAIR LOGICAL BLOCK <块号> DATAFILE <文件号>;
 
2. 闪回修复:FLASHBACK DATABASE TO SCN <坏块产生前的SCN>;(需开启闪回)
发现方法:
 
1. AI 根因分析:DBMS_AI_REPAIR.ANALYZE_LOGICAL(识别逻辑坏块是因NOLOGGING、bug 还是异常终止导致)
 
2. 智能扫描:后台线程按优先级扫描逻辑坏块(核心表优先)
 
 
处理方法:
 
1. 自动修复:AI 工具生成修复脚本,自动执行(需 DBA 确认)
 
2. 逻辑重构:对复杂逻辑错误,自动重构数据块结构
表坏块 发现方法:
 
1. 定位坏块所属表:
 
SELECT SEGMENT_NAME, OWNER FROM DBA_EXTENTS WHERE FILE_ID=<文件号> AND <块号> BETWEEN BLOCK_ID AND BLOCK_ID+BLOCKS-1;
 
2. 查询表时出现ORA-1578ORA-600错误(含表名)
 
 
处理方法:
 
1. 跳过坏块查询:SELECT * FROM <表名> SKIP CORRUPT;
 
2. 重建表:CREATE TABLE <新表> AS SELECT * FROM <旧表> SKIP CORRUPT;
发现方法:
 
1. 实时定位:SELECT * FROM V$CORRUPT_BLOCKS JOIN DBA_SEGMENTS ON V$CORRUPT_BLOCKS.OBJECT_ID=DBA_SEGMENTS.OBJECT_ID;(直接关联表名)
 
2. 分区表检查:ANALYZE TABLE <表名> VALIDATE STRUCTURE PARTITION <分区名>;
 
 
处理方法:
 
1. 在线重定义:DBMS_REDEFINITION(不中断查询,重建表规避坏块)
 
2. 分区修复:仅重建含坏块的分区
发现方法:
 
1. 表级校验:ALTER TABLE <表名> VALIDATE STRUCTURE CASCADE;(同时检查依赖索引)
 
2. DBA_TABLES新增CORRUPT_BLOCKS列(直接显示表中坏块数量)
 
 
处理方法:
 
1. 并行导出好数据:EXPDP ... QUERY=<表名>:"WHERE ROWID NOT IN (SELECT ROWID FROM ...)"
 
2. 在线迁移:ALTER TABLE <表名> MOVE ONLINE;(自动跳过坏块)
发现方法:
 
1. 行级定位:SELECT ROWID, <列名> FROM <表名> WHERE DBMS_REPAIR.IS_CORRUPT(ROWID)=1;(定位具体坏行)
 
2. 历史追踪:DBA_HIST_CORRUPTION(记录表坏块的历史变化)
 
 
处理方法:
 
1. 自动数据迁移:DBMS_TABLESPACE.MIGRATE_CORRUPT_DATA(将好数据迁移到新块)
 
2. 表分区拆分:拆分含坏块的分区,丢弃坏块部分
发现方法:
 
1. AI 智能定位:自动关联表坏块与业务 SQL(识别哪个操作触发坏块)
 
2. 优先级排序:按表的业务重要性排序坏块修复优先级
 
 
处理方法:
 
1. 智能重建:根据表大小和访问频率,自动选择在线 / 离线重建
 
2. 数据拯救:优先提取坏块中的可用数据(基于行级恢复)
索引坏块 发现方法:
 
1. ANALYZE INDEX <索引名> VALIDATE STRUCTURE;(结果存INDEX_STATSBAD_BLOCKS列非 0)
 
2. 查询时出现ORA-1578且涉及索引扫描(执行计划含INDEX
 
 
处理方法:
 
1. 删除重建:DROP INDEX <索引名>; CREATE INDEX <索引名> ON <表名>(<列名>);
 
2. 跳过坏块:ALTER INDEX <索引名> SKIP CORRUPT BLOCKS;(仅查询时生效)
发现方法:
 
1. 在线分析:ANALYZE INDEX <索引名> VALIDATE STRUCTURE ONLINE;(不阻塞 DML)
 
2. DBA_INDEXES新增BAD_BLOCKS列(直接显示索引坏块数量)
 
 
处理方法:
 
1. 在线重建:CREATE INDEX <索引名> ON <表名>(<列名>) ONLINE;
 
2. 分区索引修复:ALTER INDEX <索引名> REBUILD PARTITION <分区名> ONLINE;
发现方法:
 
1. 并行分析:ANALYZE INDEX <索引名> VALIDATE STRUCTURE PARALLEL 4;(加速检查)
 
2. 索引监控:ALTER INDEX <索引名> MONITORING USAGE;(结合V$OBJECT_USAGE发现 unused 索引中的坏块)
 
 
处理方法:
 
1. 并行重建:CREATE INDEX <索引名> ... PARALLEL 8;(利用多核加速)
 
2. 快速重建:ALTER INDEX <索引名> REBUILD FAST;(仅重建索引树,不重新排序数据)
发现方法:
 
1. 增量检查:ANALYZE INDEX <索引名> VALIDATE STRUCTURE INCREMENTAL;(仅检查新增块)
 
2. V$INDEX_CORRUPTION(专门记录索引坏块,含分区信息)
 
 
处理方法:
 
1. 智能并行:ALTER INDEX <索引名> REBUILD PARALLEL AUTO;(按 CPU 自动调整并行度)
 
2. 索引碎片与坏块同时修复:ALTER INDEX <索引名> REBUILD ONLINE COMPUTE STATISTICS;
发现方法:
 
1. AI 预测性检查:识别即将损坏的索引块(基于访问频率和历史损坏模式)
 
2. 关联分析:自动关联索引坏块与对应表的 DML 操作
 
 
处理方法:
 
1. 自愈修复:轻微坏块自动修复(无需全量重建)
 
2. 业务低峰重建:AI 预测业务低谷期,自动执行索引重建

小结:处理坏块的能力在 Oracle 11g 已经非常完善。新版本的改进不在于颠覆性方法,而在于:

  1. 自动化:如通过 Health Monitor 自动检测并生成修复建议。

  2. 集成化:与 RMAN、Data Guard Broker 更深度集成,简化操作流程。

  3. 云化:在 Oracle Cloud 环境中,提供一键式的检测和修复服务。


2. 为什么主库运行一段时间后启用 FORCE LOGGING 再做从库,容易发生坏块?

这是一个非常经典且重要的问题。原因核心在于:在主库未开启 FORCE LOGGING 模式下执行的 NOLOGGING 操作,其产生的数据变化不会记录到重做日志中。当这些操作产生的数据块通过归档日志传输到从库并尝试应用时,就会导致逻辑坏块。

详细解释如下:

  1. NOLOGGING 操作的存在:

    • 为了追求极致性能,某些大规模写入操作(如 CREATE TABLE ... AS SELECTALTER TABLE ... MOVEALTER INDEX ... REBUILD、直接路径插入 /*+ APPEND */)支持 NOLOGGING 模式。

    • 在此模式下,操作本身只会生成极少量的重做日志(主要是字典元数据变化),而实际写入的数据块内容不会被记录。

  2. 主库的默认行为:

    • 如果主库没有设置 FORCE LOGGING,用户就可以执行 NOLOGGING 操作。这些操作在主库本地是正常的,因为数据被直接写入磁盘。

  3. 从库的困境:

    • Data Guard 的运作原理是:主库将重做日志(归档日志)传输到从库,从库的 Managed Recovery Process 应用这些重做日志来保持数据同步。

    • 关键点:当从库尝试应用一个对应于主库 NOLOGGING 操作的重做日志时,它会发现日志中缺少重构对应数据块所需的完整数据内容。

    • 为了解决这个问题,Oracle 设计了一个机制:当应用进程遇到这种“无日志”的操作时,它会尝试对受影响的数据块进行一次逻辑上的“介质恢复”。但这个过程只是简单地将该数据块标记为逻辑损坏(通常会在告警日志中看到 ORA-01578ORA-26040 等错误),而不是真正地写入正确数据。

  4. 启用 FORCE LOGGING 的时机问题:

    • 如果您在主库运行了很长时间(期间可能执行过未知的 NOLOGGING 操作)之后,才启用 FORCE LOGGING 并搭建从库,那么问题就暴露了。

    • 搭建从库的过程(例如使用 RMAN Active Duplicate)会复制主库的数据文件。这些文件中已经包含了之前 NOLOGGING 操作写入的数据。

    • 当从库开始应用归档日志,并“回溯”到那些 NOLOGGING 操作对应的日志记录时,就会触发上述机制,将那些原本在主库上“正常”的数据块在从库上标记为逻辑坏块。

结论:FORCE LOGGING 模式应该在创建主库之后、投入生产业务之前就启用。这样可以确保从数据库生命周期的起点开始,所有的数据变化(包括全量操作)都被完整地记录在日志中,从而保证 Data Guard 环境的数据一致性,从根本上避免这类逻辑坏块的发生。

 posted on 2025-09-23 14:56  xibuhaohao  阅读(5)  评论(0)    收藏  举报