块损坏
- 只要对块执行读或写操作,就会执行下列一致性检查
- 块版本
- 高速缓存中的 DBA(数据块地址)值与块缓冲区中的DBA 值比较的结果
- 块校验和(如果启用)
- 类别
- 介质损坏(块格式不正确)
- 处理方法
- 恢复或删除块
- 处理硬件故障
- 逻辑(或软件)损坏
- 块损坏故障现象:ORA-01578
- 发现损坏的数据块时生成此信息
- 始终返回相对文件号和块号
- 始终返回相同的参数,则最可能的原因是块介质损坏
- 如果返回的参数每次都有变化,则可能存在硬件问题
- 返回到发出查询的会话(该查询在发现损坏时执行)
- 在 alert.log 文件中显示
如何处理损坏
- 检查预警日志和操作系统日志文件。
- 使用可用的诊断工具,找出损坏的类型。
- 多次运行检查功能,确定错误是否持续存在。
- 根据需要,从损坏的对象中恢复数据。
- 解决硬件问题
- 内存条
- 磁盘控制器
- 磁盘
- 根据需要,从损坏的对象中恢复或还原数据
与损坏相关的功能
- DBVERIFY 实用程序
- 检查块一致性
- 可以在打开数据库的情况下使用
- 局限性
- DBVERIFY 不能检测诸如 INDEX与 TABLE不匹配之类的问题
- DBVERIFY 不验证重做日志文件或控制文件
- DBVERIFY 只单独检查数据块;不考虑数据块是否属于现有对象
- 对于裸设备,应使用END 参数,以免扫描的块范围超出数据文件空间末尾
-
dbv FILE=/dev/rdsk/r1.dbf END=last_data_block#
- 示例
-
$ dbv file=/u01/oradata/users01.dbf \ blocksize=8192
- 解释 DBVERIFY 输出
- 一个“page”表示一个块
- 如果块的头尾不匹配,DBVERIFY 就会重新读取此块。如果块的头尾匹配,则报告一个流入块;否则报告一个块损坏。
- ANALYZE 命令
- 执行逻辑块检查
- 不将块标记为软损坏;只报告软损坏情况
- 验证索引项和表项
- 对象必须位于本地计算机,并且必须是在您自己的方案中,或者必须拥有ANALYZE ANY系统权限。CASCADE 选项可以验证对象,包括该对象的所有相关对象。
- 示例
-
-
SQL> ANALYZE TABLE table_name VALIDATE STRUCTURE CASCADE;
-
SQL> ANALYZE INDEX index_name VALIDATE STRUCTURE;
-
- DB_BLOCK_CHECKING(实时验证块完整性)
- 在对每个块执行自我一致性检查时,控制检查的处理程度
- 可防止内存和数据损坏
- true或false
- 四个可能的值
-
- OFF:在除 SYSTEM之外的任何表空间中都不执行块检查
- LOW:在内存中块的内容发生更改之后,执行基本的块头检查
- MEDIUM:执行所有 LOW 检查,并对所有不是按索引组织的表块执行块检查
- FULL:执行所有 LOW 和 MEDIUM检查,以及对索引块的检查
- DB_BLOCK_CHECKSUM(实时验证块完整性)
- 确定是否保持校验和,以及是否对每个块都进行验证
- 可以防止由底层 I/O 系统引起的损坏
- 使用 EXP 检测损坏
- 示例
-
$ exp hr/hr tables=departments
- 使用闪回检查逻辑损坏
- 排除物理损坏之后,可以使用闪回功能组合来确定发生逻辑损坏的时间。闪回版本查询还可以返回事务处理标识。得到事务处理标识之后,就可以查看受同一事务处理影响的所有对象。
- DBMS_REPAIR 程序包
- 包括
- CHECK_OBJECT:检测并报告表或索引中的损坏
- FIX_CORRUPT_BLOCKS:将原先由 CHECK_OBJECT 过程识别的块标记为软件(或逻辑)损坏
- DUMP_ORPHAN_KEYS:将索引条目报告到一个孤立的键表中,此键表指向损坏的数据块中的行
- REBUILD_FREELISTS:重建对象的可用列表
- SEGMENT_FIX_STATUS:段空间管理为 AUTO 时,可提供修复位图条目损坏状态的功能
- SKIP_CORRUPT_BLOCKS:在表与索引扫描期间忽略标记为损坏的块。
- ADMIN_TABLES:提供修复孤立键表所需的管理功能(创建、删除或清除)。这些表始终采用SYS 模式进行创建
- 使用 DBMS_REPAIR
- 检测并报告损坏
-
SET SERVEROUTPUT ON
DECLARE num_corrupt INT;
BEGIN
num_corrupt := 0;
DBMS_REPAIR.CHECK_OBJECT (
Schema_name => 'HR',
object_name => 'DEPARTMENTS',
repair_table_name => 'REPAIR_TABLE',
corrupt_count => num_corrupt);
END; - 评估 DBMS_REPAIR 的成本和优势
- 使对象变为可用
-
SET SERVEROUTPUT ON
DECLARE num_fix INT;
BEGIN
num_fix := 0;
DBMS_REPAIR.FIX_CORRUPT_BLOCKS (
schema_name => 'HR',
object_name => 'DEPARTMENTS',
object_type => DBMS_REPAIR.TABLE_OBJECT,
repair_table_name => 'REPAIR_TABLE',
fix_count => num_fix);
END; - 修复损坏并重建丢失的数据
-
SET SERVEROUTPUT ON
DECLARE num_orphans INT;
BEGIN
num_orphans := 0;
DBMS_REPAIR.DUMP_ORPHAN_KEYS (
schema_name => 'SCOTT',
object_name => 'PK_DEPT',
object_type => DBMS_REPAIR.INDEX_OBJECT,
repair_table_name => 'REPAIR_TABLE',
orphan_table_name => 'ORPHAN_KEY_TABLE',
key_count => num_orphans);
DBMS_OUTPUT.PUT_LINE('orphan key count: ' ||
TO_CHAR(num_orphans));
END;
块介质恢复 (BMR)
- 降低平均恢复时间 (MTTR)
- 提高介质恢复期间的可用性
- 恢复期间数据文件保持联机状态
- 只有正在恢复的块是不可访问的
- 可以通过 RMAN 使用 BLOCKRECOVER 命令进行调用
- 从可用备份中还原个别块
- 与服务器协调工作恢复块介质
- 其他
- 确定包含要进行恢复的块的备份
- 读取备份并将请求的块累积到内存缓冲区
- 必要时,通过从备份中读取归档日志来管理块介质恢复会话
- 不能用于不完全恢复
- 示例
- 恢复一组损坏的块
-
BLOCKRECOVER DATAFILE 2 BLOCK 12, 13
DATAFILE 7 BLOCK 5, 98, 99 DATAFILE 9 BLOCK 19; - 恢复一系列块,并且只从数据文件副本进行还原
-
{
BLOCKRECOVER DATAFILE 3 BLOCK 1,2,3,4,5
TABLESPACE sales DBA 4194405, 4194409, 4194412
FROM DATAFILE COPY;
} - 按备份标记限制 BMR
-
BLOCKRECOVER TABLESPACE SYSTEM DBA 4194404, 4194405
FROM TAG "weekly_backup"; - 恢复 SYSTEM表空间中的两个块,并强制从创建时间至少在两天以前的备份中进行还原
-
BLOCKRECOVER TABLESPACE SYSTEM DBA 4194404, 4194405 RESTORE
UNTIL TIME 'SYSDATE-2'; - 恢复两个块,并强制使用在 SCN 100 之前执行的备份进行还原
-
BLOCKRECOVER DATAFILE 9 BLOCK 13 DATAFILE 2 BLOCK 19 RESTORE
UNTIL SCN 100; - 恢复两个块,并强制使用在日志序列 7024 之前执行的备份进行还原
-
BLOCKRECOVER DATAFILE 9 BLOCK 13 DATAFILE 2 BLOCK 19 RESTOR
UNTIL SEQUENCE 7024; - RMAN BMR 接口
- V$DATABASE_BLOCK_CORRUPTION 视图显示当前损坏的数据库块的列表。
- V$BACKUP_CORRUPTION 视图显示数据文件备份中损坏的块的列表。
- V$COPY_CORRUPTION 视图显示图像文件副本中损坏的块的列表。
- 可以采用的替代操作
- 表:损坏的块中的数据已丢失。
-
- 删除然后重新创建表,再从导出转储中导入数据。
- 使用 SQL 或 PL/SQL,将数据从该表移到一个新建的表。
- 索引:删除然后重新创建索引。