Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1356472
  • 博文数量: 416
  • 博客积分: 10495
  • 博客等级: 上将
  • 技术积分: 4258
  • 用 户 组: 普通用户
  • 注册时间: 2005-04-23 22:13
文章分类

全部博文(416)

文章存档

2015年(7)

2014年(42)

2013年(35)

2012年(14)

2011年(17)

2010年(10)

2009年(18)

2008年(127)

2007年(72)

2006年(23)

2005年(51)

分类: Oracle

2014-01-02 17:19:23




        - 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) |
给主人留下些什么吧!~~