对非归档数据库进行open resetlogs强制打开数据库后所遇到的一个ora-600[kclchkblk_4]问题分析案例。
某OLAP数据库最开始由于存储工程导致异常宕机,该数据库为非归档模式,因此重启数据库时一直无法成功open,由于种种原因最后选择使用open resetlogs直接强制重启,于是在修改_allow_resetlogs_corruption"= true参数后执行alter database open resetlogs,数据库在进行实例恢复是抛出了ORA-00600:[kclchkblk_4]的错误之后便终止掉还没完全打开的数据库。
Sun Dec 18 09:54:43 2016 SMON: enabling cache recovery Instance recovery: looking for dead threads Instance recovery: lock domain invalid but no dead threads Errors in file /opt/oracle/db/diag/rdbms/oral/oral1/trace/oral1_ora_2602.trc (incident=752217): ORA-00600: internal error code, arguments: [kclchkblk_4], [31], [2480769047], [31], [2472519551], [], [], [], [], [], [], [] Incident details in: /opt/oracle/db/diag/rdbms/oral/oral1/incident/incdir_752217/oral1_ora_2602_i752217.trc Sun Dec 18 09:54:49 2016 Errors in file /opt/oracle/db/diag/rdbms/oral/oral1/incident/incdir_752217/oral1_ora_2602_i752217.trc: |
开始并不知道kclchkblk_4是什么错误,从字面上来看貌似是check block的意思,而从后面的值来看应该是SCN相关。
从MOS上的搜索,大部分还是与bug有关,而该数据库版本为11.1.0.7的版本,也见怪不怪。
在MOS上其中一篇文档 ID 275902.1,In 10.1.0.2: ORA-600 [kclchkblk_4] and ORA-600 [2662] After Recovery of Database ,这篇文档中讲到在10.1.0.2的版本数据库中做一个不完全恢复并使用resetlogs打开数据库,便会出现ORA-00600 [kclchkblk_4]和ORA-00600 [2662]的错误,该错误是由于临时文件在open resetlogs 时并不会重新初始化,因此使得临时表空间的SCN过高,可以尝试删除所有的临时文件,启动数据库再重建,通常可能正常启动。
但与我们所遇到不同的是,该篇文章指出在10.2版本之后并不会出现,并且,我们并仅仅是遇到了ORA-00600 [kclchkblk_4]问题。
其实在当时,我也尝试了删除所有的临时文件,但该报错还是依旧。但有一点我们可以肯定,这个错误还是与SCN值有关。在此之前也用oradebug poke 推进SCN 但依然无效。
而我们发现,每次启动数据库时后面的第5个值“2472519551”便会增加2万左右,于是猜想,如果第5个值增长到大于等于第2个值是否就能跳过该错误。而这两个值相差8百万左右,即是说如果通过启动数据库来推进的话,必须启动400多次左右,于是打算先一边使用脚本不断重启,一边想其他办法。
直接循环启动数据库脚本:
#!/bin/bash export ORACLE_SID=oral1 i=1 while((i<=400)) do sqlplus -s /nolog <<EOF conn / as sysdba startup exit; EOF i=$(($i+1)) sleep 1 done |
后面的SCN值在持续增长:
GD_HYWG_SMEXP_DB01:oracle:oral1 > tail -1000f alert*.log|grep ORA-00600 ORA-00600: internal error code, arguments: [kclchkblk_4], [31], [2480769047], [31], [2474640098], [], [], [], [], [], [], [] ORA-00600: internal error code, arguments: [kclchkblk_4], [31], [2480769047], [31], [2474640098], [], [], [], [], [], [], [] ORA-00600: internal error code, arguments: [kclchkblk_4], [31], [2480769047], [31], [2474660103], [], [], [], [], [], [], [] ORA-00600: internal error code, arguments: [kclchkblk_4], [31], [2480769047], [31], [2474660103], [], [], [], [], [], [], [] ORA-00600: internal error code, arguments: [kclchkblk_4], [31], [2480769047], [31], [2474680108], [], [], [], [], [], [], [] ORA-00600: internal error code, arguments: [kclchkblk_4], [31], [2480769047], [31], [2474680108], [], [], [], [], [], [], [] ORA-00600: internal error code, arguments: [kclchkblk_4], [31], [2480769047], [31], [2474700113], [], [], [], [], [], [], [] ORA-00600: internal error code, arguments: [kclchkblk_4], [31], [2480769047], [31], [2474700113], [], [], [], [], [], [], [] …… |
在连续启动400多次之后跳过该错误成功做完了 cache recovery:
Thread 1 opened at log sequence 417 Current log# 15 seq# 417 mem# 0: +ASM/oral/onlinelog/group_15.728.930908997 Successful open of redo thread 1 MTTR advisory is disabled because FAST_START_MTTR_TARGET is not set SMON: enabling cache recovery Successfully onlined Undo Tablespace 2. Dictionary check beginning Dictionary check complete Verifying file header compatibility for 11g tablespace encryption.. Verifying 11g file header compatibility for tablespace encryption completed Sun Dec 18 14:33:24 2016 SMON: enabling tx recovery
|
之后对于该错误还存在疑问,对此向SR进行提问,回答如下:
.kclchkblk_4是什么错误,我们能搜索到的大多数指临时文件的问题。
Answer:
ORA-00600 means we are
seeing a block with an SCN ahead of the current SCN
kclchkblk_4后面的几个值分别代表什么?
ORA-00600: internal error code, arguments: [kclchkblk_4], [31], [2480769047],
[31], [2472519551], [], [], [], [], [], [], []
Answer:
[kclchkblk_4], [block SCN wrap], [block SCN base], [file SCN wrap], [file SCN
base], [], [], [], [], [], [], []
从MOS上可以找到解释:
SCN and Checkpoint (文档 ID 1431133.1)
在Oracle内部,SCN分为两部分存储,分别称之为scn wrap和scn base。实际上SCN长度为48位,即它其实就是一个48位的整数。SCN分成了低32位(scnbase)和高16位(scn wrap)。
这里有一个重要的公式:
SCN= (SCN_WRP * 4294967296) + SCN_BASE
我们通过计算前面的数据块头记录的SCN应为(31*4294967296)+2480769047=135624755223
后面的为文件头记录的SCN为:(31*4294967296)+2472519551=135616505727
而该SCN实际是控制文件中记录的SCN相近。
至此,我们可以知道在数据库进行实例恢复的步骤cache recovery 时,发现某部分数据文件中的数据文件头记录的SCN比数据块头记录的SCN小了8百多万,而每次进行打开数据库时数据文件的SCN号会增加2万左右,直到与块SCN相近,该错误便能跳过。
我在自己的实验环境上模拟将数据文件头的SCN改小再重启数据库,但无法重现该错误。
实际上如果当时使用bbed直接修改数据文件头的SCN号应该也能解决这个问题。
Bbed的修改过程:
当前值,与以上的0x000ebe2f是两位两位相反。
假设要将scnbase 改成2480769047,先进行转换成十六进制。Scnwrap也一样。
93dd8817在修改时也两位两位到序:1788dd93