资源预览内容
第1页 / 共8页
第2页 / 共8页
第3页 / 共8页
第4页 / 共8页
第5页 / 共8页
第6页 / 共8页
第7页 / 共8页
第8页 / 共8页
亲,该文档总共8页全部预览完了,如果喜欢就下载吧!
资源描述
导数据遇见ORA-01555错误昨天在对 CALLCENTER系统的主库导入 CUSTOMER 数据的时候,遇到了ORA-01555错误。软件环境:两台 DB 都是导入工具使用: powercenter8.6主库是 redhat linux4.7备库是 windows2003 (32 位)环境在导入过程中,报:ORA-01555:快照过旧 : 回退段号1 在名称为_SYSSMU1$过小错误。1555错误产生的原因,就需要知道ORACLE的两个特性:一致性读 (Consistent Get)清除( Delayed Block Cleanout)。此外,还要知道关于回滚段的一些配置参数:和延迟块相关参数先看下 Oracle 中关于 UNDO 有哪些配置参数:SQL show parameter undoNAMETYPEVALUE- - -undo_managementstringMANUALundo_retentioninteger 900undo_suppress_errors Boolean FALSEundo_tablespacestringUNDOTBS1undo_management回滚段的 管理方式。值可以为MANUAL/AUTO。9i 中默认是 MANUAL ,10g中默认是AUTO 。从 9i 后,回滚段就以表空间的形式管理,并且支持系统自动管理回滚段。一个回滚表空间上可以创建多个回滚段,一个 数据库可以创建多个回滚表空间。但是,一个实例( Instance )只能使用一个回滚表空间。如果 undo_management设置为 MANUAL ,就是手动创建回滚段:SQL create rollback segment undo1 tablespace UNDOTBS1;如果设置为 AUTO , Oracle 就自动管理回滚段的创建,而手工创建就会失败。undo_retention这个参数设置回滚段中的被提交或回滚的数据强制保留时间,单位是秒。请注意,这个参数和1555错误有非常大的关系。但是,需要提醒的是,并不是回滚段中的数据超过这个时间以后就会被清除掉,而是等到后面事务产生的回滚数据覆盖掉“超期 ”数据。所以这就是为什么我们往往看到系统的回滚表空间占有率始终是100% 的原因了。undo_suppress_errors是否报与回滚段有关的错误。如果为FALSE ,就不会产生与回滚段有关的错误。但是,请注意,并不是不会发生回滚段错误,而只是屏蔽错误信息,错误发生了就会存在滴。在10g 中,这个参数是隐含参数。undo_tablespace为每个实例制定的唯一当前使用的回滚段表空间。面我们就模拟一下1555错误发生的情况:首先建立测试环境。由于我们只是要模拟1555错误的发生,所以需要建立一个小的回滚表空间,并且设置 undo_retention时间为 1 (秒),以便回滚数据尽快被覆盖(呵呵,要防止1555错误发生,这就一定要避免的)。CREATE UNDO TABLESPACE rbs_tsDATAFILE rbs_ts2.dbf SIZE10MAUTOEXTEND OFF;altersystem set undo_retention=1 scope=spfile;altersystem set undo_management=auto scope=spfile;altersystem set undo_tablespace=rbs_tsscope=spfile;startup forcealter tablespace rbs_tsonline;create table demo.t_dualas select * from dual;insert intot_dual values(1);commit;一致性读导致的1555错误开始读取表。SQLSQLvar cl refcursorSQL begin2open:clfor select * from demo.t_multiver;3end;4/PL/SQL procedure successfully completed.SQL更新表数据,产生回滚信息。SQL updated mo.t_multiver set b = 111 where a = 1;1 row updated.SQL commit;Commit complete.运行大批其他事务,充满所有回滚段,以致覆盖上面的回滚信息。回滚段可以通过dba_rollback_segs查看。SQL begin2for I in 1.20000loop3update demo.t_dualset dummy=1;4commit;5end loop;6end;78/PL/SQL procedure successfully completed.SQL /PL/SQL procedure successfully completed.查询到更新过的数据记录,回滚信息已经被覆盖,所以报1555错误。SQLprint :clERROR:ORA-01555: snapshot too old: rollback segment number 18 with name _SYSSMU18$toosmallnorows selectedSQL延迟块清除导致的1555错误开始读取表。SQLvar cc refcursorSQLSQL begin2open:cc for select * from t_multiver;3end;4/这时一个事务更新了该数据块,但在提交前,我们手工将buffer cache中的数据做了flush ,再做提交。这时的数据块上只记录了锁标志,没有事务标志和Commit SCN。PL/SQL procedure successfully completed.SQLSQL update t_multiver set b=115 where a=1;1 row updated.SQLSQL alter system flushbuffer_cache;System altered.SQLSQL commit;Commit complete.进行非常多的事务,将回滚段中的事务信息表中的数据全部覆盖:SQLSQL begin2-overwriterollback slot3for I in 1.40000loop4updatet_dualset dummy=1;5commit;6end loop;7end;8/PL/SQL procedure successfully completed.读取数据块前需要到回滚段的事务信息表中读取Itl 中没有标记完全的事务的状态和Commit SCN,以判断是否需要进行一致性读。但是事务信息表中的数据都已经被覆盖,所以报1555错误:SQLSQLprint :ccERROR:ORA-01555: snapshot too old: rollback segment number 20 with name_SYSSMU20$toosmallnorows selected以上两个例子看起来是好像很类似,但是,他们的本质区别是:第一个实际上是在进行一致性读得时候发生的 1555 错误,而第二个例子是在判断是否需要进行一致性读得时候发生的 1555 错误。解决 1555错误的方法现在,我们已经知道了1555 错误产生的原因。那么,就可以总结出以下方法来解决1555错误问题:1 、扩大回滚段因为回滚段是循环使用的,如果回滚段足够大,那么那些被提交的数据信息就能保存足够长的时间是那些大事务完成一致性读取。2 、增加 undo_retention时间在 undo_retention规定的时间内,任何其他事务都不能覆盖这些数据。3 、优化相关查询语句,减少一致性读。减少查询语句的一致性读,就降低读取不到回滚段数据的风险。这一点非常重要!4 、减少不必要的事务提交提交的事务越少,产生的回滚段信息就越少。5 、对大事务指定回滚段通过以下语句可以指定事务的回滚段:SET TRANSACTION USE ROLLBACK SEGMENTrollback_segment;给大事务指定回滚段,即降低大事务回滚信息覆盖其他事务的回滚信息的几率,又降低了他自身的回滚信息被覆盖的几率。大事务的存在,往往是1555错误产生的诱因。6 、使用游标时尽量使用显式游标,并且只在需要的时候打开游标,同时将所有可以在游标外做的操作从游标循环中拿出。当游标打开时,查询就开始了,直到游标关闭。减少游标的打开时间,就减少了1555 错误发生的几率。在本次操作中,笔者的解决方案是:1. 适当增大 undo 表空间的尺寸,防止回滚信息被覆盖。2. 增加 undo_retention 时间,增加到 10800 秒(在导入源和导出源都修改)。3. 删除目标表的部分索引,加快导入速度,在倒完数据后,再建立。
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号