ora-00600故障解决方法
??? 7.16号12:40分数据库服务器突然崩溃啦,root用户进入系统后执行ls时报bad error错误,执行df显示磁盘空间足够,su – oracle后还是root的环境变量,找到lsnrctl及oracle相关的执行程度,只好重启服务器。
???
启动数据库(已经mount)时报:
??? ORA-00600: internal error code, arguments: [kcratr1_lostwrt], , [], [], [], []
???
想来大家对ora600已经不再陌生啦,如何才能打开数据库呢?在metalink上搜一下,发现这个问题对9i的各个版本中都存在,如果在打数据库时报ora600错误,启动到mount状态,即是arguments后的参数不同,都可以用以后方法恢复:
??? sql>recover database;
??? sql>alter database open;
???
刚还没有松过一口气,email通知就产生了一大堆,大部分都是关于坏块的:
??? ORA-01578: ORACLE data block corrupted (file # 2, block # 247726)
ORA-01110: data file 2: '/home/oracle/oradata/esal/TS_CYBERCAFE06.dbf'
ORA-01578: ORACLE data block corrupted (file # 5, block # 243660)
ORA-01110: data file 5: '/home/oracle/oradata/esal/TS_CYBERCAFE01.dbf'
???
看到只是两个数据文件上坏了几个块,查了一下,原来是两个索引上有了坏块,就放心啦,删除或重建索引都可以解决这个个问题,做完了还不太放心,用dbv对所有的数据文件进行了检查,没有发现坏块。
?
赶紧用rman对数据库做了一个全备,然后FTP到一台备份机上。数据库恢复之后,对数据库的bdump及udump进行检查时,发现udump目录中的一些文件也出了问题,用ls命令时返回信息如下:
#ls
ls: esal_ora_18367.trc: Input/output error
ls: esal_ora_18371.trc: Input/output error
ls: esal_ora_18377.trc: Input/output error
ls: esal_ora_18373.trc: Input/output error
ls: esal_ora_18379.trc: Input/output error
?
不确定这个是否就标志磁盘出了坏块,因为偶的系统是做了raid0 + 1,从理论上讲是不应该存在坏块的,在google上搜了一下,大部分都建议用e2fsck对该分区进行扫描,为了保险起见,只对该目录进行了改名,另创建了dump使用,准备在月底时数据库备份到另一台机器上时再处理这个问题。
http://lists.debian.org/debian-user/1999/11/msg00430.html
?
很明显,服务器崩溃肯定是数据库引起的,通过对alertsid.log文件进行分析,发现数据库从7.16号12:40分就已经异常啦,平时是10-15分钟产生一个10m的日志,从12:40分开始,每分钟产生2个10m的日志。
从12:40到数据库崩溃17:20分左右,数据库一共产生了5g的日志,平时如果系统很慢的话,客户早就打电话投诉啦,但7.16始终没有人投诉,在其间偶(3:00左右)登陆到数据库一次,用top看了数据库的运行状态正常,alertsid.log也没有error产生,就没有注意日志产生的频繁哦。
到底是什么引起数据库产生大量的日志呢?如果给公司说ora600是数据库的bug,公司肯定不乐意,以为偶又在为数据库的事故找借口;一种猜测是其它同事在对数据库进行大批量的数据处理(有时会有这种情况),决定用logmnr对12:40到17:20其间的某些归档日志进行挖掘,希望能找到真凶。
?
生成字典:
SQL> exec dbms_logmnr_d.build(dictionary_filename =>'esal.ora',
dictionary_location => '/home/oracle/soft');
LogMnr Dictionary Procedure started
LogMnr Dictionary File Opened
TABLE: OBJ$ recorded in LogMnr Dictionary File
TABLE: TAB$ recorded in LogMnr Dictionary File
TABLE: COL$ recorded in LogMnr Dictionary File
TABLE: TS$ recorded in LogMnr Dictionary File
TABLE: IND$ recorded in LogMnr Dictionary File
TABLE: USER$ recorded in LogMnr Dictionary File
TABLE: TABPART$ recorded in LogMnr Dictionary File
TABLE: INDPART$ recorded in LogMnr Dictionary File
TABLE: TABSUBPART$ recorded in LogMnr Dictionary File
TABLE: TABCOMPART$ recorded in LogMnr Dictionary File
TABLE: TYPE$ recorded in LogMnr Dictionary File
TABLE: COLTYPE$ recorded in LogMnr Dictionary File
TABLE: ATTRIBUTE$ recorded in LogMnr Dictionary File
TABLE: ENCRYPTION_PROFILE$? ORA-00942: table or view does not exist
TABLE: ENCRYPTED_OBJ$? ORA-00942: table or view does not exist
TABLE: LOB$ recorded in LogMnr Dictionary File
TABLE: CDEF$ recorded in LogMnr Dictionary File
TABLE: CCOL$ recorded in LogMnr Dictionary File
TABLE: ICOL$ recorded in LogMnr Dictionary File
TABLE: ATTRCOL$ recorded in LogMnr Dictionary File
Procedure executed successfully - LogMnr Dictionary Created
PL/SQL procedure successfully completed.
??? 这个好象是9.2.0.4的问题哦,应该不会影响logmnr的处理,在google上搜了一下,果然也有其它人报这个错(http://www.dbazine.com/code/MHSYS-logminer.log.txt),如果你有加密对象的话,尽量要打补丁哦。
??? 决定从事故开始的12:40分开始分析,将这段时间产生的归档产生添加到logmnr,然后启动logmnr进行分析。由于通过SecureCRT连接到数据库的,分析与测试不是很方便,稍一不慎就会产生ora03113,然后重新连接,就需要重新执行以下脚本,所以当你start了logmnr之后,最好执行create table logmnr2 as select * from v$logmnr_contents,然后对logmnr2进行分析。这样做的好处是,你可以对logmnr2添加索引以利于分析。
exec dbms_logmnr.add_logfile(logfilename=>'/home/oracle/oradata/esal/archive/1_15079.dbf', options=>dbms_logmnr.new);
exec dbms_logmnr.add_logfile(logfilename=>'/home/oracle/oradata/esal/archive/1_15080.dbf', options=>dbms_logmnr.addfile);
exec dbms_logmnr.add_logfile(logfilename=>'/home/oracle/oradata/esal/archive/1_15081.dbf', options=>dbms_logmnr.addfile);
exec dbms_logmnr.add_logfile(logfilename=>'/home/oracle/oradata/esal/archive/1_15082.dbf', options=>dbms_logmnr.addfile);
exec dbms_logmnr.add_logfile(logfilename=>'/home/oracle/oradata/esal/archive/1_15083.dbf', options=>dbms_logmnr.addfile);
exec dbms_logmnr.add_logfile(logfilename=>'/home/oracle/oradata/esal/archive/1_15084.dbf', options=>dbms_logmnr.addfile);
exec dbms_logmnr.start_logmnr(dictfilename=>'/home/oracle/soft/esal.ora');
?
即然已经有了数据,是否可以对数据进行分析呢?又该如何分析呢?在logmnr2中,虽然只添加了六个日志,可它有了18万条以上的记录,在这么多记录中又该如何找出异常来呢?是否可以用统计的方式找到异常呢?
从分析可以看出,delete与rollback是很少的,internal、unsupported、start是占了相当大的比重的,经过精确计算,select 130304/188789 from dual=.690209705,现在需要对系统正常时的日志进行统计,希望能有所发现。
exec dbms_logmnr.add_logfile(logfilename=>'/home/oracle/oradata/esal/archive/1_15736.dbf', options=>dbms_logmnr.new);
exec dbms_logmnr.add_logfile(logfilename=>'/home/oracle/oradata/esal/archive/1_15737.dbf', options=>dbms_logmnr.addfile);
exec dbms_logmnr.add_logfile(logfilename=>'/home/oracle/oradata/esal/archive/1_15738.dbf', options=>dbms_logmnr.addfile);
exec dbms_logmnr.add_logfile(logfilename=>'/home/oracle/oradata/esal/archive/1_15739.dbf', options=>dbms_logmnr.addfile);
exec dbms_logmnr.add_logfile(logfilename=>'/home/oracle/oradata/esal/archive/1_15740.dbf', options=>dbms_logmnr.addfile);
exec dbms_logmnr.start_logmnr(dictfilename=>'/home/oracle/soft/esal.ora');
?
?
如何才能查看在日志切换过多时数据库做什么呢?通过对logmnr2表的sql_redo字段用spool的方式,把每个日志的sql_redo输出到os的平面文件,发现这些归档日志里面几乎都是针对agent_game_card_gm132的insert into操作。
然后对agent_game_card_gm132进行统计,从12:40分起,到机器崩溃,在系统高峰时间,有人向agent_game_card_gm132表上传了200万以上的记录,这期间后台共产生了5G的日志,后经查证,是清远市xx科技的数据上传引起了系统崩溃。