How To Confirm LOB Segment Corruption Using Export Utility
create table corrupted_lob_data (corrupted_rowid rowid);
set concat off
declare
error_1555 exception;
pragma exception_init(error_1555,-1555);
num number;
begin
for cursor_lob in (select rowid r, &&lob_column from &table_owner.&table_with_lob) loop
begin
num := dbms_lob.instr (cursor_lob.&&lob_column, hextoraw ('889911')) ;
exception
when error_1555 then
insert into corrupted_lob_data values (cursor_lob.r);
commit;
end;
end loop;
end;
/
After running the above procedure, it prompts for:
Enter value for lob_column : EMP_XML
Enter value for table_owner : SCOTT
Enter value for table_with_LOB: EMP
Like this, we can check the corruption in all the LOB columns.
In this example, the output of the table “CORRUPTED_LOB_DATA” is showing three rowid’s referencing the corrupted lob segment
select * from corrupted_lob_data;
CORRUPTED_ROWID
---------------------
AAEWBsAAGAAACewAAC
AAEWBsAAGAAACewAAF
AAEWBsAAGAAACewAAG
3 rows selected
Confirm the LOB corruption using Datapump:
#> expdp scott/tiger directory=data_pump_dir dumpfile=test.dmp logfile=test.log tables=EMP query=\"where rowid = \'AAEWBsAAGAAACewAAC\'\"
#> expdp scott/tiger directory=data_pump_dir dumpfile=test1.dmp logfile=test1.log tables=EMP query=\"where rowid = \'AAEWBsAAGAAACewAAF\'\"
#> expdp scott/tiger directory=data_pump_dir dumpfile=test2.dmp logfile=test2.log tables=EMP query=\"where rowid = \'AAEWBsAAGAAACewAAG \'\"
Or, confirm the LOB corruption using original export:
#> exp scott/tiger file=test.dmp log=test.log tables=EMP query=\"where rowid = \'AAEWBsAAGAAACewAAC\'\"
#> exp scott/tiger file=test1.dmp log=test1.log tables=EMP query=\"where rowid = \'AAEWBsAAGAAACewAAF\'\"
#> exp scott/tiger file=test2.dmp log=test2.log tables=EMP query=\"where rowid = \'AAEWBsAAGAAACewAAG\'\"
If any of the above export fails then the LOB corruption confirmed.
SOLUTION
1) Restore and recover the LOB segment using physical backup.
- OR -
2) Empty the affected LOBs using the UPDATE statement as mentioned in the Note 787004.1:
-- NOTE: for BLOB and BFILE columns use EMPTY_BLOB; for CLOB and NCLOB columns use EMPTY_CLOB, e.g.:
update EMP
set EMP_XML = empty_blob()
where rowid in (select corrupted_rowid
from corrupted_lob_data);
commit;
3) Perform the export excluding the corrupted rowids.
Using DataPump export:
----------------------
#> expdp scott/tiger directory=data_pump_dir dumpfile=test.dmp logfile=test.log tables=EMP query=\"where rowid not in \(\'AAEWBsAAGAAACewAAC\', \'AAEWBsAAGAAACewAAF\', \'AAEWBsAAGAAACewAAG\'\)\"
Using original export:
----------------------
#> exp scott/tiger file=test.dmp log=test.log tables=EMP query=\"where rowid not in \(\'AAEWBsAAGAAACewAAC\', \'AAEWBsAAGAAACewAAF\', \'AAEWBsAAGAAACewAAG\'\)\"
- OR -
4) Alternatively, you could use flashback query to solve the LOB corruption. However, details are beyond the scope of this article.
For more information, please refer to http://docs.oracle.com/cd/B28359_01/appdev.111/b28424/adfns_flashback.htm#i1008579