Oracle数据库坏块检测

select a. owner,

       a.file_id,

       a.segment_name,

       a. segment_type,

       a.block_id,

       a.blocks

  from dba_extents a, v$database_block_corruption b

 where a.file_id = b.file#

   and a.block_id <= b.block#

   and (a.block_id + a.blocks - 1) >= b.block#

 order by a.segment_name

#########################################
 

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<sid>.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<sid>.log,找到ORA-01578的报错信息,并记录下file#及block的值,我这里是126和88490。
  
  B、 执行以下语句看哪个段坏了
  
  SQL>Select * from dba_extents
  
  2 where file_id=<F>
  
  3 and <B> between block_id and block_id+blocks-1;
  

  这里的F指的是file#,B指的是block#

 例如: select * from dba_extents where file_id='13' and 333123 between block_id and block_id+blocks-1;

  
  我的显示结果指出是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、 要及时的检查硬件的状态,及时更换驱动器部件。

  • 15
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值