Oracle 回退段 常见问题

ORA_01555   snapshot   too   old:   rollback   segment   number   string   with   name   "string "   too   small
原因可分为以下情形:
A.   回滚段太少/太小
数据库中有太多的事务修改数据并提交,   就会发生已提交事务曾使用的空间被重用,   从而造成一个延

续时间长的查询所请求的数据已经不在回滚段中.
解决方法:   创建更多的回滚段,   为回滚段设置较大的EXTENT以及较大的MINEXTENTS

B.   回滚段被破坏
由于回滚段被破坏,   造成事务无法将修改前的内容(read-consistent   snapshot)   放入回滚段,   也会产生ORA-01555错误.
解决方法:   将被破坏的回滚段OFFLINE,   删除重建.

C.   FETCH   ACROSS   COMMIT
当一个进程打开一个CURSOR,   然后循环执行FETCH,   UPDATE,   COMMIT,   如果更新的表与FETCH的是同一个表,   就很可能发生ORA-01555错误.

解决方法:

a.   使用大的回滚段

b.   减少提交频率(可参见本论坛 "如何避免一个PROCEDURE被重复调用 "一贴中,   无名朋友的回帖)
以上两种方法只能减少该错误发生的可能,   不能完全避免.   如果要完全避免,   须从执行方法着手,   可以用以下两种方法:

c.   建立一个临时表,   存放要更新的表的查询列(如主键及相关的条件列),   从临时表FETCH,   更新原来的表.

d.   捕获ORA-01555错误,   关闭并重新打开CURSOR,   继续执行循环:
示例(示例程序的思路来源自ORACLE的UTLIP.SQL,   有兴趣的朋友可直接阅读该程序,   位置在RDBMS/ADMIN下,   程序很短,   容易读):

____DECLARE
____LAST_PK   NUMBER   :=   0;
____V_THEROWID   ROWID;
____CURSOR   C1   IS
________SELECT   ROWID,   PK,   …
________FROM   SMPLE
________WHERE   PK   >   LAST_PK
________AND   othercondition
________ORDER   BY   PK;
____BEGIN
________OPEN   c_SOURCE;
________LOOP
____________BEGIN
________________FETCH   C1   INTO   v_THEROWID,   v_PK;
________________EXIT   WHEN   C1%NOTFOUND;
____________EXCEPTION   WHEN   OTHERS   THEN
________________IF   SQLCODE   =   -1555   THEN   --   snapshot   too   old,   re-execute   fetch   query
____________________CLOSE   C1;
____________________OPEN   c_SOURCE;
____________________GOTO   NEXTLOOP01555;
________________ELSE
____________________RAISE;
________________END   IF;
____________END;
____________LAST_PK   :=   PK;
………   …   PROCESS,   UPDATE   AND   COMMIT
____________ <>
____________NULL;
________END   LOOP;
________CLOSE   C1;
____END;

D.   其它原因:
*   Delayed   logging   block   cleanout是ORACLE用来提高写性能的一种机制:   当修改操作(INSERT/UPDATE/DELETE)发生时,   ORACLE将原有的内容写入回滚段,   更新每个数据块的头部使其指向相应的回滚段,   当该操作被COMMIT时,   ORACLE并不再重新访问一遍所有的数据块来确认所有的修改,   而只是更新位于回滚段头部的事务槽来指明该事务已被COMMIT,   这使得写操作可以很快结束从而提高了性能接下来的任何访问该操作所修改的数据的操作会使先前的写操作真正生效,   从而访问到新的值.   Delayed   logging   block   cleanout   虽然提高了性能,   但却可能导致ORA-01555.   这种情况下,   在OPEN/FETCH前对该表做全表扫描(保证所有的修改被确认)会有所帮助.

*   不适当的OPTIMAL参数:   太小的OPTIMAL参数会使回滚段很快被SHRINK,   造成后续读取操作访问时,   先前的内容已丢失.   仔细设计OPTIMAL参数,   不要让回滚段过于频繁的EXTEND/SHRINK有助于问题的解决.

*   DB   BLOCK   BUFFER太小:   如果读一致性所请求的块的先前内容在缓冲区中,   那么就不用去访问回滚段.   而如果缓冲区太小,   使得先前版本的内容在CACHE中的可能性变小,   从而必须频繁的访问回滚段来获取先前的内容,   这将大大增大ORA-01555发生的可能.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值