壞塊處理10231(不過會丟失資料)

dotaddjj發表於2012-06-26

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是無法expdpcorruption blocksegment

[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 Name Type In/Out Default?

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

ROW_ID ROWID IN

TS_TYPE_IN VARCHAR2 IN DEFAULT

FUNCTION ROWID_CREATE RETURNS ROWID

Argument Name Type In/Out Default?

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

ROWID_TYPE NUMBER IN

OBJECT_NUMBER NUMBER IN

RELATIVE_FNO NUMBER IN

BLOCK_NUMBER NUMBER IN

ROW_NUMBER NUMBER IN

這裡要利用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的知識,物理擴充套件的rowid18位,採用64位編碼a~z A~Z 0~9 + /64位字元表示。

A開始標號,A表示0然後a表示260表示52+表示62/表示63,不過自己還沒有看見+/rowid偽列。

Rowid6位表示data object number79位表示相對錶空間的資料檔案號,剩下的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 Name Type In/Out Default?

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

SCHEMA_NAME VARCHAR2 IN

OBJECT_NAME VARCHAR2 IN

OBJECT_TYPE BINARY_INTEGER IN DEFAULT

FLAGS BINARY_INTEGER IN DEFAULT

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

PL/SQL procedure successfully completed.

然後expdp或者ctas來建立表,約束等的。

上述這些壞塊的處理方法都是沒備份情況下的處理,其實bbed可能更適合處理這些問題,不過由於bbed功能相對來說比較複雜,自己在這方面的研究也不是很深,後續有bbed的案例會積極拿出來分享!

[@more@]

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25362835/viewspace-1058649/,如需轉載,請註明出處,否則將追究法律責任。

相關文章