ORA-01555: 快照过旧: 回退段号 18 (名称为 "_SYSSMU18_720684835$") 太小

首先了解Oracle在什么状况下会产生ORA-01555错误:数据库

假设有一张6000万行数据的testdb表,预计testdb全表扫描1次须要2个小时,参考过程以下: 优化

一、在1点钟,用户A发出了select * from testdb;此时无论未来testdb怎么变化,正确的结果应该是用户A会看到在1点钟这个时刻的内容。日志

二、在1点30分,用户B执行了update命令,更新了testdb表中的第4100万行的这条记录,这时,用户A的全表扫描尚未到达第4100万条。毫无疑问,这个时候,第4100万行的这条记录是被写入了回滚段,假设是回滚段UNDOTS1,若是用户A的全表扫描到达了第4100万行,是应该会正确的从回滚段UNDOTS1中读取出1点钟时刻的内容的。blog

三、这时,用户B将他刚才作的操做提交了,可是这时,系统仍然能够给用户A提供正确的数据,由于那第4100万行记录的内容仍然还在回滚段UNDOTS1里,系统能够根据SCN到回滚段里找到正确的数据,但要注意到,这时记录在UNDOTS1里的第4100万行记录已经发生了重大的改变:就是第4100万行在回滚段UNDOTS1里的数据有可能随时被覆盖掉,由于这条记录已经被提交了!事务

四、因为用户A的查询时间漫长,而业务在一直不断的进行,UNDOTS1回滚段在被多个不一样的transaction使用着,这个回滚段里的extent循环到了第4100万行数据所在的extent,因为这条记录已经被标记提交了,因此这个extent是能够被其余transaction覆盖掉的!开发

五、到了1点45分,用户A的查询终于到了第4100万行,而这时已经出现了第4条说的状况,须要到回滚段UNDOTS1去找数据,可是已经被覆盖掉了,这时就出现了ORA-01555错误。io

缘由分析:"报表"程序执行时间漫长,在程序查询的过程当中其余用户对"报表"进行了更新,被更新的数据写入了回滚段,当程序到回滚段找数据时,发现数据已经被覆盖掉,因而就出现了ORA-01555错误。另外"报表"程序执行效率不高也会形成ORA-01555错误。test

解决办法:效率

一、扩大回滚段,由于回滚段是循环使用的,若是回滚段足够大,那么那些被提交的数据就能保存足够长的时间,使那些大事务完成一致性读取。以前EBS系统UNDO表空间为9GB,目前为10GB。见下图:date

二、增长undo_retention时间,由于UNDO回滚段是循环使用,里面的数据可能随时被循环覆盖掉,若是设置undo_retention时间更长,那么在retention规定的时间内,任何其余事务都不能覆盖这些数据。目前EBS系统undo_retention为10800秒(3个小时)。见下图:

 

3最重要的一点就是优化程序相关查询语句,减小查询语句的一致性读,下降读取不到回滚段数据的风险。全部的出错信息都会纪录到数据库日志alert_PROD.log文件中,下图红线部分是一条SQL查询词句,ORA-01555颇有多是这条语句形成,把这条语句提供给开发人员来分析和优化程序代码。

相关文章
相关标签/搜索