一、 问题背景
在用insert into select同步数据的时候遇到一个非常奇怪的现象,有一张一亿行的表,按行插入时间,其他时间段的同步都正常,唯独有10秒的数据(100多行)只要执行insert into select立刻就会报错ora-1555,直接select不会报错。另外直接expdp导出这些数据和update msg字段也会有ora-1555报错。
二、 排查
刚开始怀疑是不是回滚段设置有问题,在mos中搜索“ora-1555 0s”发现文档内容并不符合完全我们的情况,尝试更换重启undo表空间后问题依然存在。
继续测试发现如果insert into select时排除lob字段,插入正常,怀疑与lob字段有关系,查询mos文档发现与Doc ID 452341.1描述接近,怀疑是lob字段损坏导致。
文档中有给脚本,可以检查lob字段是否损坏
set serverout on
exec dbms_output.enable(100000);
declare
page number;
len number;
c varchar2(10);
charpp number := 8132/2;
begin
for r in (select rowid rid, dbms_lob.getlength (<your_clob_column>) len
from <your_table_with_clcob_column>) loop
if r.len is not null then
for page in 0..r.len/charpp loop
begin
select dbms_lob.substr (<your_clob_column>, 1, 1+ (page * charpp))
into c
from <your_table_with_clcob_column>
where rowid = r.rid;
exception
when others then
dbms_output.put_line ('Error on rowid ' ||R.rid||' page '||page);
dbms_output.put_line (sqlerrm);
end;
end loop;
end if;
end loop;
end;
/
检查发现确实有问题
查询相应rowid字段可以看到对应log字段的值都是<Value Error>
三、 问题处理
由于这些数据已经是很早之前的,备份已经没有了,与业务方沟通损坏的10几条数据不插入lob字段(相当于丢失部分数据)。还好这些数据不是太重要,不然真是踩到大坑了。。。
四、 报错原因
当读一致性镜像不可用时,会遇到ora-1555报错。lob数据不使用undo存储读一致性镜像,旧版本数据在任何dml操作之前存在lob段本身中。
通常有两种原因会造成lob段上的ora-1555报错:
- 查询访问到损坏了的lob段
- lob段中的读一致性镜像数据不可用。这通常是由于错误设置了lob段PCTVERSION/RETENTION属性
参考
ORA-01555 And Other Errors while Exporting Table With LOBs, How To Detect Lob Corruption. (Doc ID 452341.1)
IF: ORA-1555 Error During Export on LOB Data (Doc ID 1950937.1)