【DBA及开发必备】全解ORA-1555快照太旧错误原理及解决方案

SusanA-Oracle 2016-02-24 09:38:02
不论你的工作是管理Oracle数据库,还是开发、维护Oracle上的应用程序,通常来讲你都遇到过ORA-01555:snapshot too old这样的错误。本文为你详解错误产生的原因以及最佳解决方案。

ORA-01555产生的过程

 

我们先来看看ORA-01555是怎样产生的:



错误记录在哪?

 

通常,这个错误可能会在以下文件中出现:


1
 
Alert 告警日志文件
 

报错信息类似:


ORA-01555: snapshot too old: rollback segment number 107 with name "_SYSSMU107_1253191395$" too small


2
 
问题发生时的跟踪日志文件
 

默认情况,ORA-01555错误发生时不会自动生成跟踪日志文件。但是可以在系统里设置下面的事件,让它在错误发生时同时生成:


alter system set events '1555 trace name errorstack level 3';


设置了1555事件后,一旦错误发生,就会生成相应的日志文件,类似如下:



错误因何而来?

 

产生ORA-01555错误的根本原因是由于UNDO块被覆盖,查询语句不能获取到查询语句发起时刻所构造的数据副本。


已知的一些原因如下:


1
 
相应行数据的UNDO记录已经过期了
 

这里说的过期是当前时间(指错误发生时)离数据提交时间已经超过UNDO_RETENTION设定的值。一旦已提交的记录对应的UNDO记录是“expired”状态,就表明这部分空间可以重用,数据可以被覆盖了。


你可能会问,为什么有时候我们遇到ORA-01555错误时,查询语句运行时间比UNDO_RETENTION要长很多,有时候却短很多呢?这没什么明确的答案。


要看具体问题发生时UNDO表空间有多忙,系统负载有多大。


提示:一个活动或者未提交的事务对应的UNDO记录会被标记为“ACTIVE”状态。一旦事务被提交,相应的UNDO记录被标记为“UNEXPIRED”,它将持续一段时间(这段时间由UNDO_RETENTION参数决定,如果使用了自动还原段管理,那是由TUNED_UNDORETENTION决定,该参数的值系统自动评估),过了这一时间后,这一UNDO记录被标记为“EXPIRED”,该空间可被重用。


2
 
相应行数据的UNDO记录状态并非过期,但仍然被覆盖了
 

发生这种情况有2个必要条件:


  • 对UNDO表空间没有设置RETENTION GUARANTEE

  • UNDO表空间满了


这个时候,“UNEXPIRED”状态的UNDO记录就可能被覆盖了。


3
 
LOB段的LOB段的读一致性副本不再可用
 

依赖于LOB字段是怎样配置的,in-row还是out-of-row,in-row方式的LOB字段在UNDO表空间中采用跟普通行一样的UNDO算法。


Out-of-row方式的LOB字段不一样,它的读一致性副本有下面2种控制方式


1)老的方式:PCTVERSIOIN


这个参数关系到LOB数据的一致读,指的是表lob字段所在的表空间需要预留给lob的前映象使用的最大百分比,默认值是10。也就是说,只要使用不超过10%,LOB字段的前映像的数据是不会被覆盖的。


2) 新的方式(自动还原段管理使用):RETENTION


Oracle用UNDO_RETENTION参数来决定在数据库中保留多少已经提交的UNDO数据。这种方式LOB段跟普通段使用相同的过期策略。


在这种方式中,用LOB字段的语句发生ORA-1555的话,意味着:


LOB字段的前映像的使用已经超过PCTVERSION,读一致性数据被覆盖。


或者,LOB字段前映像超过了RETENTION的值,在查询发生时一些行的LOB字段前映像已经被覆盖,于是ORA-1555触发。


解决方案

 

1
 
检查错误日志信息
 

通过检查告警日志,或者包含ORA-1555错误信息的跟踪日志,可以更详细的看到具体的错误类型:


1)提示回滚段太小


错误提示:


ORA-01555: snapshot too old: rollback segment number with name "" too small(注意!!!这里的回滚段名字是空的)


或者,


ORA-22924: snapshot too old


这种错误说明是访问的UNDO数据是LOB字段类型。LOB字段访问遇到ORA-1555错误通常是下面几个原因导致的:


  • LOB段损坏


参考MOS文档检查是不是这个问题:


Document 452341.1 ORA-01555 And Other Errors while Exporting Table With LOBs, How To Detect Lob  Corruption


  • 如果没有LOB损坏,检查Retention/Pctversion值是不是合适


参考MOS文档,确认是不是需要调高Retention/Pctversion:


Document 846079.1 LOBs and ORA-01555 troubleshooting


ORA-01555: snapshot too old: rollback segment number 107 with name "_SYSSMU107_1253191395$" too small


注意,这个错误提示跟上面不一样。"_SYSSMU107_1253191395$"表示UNDO数据是在UNDO表空间的。


这个ORA-1555错误报告是在访问UNDO表空间的UNDO数据时发生错误的,用后续的方法来诊断问题。


2)查询耗时太长


在一些ORA-1555错误发生时,会在alert日志或者是应用日志中出现查询失败时耗时(Duration)的秒数:


ORA-01555 caused by SQL statement below (Query Duration=1974 sec, SCN: 0x0002.bc30bcf7):


如果发现错误日志中,duration=0或者耗时很短,查看下面的文档:


Document 1131474.1 ORA-01555 When Max Query Length Is  Less Than Undo Retention, small or 0 Seconds


如果查询耗时超过UNDO_RETENTION值,可以考虑加大UNDO_RETETION,同时要记得调整UNDO表空间大小。


如果查询耗时等于或者接近UNDO_RETENTION,继续看后面的文字。


2
 
检查UNDO数据文件
 


如果UNDO数据文件没有关闭自动扩展功能,可能会导致TUNED_UNDORETENTION值被计算得很高,因此UNDO空间分配是偏向于更多的空间。那怎么破呢?使用UNDO数据文件自动扩展功能,即使存储可用空间足够的时候也带上MAXSIZE。


注意:强烈建议,不要让UNDO表空间里同时存在关闭自动扩展功能的UNDO数据文件和打开自动扩展功能的UNDO数据文件,因为这会导致TUNED_UNDORETENTION计算错乱。


3
 
检查 TUNED_UNDORETENTION
 


1)TUNED_UNDORETENTION比MAXQUERYLEN小


这种情况表明UNDO表空间有空间上的压力,实际保留的UNDO记录比理论上的要少。


解决办法是扩大UNDO表空间。


2)TUNED_UNDORETENTION比MAXQUERYLEN大很多


通常发生在UNDO表空间的数据文件关闭自动扩展选项的情况下。内部的算法是尽可能久的保持UNDO记录,因此TUNED_RETENTION的值就会比较高。


解决办法是把所有的UNDO数据文件设置为自动扩展,并且加上MAXSIZE选项。


长时间运行的查询语句也会把TUNED_RETENTION的值搞得很高。这种情况。就要优化SQL语句来避免保留过多UNDO数据在UNDO表空间了。


通过下面的语句来识别哪些查询语句耗时较久:



3)状态为ACTIVE/UNEXPIRED的UNDO占比很高



下面的几种情况可能会产生大量ACTIVE/UNEXPIRED状态的UNDO:


  • UNDO_RETENTION或TUNED_UNDORETENTION值很大

  • 在某个特定时间点产生了大量UNDO数据。用下面的语句诊断:

  • 大量的死事务回滚

  • 使用了闪回数据查询


关于状态为ACTIVE的UNDO的信息,可以参阅:


Document 1337335.1 How To Check the Usage of Active Undo  Segments in AUM


4
 
UNDO_RETENTION
 

建议将UNDO_RETENTION的值至少设置为MAXQUERYLEN的一半。如果发生了ORA-1555错误,则适当调大。


到此,基本上涉及ORA-01555错误的原理和诊断就说完了。


如果还有不明白的,请在文章下留言,我们继续探讨。


【本文为DBA+社群独家译稿。原文地址:https://community.oracle.com/community/support/support-blogs/database-support-blog/blog/2015/12/09/ora-1555-do-you-know-how-to-resolve-this-issue】

 

译者:杨志洪

  • 【DBA+社群】联合发起人

  • 数据管理专家。Oracle ACE、OCM、 SHOUG/ZJOUG核心成员、DAMA会员/CCF会员,译著《Oracle核心技术》。

  • 在Oracle OOW、DTCC及2015Oracle数据库技术大会等全国性技术会议上发表主题分享,并主办了2014Oracle全国技术巡讲。

  • 2015年创立DBA+社群迅速成为全中国最大的涵盖数据架构师、DBA及中间件的专业社群。


 

全球敏捷运维峰会【杭州站】

 
 
 


2016 年4月16日,与你相约杭州,来一场敏捷与运维的美丽邂逅!DBA+社群联合三墩IT人开启全球敏捷运维峰会第一站:杭州站!峰会力邀来自互联网与传统企 业的资深专家,各路大咖齐聚,汇聚500+行业精英,聚焦架构、敏捷、运维三大主线,开启一场专属于IT人的年度之约!


专家阵容:或行业资深派、或著书力作派、或传统转型派、或一线实战派,总有一款是你喜欢!


绝对干货:聚焦架构、敏捷、运维三大主线,共讨传统企业在技术转型过程中的实践与困境、互联网企业在前沿技术方面的应用与心得、技术服务型企业在新老技术之间如何切换与落地,拒绝无营养的广告,绝对干货,精彩不容错过!


连接联动:汇聚社群数百顶级专家人脉,携数万社群成员声势,联合数十家媒体单位,共同打造一场连接敏捷与运维圈子的年度之约!


票价优惠

 
原价
 
 
门票:99元
VIP票:299元(含VIP坐席、午餐)
新年优惠
 
 

门票:免费!(限时限额)

VIP票:199元(限3月18日前)

 
官网报名:http://gdevops.com/
最新评论
访客 2024年04月08日

如果字段的最大可能长度超过255字节,那么长度值可能…

访客 2024年03月04日

只能说作者太用心了,优秀

访客 2024年02月23日

感谢详解

访客 2024年02月20日

一般干个7-8年(即30岁左右),能做到年入40w-50w;有…

访客 2023年08月20日

230721

活动预告