一个JAVA故障的处理过程

转自 白鳝个人博客


今天碰到一个案例,虚惊了一场。一个客户说今天换了块板子,重启数据库的时候数据库启动后很快就宕了,ALERT LOG信息如下:

Errors in file /oracle/app1/oracle/product/9.2/admin/xxxlyg/udump/xxxlyg_ora_4964.trc:
ORA-07445: 出现异常: 核心转储 [kgllkdl()+3072] [SIGSEGV] [Address not mapped to object] [0x290000000000008] [] []
Wed Mar 10 21:52:12 2010
Errors in file /oracle/app1/oracle/product/9.2/admin/xxx/udump/xxxlyg_ora_4894.trc:
ORA-00600: 内部错误代码,参数: [26599], [1], [229], [], [], [], [], []
ORA-29549: 类SYS.oracle/jdbc/dbacc

我问客户做了什么改动,客户说没有任何改动,只是正常SHUTDOWN,然后关机,换板子,重启服务器,再重启数据库,数据库启动后,LISTENER一启动,数据库就报错宕了。

我查了一下,发现有两个BUG和这个情况类似:Bug 3691672和 Bug 2882661 ,于是建议客户先打PATCH 3691672,并且建议客户查查JVM有没有什么问题。由于这是一个限制性PATCH,于是找人下补丁。

对于BUG 2882661,可以通过下面的方法修复JVM:

begin
    
initjvmaux.rollbacksetup;
commit;
    
initjvmaux.rollbackset;
delete from java$rmjvm$aux;
commit;
    
initjvmaux.rollbackset;
insert into 
java$rmjvm$aux (select joxftobn from x$joxfc where bitand(joxftflags,96)=0);
commit;
    
initjvmaux.rollbackset;
delete from java$rmjvm$aux where obj# in
    (select obj# from obj$ where type#=29 and
    mtime>(select date_loaded from registry$ where cid='CATPROC'));
commit;
    
initjvmaux.rollbackset;
delete from dependency$ where d_obj# in (select obj# from java$rmjvm$aux);
    
commit;
initjvmaux.rollbackset;
    
update obj$ set status=5 where
type#=29 and obj# in 
(select obj# from java$rmjvm$aux);
    
commit;
initjvmaux.rollbackset;
    
delete from java$rmjvm$aux;
commit;
    
initjvmaux.rollbackcleanup;
end;   
/

 

alter system flush shared_pool;
alter system flush shared_pool;
alter system flush shared_pool;

@?/rdbms/admin/utlrp

客户觉得最好能不打补丁,直接试试上述方法修复。我建议先不要做,还是先打补丁,在等补丁这段时间里,最好把ORACLE_HOME和数据文件先备份一下。在等待的过程中,客户十分焦急,业务部门一直在催系统什么时候能用,客户也在网上找到了重建JVM的方法,想执行一下 create or replace java system;
我建议客户先不要做任何操作,还是先打补丁比较保险。如果补丁不起作用再想办法。从目前情况看,肯定是JVM出问题了,按理说数据库正常关闭,重启,没有任何改动的情况,JVM损坏的可能性很小。于是我再次询问哪里做了改动。

补丁终于拿到了,我正在传补丁给客户,客户突然告诉我,发现了一处变更,有人修改了JAVA_HOME,而修改后的JAVA_HOME环境变量指向的那个文件系统现在没有加载。会不会是这个问题造成的。我说这个变更可能引起JVM故障,因此建议马上加载文件系统,然后试试是否解决了问题。

10分钟后,系统运行正常,看样子这个问题解决了。

 

通过这个案例,我们可以学到点什么呢?

1、在问题没有分析清楚前,千万不要轻易做有风险的操作。如果当时做了replace jvm的操作,可能扩大故障

2、打补丁的风险肯定小于其他修复操作,应该是首选的操作,因为opatch的补丁可以很方便的回退

3、JAVA_HOME的设置要十分注意,因为如果没有设置JAVA_HOME,ORACLE会使用默认的JAVA_HOME(ORACLE_HOME下的),如果设置了JAVA_HOME ,那么将使用JAVA_HOME指定的JVM。

你可能感兴趣的:(java,jvm,oracle,数据库,System,patch)