如果自己搞不定可以找诗檀软件专业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.7到12.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 是 CLOB或NCLOB 数据类型, 用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);
Leave a Reply