暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

ORA-8103故障处理案例分享

白鳝的洞穴 2020-05-28
2998
前两天介绍了一个ORA-8102的案例,今天再介绍一个ORA-8103的案例。ORA-81XX大多数是和block corrupt有关的错误。ORA-8102是索引键值与表中相关记录的键值不一致的报错。而ORA-8103是表上的数据块错误。

如上图所示,在一个表的一个extent中,正常情况下,所有的块的类型都应该是TYPE=4,TRANS DATA类型。但是在某种情况下,这些块里突然混入了一个类型不是数据块的块。当Oracle扫描到这个块的时候就会报ORA-8103错误,发现了一个不一致的块。
什么样的情况会出现类似的错误呢?ORACLE BUG,服务器内存错误,存储BUG或者存储非正常的宕机写缓存乱了,可能导致类似的问题。一般的服务器宕机,掉电之类的一般不会导致类似问题,顶多丢失一些IO而已。老白遇到过几次这样的问题,有2次是客户做block recover失败后出现了类似的错误。还有一次就是老白今天分享给大家的案例,据说是客户的服务器的电源故障导致宕机,启动后就这样了。实际上这个可能性并不是很大,在老白到现场前,已经有几批人做了无数操作了。到底是怎么导致这个问题已经无从考证了。
这个案例比上回介绍的ORA-8102更早,是2007年7月一个电力公司的案例。当时用户发现yh_dnb表无法访问,程序出现ora-8103错误。经检查,对该表的全表扫描、EXP等操作都无法进行,报错画面如下:

ALERT LOG看,在客户据说的故障发生前,出现了DBWR导致的数据块实例宕机现象,不过这个宕机和出现ORA-8103是不一定有关系的:

Fri May 25 10:46:252007

Errors in file/ora/app/oracle/admin/ora9/bdump/ora9_pmon_65086.trc:

ORA-00471: DBWR processterminated with error

Fri May 25 10:46:25 2007

PMON: terminating instance dueto error 471

Instance terminated by PMON,pid = 65086

据现场DBA的描述,2007523-2007525期间,软件开发商历史数据进行了迁移,在20075251046左右,由于dbwr进程出现故障而导致数据库宕机,系统重启后部分表出现了逻辑坏块。接下来20076月份也相应地出现了坏块现象,都通过跳过坏块,重建表的方式解决掉了。

7月开始发现的是另外一种坏块的形式,在yh_dnb表的某个extent中,在高水位下有个BLOCK对应的type是错误的,当对该表进行扫描或者访问到某个记录的时候,访问到这种块就会出现ora-8103报错,操作无法正常进行。如果存在这种形式的坏块,无法对表进行全表扫描,也无法将该表exp出来。

幸运的是,这张表有一个主键索引是好的,于是通过主键索引找到这张表的所有行,然后一行一行的去查找数据,如果某行报错,就把ROWID打印出来,通过对该表的检查,发现坏块的rdba是:72/13283,检查结果如下:

这张表的坏块中,有13行数据。从这个情况来看,还是比较乐观的。除了这13行数据,其他数据都是好的。于是处置这个问题的最简单方案就形成了。写一个存储过程,把除了这十三行数据的其他数据都取出来,插入到一张新表中,把有问题的这十三条记录的主键存储到另外一张表中,然后把旧表rename,把新表renname为这张表的名称。再通过档案数据补齐这十三条数据就可以了。

set serveroutput on

 

declare

nrows number;

badrows number;

VYHDABH VARCHAR2(50);

VFGSBH VARCHAR2(50);

VJBH   VARCHAR2(50);

begin

 badrows:=0;

 nrows:=0;

 fori in (select *+ index (tab1) */ rowid,FGSBH from ld_data.yh_dnb tab1) loop

 begin

  insert into ld_data.newtb select

   *

  from ld_data.yh_dnb where rowid=i.rowid;

 

  if (mod(nrows,20000)=0) then commit; end if;

 

 exception when others then

  badrows:=badrows+1;

  select /*+ index(a YH_DNB_IND_2) */ yhdabh,FGSBH,JBH into VYHDABH,VFGSBH,VJBH from ld_data.yh_dnb a whererowid=i.rowid;

 

  insert into bad_rows values (i.Rowid,VFGSBH,VYHDABH,VJBH);

  commit;

 end;

 nrows:=nrows+1;

 endloop;

 dbms_output.put_line('Total rows:'||to_char(nrows)||' Bad rows: '||to_char(badrows));

 Commit;

end;

/

 

大多数ORA-8103错误都是一顿操作猛如虎的后果,处理ORA-8103的方法也是比较简单的,不过也提醒我们DBA,在做故障处置的时候一定要谨慎。

最后修改时间:2020-05-29 16:24:44
文章转载自白鳝的洞穴,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论