Chinaunix首页 | 论坛 | 博客
  • 博客访问: 927888
  • 博文数量: 358
  • 博客积分: 8185
  • 博客等级: 中将
  • 技术积分: 3751
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-15 16:27
个人简介

The views and opinions expressed all for my own,only for study and test, not reflect the views of Any Company and its affiliates.

文章分类

全部博文(358)

文章存档

2012年(8)

2011年(18)

2010年(50)

2009年(218)

2008年(64)

我的朋友

分类: Oracle

2009-06-09 15:50:24

dbms_repair
dbms_repair
ORA-01578:Oracle data block corrupted(file # num,block # num)
ORA-01578(数据块损坏) 错误解决
2008-11-04 21:25

执行select b.dataname, count(distinct a.username)
from ics001.user_info a, ics001.data_dict_info b
where feestatus=1 and regflag=1
and a.localarea=b.subclassid
and b.dicttype=102
and registdate>=to_date('2008-10-10 00:00:00', 'yyyy-mm-dd hh24:mi:ss')
and registdate<=to_date('2008-10-16 23:59:59', 'yyyy-mm-dd hh24:mi:ss')
group by b.dataname

报错

ORA-01578: ORACLE 数据块损坏(文件号15,块号55470)
ORA-01110: 数据文件 15…………

解决措施:

1. 检查损坏的对象

SELECT *
FROM dba_extents
where file_id = 15 and 55401 between block_id and block_id+blocks-1

查到是user_info表

2. 设置内部事件,使exp跳过损坏的block
ALTER SYSTEM SET EVENTS=’10231 trace name context forever,level 10’

3. 导出表
exp share/passwd    file=user_info.dmp tables=user_info

4. 删除有坏块的表
drop table user_info

drop table user_info purge (10G)

-- 5. 导入表
imp share/passwd file=user_info.dmp tables=user_info

-- 6. 清除跟踪事件
ALTER SYSTEM SET EVENTS=’10231 trace name context off’ ;

贴一篇别人解决此问题的案例

块即ORA-01578错,同时还可能伴随ORA-01110错,这种错误对于初学者或是那些没有实践经验的dba来说无疑是很棘手的。我当初就深受其害,写下这篇文章则是希望对大家有所帮助。
一、出问题时的情景
1、 我的一个计费的入库的进程停掉,报的便是ORA-01578错,对应用相关的表tg_bill03做SQL>select from tg_cdr03 where rownum<10;这样是可以的,但做SQL>select count(*) from tg_bill03;时则报ORA-01578错。
2、 检查alter.log中看到一几条报错信息:
Errors in file /oracle816/app/admin/billing/udump/ora_7281_billing.trc:
ORA-01578: ORACLE data block corrupted (file # 126, block # 88490)
ORA-01110: data file 126: '/dev/vgjf7/rdata471'

二、事后分析产生这种问题的原因
1、 十之八九这个Oracle的数据库
打开了异步I/O(async io)或增加了写进程。
2、 硬件的I/O出现了错误。
3、 操作系统的I/O或缓存出现我问题,比如操作系统对于异步I/O的补丁没有打。
4、 手动的修改了数据文件中的数据,我模拟这个错误用的便是这种方式。

三、解决方法
这种问题的解决方法是很多的,如果你用的是归档方式,则可以基于时间点恢复来解决。不过这里介绍一种比较方便的解决方式,因为我的库没有开归档。Metaline关于ORA-01578的文字也很多,不过我看过后总觉得都不那么实用,不能解决实际的问题。
1、 解决这种问题的第一步是首先你要确定是什么段、哪个段了,是索引还是表?
A、 打开alter.log,找到ORA-01578的报错信息,并记录下file#及block的值,我这里是126和88490。
B、 执行以下语句看哪个段
SQL>Select * from dba_extents
2 where file_id=
3 and between block_id and block_id+blocks-1;
这里的F指的是file#,B指的是block#
我的显示结果指出是tg_bill03出现了块。

2、如果确定下来的是索引段,这时你就可以轻舒一口气了,只要把这个索相删除然后重建一下就可以了,如果出现的是表段,则应往下走了。

3、 记录下这个表的建表语句
为我方便,建议使用PL/SQL Developer来完成,如果你没有可以在http://www.allroundautomations.com/plsqldev.html去下载一个,操作步骤是这样的。
A、 以表的owner用pl/sql developer连入oracle
B、 在左面的树状栏中找到这个表tg_bill03,右击该表->view->View
,记录下sql,以备以下步骤中重建索引。
4、 实际处理了,以我的那个表为例
A、 以tg_bill03的owner连入oracle
B、 使用诊断事件10231
SQL> ALTER SYSTEM SET EVENTS ‘10231 trace name context forever,level 10’;
C、创建一个临时表tg_bill_tmp的表中除块的数据都检索出来
SQL>CREATE TABLE tg_bill03_tmp as select * from tg_bill03;
C、 更名原表,并把tg_bill03_tmp为tg_bill03
SQL>alter table tg_bill03 rename to tg_bill03_bak;
SQL>alter table tg_bill03_tmp to tg_bill03;
D、在tg_bill03上重新创建索引、约束、授权、trigger等对象
E、 利用表之间的业务关系,把块中的数据补足。

四、如何尽量减少问题及问题的损失呢
分析了产生问题的原因,我认为可以采取以下几个措施
1、 在为提高性能为操作系统打开异步I/O时,一定要与oracle及操作系统技术支持联系把操作系统与异步I/O相关的补丁要打全。
2、 制定一个良好的
恢复策略,最好有表的exp备份
3、 要及时的检查硬件的状态,及时更换驱动器部件。

结篇:其实块涉及的内容很多的,如果块发生的回滚段表空间、数据字典(system表空间)或联机日志,这些处理都是特难的,需要与oracle的supporter联系。不过这些方面的的机率很少很少的,在以后的文章中我也会做介绍。  

阅读(1121) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~