ORA-01555: snapshot too old

ORA-01555: snapshot too old

 在电信行业这种数据量巨大的环境中,ora-01555错是一个很常见的错误。这个错误使得应用失败。例如,这一错误可能停止一个在深夜运行的批处理任务,随后也使依赖于该任务的其他任务失败。这使用户不能及时得到所需的信息(如报表没打印出来、数据未被导出等等)。尽管这一错误通常发生在大任务上,但在小任务上也会发生。

  ORA-1555通常是一个偶然出现的错误。有时在发生了该错误以后,重新运行该任务就有可能不再碰到类似的错误。这个错误最麻烦的是它并不会立刻发生,运行时间长的任务在错误失败以前可能已经运行了一段时间了(可能几个小时)。只是简单地重新运行该任务并不能保证它能成功,可能在运行了一段时间以后仍然失败。

  1 原因分析

  ORA-1555错的根本原因是因为oracle要保证读一致性。读一致性是指当有多个用户对一个数据块内的行进行修改时,这些块变“脏”或处于变化之中直到被确认。在被确认以前,它们对事务中的所有语句都是可见的,但是对别的事务或语句而言是不可见的。一旦确认以后,对所有后继的事务或语句就都是可见的了。但在事务被确认前的语句不能看到修改,因为这些修改还未发生。

  例如,事务T 1(如对某大表的exp操作)在22 :00开始而事务T 2(如对同一大表的update操作)在22 :01时开始,因为T 1需遍历一个很大的表,其读取要花很长的时间,而T 2可能对同一个表中的数据进行基于索引的更新操作。这样, T2可能在几秒钟之内完成,而T 1可能要运行很长时间,假定4 0分钟。当T 1到达T 2做过修改的地方时(根据当前的SC N时间戳可以识别出新作的改变),尽管T2所进行的写已经被确认,但为了保证读一致性,它不会读到修改后的数据,它只访问在22 :00时的数据,在22 :01时所做的改变不能被读取 。
T1从回滚段中读取改变前的数据以保证读一致性。但因为事务T2已经提交,T2事务使用的回滚段oracle认为已经可以重新利用,当回滚段太少或事务较密集时,oracle有可能会用新事务覆盖掉原来T2事务的回滚段,这时T1事务读到被T2修改过的数据时,再从回滚段中就无法找到修改前的数据,这时就会报ORA-1555,snapshot too old错。

  下面我们可以结合实例来将此过程回溯一遍:

  (1)事务T1在22点开始执行了对某一个大表Test1的exp操作(Test1表数据量可能有几千万甚至更多),那么按照经验,此操作可能需要执行40分钟左右或更长;

  (2)事务T2在22点01分开始执行对Test1表某行的update操作,并且操作条件上有索引(将col1为00的行,col2值由90修改为100),故此操作很快完成,比如5秒钟完成操作并commit;

  (3)此时事务T2已经执行完毕,而事务T1还在执行中;

  (4)当事务T1需要将col1为00的行导出为dmp文件时,Oracle为了保证读一致性,即T1导出的必须是22点时数据库表的值,故col1为00的行对于T1任务来说值仍然为90,而非100;

  (5)由于T2事务在22点02分前就已经做完(提交),并且T2认为回滚段是可以重新利用的;

  (6)如果此时由于回滚段太少或业务量较密集,oracle就可能会重新利用刚才T2事务所使用的回滚段。这时T1事务读到此处时,就会造成无法找到回滚段中修改前的数据,产生错误。

  2 9i中对回滚段管理

  在9i中,可以有两种解决方法来维护事务的读一致性,即或者使用自Oracle 6以来就一直使用的回滚段,或者是使用Undo Tablespace来进行的自动重做管理,但是这两种方法不能同时使用。

  建议在9i 中使用撤销表空间而不是8i 的回滚段模式来管理数据库。

  (1)建立undo tablespace

  建立undo tablespace的语法如下:

  create undo tablespace tablespace_name
  datafile 'fullpath datafilename' size XXM
  [autoextend on|off next XX maxsize XX];
 其中方括号内为可选项。

  9i的undo tablespace必须是本地管理的,不能使用创建字典管理表空间的方法创建undo tablespace,否则会报错。同时,建立undo tablespace时不能指定uniform size关键字,undo tablespace的extent大小必须由oracle自动分配,不能手工指定。

  一个数据库可以建立多个undo tablespace,但每个instance同时只能使用一个undo tablespace。可以用alter system命令来修改数据库当前的undo tablespace。

  如当前的undo tablespace是undotbs1,现在新建一个undotbs2,然后将系统当前的undo tablespace改为undotbs2的步骤为:

  SQL>create undo tablespace undotbs2
  datafile '/dev/rlv_undotbs2' size 100M;

  Tablespace created.

  SQL〉alter system set undo_tablespace='undotbs2' scope=both;(动态指定)
  System altered.

  (2)影响undo tablespace的关键初始化参数

  有几个初始化参数对9i中的undo tablespace有决定性影响,这几个参数分别是undo_management、undo_tablespace、undo_retention和undo_suppress_errors

  undo_management

  Undo_management参数决定是使用undo tablespace还是使用手工建立的回滚段。如果该参数为auto,则表示使用undo tablespace。为manual,表示使用手工管理回滚段,这时同 8i一样,也需要建立回滚表空间,且要建立回滚段。在9i R2中,该参数缺省值为auto。建议继续使用该缺省值,即使用undo tablespace,不用手工建立回滚段。

  undo_tablespace

  该参数必须被设置为一个有效的undo tablespace名称。当undo_management设为auto时,数据库将使用undo_tablespace指定的undo tablespace。

  undo_retention

  该参数的单位为秒,当undo_management参数为auto时,undo_retention表示在undo_tablespace中保留多长时间的回滚(undo)信息,9i的flash_back功能同该值有关。该值设为多大同undo_tablespace 的大小有关,在9i R2中缺省值为10800,一般情况下已经够了,不建议修改该参数。

  3 Ora-01555规避方法

  (1)产生ora-01555错的表面原因可以归结于sql执行时间过长,sql执行时间越长则产生错的几率越高。故首先需要排除sql执行时间长是否为数据库服务器负载过高、主机性能不够、网络环境不好等因素。如果因为外界环境造成sql语句执行时间过长,就需要重点解决外部环境问题。

  (2)排除外部环境问题就可以考虑程序的优化(尤其是存储过程),避免不合理的长时间查询,比如存储过程有一个查询数据的cursor,然后根据cursor的内容来对其他数据表进行计算或者清理,如果这个过程很长,则有可能出现ora-01555的错误,这和当时系统的负荷,undo tablespace大小,undo_retention可能都有关系。可以通过创建临时表或者使用bulk collect等来规避。

  (3)如果以上一切正常,由于9i中引入了undo tablespace,只要把undo tablespace设的足够大,
并把undo_retention设的足够大(大于完成大事务所需的时间),就有可能彻底解决ORA-1555错(但将undo tablespace设的太大会引起系统性能下降)。

转自:http://database.ctocio.com.cn/dbzjdysummary/209/8705709_2.shtml
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值