如果自己搞不定可以找诗檀软件专业ORACLE数据库修复团队成员帮您恢复!

诗檀软件专业数据库修复团队

服务热线 : 13764045638 QQ号:47079569 邮箱:service@parnassusdata.com

Oracle 数据库企业版- 版本8.1.7.0 12.1.0.1 [版本 8.1.7 12.1] Oracle 数据库标准版版本8.1.7.0 12.1.0.1 [版本 8.1.712.1] 本文的信息适用于任何平台。

症状

目的: 本文的写作目的是提供一个更新LOB列的脚本,参考由于NOLOGGING 操作引起损坏的LOB块和一个空LOB. sql 语句,如SELECT ,访问LOB列时,会避免出现错误ORA-1578 / ORA-26040 如果需要,可以产生一个表输出。 问题: 读取表中的LOB列时,会产生ORA-1578 ORA-26040:

ORA-1578 : Oracle数据块损坏(file # %s, block # %s) ORA-26040: 使用NOLOGGING选项加载数据块

因为出现错误DBV-200,产生错误的数据文件DBVERIFY失败 (rdbms version < 10.2.0.4) or DBV-201 (rdbms version >= 10.2.0.4):

DBV-00200: Block, dba <dba number>, 已标记为损坏 DBV-00201: Block, DBA <rdba>,标记为无效重做应用损坏

例如:

dbv file=/oracle/oradata/data.dbf blocksize=8192 DBV-00200: Block, dba 54528484, 已标记为损坏 .....

DBA可以用于获取相对文件号和块号:

相对文件号: SQL> select dbms_utility.data_block_address_file(54528484) from dual; DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(54528484) ---------------------------------------------- 13 块号: SQL> select dbms_utility.data_block_address_block(54528484) from dual; DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(54528484) ----------------------------------------------- 2532

重要性 ORA-26040 ORA-1578不同时产生,别的原因引起块损坏时,块介质恢复可用于修复类似RMAN BLOCKRECOVER的损坏。

原因

LOB 段已被定义为 NOLOGGING,数据文件恢复后,LOB 块由Oracle标记为损坏。

解决方法

参考LOB段识别表 sql 语句访问LOB列时的错误实例:

ORA-01578 : ORACLE data block corrupted (file #13 block # 2532) ORA-01110 : datafile 10: '/oracle/oradata/data.dbf' ORA-26040 : Data block was loaded using the NOLOGGING option.

1. 查询DBA_EXTENTS找出LOB段名.

从上述错误 ORA-1110 获取数据文件编号,因为它代表了绝对文件编号 (AFN),运行下一个查询以确定受影响的LOB:

select owner, segment_name, segment_type from   dba_extents where  file_id = 10 and    2532 between block_id and block_id + blocks - 1;

在我们的例子中,它返回:

owner=SCOTT segment_name=SYS_LOB0000029815C00006$$ segment_type=LOBSEGMENT

2. 查询dba_lobs 识别表名和LOB列名:

select table_name, column_name from   dba_lobs where  segment_name = 'SYS_LOB0000029815C00006$$' and    owner = 'SCOTT';

在我们的例子中,它返回:

table_name  = EMP column_name = EMPLOYEE_ID_LOB

XMLTYPE

以下是 lob 段可能关联到XMLTYPE的例子:

select table_name from dba_lobs where segment_name = 'SYS_LOB0000013274C00003$$' and owner = 'SCOTT'; TABLE_NAME ------------------------------ TABLE_WITH_XML_COLUMN SQL> describe scott.TABLE_WITH_XML_COLUMN Name Null?      Type --------------- ------------ FILENAME        VARCHAR2(64) XML_DOCUMENT    XMLTYPE

XML_DOCUMENT 是该例中的LOB列。 修复

3.

通过运行以下的PL SQL脚本,参考损坏的LOB段块标识表行ID:

drop table bad_rows; create table bad_rows (row_id ROWID ,oracle_error_code number); set concat off set serveroutput on declare n number; error_code number; bad_rows number := 0; ora1578 EXCEPTION; ora600 EXCEPTION; PRAGMA EXCEPTION_INIT(ora1578, -1578); PRAGMA EXCEPTION_INIT(ora600, -600); begin for cursor_lob in (select rowid rid, &&lob_column from &&table_owner.&table_with_lob) loop begin n:=dbms_lob.instr(cursor_lob.&&lob_column,hextoraw('889911')) ; exception when ora1578 then bad_rows := bad_rows + 1; insert into bad_rows values(cursor_lob.rid,1578); commit; when ora600 then bad_rows := bad_rows + 1; insert into bad_rows values(cursor_lob.rid,600); commit; when others then error_code:=SQLCODE; bad_rows := bad_rows + 1; insert into bad_rows values(cursor_lob.rid,error_code); commit; end; end loop; dbms_output.put_line('Total Rows identified with errors in LOB column: '||bad_rows); end; / undefine lob_column select * from bad_rows;

受到变量值驱使时,例子如下:

Enter value for lob_column: EMPLOYEE_ID_LOB Enter value for table_owner: SCOTT Enter value for table_with_lob: EMP

XMLTYPE

如果LOB段与 XMLTYPE有关, 那么替换 cursor_lob.&&lob_column cursor_lob.&&lob_column. 在上述plsql 获得CLOBVal() (CLOB ) 或获得BLOBVal() (BLOB); CLOB的整个行会是:

n:=dbms_lob.instr(cursor_lob.&&lob_column.getCLOBVal(),hextoraw('889911')) ;

相似地,受变量值驱使时,例子如下:

Enter value for lob_column: XML_DOCUMENT Enter value for table_owner: SCOTT Enter value for table_with_lob: TABLE_WITH_XML_COLUMN

4. 用空LOB更新LOB列,避免出现ORA-1578 ORA-26040:

SQL> set concat off SQL> update &table_owner.&table_with_lob set &lob_column = empty_blob() where rowid in (select row_id from bad_rows);

如果&lob_column CLOBNCLOB 数据类型, empty_clob替换 empty_blob

XMLTYPE

如果lob XMLTYPE 相关,使用XMLType.createXML('')而不是空 lob:

SQL> update scott.TABLE_WITH_XML_COLUMN set XML_DOCUMENT = XMLType.createXML('') where rowid in (select row_id from bad_rows);