oracle 10231事件,坏块处理10231(不过会丢失数据)

在alter日志中发现如下错误:

ORA-01578: ORACLE data block corrupted (file # 41, block # 1830)

ORA-01110: data file 41: '/db/oracle10g/oradata/hnst/hnst38.dbf'

同样用dbv也检索到file 41的一个坏块,不过由于之前已经检索过,坏块的具体信息没有全部标示出来,而这个dba 171968294具体的组成成分是哪些也是个人比较疑惑的地方,按理是文件号和块号,不过这里详细的划分方法自己还是很迷惑的。期待大牛解答。

[oracle@hns_hy_hn_xwb_tomora ~]$ dbv file='/db/oracle10g/oradata/hnst/hnst38.dbf' blocksize=8192 logfile='/home/oracle/dbv0626.log'

DBVERIFY: Release 10.2.0.1.0 - Production on Tue Jun 26 13:56:00 2012

Copyright (c) 1982, 2005, Oracle.All rights reserved.

DBV-00200: Block, dba 171968294, already marked corrupted

不过虽然dbv已经标识出具体的坏块,但是并不写入v$database_block_corruption视图中,如果有备份集可以利用oracle 9i推出的数据块的恢复来轻松解决

Backup validate datafile 41;

blockrecover datafile 41 block 1830即可实现轻松的恢复。Backup validate datafile 41会检索坏块然后将坏块的记录写入v$database_block_corruption。

通过block#已经知道这是生产系统中一张重要的table segment,于是考虑用expdp配合oracle的内部事件跳过受损数据来处理(当然有bbed的高手可能会有更好的方法)。

不设置10231 event是无法expdp有corruption block的segment。

[oracle@hns_hy_hn_xwb_tomora ~]$ expdp hnst/hnst dumpfile=0626robots_article.dmp logfile=0626.log parallel=8 directory=back tables=robots_article

Export: Release 10.2.0.1.0 - 64bit Production on Tuesday, 26 June, 2012 13:40:58

Copyright (c) 2003, 2005, Oracle.All rights reserved.

Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bit Production

With the Partitioning, OLAP and Data Mining options

Starting "HNST"."SYS_EXPORT_SCHEMA_01":hnst/******** dumpfile=0626robots_article.dmp logfile=0626.log parallel=8 directory=back tables=robots_article

Estimate in progress using BLOCKS method...

--------skipping

ORA-31693: Table data object "HNST"."ROBOTS_ARTICLE" failed to load/unload and is being skipped due to error:

ORA-29913: error in executing ODCIEXTTABLEPOPULATE callout

ORA-01578: ORACLE data block corrupted (file # 41, block # 1830)

ORA-01110: data file 41: '/db/oracle10g/oradata/hnst/hnst38.dbf'

ORA-39095: Dump file space has been exhausted: Unable to allocate 8192 bytes

Job "HNST"."SYS_EXPORT_SCHEMA_01" stopped due to fatal error at 13:41:44

由于存在corrupted block无法expdp,设置10231 event来跳过坏块可以正常导出.

SQL> alter system set events='10231 trace name context forever,level 10';

System altered.

其实也可以利用rowid来做处理的。

SQL> desc dbms_rowid;

FUNCTION ROWID_BLOCK_NUMBER RETURNS NUMBER

Argument NameTypeIn/Out Default?

------------------------------ ----------------------- ------ --------

ROW_IDROWIDIN

TS_TYPE_INVARCHAR2IN DEFAULT

FUNCTION ROWID_CREATE RETURNS ROWID

Argument NameTypeIn/Out Default?

------------------------------ ----------------------- ------ --------

ROWID_TYPENUMBERIN

OBJECT_NUMBERNUMBERIN

RELATIVE_FNONUMBERIN

BLOCK_NUMBERNUMBERIN

ROW_NUMBERNUMBERIN

这里要利用dbms_rowid.rowid_create这个function来模拟1830 block的各行数据的rowid。

SQL> select /*+rule*/ data_Object_id from dba_objects where object_name='ROBOTS_ARTICLE';

DATA_OBJECT_ID

--------------

51717

SQL> select dbms_rowid.rowid_create(1,51717,41,1830,0) from dual;

DBMS_ROWID.ROWID_CREATE(1,5171

------------------------------

AAAMoFAApAAAAcmAAA

SQL> select dbms_rowid.rowid_create(1,51717,41,1831,0) from dual;

DBMS_ROWID.ROWID_CREATE(1,5171

------------------------------

AAAMoFAApAAAAcnAAA

这里自己说一下rowid的知识,物理扩展的rowid有18位,采用64位编码a~z A~Z 0~9 + /共64位字符表示。

从A开始标号,A表示0然后a表示26、0表示52、+表示62、/表示63,不过自己还没有看见+和/的rowid伪列。

Rowid前6位表示data object number,7到9位表示相对表空间的数据文件号,剩下的6位表示block所在的block_id,最后的三位表示block中的第几条记录。

由于oracle的读取的最小单位是block,那么一旦block中的某个数据行损坏那么整个数据块都无法正常读取。接下来的思路很明确了,利用中间表来保存非1830 block的数据信息。

SQL> insert into robots_article001 select /*+rowed(robots_article)*/* from robots_article where rowid1;

SQL> insert into robots_article001 select /*+rowed(robots_article)*/* from robots_article where rowid>'AAAMoFAApAAAAcnAAA' and 1<>1;

剩下的就是rename表。建立在新建robots_article表时都建立相应的索引,然后再执行插入,毕竟大表上线后create index还是很慢的。

可以运用强大的dbms_repair包来跳过坏块。(dbms_repair功能非常强大,还有很多非常时期的用法)

PROCEDURE SKIP_CORRUPT_BLOCKS

Argument NameTypeIn/Out Default?

------------------------------ ----------------------- ------ --------

SCHEMA_NAMEVARCHAR2IN

OBJECT_NAMEVARCHAR2IN

OBJECT_TYPEBINARY_INTEGERINDEFAULT

FLAGSBINARY_INTEGERINDEFAULT

SQL> execute dbms_repair.skip_corrupt_blocks('HNST','ROBOTS_ARTICLE');

PL/SQL procedure successfully completed.

然后expdp或者ctas来创建表,约束等的。

上述这些坏块的处理方法都是没备份情况下的处理,其实bbed可能更适合处理这些问题,不过由于bbed功能相对来说比较复杂,自己在这方面的研究也不是很深,后续有bbed的案例会积极拿出来分享![@more@]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值