正德厚生,臻于至善

Oracle数据库坏块简析

坏块介绍
Oracle数据库坏块是指在数据库的一个或多个数据块出现内容混乱的现象。正常的数据块都有固定合法的内容格式,坏块的出现,导致数据库读写进程无法正常解析数据块的内容,进而使数据库进程报错乃至挂起,并可能会导致整个数据库实例出现异常。

坏块产生的原因
Oracle坏块产生的原因有很多种,大概分为如下几类:
1. 硬件问题
内存故障,CPU模块故障,存储系统故障
2.操作系统异常
内核调用异常,系统BUG,I/O错误,内存或交换空间异常,非数据库进程异常使用Oracle缓冲池
3. Oracle BUG
4. 异常断电,异常停止服务,日常操作存储的扩容等

当出现坏块时,为找到根因,需要花费大量的人力与精力去分析排查,很可能有些场景是无法重现的。在生产环境上,需要尽快恢复系统的可用性,所以会破坏现场,所以分析根因起来更加困难。我们只能从日常的运维过程中,尽量的预防此事件发生。

坏块表象
在出现Oracle坏块时,我们经常会碰到以下错误:
1)ORA-01578错误
2)ORA-1110错误
3)ORA-00600错误
4)Trace文件中出现分析对象失败
5)其它异常事件

坏块检验
1)Oracle提供Recovery Manager工具,具备扫描文件检查坏块的功能
RMAN> validate datafile n block xxx ;
RMAN> backup check logical validate datafile n ;
SQL> select * from v$database_block_corruption ;
可以检查数据文件是否包含坏块。

2)DBV工具检查
注:因为dbv要求file后面跟的必须是一个文件扩展名,所以如果用裸设备存储的,就必须使用ln链接裸设备到一个文件,然后再用dbv对这个链接文件进行检查。
SQL> analyze table tablename validate structure cascade;
它执行坏块的检查,但是不会标记坏块为corrupt,检测的结果保存在USER_DUMP_DEST目录下的用户trace文件中。

3) exp工具导出整个数据库可以检测坏块
但是以下情况的坏块是检测不出来的:
HWM以上的坏块、索引中存在的坏块、数据字典中的坏块

坏块处理
1)使用RMAN备份进行恢复
首先由上面的RMAN检验工具进行检查,找出文件号与数据块号,根据结果执行如下命令进行恢复:
RMAN> blockrecover datafile * block ** from backupset;

2)没有备份的情况下(备份很重要啊,兄弟们)
采用exp导出命令,对报错的表或者对象进行导出。
exp user/password file=bad.dmp tables=bad_table;

导出命令在执行中会报ORA-01578错误,会提示那个文件号的文件以及这个文件中的哪个块被损坏,如:ORA—01578:ORACLE 数据块损坏(文件号 30,块号 31156)
查询那些对象被损坏:
select tablespace_name,segment_type,owner,segment_name From dba_extents Where file_id=30 and 31152 between block_id and block_id+blocks-1;

如果被损坏的块是索引,可以通过索引重建来解决;如果损坏的是数据,那么恭喜,只能丢失了。
设置如下内部事件使得exp操作跳过坏块。
alter session set events='10231 trace name context forever,level 10';
重新执行导出命令,导出相关的表,再删除表后导入表数据进行重建。丢了就丢了吧。

3)使用bbed恢复
这个官方不做技术支持,你爱干就可以干,我也不会用。

4)使用dbms_repair来标记和跳过坏块(网上大把介绍)
4.1)创建管理表:
SQL> exec DBMS_REPAIR.ADMIN_TABLES('REPAIR_TABLE',1,1,'USERS');
SQL> exec DBMS_REPAIR.ADMIN_TABLES('ORPHAN_TABLE',2,1,'USERS');

4.2)检查坏块:
Set serveroutput on;
DECLARE
   BAD NUMBER;
BEGIN
   DBMS_REPAIR.check_object (schema_name => 'APPS', 
                             object_name => 'BAD_OBJECT',
                             corrupt_count => BAD);
   DBMS_OUTPUT.put_line ( TO_CHAR (BAD));
END;
/

SELECT   *  FROM   repair_table;     
4.3) 定位坏块:dbms_repair.fix_corrupt_blocks     
DECLARE
   BAD   NUMBER;
BEGIN
   DBMS_REPAIR.fix_corrupt_blocks (schema_name   => 'APPS',
                                   object_name   => 'BAD_OBJECT',
                                   fix_count     => BAD);
   DBMS_OUTPUT.put_line (a => TO_CHAR (BAD));
END;
/

4.4) 跳过坏块:skip_corrupt_blocks
exec dbms_repair.skip_corrupt_blocks(schema_name => 'APPS',object_name => 'BAD_OBJECT',flags => 1);

总结:坏块虽讨厌,但是做好备份,做好预案,数据库服务器上别瞎整一些其它应用,定期升级打补丁,还是可以保住饭碗的。

---END---
赞(0) 打赏
未经允许不得转载:徐万新之路 » Oracle数据库坏块简析

支持快讯、专题、百度收录推送、人机验证、多级分类筛选器,适用于垂直站点、科技博客、个人站,扁平化设计、简洁白色、超多功能配置、会员中心、直达链接、文章图片弹窗、自动缩略图等...

联系我们

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续提供更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫

微信扫一扫

登录

找回密码

注册