我们进行大查询时,可能会出现ORA-1555:snapshot too old
错误,Oracle提示的错误原因是回滚段太小(
rollback segment number string with name "string" too
small
),而实际上无论怎么设置回滚段,都有可能出现这个问题。
一个
事务
执行时 ,Oracle会检查所有的行,确认这些数据从
事务
启动的那个时间点开始没有发生变化。如果要访问的数据发生的变化,那么Oracle会到回滚段中去查找那个时间点的数据。若使数据发生变化的事务没有被提交,则数据会一直在回滚段中存在,此时不会产生ORA-1555错误;若事务被提交,那么回滚段就有可能被其他事务覆盖,碰到这种情况,Oracle
无法通过UNDO中的记录
完成读取一致性查询
,因此报ORA-1555。即
执行大查询时,访问的数据已发生变化,但未提交--->去undo中的回滚段查找那个时间点的数据--->查询尚未结束前,变化数据被提交,此时回滚段允许被覆盖--->查询仍为结束,回滚段被其他事务覆盖--->Oracle无法完成一致性读,产生ORA-1555错误。
无论系统有多大的回滚段,提交过的事
务相关的
回滚段都有可能被覆盖。当然,回滚段越大,被覆盖的机会越小,但几率小不等于不发生。针对这个问题,我们只能尽量去避免。
1. 在业务允许的范围内,调整大事务的执行时间,使之能够在其他事务较少时执行,或者把大事务分解成多个小事务。
2. 确保所有回滚段在线。回滚段越多,回滚信息被覆盖的几率越小。
3. 确保所有回滚段的扩展属性大小相同。较小的、容易发生回转的回滚段更易导致ORA-1555。
4. 设置
UNDO_RETENTION参数
UNDO_RETENTION
参数是UNDO信息在UNDO表空间的保留时间,单位是秒。理论是来说,在保留时间内,回滚段是不会被覆盖的,但如果UNDO表空间容量不够大,
UNDO_RETENTION
范围内的UNDO数据也有可能被覆盖(若开启了“保证
”模式,当UNDO表空间不足以支撑
UNDO_RETENTION的需要,Oracle
会
报UNDO表空间不足
)
。
总的来说,
UNDO_RETENTION参数可以解决大部分ORA-1555问题,前提是
有足够的UNDO表空间与之匹配。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29674916/viewspace-2786709/ ,如需转载,请注明出处,否则将追究法律责任。