oracle 存储过程_Oracle RAC数据库掉电导致系统崩溃的恢复过程

更新时间:2020-03-14    来源:Oracle教程    手机版     字体:

【www.bbyears.com--Oracle教程】

这里简单记录一下,此次国庆加班恢复的某客户的2套Oracle RAC数据库,整个恢复过程中,2套rac差不多,因此这里以其中一套数据库的恢复过程为例进行简单分析说明。数据库由于为非归档,由于掉电导致重启之后系统无法正常open。

在正常open的过程中,报错如下错误:


SQL> alter database open;
alter database open
*
ERROR at line 1:
ORA-00600: internal error code, arguments: [kcratr1_lastbwr], [], [], [], [],
[], [], []
 
SQL> shutdown immediate
ORA-01109: database not open
 
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORACLE instance started.
 
Total System Global Area 4294967296 bytes
Fixed Size                  2089576 bytes
Variable Size            2751466904 bytes
Database Buffers         1526726656 bytes
Redo Buffers               14684160 bytes
Database mounted.
ORA-00600: internal error code, arguments: [kcratr1_lastbwr], [], [], [], [],
[], [], []
对于该错误,网上的解决方法也很多,可惜都不管用。这种情况之下,往往都是需要强制打开数据库的,首先需要做一个不完全恢复,如下:


SQL> recover database
ORA-00279: change 236912204 generated at 09/29/2015 12:49:13 needed for thread
1
ORA-00289: suggestion : /xxxx/1_5112_877094801.dbf
ORA-00280: change 236912204 for thread 1 is in sequence #5112
 
Specify log: {=suggested | filename | AUTO | CANCEL}
auto
ORA-00308: cannot open archived log "/xxxx/1_5112_877094801.dbf"
ORA-27037: unable to obtain file status
IBM AIX RISC System/6000 Error: 2: No such file or directory
Additional information: 3
在进行相关操作之后,我备份了一下当前的控制文件信息,便于后面如果有问题,方便处理。强制open的过程中,发现报如下错误:


Sat Oct  3 11:49:31 2015
Instance recovery: looking for dead threads
Instance recovery: lock domain invalid but no dead threads
Sat Oct  3 11:49:33 2015
Errors in file /oracle/oracle/admin/cwdb/udump/cwdb1_ora_6029586.trc:
ORA-00600: internal error code, arguments: [kclchkblk_4], [1], [18446744072394632417], [1], [18446744072392296306], [], [], []
Sat Oct  3 11:49:34 2015
Errors in file /oracle/oracle/admin/xxxx/udump/xxxx1_ora_6029586.trc:
ORA-00600: internal error code, arguments: [kclchkblk_4], [1], [18446744072394632417], [1], [18446744072392296306], [], [], []
Sat Oct  3 11:49:34 2015
Error 600 happened during db open, shutting down database
USER: terminating instance due to error 600
Instance terminated by USER, pid = 6029586
这个错误已经处理过多次了。同样,百度一下,会发现很多人都写过相关的文章,包括Oracle mos的文章解释也是说这是临时块的scn过大导致,通过drop  tempfile即可绕过该问题。实际上,这种情况之下,根本不会起作用。
但是不管如何,这个问题很明显都是跟block的scn有关系。既然是跟scn有关系,那么处理就不难了,通过推进scn即可。
通过推进scn 之后,再次open resetlogs成功打开数据库,可惜的是alert log报了一堆错误,如下所示:


Sat Oct  3 13:10:34 2015
Errors in file /oracle/oracle/admin/xxxx/bdump/xxxx1_smon_10420246.trc:
ORA-00600: internal error code, arguments: [4137], [], [], [], [], [], [], []
Opening with internal Resource Manager plan
where NUMA PG = 1, CPUs = 40
Sat Oct  3 13:10:35 2015
ORACLE Instance xxxx1 (pid = 25) - Error 600 encountered while recovering transaction (23, 85).
Sat Oct  3 13:10:35 2015
Errors in file /oracle/oracle/admin/xxxx/bdump/xxxx1_smon_10420246.trc:
ORA-00600: internal error code, arguments: [4137], [], [], [], [], [], [], []
Sat Oct  3 13:10:35 2015
Trace dumping is performing id=[cdmp_20151003131035]
Sat Oct  3 13:10:35 2015
replication_dependency_tracking turned off (no async multimaster replication found)
Sat Oct  3 13:10:36 2015
Instance recovery: looking for dead threads
Instance recovery: lock domain invalid but no dead threads
Sat Oct  3 13:10:36 2015
Errors in file /oracle/oracle/admin/xxxx/bdump/xxxx1_smon_10420246.trc:
ORA-00600: internal error code, arguments: [4137], [], [], [], [], [], [], []
Sat Oct  3 13:10:37 2015
Starting background process QMNC
Sat Oct  3 13:10:37 2015
ORACLE Instance xxxx1 (pid = 25) - Error 600 encountered while recovering transaction (23, 85).
Sat Oct  3 13:10:37 2015
Errors in file /oracle/oracle/admin/xxxx/bdump/xxxx1_smon_10420246.trc:
ORA-00600: internal error code, arguments: [4137], [], [], [], [], [], [], []
QMNC started with pid=53, OS id=7536816
Sat Oct  3 13:10:41 2015
LOGSTDBY: Validating controlfile with logical metadata
Sat Oct  3 13:10:41 2015
LOGSTDBY: Validation complete
Sat Oct  3 13:10:46 2015
Errors in file /oracle/oracle/admin/xxxx/bdump/xxxx1_mmon_9110004.trc:
ORA-00600: internal error code, arguments: [qertbFetchByRowID], [], [], [], [], [], [], []
Sat Oct  3 13:10:48 2015
Errors in file /oracle/oracle/admin/xxxx/udump/xxxx1_ora_6619434.trc:
ORA-00600: internal error code, arguments: [kdsgrp1], [], [], [], [], [], [], []
Completed: alter database open resetlogs
这部分错误处理其实都不难。对于第一个ora-00600 [4137] 错误,很明显这是跟undo有关系的,其中(23,85)中的23表现第23号回滚段;通过屏蔽第23号回滚段可以很容易解决该错误,当然,这会儿导致事务的不一致性,这是没办法的,已经undo异常,Oracle 已经没有办法进行正常的事务恢复了。
其次,对于第2个ora-00600  [qertbFetchByRowID] 错误,处理也很简单,其大致意思是通过rowid访问获取数据有异常,很明显这是跟index有关系,通过重建index 可以解决该问题,其次最后一个[kdsgrp1] 错误就更常见了,通常也是Index的问题,重建即可。
看上去一切的恢复过程都很简单,很顺利,然而这里真正的难题,真正的问题才开始。
也就是最后一个看似很简单的错误ora-00600 [kdsgrp1]错误,对我们产生了极大的困难。首先我们来看下产生该错误时涉及到那些对象:


Validate domain 0
Validated domain 0, flags = 0x0
kwqmnich: current time:: 13: 31: 34
kwqmnich: instance no 0 check_only flag 1
kwqmnich: initialized job cache structure
            row 0041edda.2e continuation at
            file# 1 block# 126426 slot 47 not found
**************************************************
KDSTABN_GET: 0 ..... ntab: 1
curSlot: 47 ..... nrows: 175
**************************************************
*** 2015-10-03 13:31:40.864
ksedmp: internal or fatal error
ORA-00600: internal error code, arguments: [kdsgrp1], [], [], [], [], [], [], []
Current SQL statement for this session:
SELECT OWNER,NAME,TYPE,COUNT(*) FROM DBA_SOURCE WHERE SUBSTR(OWNER,1,4)="FMIS" GROUP BY OWNER,NAME,TYPE HAVING COUNT(*)>1000
----- PL/SQL Call Stack -----
 
 Object id on Block? Y
 seg/obj: 0x12  csc: 0x01.b1957474  itc: 3  flg: O  typ: 1 - DATA
     fsl: 0  fnx: 0x0 ver: 0x01
 
 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0009.00e.0003968d  0x0c07f50f.1ea7.5d  --U-    1  fsc 0x0053.b1957475
0x02   0x0017.005.0006755c  0x0c0774de.1be3.38  C---    0  scn 0x0001.b1957451
0x03   0x0002.042.00010d39  0x0080b268.0cf1.22  C---    0  scn 0x0001.b1957429
 
data_block_dump,data header at 0x110f46074
===============
tsiz: 0x3f88
hsiz: 0x170
pbl: 0x110f46074
bdba: 0x0041edda
     76543210
flag=--------
ntab=1
nrow=175
frre=0
fsbo=0x170
fseo=0x783
avsp=0x3cbe
tosp=0x3d13
0xe:pti[0]      nrow=175        offs=0
0x12:pri[0]     sfll=1
0x14:pri[1]     sfll=2

我们可以发现,除开其他的非核心对象之后,这里还涉及到一个obj#=18,也就是obj$ 这个核心的数据字典表。而该数据字典表上的几个Index,
i_obj1,i_obj2,i_obj3 都是object_id 小于57的核心对象,这部分对象是属于bootstrap$ 的核心数据字典对象。即是Index也无法通过
rebuild,38003 event或在upgrade模式下进行重建。
当然,这里也不是说完全无法去重建上述数据字典表,我后面有一篇文章会相信讲解如何去重建。
在分析过程中,我发现其中的前面2个Index都有问题,如下:


SQL> analyze table obj$ validate structure;
 
Table analyzed.
 
SQL> select index_name from dba_indexes where table_name="OBJ$";
 
INDEX_NAME
------------------------------
I_OBJ1
I_OBJ2
I_OBJ3
 
SQL> analyze index I_OBJ1 validate structure;
analyze index I_OBJ1 validate structure
*
ERROR at line 1:
ORA-08100: index is not valid - see trace file for diagnostics
 
SQL> analyze index I_OBJ2 validate structure;
analyze index I_OBJ2 validate structure
*
ERROR at line 1:
ORA-08100: index is not valid - see trace file for diagnostics
 
SQL> analyze index I_OBJ3 validate structure;
 
Index analyzed.

不过这里我们也要注意的时,虽然前面2个index都有问题,然而上述错误产生时涉及到的index并不是2个都用到了,其实只是用到了第一个index就
报错ora-00600错误了。由于客户想通过expdp schema的方式去导出数据,然而发现执行时报错ora-00600 [kdsgrp1],包括exp执行时也报该
错误,不过exp tables的方式,不会报错;由于对象太多,将近50万个对象(包括表,index以及其他)。很明显,只能通过用户级别的导出。
那么也就在意味着我们必须修复这个错误才。
通过dump 相关的block,我们发现错误是很奇怪的,如下:


*** SESSION ID:(1052.1243) 2015-10-03 17:56:59.784
Block Checking: DBA = 4684328, Block Type = KTB-managed data block
*** previous block dba dba: 477a2adoes not match my previous block dba dba: 477a26
**** row 0: key out of order
---- end index block validation
---- for block 4684328 = 0x00477a28
Block header dump:  0x00477a28
 Object id on Block? Y
 seg/obj: 0x24  csc: 0x02.80026908  itc: 19  flg: O  typ: 2 - INDEX
     fsl: 0  fnx: 0x477a1c ver: 0x01
 
 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0015.01f.00020a0a  0x00867c38.0862.04  C---    0  scn 0x0001.83f32656
0x02   0x002e.044.00002415  0x0082989a.0477.52  C---    0  scn 0x0001.74d90109
0x03   0x002c.00a.000012c5  0x0b804b78.012b.70  C---    0  scn 0x0001.74d9011c
0x04   0x0002.001.00003a72  0x00861aab.024b.0a  C---    0  scn 0x0001.74fa8cf1
0x05   0x002f.02e.000065eb  0x0b816866.0217.5b  C---    0  scn 0x0001.74fb0205
0x06   0x0026.011.00002000  0x0b814f02.016d.14  C---    0  scn 0x0001.74fc3dbf
0x07   0x0006.011.00003b1c  0x0084c65b.01f9.10  C---    0  scn 0x0001.74fde478
0x08   0x0029.05f.00003258  0x0084faa6.017c.2f  C---    0  scn 0x0001.74fdedad
0x09   0x001b.023.00003fe6  0x008a8718.025b.3b  C---    0  scn 0x0001.74fdfedc
0x0a   0x001b.006.00004057  0x0b804f24.025c.33  C---    0  scn 0x0001.751a25ed
0x0b   0x001b.02a.00004039  0x0b804f24.025c.49  C---    0  scn 0x0001.751a2609
0x0c   0x001b.024.0000404f  0x0b804f24.025c.63  C---    0  scn 0x0001.751a2627
0x0d   0x000a.018.00021b0b  0x0b821c8b.04cc.45  C---    0  scn 0x0001.751a263f
0x0e   0x000a.055.00021b0a  0x0b821c8b.04cc.5e  C---    0  scn 0x0001.751a265c
0x0f   0x000a.031.00021aec  0x0b821c8c.04cc.09  C---    0  scn 0x0001.751a2678
0x10   0x0022.05e.00001dbd  0x008a88df.01e0.2e  C---    0  scn 0x0001.74d8ff09
0x11   0x0025.010.00001ead  0x00860446.01ac.20  C---    0  scn 0x0001.74d8ff7d
0x12   0x002b.043.00001228  0x0084dc65.0164.11  C---    0  scn 0x0001.74d8ffe2
0x13   0x001f.015.00001de8  0x0b81a76a.0183.4e  C---    0  scn 0x0001.74d90071
 
Leaf block dump
===============
header address 504403185228956148=0x70000064725c1f4
kdxcolev 0
KDXCOLEV Flags = - - -
kdxcolok 0
kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y
kdxconco 1
kdxcosdc 2
kdxconro 0
kdxcofbo 36=0x24
kdxcofeo 15816=0x3dc8
kdxcoavs 15780
kdxlespl 0
kdxlende 0
kdxlenxt 4684330=0x477a2a
kdxleprv 4684326=0x477a26
kdxledsz 6
kdxlebksz 15816
*** dummy key ***
row#0[9549] flag: ---D--, lock: 0, len=14, data:(6):  00 44 03 10 00 7c
col 0; len 5; (5):  c4 04 24 25 2f
----- end of leaf block dump -----
dumping parent of corrupted subtree, row # = 1202
dumping parent of corrupted subtree, row # = 3

对于上述这个index 的错误,我是第一次遇见,跟老熊讨论了一下,他认为可能是index split情况之下出现的。在远程时,我也用过bbed
对前后将近10个index block进行了分析,通过比较index 的链表,发现确实不匹配。
对于这种情况之下,想通过bbed去修复 index,难度可想而知,因此果断放弃这种方式。最后无奈之下,只能通过处理数据字典表
的方式来处理掉i_obj1,i_obj2 这2个index。最后再让客户进行exp 用户级别的导出,只不过这个导出的时间比较漫长了

本文来源:http://www.bbyears.com/shujuku/87093.html