Oracle ORA-1628错误的定位分析(2012/1/8)
在Oracle 10.2.0.1.0中,只要设置了undo表空间自动管理,不管有没开启自动扩展,不管undo_retention设置为多少,都会启用 Automatic Tuning of undoretention的新特性。这个新特性中计算RETENTION算法有问题,会导致unexpired undo数据奇高,并最终导致出现ORA-1628: max # extents 32765reached for rollback segment错误。
1 问题现象
Oracle版本:10.2.0.1.0。
浙江现场NQA在执行update/insert操作失败,ORACLE返回ORA-1628错误,并且ORACLE的alert日志中ORA-1628出现的非常频繁。错误日志:
Update fail,msg::ORA-01628: max # extents (32765) reached for rollback segment _SYSSMU7$
2 分析
我们在alert日志中发现了ORA-30036错误,出现ORA-30036表示UNDO表空间太小。
ORA-30036的错误描述:
Update fail,msg::ORA-30036: unable to extend segment by 8 in UNDOtablespace 'UNDOTBS1'
事务申请undo空间的流程如下:
1) 事务启动时,ORACLE会为之分配一个undo segment。ORACLE的设计目标是一个事务对应一个undo segment。ORACLE启动时,只使得部分undo segments变为online。随着事务数量的增多,更多的offline UNDOsegments变为online状态。如果所有undo segment已经是online状态,且undo表空间还有足够的空间,oracle会创建新undo segment;如果undo表空间的空间已经用尽,几个事务会合用一个undo segment。
2) 检查事务对应的undo segment是否有空闲区(extent),如果有直接使用。
3) 如果没有,使用本segment中处于expired状态的extent,这些extent存储了由其它事务提交或回滚留下的过期数据。这个动作称为一次扩展(wrap),计入v$rollstat的wraps列。
4) 如果本回滚段中没有可用的区,从UNDO表空间中请求区。这被称为一次Extend,记入v$rollstat的EXTENTS列。
5) UNDO表空间中没有Free区,从其他回滚段Steal过期的区。Steal的单位一定是以区为单位。无论Steal是否成功,V$UNDOSTAT的EXPSTEALCNT列都会加1,此列统计的是次数。EXPBLKRELCNT列是成功Steal的块数。
6) 如果Steal过期区不成功,试图扩展数据文件。
7) 如果无法扩展文件,在本回滚段中重用未过期的区, V$UNDOSTAT.UNXPBLKREUCNT列增加(增加值是区中块的个数)
8) 如本回滚段无过期的块,则Steal其他回滚段中未过期的区。每Steal一次,无论是否成功,都会记入V$UNDOSTAT.UNXPSTEALCNT列。Steal的块数记入NXPBLKREUCNT列。
9) 如还不行,报ORA-30036错误。
于是,创建新的undo 表空间UNDOTBS2,UNDOTBS2包含了4个数据文件,每个文件有31GB。然后切换至新的undo表空间。为什么数据文件大小是31G,在block大小为8K的情况下,数据文件大小限制是32G,有人说数据文件变为32G后会出现bug,为了避免这种情况,于是设置数据文件大小为31G。
【切换undo的表空间的代码如下】
--查看当前的undo表空间
show parameter undo_tablespace;
--查看所有undo表空间
select * from dba_tablespaces where contents='UNDO';
--查看当前undo表空间对应的文件
select * from dba_data_files wheretablespace_name='UNDOTBS1';
--创建新undo表空间注意修改大小!!!!!!!
create undo tablespace UNDOTBS2datafile
'/opt/oracle/oracle/oradata/orcl/undotbs02_1.dbf' size 31G autoextend off,
'/opt/oracle/oracle/oradata/orcl/undotbs02_2.dbf' size 31G autoextend off,
'/opt/oracle/oracle/oradata/orcl/undotbs02_3.dbf' size 31G autoextend off,
'/opt/oracle/oracle/oradata/orcl/undotbs02_4.dbf' size 31G autoextend off,
extent management local autoallocate retention nogurantee;
--确认是否创建成功
select * from dba_tablespaces where contents='UNDO';
--切换当前表空间
alter system setundo_tablespace=UNDOTBS2 scope=both;
--确认UNDOTBS1上没有活动的事务,若有,则等待
select usn,xacts,status from v$rollstatwhere xacts != 0;
--删除旧undo表空间
drop tablespace UNDOTBS1 includingcontents and datafiles cascade constraints;
切换undo表空间4个小时后,出现了一次ORA-01555错误,日志如下:
ORA-01555 caused by SQLstatement below (SQL ID: 0qdadgcckc5xd, Query Duration=1233 sec, SCN:0x0001.c06cbc64):
Fri Dec 28 16:15:51 2012 select tavppfr0_.UMFAILUREREASON as col_0_0_,count(*) as col_1_0_ from tAVP_PFR tavppfr0_ wheretavppfr0_.UMEVENTTIMESTAMP>=1356652518561 group by tavppfr0_.UMFAILUREREASON
Fri Dec 28 16:16:57 2012
ORA-01555是ORACLE中非常常见的错误。在undo表空间切换后,旧的undo表空间变为offline,如果事务访问旧undo表空间的数据就会得到ORA-01555错误。这是因为offline的undo表空间可能包含了为达到事务一致性所必需的数据。所以切换表空间的短时间内出现ORA-01555错误可以忽略。
悲催的是,切换undo表空间8个小时后出现ORA-01628错误。难道是UNDO表空间又满了? 于是查看处于undo空间分配情况,从表dba_undo_extents可以发现处于active/unexpired/expired状态的undo数据分别为81M/35G/1M。
>select tablespace_name,status,SUM (bytes) fromdba_undo_extents GROUP BY tablespace_name,status;
TABLESPACE_NAME STATUS SUM(BYTES)
UNDOTBS2 EXPIRED 1114112
UNDOTBS2 UNEXPIRED 3.5858E+10
UNDOTBS2 ACTIVE 81002496
然后查看了最大和最小的undosegment。最小undosegment只有4个区(extent),只占用了1M空间,而最大的undo segment中的区(extent)数量已经达到了其最大值32765。
>select SEGMENT_NAME,TABLESPACE_NAME, BYTES/1024/1024, EXTENTS,MAX_EXTENTS from dba_segments whereTABLESPACE_NAME='UNDOTBS2';
SEGMENT_NAME TABLESPACE_NAMEBYTES/1024/1024 EXTENTS MAX_EXTENTS
_SYSSMU84$ UNDOTBS2 24738.6875 32765 32765
_SYSSMU104$ UNDOTBS2 1.1875 4 32765
到这里,我感到非常困惑。困惑点一,undo表空间是非常富余的,为什么有的undo segment的extents到达了极限32765,而有的undosegment仅仅包含4个extent。困惑点二,UNEXPIRED状态的undo数据远远大于其它状态的数据量。难道有大事务正在回滚,因为我测试发现,事务回滚后,其undo 数据会变为unexpired状态。通过查询x$ktuxe视图,发现回滚事务占用undo空间仅为338*block_size=2.5M。注意操作x$ktuxe需要使用sys用户。
>select sum(ktuxesiz) from x$ktuxe whereKTUXESTA='ACTIVE';
SUM(KTUXESIZ)
-------------
338
可不可以通过修改undosegment的MAXEXTENTS属性,从而避免这个错误。执行后发现UNDO_MANAGEMENT处于AUTO模式下,无法修改器storage参数的。
>alter rollback segment "_SYSSMU84$" storage(MAXEXTENTS 40000);
ORA-02221: invalid MAXEXTENTS storage option value
难道是UNDO_RETENTION调整的非常大导致处于unexpired状态的数据异常的大?通过查看v$undostat发现最新记录的TUNED_UNDORETENTION字段仅为900秒,并且在创建undo表空间指定了retention nogurantee,所以这个原因也排除了。
>slect begin_time,end_time from v$undostat order bybegin_time desc;
至此,一切陷入僵局。只能继续从业务下手,通过每隔30秒采集数据来找出大事务。脚本见第4小节。一天后发现,最大的事务也只占用了1G的undo空间。于是开始强烈怀疑是ORACLE自身的bug所至,google一下后发现了ORACLE的10G版本在计算RETENTION算法有bug。于是试着使用其内部参数_undo_autotune关闭其自动调整RETENTION,即执行如下语句。
>alter system set "_undo_autotune" = falsescope=both;
执行上述操作900秒后发现,unexpired状态从35G下降至169M,且_SYSSMU84$的数量从32765下降到了132。
>select tablespace_name,status,SUM (bytes) fromdba_undo_extents GROUP BY tablespace_name,status;
UNDOTBS2 EXPIRED 232.75
UNDOTBS2 UNEXPIRED 16957.625
UNDOTBS2 ACTIVE 61.9375
>select usn,extents from V$ROLLSTAT;
--只贴出了部分记录
USN EXTENTS
84 132
至此可以确认,ORACLE的计算retention算法是有bug的。后来咨询了ORACLE的售前工程师,答复如下。
Oracle 10gr2的后续版本中添加了撤销(UNDO)信息最短保留时间段自动调优的特性,不再仅仅依据参数UNDO_RETENTION的设定,(需注意10.2.0.3以下有BUG,10gR2的bug现象为,只要设置了undo表空间自动管理,不管有没开自动扩展,不管undo_retention设置为多少,都会启用 Automatic Tuning of undo retention的新特性。这个bug在10.2.0.4中已经修复,建议找时间停机打patch)其调优原则如下:
当撤销表空间(UNDO TABLESPACE)大小固定,Oracle将根据表空间的大小和实际的系统负载动态调整撤销信息保存时间,该最短保存时间的具体长短基于撤销表空间大小的一定比例值公式换算后获得;它总是比设定的UNDO_RETENTION大,当撤销表空间大量空闲情况下可能远远大于UNDO_RETENTION。
当撤销表空间设定为自动扩展空间情况下,Oracle将动态调整撤销信息最短保留时间为该时段最长查询时间(MAXQUERYLEN)加上300秒或参数UNDO_RETENTION间的较大者,即MAX((MAXQUERYLEN+300),UNDO_RENTION);同样的,该最短保存时间可能远远大于设定的UNDO_RETENTION。
在自动调整情况下,实际的撤销信息最短保留时间可以通过查询V$UNDOSTAT视图上的TUNED_UNDORETENTION列获得,在无法就撤销表空间做相应修改的情况,我们可以通过修改隐式参数” _UNDO_AUTOTUNE”为FALSE关闭该自动调优特性。以上设定生效后,V$UNDOSTAT视图上TUNED_UNDORETENTION列不再更新,且撤销信息最短保留时间固定为参数UNDO_RETENTION的设定值。该参数可以不用重启数据库而动态设置生效。
3 结论
在Oracle 10.2.0.1.0中,只要设置了undo表空间自动管理,不管有没开自动扩展,不管undo_retention设置为多少,都会启用 Automatic Tuning of undoretention的新特性。这个新特性中计算RETENTION算法有问题,会导致unexpired undo数据奇高,并最终导致出现ORA-1628: max # extents 32765reached for rollback segment错误。可以通参数_undo_autotune来关闭这个新特性,从而避免问题的产生。
Oracle ORA-1628错误的定位分析(2012/1/8)相关推荐
- Oracle Ora 错误解决方案合集
Oracle Ora 错误解决方案合集 参考文章: (1)Oracle Ora 错误解决方案合集 (2)https://www.cnblogs.com/ios9/p/8627643.html 备忘一下 ...
- oracle提示01034,oracle数据库ORA 01034错误问题解决方案
ORA-01034错误的话: Oracle常见错误之一 这是个Oracle数据库服务器比较常见的错误.有经验的用户几乎马上就能解决这个错误,再不济也能马上到Metalink去搜索一下. 不幸的是,大多 ...
- oracle11g ora 29927,【案例】Oracle内存泄漏 进行10046跟踪分析07445导致数据库宕机
天萃荷净 在一次ORA-7445导致oracle数据库down掉故障分析中,发现sql因某种原因导致大量的sql area中很多内存泄露,最终导致数据库down掉.通过实验找出类此奇怪SQL. SEL ...
- Oracle的常见错误及解决办法
ORA-12528: TNS:listener: all appropriate instances are blocking new connections ORA-12528问题是因为监听中的服务 ...
- Oracle ORA
ORA-00001: 违反唯一约束条件 (.) 错误说明:当在唯一索引所对应的列上键入重复值时,会触发此异常. ORA-00017: 请求会话以设置跟踪事件 ORA-00018: 超出最大会话数 OR ...
- oracle 配置数据库错误,Oracle数据库配置错误信息解决方法
Oracle数据库配置错误信息 Oralce数据库的错误信息经常会出现,我们看见的都是错误的代码,至于错误原因究竟是什么还一时半会难以解答,所以就把一些常见的错误整理了一下,来看看也许对你有帮助的. ...
- ORA-28547:连接服务器失败,可能是Oracle Net管理错误
描述:监听和服务都正常启动了,但是远程连接的时候会有这种错误 ORA-28547:连接服务器失败,可能是Oracle Net管理错误 解决办法: listener.ora 文件中 DEFAULT_SE ...
- Oracle ORA-600 [2662] 错误
Oracle ORA-600 [2662] 错误 数据库版本:10.2.0 背景: 客户那边数据库突然出现一个current日志文件坏了,导致数据库crash了,然后现场工程师使用_ALLOW_RE ...
- ISE调用Notepad++并且实现错误高亮定位的方法
ISE调用Notepad++并且实现错误高亮定位的方法 不管是ISE还是QII,自带的文本编辑软件虽有改进,但仍然让人不过瘾,写代码一直用的是Notepad++,一个很好用的文本编辑软件.最近做毕设, ...
最新文章
- android环境安装之android4.2安装(转)
- 【转载】用 PHP V5 开发多任务应用程序
- Windows下本机简易监控系统搭建(Telegraf+Influxdb+Grafana)
- 爬虫python代码-Python爬虫入门(01) -- 10行代码实现一个爬虫
- TCP核心概念-慢启动,ssthresh,拥塞避免,公平性的真实含义
- Flink的重启策略
- 《朝花夕拾》金句摘抄(二)
- 使用Boxfuse为您的REST API设置https
- html调用父页面的函数,javascript – 如何从子窗口jquery调用父窗口函数?
- python随机读取字符_利用python3随机生成中文字符的实现方法
- GitHub上最励志的计算机自学教程,绝对牛B
- 全数字FM接收机 --(1)结构
- 查看linux中某个端口(port)是否被占用***
- axure8.0注册码
- 【小程序】rpx(responsive pixel)自适应像素浅析
- Pos应用与扫盲一路通
- 面试官:设计模式是什么?
- 对于AI 既有期待也要思考
- 2023情人节送另一半什么好?四款适合送女友的数码好物分享
- DDL、DML和DCL的理解(1、总述)
热门文章
- 关于EMC DAE、DPE、SPE、SPS的解释
- 51单片机程序烧写说明
- python能调用身份证读卡器吗_华视身份证读卡机Python二次开发
- vue之使用vue-cli搭建SPA项目
- java redis srem_Java Jedis.srem方法代碼示例
- 神经网络的三种训练方法,神经网络常用训练方法
- C++ Struct(结构体)详解
- linux gdb 跳出函数,gdb调试程序时跳进函数和跳出函数
- 零基础入门C语言,只需2小时轻松学会!
- 一个Android开发者自学Python的心路历程