Oracle LOB段中的ORA-1578 ORA-26040 – 解决错误的脚本

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

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

服务热线 : 13764045638 QQ号:47079569 邮箱:[email protected]

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);


Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *