ORA-01578(数据块损坏) 错误解决

执行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’ ; 

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

ORACLE块即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的数据库server打开了异步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,记录下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联系。不过这些方面的的机率很少很少的,在以后的文章中我也会做介绍。  


 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/14075938/viewspace-471575/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/14075938/viewspace-471575/

你可能感兴趣的:(操作系统,数据库)