Oracle 老熊 块损坏处理实战

Oracle 老熊 块损坏处理实战

来源:老熊 (Laoxiong) / laoxiong.net 适用版本:Oracle Database 全版本 文档版本:v1.0 / 2026-07-22


1. 概述

老熊对块损坏处理有深度实战经验[1]。

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


2. 块损坏类型

2.1 物理损坏

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

2.2 逻辑损坏

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

2.3 老熊分类

- 软损坏:可绕过
- 硬损坏:物理
- 严重:需工具

3. 检测方法

3.1 alert log

- ORA-01578
- ORA-01110
- 文件号/块号

3.2 RMAN VALIDATE

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

3.3 DBV

dbv file=/u01/oradata/users01.dbf blocksize=8192

3.4 ANALYZE

ANALYZE TABLE emp VALIDATE STRUCTURE CASCADE;

3.5 老熊方法

- 多种验证
- 全面
- 定位

4. v$database_block_corruption

4.1 查看

SELECT file#, block#, blocks, corruption_type 
FROM v$database_block_corruption;

4.2 corruption_type

- ALL ZERO:全零
- FRACTURED:不完整
- CHECKSUM:校验和
- CORRUPT:损坏
- UNKNOWN

4.3 老熊分析

- 类型决定方案
- 评估
- 选择

5. 恢复方法

5.1 RMAN BLOCKRECOVER

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

5.2 数据文件恢复

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

5.3 DBMS_REPAIR

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

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

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

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

5.4 ROWID 提取

-- 跳过坏块
CREATE TABLE emp_new AS
SELECT * FROM emp WHERE ROWID NOT IN (
  SELECT ROWID FROM emp 
  WHERE DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) = 100
);

5.5 老熊顺序

1. BLOCKRECOVER(首选)
2. 数据文件恢复
3. DBMS_REPAIR
4. ROWID 提取
5. BBED(最后)

6. 老熊案例 1:ORA-01578

6.1 现象

- SELECT 报 ORA-01578
- file 5, block 100

6.2 诊断

- DBV 验证
- v$database_block_corruption
- 类型

6.3 恢复

RMAN> BLOCKRECOVER DATAFILE 5 BLOCK 100;

6.4 验证

SELECT * FROM emp;
-- 无错误

7. 老熊案例 2:无备份

7.1 现象

- 块损坏
- 无 RMAN 备份
- 紧急

7.2 老熊方案

- DBMS_REPAIR 跳过
- ROWID 提取
- BBED(最后)

7.3 DBMS_REPAIR

EXEC DBMS_REPAIR.ADMIN_TABLES('REPAIR_ADMIN', 1, 1, 'USERS');
EXEC DBMS_REPAIR.CHECK_OBJECT('SCOTT','EMP', NULL, 1, 'REPAIR_ADMIN');
EXEC DBMS_REPAIR.FIX_CORRUPT_BLOCKS('SCOTT','EMP', NULL, 1, 'REPAIR_ADMIN');
EXEC DBMS_REPAIR.SKIP_CORRUPT_BLOCKS('SCOTT','EMP', 1);

7.4 重建

CREATE TABLE emp_new AS SELECT * FROM emp;
DROP TABLE emp;
RENAME emp_new TO emp;
-- 重建索引

8. 老熊案例 3:索引损坏

8.1 现象

- 索引块损坏
- ORA-01578

8.2 老熊方案

- 重建索引
- 简单

8.3 重建

ALTER INDEX emp_idx REBUILD ONLINE;

9. 老熊案例 4:SYSTEM 损坏

9.1 现象

- SYSTEM 块损坏
- 严重
- 数据库不稳定

9.2 老熊方案

- RMAN 恢复
- 不完全恢复
- 联系 Support

9.3 恢复

RMAN> STARTUP MOUNT;
RMAN> RESTORE DATABASE;
RMAN> RECOVER DATABASE;
RMAN> ALTER DATABASE OPEN;

10. BBED 深度

10.1 介绍

- Block Browser and Editor
- 块级编辑
- 高级工具

10.2 老熊警告

- 危险
- 仅最后手段
- 需经验
- 联系 Support

10.3 用途

- 修改 SCN
- 修复块头
- 抢救数据

10.4 示例

# 启动
bbed parfile=bbed.par

# 查看块
set dba 5,100
dump

# 修改
modify /x 01 offset 4

10.5 老熊强调

- 谨慎
- 备份原块
- 测试

11. 预防

11.1 备份

- RMAN 定期
- VALIDATE
- 多副本

11.2 参数

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

11.3 监控

- alert log
- VALIDATE 定期
- DBV

11.4 存储

- RAID
- 冗余
- 监控

12. 老熊经验

12.1 优先级

1. BLOCKRECOVER
2. 数据文件
3. DBMS_REPAIR
4. ROWID
5. BBED

12.2 原则

- 备份优先
- 保护现场
- 评估损失
- 慎重

12.3 工具

- RMAN
- DBMS_REPAIR
- DBV
- BBED
- 第三方

13. 监控

13.1 定期

RMAN> BACKUP VALIDATE CHECK LOGICAL DATABASE;
SELECT * FROM v$database_block_corruption;

13.2 自动

- 定时任务
- 告警
- 响应

13.3 老熊推荐

- 周度 VALIDATE
- 监控 alert
- 响应

14. 最佳实践

  1. 备份:RMAN
  2. VALIDATE:定期
  3. BLOCKRECOVER:首选
  4. DBMS_REPAIR:次选
  5. BBED:最后
  6. 备份原块:修改前
  7. 监控:alert
  8. 参数:启用
  9. 存储:冗余
  10. 演练:故障

15. 参考资料

[1] 老熊, “块损坏处理”, https://www.laoxiong.net [2] Oracle Database Backup and Recovery User’s Guide 19c