前几天帮一个北京的用户成功修复了一个900G的生产库无法打开的问题,该库的背景是一个900GB的重要生产库,但是之前几乎没有任何备份,且在instance crash的情况下丢失了当前undo表空间。 尝试打开数据库OPEN database时没有报什么ORA-600[4XXX] 如[4000]的内部错误,而是直接报:
ORA-00604: error occurred at recursive SQL level 1 ORA-00376: file 2 cannot be read at this time ORA-01110: data file 2: Error 604 happened during db open, shutting down database USER: terminating instance due to error 604 Instance terminated by USER, pid = 573600 ORA-1092 signalled during: ALTER DATABASE OPEN... ORA-01157: cannot identify/lock data file 2 - see DBWR trace file ORA-01110: data file 2: ORA-27037: unable to obtain file status IBM AIX RISC System/6000 Error: 2: No such file or directory Additional information: 3 ORA-27037: unable to obtain file status IBM AIX RISC System/6000 Error: 2: No such file or directory Additional information: 3 ORA-27037: unable to obtain file status IBM AIX RISC System/6000 Error: 2: No such file or directory Additional information: 3 ORA-01157: cannot identify/lock data file 2 - see DBWR trace file ORA-01110: data file 2: ORA-27046: file size is not a multiple of logical block size Additional information: 1 Additional information: 444166144 Additional information: 16384
即递归SQL错误+ORA-00376: file 2 cannot be read at this time+ORA-01110,相关的TRACE文件里也没有报出对应的错误。
ORA-00604+ORA-00376仍是因为bootstrap对象上的一些块有活动的事务,在读取这些数据块时为了满足一致性要去读UNDO表空间,但是UNDO表空间数据文件已经被OFFLINE DROP了。
此时首先一点要明确是那些bootstrap对象的数据块中有活动事务,在该场景中几个TRACE里都没有带出这些块的位置信息,这个时间做一个errorstack就可以了:
alter system set events '604 trace name errorstack level 3';
然后OPEN database并触发错误,由于ERRORSTACK会将发生错误时的Data block buffer打印在TRACE中,所以可以直接看到是哪些块有活跃事务,这是直接搜索ITL上LCK>0的记录,并定位相关lb/lock不是0的行记录即可。定位到这些记录后需要手动BBED修复这些数据块中的活跃事务。
在这个实际案例中,发现TRACE中有十几处有活跃事务,那么就是力气活要修复达十几个块了,完全修好这十几个块后OPEN DATABASE成功,接着加上”_corrupted_rollback_segments”参数并必要地修改数据字典从而把老的UNDO表空间彻底DROP掉,并创建新的UNDO表空间并切换之,之后CREATE TABLE等操作就可以顺利执行了。
后续可能还需要修复一些数据表,因为老的UNDO被DROP 掉,可能一些应用数据表上还需要依赖其读一致性数据,因此可能出现ORA-01555错误,可以通过加上对应undo rollback segment的”_corrupted_rollback_segments”来重建这些数据表,最后达到基本修复该数据库的目的。
Leave a Reply