Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4482942
  • 博文数量: 109
  • 博客积分: 10011
  • 博客等级: 上将
  • 技术积分: 2457
  • 用 户 组: 普通用户
  • 注册时间: 2006-10-18 19:04
文章分类

全部博文(109)

文章存档

2011年(1)

2010年(10)

2009年(36)

2008年(62)

我的朋友

分类: Oracle

2008-06-29 11:03:32

 

ORA-01555:SNAPSHOT TOO OLD浅析



今天同事在做数据库服务器日监控检查时,在日志中发现了ORA-01555: snapshot too old.的错误。根据日志中显示的SQL代码,结合应用程序的日志信息,是由于应用程序作了一个大数据量的update,导致回滚段不足。
一般导致ORA-01555的原因是:
1. 回滚段数量不足,导致回滚段Transaction Slot被overwrite
2. 回滚段剩余空间不足,导致回滚段被overwrite
3. undo_retention(要大于执行运行时间最长的事务所需的时间)设置太小,导致expired回滚段被overwrite

Oracle9i以后,rollback segment一般采用自动回滚段管理,涉及的参数有:
undo_management                      string      AUTO
undo_retention                            integer     3600
undo_suppress_errors                 boolean     FALSE
undo_tablespace                         string      undotbs1
在自动回滚段管理中,回滚段的数量是由系统来决定的。
回滚段的扩展则要取决于undo tablespace的设置
undo_retention的实现是要取决于undo tablespace的大小,即使undo_retention设置很大,但是undo tablespace的大小不足以支持,还是会出现unexpired回滚段信息被overwrite,从而导致ORA-01555。
回滚段一般有3种状态:active(未提交的事务),expired(已经提交的事务,超过undo_retention),unexpired(已经提交的事务,超过undo_retention)。expired回滚段有可能在后续的应用中被系统overwrite。

undo tablespace的大小可以根据公式来计算:
SELECT ((ur * (ups * dbs)) + (dbs * 24)) / 1024 / 1024 AS "Bytes"
  FROM (SELECT VALUE AS ur
          FROM v$parameter
         WHERE NAME = 'undo_retention'),
       (SELECT MAX (undoblks / ((end_time - begin_time) * 86400)) AS ups
          FROM v$undostat),
       (SELECT block_size AS dbs
          FROM dba_tablespaces
         WHERE tablespace_name = UPPER ((SELECT VALUE
                                           FROM v$parameter
                                          WHERE NAME = 'undo_tablespace')))

可能的解决办法:
1. 合理设置undo tablespace大小和undo_retention大小
2. 对于涉及到大数据量的update/delete操作,要分批Commit,减少对回滚段的冲击。
3. 对于查询SQL,要调整执行规划,增加合适的索引来缩短查询时间。
阅读(4212) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~