Export Receives The Errors ORA-1555 ORA-22924 ORA-1578 ORA-22922 (Doc ID 787004.1)

Export Receives The Errors ORA-1555 ORA-22924 ORA-1578 ORA-22922 (Doc ID 787004.1)

APPLIES TO:

Oracle Database - Enterprise Edition - Version 12.1.0.2 to 12.1.0.2 [Release 12.1]
Oracle Database - Enterprise Edition - Version 9.2.0.1 to 11.2.0.3 [Release 9.2 to 11.2]
Oracle Database Cloud Schema Service - Version N/A and later
Oracle Database Exadata Cloud Machine - Version N/A and later
Oracle Cloud Infrastructure - Database Service - Version N/A and later
Information in this document applies to any platform.

SYMPTOMS

When exporting tables having LOB columns, using data pump or conventional export the following errors might occur:

当导出具有LOB列的表,使用数据泵或常规导出时,可能会发生以下错误

expdp:

Processing object type DATABASE_EXPORT/SCHEMA/POST_SCHEMA/PROCACT_SCHEMA
ORA-31693: Table data object "<SCHEMA_NAME>"."<TABLE_NAME>" failed to load/unload and is being skipped due to error:
ORA-29913: error in executing ODCIEXTTABLEPOPULATE callout
ORA-01555: snapshot too old: rollback segment number with name "" too small
ORA-22924: snapshot too old

exp:

. . exporting table <TABLE_NAME>
EXP-00056: ORACLE error 1555 encountered
ORA-01555: snapshot too old: rollback segment number with name "" too small
ORA-22924: snapshot too old

or:

EXP-00056: ORACLE error 22922 found
ORA-22922: nonexistent LOB value
. . Export der Tabelle <TABLE_NAME> 2 rows exported

CHANGES

CAUSE

The ORA-1555 does not always confirm a corruption in LOB segment. This can also occur due to the fact that LOB PCTVERSION or RETENTION are low. The proposed solution below should not be used on ORA-1555, if:

ORA-1555并不总是确认LOB段中的损坏。由于LOB PCTVERSION或RETENTION较低的事实,也可能发生这种情况。如果满足以下条件,则以下建议的解决方案不应该在ORA-1555上使用

1. You can't confirm that no updates were made to that LOB while you ran the script

1.您无法确认在运行脚本时未对该LOB进行任何更新

and:

2. You don't have confirmation that exactly the identical ROWIDs are reported by 2 independent script executions.

2.您没有确认完全相同的ROWID由2个独立脚本执行报告

Otherwise, all the above errors are produced when exporting, because the LOBs stored in the table to be exported might be corrupted.

否则,导出时会产生上述所有错误,因为存储在要导出的表中的LOB可能已损坏

To have this checked a PLSQL block should be run against the table.

要对此进行检查,应针对该表运行一个PLSQL块

As there is already a PLSQL procedure indicated in various notes such as: Note 452341.1 or Note 253131.1, the reason for this article is to propose a PLSQL block which will run faster and consumes much less memory.

由于已经在各种注释中指出了PLSQL过程,例如:注释452341.1注释253131.1,本文的目的是提出一个PLSQL块,该块将运行得更快并且消耗更少的内存

The PLSQL indicated in the previous articles cannot be run against large tables due to the fact that they can fail with memory errors like an ORA-04031 error.

上一篇文章中指出的PLSQL不能针对大型表运行,因为它们可能因内存错误(例如ORA-04031错误)而失败

SOLUTION

To verify for corruption use the PLSQL block below. It is built to not consume much of the system resources and to run faster on large tables.

要验证是否损坏,请使用下面的PLSQL块。它的构建不会消耗大量系统资源,并且可以在大型表上更快地运行

Note: Replace <TABLE_NAME> with the name of the table that has the LOB column (<LOB_COLUMN>) where the corruption is suspected:

注意:用怀疑有损坏的LOB列(<LOB_COLUMN>)的表的名称替换<TABLE_NAME>:

-- 1. Create a new temporary table for storing all rowids of the corrupted LOBs. Let's call it "corrupt_lobs"

SQL> create table corrupt_lobs (corrupt_rowid rowid, err_num number);

-- 2. Make a desc on the table containing the LOB column:

DESC <TABLE_NAME>

Name         Null?     Type
----------   --------- ------------
<COL1>       NOT NULL  NUMBER
<LOB_COLUMN>           BLOB

-- Run the following PLSQL block:

declare
  error_1578 exception;
  error_1555 exception;
  error_22922 exception;
  pragma exception_init(error_1578,-1578);
  pragma exception_init(error_1555,-1555);
  pragma exception_init(error_22922,-22922);
  n number;
begin
  for cursor_lob in (select rowid r, <LOB_COLUMN> from <TABLE_NAME>) loop
  begin
    n:=dbms_lob.instr(cursor_lob.<LOB_COLUMN>,hextoraw('889911'));
  exception
    when error_1578 then
      insert into corrupt_lobs values (cursor_lob.r, 1578);
      commit;
    when error_1555 then
      insert into corrupt_lobs values (cursor_lob.r, 1555);
      commit;
    when error_22922 then
      insert into corrupt_lobs values (cursor_lob.r, 22922);
      commit;
    end;
  end loop;
end;
/

-- In the end all rowids of the corrupted LOBs will be inserted into the corrupt_lobs newly created table.

-- A possible solution would then be to empty the affected LOBs using a statement like:

SQL> update <TABLE_NAME> set <LOB_COLUMN> = empty_blob()
     where rowid in (select corrupt_rowid from corrupt_lobs);

( for BLOB and BFILE columns use EMPTY_BLOB; for CLOB and NCLOB columns use EMPTY_CLOB )

-- Or export the table without the corrupted row, like:

% expdp system/<PASSWORD> DIRECTORY=my_dir DUMPFILE=<dump_name>.dmp LOGFILE=<logfile_name>.log TABLES=<SCHEMA_NAME>.<TABLE_NAME> QUERY=\"WHERE rowid NOT IN \(\'<corrupt_rowid>\'\)\"

 

REFERENCES

NOTE:253131.1 - Concurrent Writes May Corrupt LOB Segment When Using Auto Segment Space Management (ORA-1555)
NOTE:452341.1 - ORA-01555 And Other Errors while Exporting Table With LOBs, How To Detect Lob Corruption.

posted @ 2019-12-01 11:01  ZYLONG-SYS  阅读(561)  评论(0编辑  收藏  举报