ORA-07445: 出现异常错误: 核心转储(oracle bug)
ORA-07445: 出现异常错误: 核心转储(oracle bug)
目录(?)[+]近来在测试时碰到一莫名问题,研发声称在开发环境中正常,而我们在测试环境中则经常遭遇,几番折腾,发现是oracle的bug所致。不过即使是oracle出bug,人家在metalink上也井井有条的写着从哪个版本到那个版本存在这样的问题,在什么版本上可以fix掉这个bug,在什么条件下会触发这个bug,又通过什么样的解决方案可以把这个bug规避掉。
数据库版本:
oracle10.2.0.4
问题现象:
日志中出现如下报错:
2011
-
06
-
21
10
:
20
50
,
010
: INFO [http-
8180
-Processor11|http-
8180
-Processor11] ([PublishSequenceDetailHibernateDao].java:
307
) - 准备数据存储过程参数:publishType[
1
]publishSeq[
813007
]currentFolderIds[
37
]
2011
-
06
-
21
10
:
20
52
,
103
:ERROR [http-
8180
-Processor11|http-
8180
-Processor11] ([PublishSequenceDetailHibernateDao].java:
317
) - 存取过程操作失败无法从套接字读取更多的数据
2011
-
06
-
21
10
:
20
52
,
104
: INFO [http-
8180
-Processor11|http-
8180
-Processor11] ([PublishSequenceDetailHibernateDao].java:
330
) - 准备数据存储过程返回参数:N
2011
-
06
-
21
10
:
20
52
,
109
:ERROR [http-
8180
-Processor11|http-
8180
-Processor11] (JDBCTransaction.java:
155
) - JDBC commit failed
java.sql.SQLException: 无法从套接字读取更多的数据 at oracle.jdbc.driver.[DatabaseError].throwSqlException([DatabaseError].java:
112
) at oracle.jdbc.driver.[DatabaseError].throwSqlException([DatabaseError].java:
146
) at oracle.jdbc.driver.[DatabaseError].throwSqlException([DatabaseError].java:
208
) at oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.java:
1118
) at oracle.jdbc.driver.T4CMAREngine.unmarshalSB1(T4CMAREngine.java:
1070
) at oracle.jdbc.driver.T4C7Ocommoncall.receive(T4C7Ocommoncall.java:
106
) at oracle.jdbc.driver.T4
CConnection.doCommit(T4CConnection.java:
523
)
oracle alert日志中出现如下报错
Errors in file /oracle/oracle/product/10.2.0/db_1/admin/test/udump/test_ora_2451.trc:
ORA-07445: exception encountered: core dump [opiptp()+56] [SIGSEGV]
[Address not mapped to object] [0x7F8777FAF080]
不同数据库环境的现象:
测试环境中,数据库版本为oracle10.2.0.4,出现此问题的概率极大;
开发环境中,数据库版本为oracle10.2.0.1,则不会出现此问题。
现场环境中,数据库版本为oracle10.2.0.4,存储过程逻辑大致相同,也不会出现此问题。
经过研发同学的排查,最终定位到存储过程在执行下列sql的时候,测试环境的数据库alertlog中,就会不断的出现ORA-07445的错误。
select PUBLISH_SEQUENCE.nextval, 812486, 1,x.id,null,x.assettype,decode(x.status, 3, 41, 40),x.folderid,x.assetid
FROM vod_cms_cont2flder x WHERE x.pubauditstatus=4 and x.locatestring LIKE substr('1#2$2', 1, instr('1#2$2', '$') - 1)||'%';
该sql在现场正式环境中的oracle10.2.0.4数据库中也可正常运行,唯一区别是,现场正式环境的vod_cms_cont2flder对象为数据表,而测试环境中因代码重构,该对象实际是视图。
尝试将insert之后的append hints去掉,该sql即可正常执行,将整个发布准备数据的存储过程中所有的append hints去掉后,发布功能恢复正常。是否问题就出在这个append的hints上么?
还需要在metalink上查证问题根源。
问题分析
浅析ORA-07445错误
一般情况下,ORA-600被证明为oracle的内部错误,通常由oracle的bug引起,需要打oracle相应的补丁程序。而当oracle服务器进程从操作系统收到一个致命的错误信息时会抛出ora-07445错误,这个错误可以被oracle后台进程或者用户进程激发。当错误被抛出时,系统会首先写一个错误日志到alert.log文件中,然后会写跟踪文件到user_dump_dest或background_dump_dest中;最后会将主存信息转储到core_dump_dest中。
操作系统有很多的非法操作设计,一个经常会碰到的情况就是,当一个进程访问一个非法地址(比如系统预留地址)时致命错误将会产生。
Ora-07445错误是一个非常普通的错误,可能在oracle的任何代码中产生,该错误代码更详细的描述需要进一步跟踪其跟踪文件。
问题根源分析
在metalink上输入关键字:ORA-07445: exception encountered: core dump
在10.2.0.2以下的版本,则没有这个bug,所以解释了测试环境中有而开发环境中无的现象;现场版本使用的是对象表,不是视图,所以也没问题...
然而在该文档中并未提到insert 这个动作是否会触发bug,虽然从现象上看去掉append的hint之后,问题就不再出现,但是问题的根源是否就找到了呢?根据该文档中提供的解决方案,执行以下sql修改隐含参数之后,让测试恢复insert 的hint,继续观察测试的结果。
alter system set
"_optimizer_rownum_pred_based_fkr"
=
false
;
果然没过多久,同样的问题继续出现...只好继续回头分析alert日志中提到的trace文件,/oracle/oracle/product/10.2.0/db_1/admin/test/udump/test_ora_2451.trc,发现日志中有如下内容:
ksedmp: internal or fatal error
ORA-
07445
: exception encountered: core dump [opiptp()+
56
] [SIGSEGV] [Address not mapped to object] [
0x7F981BBE34D8
] [] []
Current SQL statement
for
this
session:
select T.* FROM T_PAGE T START WITH T.ID = :B1 CONNECT BY PRIOR T.PARENT_ID =T.ID
额...仔细分析vod_cms_cont2flder视图的生成sql,发现这个视图不简单哪,竟然还调用了一个函数,函数中则使用了上述connect by prior递归查询的sql,好吧,继续metalink...
这次通过关键字 ORA-07445 core dump opiptp CONNECT BY PRIOR 的组合进行查询,可以搜到id号为436199.1的一篇文章,文中说明,在10.2.0.2版本至10.2.0.5版本,存在bug 5968363,假如尝试使用insert append,或者在查询中存在CONNECT BY, WITH, 函数调用等复杂操作时,会触发此bug。宾果,版本、动作、现象全中,这才是问题的始作俑者嘛
解决方案
接下来的解决方案就简单了,根据oracle metalink上提供的solution,在数据库级别执行以下sql,以设置隐含参数,即可避免出现此问题。
alter system set
"_optimizer_connect_by_cost_based"
=
false
scope=both ;
或者在session级别执行下列sql:
alter session set
"_optimizer_connect_by_cost_based"
=
false
scope=both ;
或者直接在语句级别加hint:
当然,从本case的实际情况看,在数据库级别执行隐含参数的设置是最为合适的,避免在程序中做过多的改动。
目录 返回
首页