- Find out which table the LOB belongs to:
Eg:
SELECT table_name, column_name
FROM dba_lobs
WHERE owner='&OWNER'
AND segment_name='&SEGMENT_NAME';
- If the table is owned by "SYS" then contact Oracle support with all
details. The database is likely to require recovery.
- For non-dictionary tables ...
Get index and constraint information for the table which has
the corrupt LOB data using the SQL in the TABLE
section, then return here to find details of the exact rows
affected.
Finding the exact row which references the corrupt LOB block
can be a challenge as the errors reported do not show any
detail about which table row owns the lob entry which is corrupt.
Typically one can refer to application logs or any SQL_TRACE
or 10046 trace of a session hitting the error (if available) or
see if having event "1578 trace name errorstack level 3"
set in the session helps identify the current SQL/binds/row.
eg:
ALTER SYSTEM SET EVENTS '1578 trace name errorstack level 3';
Then wait for the error to be hit by the application
and find the trace file.
If there are no clues then you can construct a PLSQL block
to scan the problem table row by row extracting the LOB
column data which loops until it hits an error. Such a technique
may take a while but it should be possible to get a primary key
or rowid of any row which references a corrupt LOB block.
eg:
set serverout on
exec dbms_output.enable(100000);
declare
error_1578 exception;
pragma exception_init(error_1578,-1578);
n number;
cnt number:=0;
badcnt number:=0;
begin
for cursor_lob in
(select rowid r, &LOB_COLUMN_NAME L from &OWNER..&TABLE_NAME)
loop
begin
n:=dbms_lob.instr(cursor_lob.L,hextoraw('AA25889911'),1,999999) ;
exception
when error_1578 then
dbms_output.put_line('Got ORA-1578 reading LOB at '||cursor_lob.R);
badcnt:=badcnt+1;
end;
cnt:=cnt+1;
end loop;
dbms_output.put_line('Scanned '||cnt||' rows - saw '||badcnt||' errors');
end;
/
It is possible to have a corrupt LOB block which is only
present as an old version (for consistent read) and which has
not yet been re-used in which case all table rows will be
accessible but it may not be possible to insert / update
the LOB columns once that block is reclaimed for reuse.
Options:
If the OWNER is "SYS" then contact Oracle support with all details.
The database is likely to require recovery.
For non dictionary tables possible options include:
Recovery
OR Salvage data from the table (and its LOB column/s)
THEN Recreate the table
OR Leave the corruption in place
(It is not possible to use DBMS_REPAIR on LOB segments)
阅读(835) | 评论(0) | 转发(0) |