欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

Oracle数据库 ORA-01555 快照过旧

程序员文章站 2022-06-02 21:14:06
...

用户user1对表进行了更新操作,用户user2在user1还没有进行提交前读表中数据,而且是大批量的读取(打个比方:耗时3分钟)而在这3分钟

产生原因:

用户user1对表进行了更新操作,用户user2在user1还没有进行提交前读表中数据,而且是大批量的读取(打个比方:耗时3分钟)而在这3分钟内user1进行了提交操作,当事务提交以后,该事务占用的回滚段事务会被标记为非活动,回滚段空间可以被覆盖重用。.那么一个问题就出现了,如果一个查询需要使用被覆盖的回滚段构造前镜像实现一致性读,那么此时就会出现Oracle著名的ORA-01555错误。

ora-01555快照过旧就是因为undo空间不够大,其中一部分undo数据被覆盖了,用户无法获得修改前的数据。

undo数据分为三种:
活动的undo:未提交事务的undo数据,这些undo数据永远不能覆盖,用于回滚rollback事务。
过期的undo:已提交事务的undo数据,这些undo数据可以覆盖。
未过期的undo:事务已提交,但事务提交前,有些查询正在进行,它要读取的是提交前的数据,这部分数据就是未过期数据。如果这部分undo数据被覆盖了,就会发生ora-01555错误。

解决的办法

(1)增加UNDO表空间大小

(2)增加undo_retention 时间,默认只有15分钟

(3)优化出错的SQL,减少查询的时间,首选方法

(4)避免频繁的提交


在Oracle 9i的文档中这样描述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


可以看到,在Oracle 9i自动管理UNDO表空间模式下,UNDO_RETENTION参数的引入正是为了减少ORA-01555错误的出现。这个参数设置当事务提交之后(回滚段变得非活跃),回滚段中的前镜像数据在被覆盖前保留的时间,该参数以秒为单位,9iR1初始值为900秒,在Oracle 9iR2增加为10800秒。

显然该参数设置的越高就越能减少ORA-01555错误的出现,但是保留时间和存储空间是紧密相关的,如果UNDO表空间的存储空间有限,那么Oracle就会选择回收已提交事务占用的空间,置UNDO_RETENTION参数于不顾。

在Oracle 9i的AUM模式下,UNDO_RETENTION实际上是一个非担保(NO Guaranteed)限制。也就是说,如果有其他事务需要回滚空间,而空间出现不足时,这些信息仍然会被覆盖;从Oracle 10g开始,Oracle对于UNDO增加了Guarantee控制,也就是说,可以指定UNDO表空间必须满足UNDO_RETENTION的限制。当UNDO表空间设置为Guarantee,那么提交事务的回滚空间必须被保留足够的时间,如果UNDO表空间的空间不足,那么新的事务会因空间不足而失败,而不是选择之前的覆盖。

从各个不同版本回滚段的管理变迁,我们可以看出Oracle一直在进步。

Oracle提供了一个内部事件(10203事件)可以用来跟踪数据库的块清除操作,10203事件可以通过以下命令设置,设置后需要重新启动数据库该参数方能生效:

alter system set event="10203 trace name context forever" scope=spfile;

需要注意的是,可能存在另外一种情况,就是当执行延迟块清除时,回滚段或原回滚表空间已经被删除,,此时Oracle仍然可以通过字典表UNDO$来获得SCN信息,执行块清除。

相关阅读:

Oracle ORA-01555 快照过旧 说明

ORA-01078 和 LRM-00109 报错解决方法

ORA-01555超长的Query Duration时间

ORA-00471 处理方法笔记

ORA-00314,redolog 损坏,或丢失处理方法

ORA-00257 归档日志过大导致无法存储的解决办法