Oracle Eygle 数据块损坏修复详解

Oracle Eygle 数据块损坏修复详解

来源:盖国强 (Eygle) / eygle.com 适用版本:Oracle Database 全版本 文档版本:v1.0 / 2026-07-22


1. 概述

数据块损坏是严重故障,Eygle 有系列案例[1]。

详细见:Oracle DBMS_REPAIR 修复损坏块详解


2. 块损坏类型

2.1 物理损坏

- 块头损坏
- 校验和失败
- 块版本错误

2.2 逻辑损坏

- 行数据不一致
- 索引与表不符
- SCN 异常

2.3 常见错误

- ORA-01578: data block corrupted
- ORA-01110: data file
- ORA-00600: internal error

3. 检测

3.1 alert log

- ORA-01578
- 损坏块地址
- 文件号/块号

3.2 RMAN 检查

RMAN> BACKUP VALIDATE CHECK LOGICAL DATABASE;
RMAN> BACKUP VALIDATE CHECK LOGICAL DATAFILE 5;

3.3 DBV

dbv file=/u01/oradata/users01.dbf

3.4 ANALYZE

ANALYZE TABLE emp VALIDATE STRUCTURE;
ANALYZE INDEX emp_idx VALIDATE STRUCTURE;

3.5 v$database_block_corruption

SELECT * FROM v$database_block_corruption;

4. 恢复方法 1:RMAN BLOCKRECOVER

4.1 适用

- 有 RMAN 备份
- 块级恢复
- 在线

4.2 命令

RMAN> BLOCKRECOVER DATAFILE 5 BLOCK 10, 11, 12;
RMAN> BLOCKRECOVER CORRUPTION LIST;
RMAN> BLOCKRECOVER ALL;

4.3 Eygle 推荐

- 首选
- 在线
- 快速

5. 恢复方法 2:数据文件恢复

5.1 适用

- 多块损坏
- 无块级备份

5.2 命令

RMAN> SQL 'ALTER DATABASE DATAFILE 5 OFFLINE';
RMAN> RESTORE DATAFILE 5;
RMAN> RECOVER DATAFILE 5;
RMAN> SQL 'ALTER DATABASE DATAFILE 5 ONLINE';

6. 恢复方法 3:DBMS_REPAIR

6.1 适用

- 无备份
- 跳过坏块
- 抢救数据

6.2 流程

-- 1. 创建修复表
EXEC DBMS_REPAIR.ADMIN_TABLES('REPAIR_ADMIN', 1, 1, 'USERS');

-- 2. 创建孤儿表
EXEC DBMS_REPAIR.ADMIN_TABLES('ORPHAN_ADMIN', 2, 1, 'USERS');

-- 3. 检查
EXEC DBMS_REPAIR.CHECK_OBJECT('SCOTT','EMP', NULL, 1, 'REPAIR_ADMIN');

-- 4. 标记
EXEC DBMS_REPAIR.FIX_CORRUPT_BLOCKS('SCOTT','EMP', NULL, 1, 'REPAIR_ADMIN');

-- 5. 跳过
EXEC DBMS_REPAIR.SKIP_CORRUPT_BLOCKS('SCOTT','EMP', 1);

-- 6. 重建索引
EXEC DBMS_REPAIR.DUMP_ORPHAN_KEYS('SCOTT','EMP_IDX', NULL, 1, 'ORPHAN_ADMIN');

6.3 Eygle 警告

- 会丢数据
- 跳过坏块
- 抢救部分
- 评估

7. 恢复方法 4:ROWID 提取

7.1 适用

- 无备份
- DBMS_REPAIR 失败
- 最后手段

7.2 提取

-- 坏块 file_id=5, block_id=100
-- 跳过坏块提取
SELECT * FROM emp WHERE ROWID NOT IN (
  SELECT ROWID FROM emp WHERE DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) = 100
    AND DBMS_ROWID.ROWID_TO_ABSOLUTE_FNO(ROWID,'SCOTT','EMP') = 5
);

7.3 重建表

1. 新建表
2. 插入好块数据
3. 重命名
4. 重建索引

8. 恢复方法 5:Data Guard

8.1 适用

- 有备库
- 块自动修复

8.2 配置

ALTER SYSTEM SET db_block_checksum=true;
ALTER SYSTEM SET db_block_checking=full;

8.3 自动

- 主库块损坏
- 备库自动修复
- 透明

9. Eygle 案例:ORA-01578

9.1 现象

- SELECT 报错 ORA-01578
- 块损坏

9.2 诊断

- alert log
- 查看文件号/块号
- DBV 验证

9.3 恢复

- RMAN BLOCKRECOVER
- 或 DBMS_REPAIR
- 评估数据

9.4 验证

SELECT * FROM emp;
-- 无错误

10. 预防

10.1 备份

- RMAN 定期
- 验证
- 多副本

10.2 监控

- RMAN VALIDATE
- DBV
- 定期

10.3 参数

ALTER SYSTEM SET db_block_checksum=true;
ALTER SYSTEM SET db_block_checking=full;
ALTER SYSTEM SET db_lost_write_protect=TYPICAL;

10.4 存储

- RAID
- 冗余
- 监控

11. 常见问题

11.1 索引块损坏

- 重建索引
- 简单

11.2 SYSTEM 块损坏

- 严重
- 需恢复
- 数据库无法启动

11.3 UNDO 块损坏

- 事务问题
- 隐含参数
- 救急

12. 最佳实践

  1. RMAN 备份:定期
  2. VALIDATE:检查
  3. BLOCKRECOVER:首选
  4. DBMS_REPAIR:次选
  5. ROWID:最后
  6. Data Guard:自动
  7. 监控:alert log
  8. 参数:启用
  9. 存储:冗余
  10. 演练:故障

13. 参考资料

[1] Eygle, “数据块损坏修复”, https://www.eygle.com [2] Oracle Database Backup and Recovery User’s Guide 19c