求助,奇怪的ORA-1555错误:

duk 2010-03-28 12:55:58

有谁解决过ora-1555:snapshot too old 错误么?我这里出现的问题跟通常的1555错误有点不太一样,我弄了两天,怎么样都搞不定,非常着急,请帮忙分析下?

数据库版本是oracle 10g ,采用AUTO方式自动管理undo表空间,最近爆ora-1555错。后来发现是当做
insert into table1(select * from table2 where data<YYMMDD)的时候出错。
其中table2记录条数几万多,table1记录几十万条。表中有lob字段。表空间大小为几十G。

一般的方法是增加undo tablespace和undo_retention。我将undo tablespace增加到20G,undo_retention设置到10800.可是问题依然存在。

在sqlplus中单独执行该语句,并把数据库的其他操作都停掉,单做这一句话,并把YYMMDD的时间缩小,使得(select * from table2 where data<YYMMDD)的记录数在几十条左右。但是大概1分钟左右就爆同样的错误。

需要说明的是,表中有lob字段啊,Blog类型,lob字段中存的数据大概是几百k。

数据库中一共有4个表做这样的操作时出问题,全部都是有lob字段的,但是其他有lob字段的表没有这个问题。不含lob类型的表全部都没有问题。

请帮忙分析下是什么问题?
...全文
250 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
duk 2010-05-01
  • 打赏
  • 举报
回复
各位朋友,找到问题了,是我的oracle版本老了,是10.2.0.2,更新到10.2.0.3就行了。
oracle的bug列表中提到过这个问题,如果有lob字段,那么在对回滚段利用的时候,会产生错误。
tangren 2010-04-09
  • 打赏
  • 举报
回复
试试每次insert都commit,还会出这种错误吗?
bangqiuxiong2009 2010-04-09
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 47522341 的回复:]
lob字段是有最大值的,比如clob字段大小不能超过32767,一旦你更新该字段内容并超过了这个最大值,就会产生value error错误。
[/Quote]

clob好像可以达到4G吧,我也正遇到ora-1555的问题,只是报错的环境我访问不了,在测试环境上又重现不了,愁死我了,得到的说明是说在clob类型字段上做循环insert和update的时候报的错,又高人指点一下怎样才能造出ora-1555的错吗?
47522341 2010-03-29
  • 打赏
  • 举报
回复
lob字段是有最大值的,比如clob字段大小不能超过32767,一旦你更新该字段内容并超过了这个最大值,就会产生value error错误。
zhangwonderful 2010-03-29
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 47522341 的回复:]

对于ORA-01555这个经典错误想来大家都很熟悉了,一讲到这个可以滔滔不绝:)
不过当01555是发生在读取LOB字段上估计还是有人不太清楚。
想要了解这个问题,首先要说明一下oracle是如何处理LOB的读一致性的。

首先我们来建立一个含有LOB字段的表TEST
1 create table test(
2 id number,
3 pic blob)
4 lob(……
[/Quote]
学习了
duk 2010-03-29
  • 打赏
  • 举报
回复
嗯,你说的,很对。我今天确定出错的原因就是因为LOB字段的原因。

我发现语句中,如果包含某些记录,就会提示这个错误。然后我发现这些记录中有个共同特征,就是在pl/sql中,显示的LOB列,都是<Value Erro>。

我根据对历史备份文件的查询,可以确定,这些记录一开始的时候,LOB列的字段是有效的。但是不知道为什么会被修改错误了。

你能帮我分析一下原因么?谢谢 了
47522341 2010-03-28
  • 打赏
  • 举报
回复
对于ORA-01555这个经典错误想来大家都很熟悉了,一讲到这个可以滔滔不绝:)
不过当01555是发生在读取LOB字段上估计还是有人不太清楚。
想要了解这个问题,首先要说明一下oracle是如何处理LOB的读一致性的。

首先我们来建立一个含有LOB字段的表TEST
1 create table test(
2 id number,
3 pic blob)
4 lob(pic) store as pic_lob(
5 disable storage in row
6 chunk 8k
7 pctversion 10
8 nocache nologging
9 index ind_pic_lob
10* )
SQL> /

Table created.

SQL> l
1* select object_name,object_type from user_objects
SQL> /

OBJECT_NAME OBJECT_TYPE
—————————— ——————
PIC_LOB LOB
TEST TABLE

SQL> select segment_name,segment_type from user_segments;

SEGMENT_NAME SEGMENT_TYPE
—————————— ——————
TEST TABLE
IND_PIC_LOB LOBINDEX
PIC_LOB LOBSEGMENT

oracle创建了两个objects TEST这个是我们很熟悉的表了,PCT_LOB就是LOB了
创建了三个segment,一个是表,一个是LOBSEGMENT,另外一个是LOBINDEX
这个看上去好像莫名其妙的LOBINDEX就是主要为我们的LOB read consistency服务的

注意我们在创建表的时候指明了disable storage in row,所以lob存储将采取out-line的方式存储到LOBSEGMENT中。
如果是enable storage in row的话,那么长度小于3960bytes的采用in-line的方式存储,那么这时undo, redo的产生和普通的数据一样。
修改数据的时候old version存储在回滚段中,这样query可以利用undo信息重构block生成其所需的前镜像。

当采用out-line的方式存储的时候,这时读一致性可以说完全是由LOBINDEX+LOGSEGMENT来保证的。
LOBINDEX类似于B-tree的结构,存储各个LOB entry的LOB ID,LOB ID指向LOBSEGMENT中的实际存储区域。
如果要delete一条数据,删除的操作就是更新一下LOBINDEX, 并不会去将LOBSEGMENT中的内容写入回滚段中,这时候有少量的undo信息产生,但是是因为修改LOGINDEX产生的。
如果是update LOB,并不是去update原来的LOB entry,而是插入一条新的LOB entry,并且对LOB自身不产生undo信息,原来旧的数据仍然存放于LOBSEGMENT中(LOBSEGMENT中会存储相关的SCN信息)

这样query需要读取old version的数据就不是从回滚段中读取old value来重构,而是从LOBSEGMENT中读取原先的LOB entry。

如果delete,update操作很多,oracle会不会一直保存这些old version的数据呢?答案是不会。
这时就靠我们上面在创建LOB时的参数PCTVERSION来控制了。PCTVERSION=10的含义就是在HWM下留有10%的空间用于存放Old version的数据.
如果存放old version的空间多于PCTVERSION,那么就可以被重用。这时如果有query需要重构旧的数据,就会产生ORA-01555错误。
想要避免01555的话一个就是尽量缩短query的时间,另外就是增大PCTVERSION,当然这会消耗更多的空间存放旧数据。

那么最后一个问题是如果辨别ORA-01555是不是发生在LOB上的

一般来说,普通的01555错误会指明发生01555的rollback segment,而LOB的则没有,而是伴随着ORA-22924出现

xfan-tiger1$> oerr ora 22924
22924, 00000, “snapshot too old”
// *Cause: The version of the LOB value needed for the consistent read was
// already overwritten by another writer.
// *Action: Use a larger version pool.
xfan-tiger1$> oerr ora 01555
01555, 00000, “snapshot too old: rollback segment number %s with name \”%s\” too small”
// *Cause: rollback records needed by a reader for consistent read are
// overwritten by other writers
// *Action: If in Automatic Undo Management mode, increase undo_retention
// setting. Otherwise, use larger rollback segments
47522341 2010-03-28
  • 打赏
  • 举报
回复
你这个表的lob字段是不是在执行期间被占用或者修改过?

17,377

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 基础和管理
社区管理员
  • 基础和管理社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧