前几天刚处理了 logic standby故障,还没缓过神来 , logical standby 又出问题了。 还是那张表,那个错误 不得不让我怀疑 是不是那张表出现了问题。记录一下解决的过程:
2012-03-16 11:45:00 update “PROD_DATA2″.”PM_SUPPLIER” ORA-01403: no data found
set
“PRODUCT_CODE” = ‘0021244213’,
2012-03-16 11:44:29 update “PROD_DATA2″.”PM_SUPPLIER” ORA-01403: no data found
set
“PRODUCT_CODE” = ‘0021244213’,
依然是这个老错误,这张表的同步出现了不一致,下面我们来看看这张表的结构:
SQL> desc “PROD_DATA2″.”PM_SUPPLIER”;
Name Null? Type
—————————————– ——– —————————-
ID NOT NULL NUMBER(18)
PRODUCT_DESCRIPTION NCLOB
…..
IS_DELETED NUMBER(1)
UNIT VARCHAR2(10)
CATEGORY_SEARCH_NAME VARCHAR2(200)
这张表包含了一个NCLOB 字段,针对之前同步这张表的报错,让我们怀疑是不是NCLOB 出现了问题,让我们看看当时同步这张表的报错:
SQL> exec DBMS_LOGSTDBY.INSTANTIATE_TABLE(‘PROD_DATA2′,’PM_SUPPLIER’,’dblinkprimary’);
ERROR at line 1:
ORA-20001: ORA-31693: Table data object “PROD_DATA2″.”PM_SUPPLIER” failed to
load/unload and is being skipped due to error:
ORA-12161: TNS:internal error: partial data received
ORA-02063: preceding from
ORA-06512: at “SYS.KUPW$WORKER”, line 113
ORA-02063: preceding from
ORA-01555: snapshot too old: rollback segment number with name “” too small
ORA-22924: snapshot too old
ORA-02063: preceding 2 lines from DBLINKPRIMARY
ORA-01555: snapshot too old: rollback segment number with name “” too small
ORA-22924: snaps
ORA-06512: at “SYS.DBMS_LOGSTDBY”, line 664
ORA-06512: at line 1
snapshot too old: rollback segment number with name “” too small 这种报错十分值得怀疑,一般情况下LOB字段默认采用pctversion=10,在不是特别频繁修改LOB字段的情况下,是不会报错的.何况当时是凌晨3点左右同步的这张表,这种报错更加值得怀疑,使用如下脚本检查lob字段的可用性:
create table corrupted_data (corrupted_rowid rowid);
set concat off
declare
error_1555 exception;
pragma exception_init(error_1555,-1555);
v_lob NCLOB;
n number;
begin
for cursor_lob in (select rowid r from prod_data2.PM_SUPPLIER) loop
begin
select PRODUCT_DESCRIPTION into v_lob from prod_data2.PM_SUPPLIER where rowid=cursor_lob.r;
n:=dbms_lob.instr(v_lob,hextoraw(‘889911′)) ;
exception
when error_1555 then
insert into corrupted_data values (cursor_lob.r);
commit;
end;
end loop;
end;
/
undefine lob_column
之后查看 corrupted_data 发现17条记录存在问题:
sys@item> select * from corrupted_data;
CORRUPTED_ROWID
——————
AAAEKcAAMAABhYrAAA
AAAEKcAAMAABhYrAAB
AAAEKcAAMAABhYrAAC
AAAEKcAAMAABhYrAAD
AAAEKcAAMAABhYrAAE
AAAEKcAAMAABhYrAAF
AAAEKcAAMAABhYrAAG
AAAEKcAAMAABhYrAAH
AAAEKcAAMAABhYrAAI
AAAEKcAAMAABhYrAAJ
AAAEKcAAMAABhYrAAK
AAAEKcAAMAABhYrAAL
AAAEKcAAMAABhYrAAM
AAAEKcAAMAABhYrAAN
AAAEKcAAMAABhYrAAO
AAAEKcAAMAABhZrAAA
AAAEKcAAMAABhXSAAG
17 rows selected.
查看任意一条记录 报错:
select PRODUCT_DESCRIPTION from prod_data2.PM_SUPPLIER where rowid=’AAAEKcAAMAABhYrAAA’;
ORA-01555: snapshot too old: rollback segment number with name “” too small
ORA-22924: snapshot too old
这17条记录的NCLOB 都出现了问题,下面修复这些错误的column 信息
update prod_data2.PM_SUPPLIER set PRODUCT_DESCRIPTION=null where rowid in (select CORRUPTED_ROWID from corrupted_data);
Reference:
Export Fails With ORA-2354 ORA-1555 ORA-22924 and How To Confirm LOB Segment Corruption Using Export Utility? [ID 833635.1]
Export Receives The Errors ORA-1555 ORA-22924 ORA-1578 ORA-22922 [ID 787004.1]
For this reason I propose a simple PLSQL block in this new note, which runs faster and does not consume much of the system resources.
LOBDATA was used as the table which should be checked for any potential corrupted LOBs:
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 LOBDATA
Name Null? Type
—————————————– ——–
ID NOT NULL NUMBER
DOCUMENT 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, document from LOBDATA) loop
begin
n:=dbms_lob.instr(cursor_lob.document,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 LOBDATA set document = empty_blob()
where rowid in (select corrupt_rowid from corrupt_lobs);
这里我们采用set null的方法 关于LOB 字段 null or empty 参考以下定义:
You can set an internal LOB — that is, a LOB column in a table, or a LOB attribute in an object type defined by you– to be NULL or empty:
Setting an Internal LOB to NULL:
A LOB set to NULL has no locator. A NULL value is stored in the row in the table, not a locator. This is the same process as for all other datatypes.
Setting an Internal LOB to Empty:
By contrast, an empty LOB stored in a table is a LOB of zero length that has a locator. So, if you SELECT from an empty LOB column or attribute, you get back a locator which you can use to populate the LOB with data via one of the six programmatic environments, such as OCI or PL/SQL(DBMS_LOB).
这里修改完毕后恢复pctversion为10(之前我们设置为90) 重新同步这张表到3个逻辑备库,很顺利的完成,后续效果待观察。
Export Fails With ORA-2354 ORA-1555 ORA-22924 and How To Confirm LOB Segment Corruption Using Export Utility? [ID 833635.1]
Modified 25-AUG-2011 Type PROBLEM Status PUBLISHED
In this Document
Symptoms
Cause
Solution
References
Applies to:
Oracle Server – Enterprise Edition – Version: 10.2.0.1 to 11.2.0.2 – Release: 10.2 to 11.2
Oracle Server – Enterprise Edition – Version: 10.2.0.1 to 11.2.0.2 [Release: 10.2 to 11.2]
Information in this document applies to any platform.
Symptoms
Following errors encountered during export:
ORA-02354: error in exporting/importing data
ORA-01555: snapshot too old: rollback segment number with name ” ” too small
ORA-22924: snapshot too old
Cause
LOB segment corruption.
How To Confirm LOB Segment Corruption Using Export Utility
– Identify the table rowid’s referencing the corrupted LOB segment blocks by running the PL/SQL procedure mentioned in the Note 787004.1.
As there is already a similar PL/SQL procedure indicated in various notes such as: Note 452341.1 or Note 253131.1, the reason for this article is to propose a method to confirm the LOB segment corruption using export utility by exporting the corrupted rowids.
For Example:
If you encounter the error “ORA-1555: snapshot too old: rollback segment number with name ” ” too small” during export of table EMP (EMP has a LOB column EMP_XML and this segment is owned by schema SCOTT), then run the PL/SQL procedure mentioned in the Note 787004.1.
Note: Run the PL/SQL procedure after creating a temporary table “CORRUPTED_LOB_DATA”. This table is used to spool the corrupted rowids.
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.
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
– Restore and recover the LOB segment using physical backup.
Or:
– Empty the affected LOBs using the UPDATE statement as mentioned in the Note 787004.1:
update EMP
set EMP_XML = empty_blob()
where rowid in (select corrupted_rowid
from corrupted_lob_data);
commit;
– 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\’\)\”
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.
NOTE:787004.1 – EXP ORA-01555 ORA-22924 ORA-01578 ORA-22922
Related
Products
Oracle Database Products > Oracle Database > Oracle Database > Oracle Server – Enterprise Edition
Oracle Database Products > Oracle Database > Oracle Database > Oracle Server – Enterprise Edition
Errors
ORA-1555; ORA-2354; ORA-22924
Back to top
Rate this document
Logical corruption of LOB data during recovery. [ID 1206814.1]
Modified 08-SEP-2011 Type ALERT Status PUBLISHED
In this Document
Description
Likelihood of Occurrence
Possible Symptoms
Workaround or Resolution
Patches
Modification History
References
Applies to:
Oracle Server – Enterprise Edition – Version: 10.1.0.2 to 11.2.0.1.0 – Release: 10.1 to 11.2
Oracle Server – Enterprise Edition – Version: 10.1.0.2 to 11.2.0.1.0 [Release: 10.1 to 11.2]
Information in this document applies to any platform.
Description
During recovery of blocks for a LOB segment, redo may be applied in the wrong order, resulting in the wrong data in the LOB itself.
Likelihood of Occurrence
This issue is intermittent and only occurs after recovery applies redo modifying a LOB segment.
Possible Symptoms
One of these 2 high level symptoms is observed:
1. Some expected LOB data is missing following recovery (either with a normal database or a mounted physical standby), or
2. Recovery on an Active Data Guard standby fails with ORA-600 [kcbr_apply_change_11] while applying redo to modify a LOB segment.
If the redo for the LOB block is dumped then there should be two redo records with the same ‘SCN’. The change vectors are both TYP:1, OP:19.1, and the version#’s are 1 apart e.g. “Version: 0x0000.00000002” and “Version: 0x0000.00000001”. The higher version# block’s change has more non-zero data.
[ this version has all the expected data ]
REDO RECORD – Thread:1 RBA: 0x009cd8.000eb34f.0018 LEN: 0x2024 VLD: 0x01
SCN: 0x0883.59a1173c SUBSCN: 1 06/01/2010 10:32:00
CHANGE #1 TYP:1 CLS: 1 AFN:183 DBA:0x2ddae1ea OBJ:154661
SCN:0x0883.59a1173c SEQ: 1 OP:19.1 ENC:0
Direct Loader block redo entry
Long field block dump:
Object Id 154661
LobId: 000108242D7EE1 PageNo 0
Version: 0x0000.00000002 pdba: 769319314
[ LOB DATA ]
[ this version has less data (ie more 0’s at the end) ]
REDO RECORD – Thread:1 RBA: 0x009cd8.000eb3d3.00c8 LEN: 0x2024 VLD: 0x01
SCN: 0x0883.59a1173c SUBSCN: 1 06/01/2010 10:32:00
CHANGE #1 TYP:1 CLS: 1 AFN:183 DBA:0x2ddae1ea OBJ:154661
SCN:0x0883.59a1173c SEQ: 1 OP:19.1 ENC:0
Direct Loader block redo entry
Long field block dump:
Object Id 154661
LobId: 000108242D7EE1 PageNo 0
Version: 0x0000.00000001 pdba: 769319314
[ LOB DATA ]
Workaround or Resolution
If the issue occurs in a Data Guard environment with a physical standby, the datafile with the affected LOB segment can be refreshed using a new backup made from the primary. If the ORA-600 was not reported and the LOB segment that is affected is known, it can be updated again on the primary and will be updated properly by managed recovery on the physical standby.
If the issue occurs during normal database recovery, the LOB can be updated manually after the database is opened READ-WRITE.
Note: These steps will only correct existing corruption. Please see the Patches section for fixes.
Patches
Option 1)
On all databases (including standbys to prepare for future role changes) set the following initialization parameter:
_log_parallelism_max=1
Option 2)
Apply the 11.2.0.2 patchset or Patch 9532911.
This fix will not correct existing redo, it only fixes future redo. It must be applied on the primary to avoid further corruption in a Data Guard environment. For non-Data Guard environments where viewing the LOB data is critical to business needs, it should be applied as soon as possible, before recovery is needed.
Modification History
16-Sep-2010 Created alert.
17-Sep 2010 Alert published.
08-Sep 2011 Included another fix option
References
Related
Products
Oracle Database Products > Oracle Database > Oracle Database > Oracle Server – Enterprise Edition
Oracle Database Products > Oracle Database > Oracle Database > Oracle Server – Enterprise Edition
Keywords
DATA CORRUPTION; DATA GUARD; DATABASE RECOVERY; LOB; PHYSICAL STANDBY; STANDBY RECOVERY
Errors
KCBR_APPLY_CHANGE_11; ORA-600[KCBR_APPLY_CHANGE_11]
Back to top
Rate this document
Truly good site thank you so much for your time in publishing the posts for all of us to learn about.