A-A+

oracle 10g数据库坏块的处理记录

2016年05月11日 Oracle 暂无评论 阅读 562 次
摘要:

记录一次oracle数据库坏块的处理过程,包含了undo坏块和数据文件坏块,丢失部分数据。

前些天客户oracle 10g数据库发生的坏块处理,同事反应客户exp备份时出现exp-00056错误,exp数据的时候报错,其他表可以

oraclebadblock1

从ora-01578可以看到文件号5的块号568107损坏了,第一反应就是使用rman 的blockrecover datafile 5 block 568107 修复,只是确认了下发现数据库没有在归档模式运行。看来是的丢失部分数据了。

查询了下568107上面的对象

select tablespace_name,segment_type,owner,segment_name from dba_extents where file_id=5 and 568107between block_id AND block_id + blocks - 1;

经过开发确认,损坏的表为历史表,可以忍受丢失部分数据。

下面要重建下这张表,用ctas方式同样的错误

oraclebadblock2

这是需要设置10231事件忽略坏块,然后使用CTAS方式重建表最后rename table,然后再rebuild index
alter session SET EVENTS '10231 trace name context forever,level 10';
create table tab_new as select * from tab;
rename tab to tab_bak;
rename tab_new to new;
alter index indexname rebuild;

session中设置完时间后成功ctas,丢失了几千条数据,接受范围内。

select  INDEX_NAME  from user_indexes where table_name='xxxxx'; 发现没有索引,省下了重建索引的步骤。

然后别忘记关闭事件

alter session SET EVENTS '10231 trace name context off';

当时也猜测可能不止有一个坏块,就做了下全库校验。

 rman>backup validate check logical database;

validate check logical database可以验证物理损坏和逻辑损坏,执行VALIDATE命令后通过查询V$DATABASE_BLOCK_CORRUPTION 视图可以获得坏块的详细信息

检验后查询视图

oraclebadblock3

发现不止一个数据文件有问题

dbv file5 48个坏块

oraclebadblock4

 

file#2是undo表空间,幸运的是其他的坏块上面都没有对象,新建一个UNDOTBS2看看

oraclebadblock5

在使原undo下线的过程中发生错误

oraclebadblock6

查询下活动的段

select sum(bytes) from dba_undo_extents where tablespace_name='UNDOTBS1' and status='ACTIVE';  

oraclebadblock7

select tablespace_name,segment_name,status from dba_rollback_segs;

oraclebadblock8 oraclebadblock9

等了半个多小时还是没有offline,重启了数据库成功切换过来。这里不知道有没有其他风险?

下面处理file#5 上面的坏块,由于没有数据,查询坏块位置在空闲段上面

Select * from dba_free_space where file_id= 5 and 568379    between block_id and block_id + blocks -1;

处理这样坏块的方法是查询下这个数据文件的剩余空间是多少,建一个表,把剩余区段分配给这个表,插入数据占用剩余空间,覆盖损坏的块。

查询剩余空间

数据文件的可用空间

    SQL> select tablespace_name,file_id,sum(bytes/1024/1024) Mb from dba_free_space where file_id=5 group by tablespace_name,file_id;

新建张测试表

   SQL> create table s (n number, c varchar2(4000)) nologging tablespace xxxx;

手动分配段

   SQL> alter table s allocate extent (DATAFILE ‘D:xxxxxxx′ SIZE 剩余空间M);

向该表中插入100行数据:
BEGIN
FOR i IN 1..100 LOOP
INSERT INTO s VALUES(i,’x');
END LOOP;
END;
/

然后对其进行循环插入,直到前文中所述的坏块被使用。

BEGIN
FOR i IN 1..1000000000 LOOP
INSERT INTO s select * from s;
END LOOP;
END;
/

空间用完后,坏块被覆盖。

进入rman,重新校验数据库。

查询结果,很奇特

oraclebadblock10

file#2 已经没有了,但是还提示有问题,这个视图不能删除记录,重启也没消失。

想到一个办法,新建一个表空间,它的数据文件为2,在校验数据库,由于是新建的一定没有问题,验证后发现此方法可行
oraclebadblock11

查询v$database_block_corruption ,结果已经为空,此时删除qwe这个表空间,问题到此结束。

当然,数据库改成了归档模式。

归档模式下,rman>blockrecover corruption list; 在大量损坏时很方便。

给我留言

Copyright © 2011-2016 零下二十四度Theme By  Ality  京ICP备16007547号   关于本站

用户登录