一、问题描述:
客户反映在做查询时报ORA-01578错,对应用相关的
表为area。请求恢复。
二、问题分析:
检查alter.log中看到一几条报错信息:
Errors in file
d:/oracle/app/admin/sang/udump/ora_741_sang.trc:
ORA-01578: ORACLE data block corrupted
(file # 6, block # 88490)
很明显的,是数据块损坏了,导致查询失败。
三、解决步骤:
步骤一:
解决这种问题的第一步是首先你要确定是什么段、哪个段坏了,是索引还是表?
SQL>Select * from dba_extents
where file_id=and between block_id and block_id+blocks-1;
这里的F指的是file#,B指的是block#
如果是索引段那就恭喜你啦,只要把损坏的索引段删除,然后重建就OK了。可惜今天运气不佳啊。显示结果指出是表area出现了坏块,是表段损坏了这就比较麻烦了.
步骤二:
使用DBV检查数据文件
C:\Documents and Settings\Administrator>dbv file=F:\oracle\product\10.2.0\oradat
a\movo\erp.DBF blocksize=8192
DBVERIFY: Release 10.2.0.1.0 - Production on星期四 11月12 18:12:35 2010
Copyright (c) 1982, 2005, Oracle. All rights reserved.
DBVERIFY -开始验证: FILE = F:\oracle\product\10.2.0\oradata\movo\BLOCK.DBF
页20标记为损坏
Corrupt block relative dba: 0x01800014 (file 6, block 20)
Bad check value found during dbv:
Data in bad block:
type: 6 format: 2 rdba: 0x01800014
last change scn: 0x0000.0015e13c seq: 0x1 flg: 0x06
spare1: 0x0 spare2: 0x0 spare3: 0x0
consistency value in tail: 0xe13c0601
check value in block header: 0xf7d7
computed block checksum: 0x7772
DBVERIFY -验证完成
检查的页总数: 128
处理的页总数(数据): 109
失败的页总数(数据): 0
处理的页总数(索引): 0
失败的页总数(索引): 0
处理的页总数(其它): 18
处理的总页数(段) : 0
失败的总页数(段) : 0
空的页总数: 0
标记为损坏的总页数: 2
流入的页总数: 0
最高块SCN: 1433924 (0.1433924)
损坏的总页数为2,这说明损坏的数据量不是很多。
步骤三:
如果数据库处于归档模式,并且存在有效的备份,可通过备份进行不完全恢复。
大致的恢复步骤:
1、把备份数据、归档日志文件等拷贝至测试机,在测试机上进行不完全恢复。
2、在生产库中删除数据块损坏的表
3、在测试库中导出数据块损坏的表
4、导入生产库
实际上从客户那里了解不存在有效的备份,利用备份恢复是不可能了,这也说明可以肯定损坏的块,一定是丢失了,找不回来了。目前能做的是让系统正常服务,尽量减少数据丢失。
步骤四:
1、首先记录下area表的建表脚本,可通过PL/SQL Developer获得。
2、使用诊断事件10231,在进行全表扫描的时候跳过损坏的块。如果直接用exp导出该表的数据肯定是报错的。
ALTER SYSTEM SET EVENTS ‘10231 trace name context forever,level 10’;
3、利用收集的脚本,创建一个临时表area_tmp,把area表中除坏块的数据都检索出来
CREATE TABLE area_tmp as select * from area;
查询area_tmp表记录数,发现只丢失了38条数据,告诉了客户,客户可以接受。继续恢复。
4、更名原表,并把area_tmp为area
SQL>alter table area rename to area_bak;
SQL>alter table area_tmp to area;
5、在area上重新创建索引、约束、授权、trigger等对象
6、利用表之间的业务关系,把坏块中的数据补足。
如果不打算补齐数据,那就需要注意,损坏的表可能与其他表存在主次表的关系,这可能就导致联合查询失败。解决方法,可以把与丢失数据存在关联关系的数据删除(留着也没有意义了),另外也可以以空值代替丢失的数据。