前几天由于单位断电了,导致一台 BK * 应用的开发数据库环境无法 open 打开,本以为借助于 advise/repair failure 就可以实现恢复,中间还是费了不少周折。
这算是自己第一次处理稍微比较复杂的恢复问题,以前碰见的问题都是比较常规简单的,对于备份恢复来说,一直想找一个时间更系统的学习一下,这个问题处理的过程当中才发现这些基础理论的重要性,因此一些处理步骤上还是比较混乱的,思路并不是很清晰,胡子眉毛一把装,尝试了所有会用或能用的方法,虽然最后拉起了库,但按照惜分飞大师的说法,还是有一些幸运的成分,不得不承认,差距还是很大,因此下面叙述中要有不到位的,还请各位指正。
环境信息:
版本:12.1.0.2.0
用途:开发环境
其他信息:未开启归档模式
现象:上班后开发人员发现 start 数据库错误,根据网上的信息,做了重建控制文件等操作,但依旧无法启动,系统此时已经有些混乱了,可能都记不太清楚还做了什么。
1. 使用 LIST/ADVISE/REPAIR FAILURE
尝试使用 LIST FAILURE,发现有几个 HIGH、CRITICAL 的错误,由于未截图,所以只能描述,记得其中一个错误是某个数据文件出现了坏块,另一个错误是控制文件不是最新状态,好像还有个错误是系统表空间 SYSTEM 出现坏块 (印象已经不深了)。
使用 ADVISE FAILURE,指出了一些修复的方法和脚本。
然后执行了 REPAIR FAILURE,执行了自动修复,发现一直刷屏,等了许久未结束,强制结束后,再次执行 LIST FAILURE,发现仍旧存在数据文件坏块的错误。
2. 查询有坏块的数据文件信息
使用 dbv 检测这一个有问题的数据文件,
从 V$DATABASE_BLOCK_CORRUPTION 视图查看坏块信息,
说明是 10 号文件的 1678871 和 1678883 块,各自有一个坏块。
其中,CORRUPTION_TYPE 都是 FRACTURED,表示块头看起来是正常,但是块中存在不一致的版本。
使用如下 SQL 可以查看这些坏块中具体存在什么信息,
说明坏块中存在的一张表使用的索引。
3. 尝试修复坏块
尝试重建索引看看,
提示数据文件块损坏,显然这种方式行不通了。
说到修复坏块,江湖上还是有一些神器的,查了下,
(1) ODU:ORACLE DATABASE UNLOADER,老熊和 dbsnake 现在负责维护。
(2) DUL:DATA UNLOADER,Oracle 内部的一个非商业化产品。
(3) AUL:也称 MyDUL,d.b.c.a(楼方鑫) 大神负责维护。
(4) 刘大的 PRM-DUL。
(5) bbed,可以做一些数据块修改的工作。
我之前没有用过任何一款,现学起来还是需要些时间。以上软件大部分有免费版,但对数据文件大小有限制,只能做很小的数据恢复,要想全部恢复,就要买 license,虽然我和 dbsnake 是同事,但为了这么个开发库,而且是这么一个我认为在大神看来其实可能很简单的问题,还是别来麻烦别人了,自己选择继续扛下来,也算让自己锻炼一把。
4. 尝试屏蔽坏块数据文件
既然是索引,不是数据,尝试下是不是可以屏蔽这个存在坏块的数据文件。
重建控制文件,可以参考 eygle 的文章《如何获得创建控制文件的脚本并重建控制文件》()
生成的控制文件模版中有 RESETLOGS/NORESETLOGS 两种模式,采用 noresetlogs 脚本的控制文件,执行,
提示 open 的时候出现了 ORA-00600 的错误。
再查看 alert 日志,
…
…
…
出现了一系列 ORA-00600 的错误,最后由 PMON 进程结束了数据库实例的操作。我们知道 ORA-600 除了是我们李老师的网名:) 之外,是 Oracle 中比较著名的一个错误号。可以参考戴老师这篇文章,对 600 错误有一个比较详细的解释 ()。
从报错看,ORA-00600 跟着的参数,第一个是 4194、4137,从定义看,都是和交易相关,
彭小波大师推荐了一篇 MOS 文章 (Step by step to resolve ORA-600 4194 4193 4197 on database crash (文档 ID 1428786.1)),惜分飞博客文章中有译文 (《ORA-600 4194/ORA-600 4193/ORA-600 4137 故障解决》)。
描述的就是 alert 中出现 ORA-00600 4xxx 错误的原因,
同时给出了解决方案,
之所以创建新回滚表空间的原因,就是因为他的回滚段序号要高于目前正使用的段,这样在一个交易需要参考已经不存在的回滚段做块清除操作的时候,才会继续完成这项操作。
尝试下操作。
(1) 根据 spfile 创建 pfile,
- create pfile from spfile;
(2) 停止实例,编辑文件,增加:
- *.undo_management=manual
- *.event='10513 trace name context forever, level 2'
使用文件 pfile 以 restrict 启动,
- SQL> startup restrict pfile=/u01/app/oracle/product/12.1.0/dbhome_1/dbs/initXXXXX.ora
(3) 查看 dba_rollback_segs 视图,
发现并不是像上面文章说的 OFFLINE 状态,是 PARTLY AVAILABLE,换句话说需要 SR?先创建了新的回滚表空间 UBDOTBS2 再说。
(4) 删除旧回滚表空间错误,
(5) 参考,屏蔽这些 SYSSMU 表空间,pfile 文件增加,
(6) 再次重启删除,
- SQL> drop tablespace undotbs1 including contents and datafiles;
正常,
(7) 再次重启,切换表空间,
(8) 数据库可以打开了,查询一些应用表,可是报错了,
开始想出的方法是使用
- select dbms_metadata.get_ddl('TABLE','XXX','XXX') from dual;
- select dbms_metadata.get_ddl('INDEX','XXX','XXX') from dual;
得出原始建表和索引的语句,但数据无法恢复。
(9) 参考,设置 10231 事件后使用 CTAS 方式重建表,
再使用表所属用户执行 rename 创建原表,
记得关闭事件,
此时,表数据可以恢复使用了,
总结:
1. 备份恢复的基础,还是需要理解数据库运转的工作原理,出现任何报错,都是有原因,提示的信息非常重要,要能透过现象看出本质。这不是一朝一夕就能掌握的技能,但需要一朝一夕的积累,这块还需要自己多努力学习和实践。
2. 还是需要有备份,如果开启了归档,或者有一些冷备,恢复起来就会方便一些。即使这是一套开发库。
3. 整个过程还要感谢白鳝、惜分飞、彭小波以及道长的支持。
欢迎关注我的个人微信公众号:bisal 的个人杂货铺
来源: http://blog.csdn.net/bisal/article/details/60355256