|
概述 Oracle数据库出现坏块现象是指:在Oracle数据库的一个或多个数据块(一个数据块的容量在创建数据库时由db_block_size参数指定,缺省为8K)内出现内容混乱的现象。由于正常的数据块都有固定的合法内容格式,坏块的出现,导致数据库进程无法正常解析数据块的内容,进而使数据库进程报错乃至挂起,并级联导致整个数据库实例出现异常。 坏块的产生原因 坏块产生的原因大致有以下几种:
由上可见,坏块的形成原因复杂。当出现坏块时,为了找到确切的原因,需要大量的分析时间和排查操作,甚至需要多次重现才能找出根本原因。但当故障发生在生产系统上,我们为了减少停机时间,会尽快实施应急权变措施以保证系统的可用性,这样就破坏了故障现场,对根本原因的分析因而也更加困难了。 坏块的预防 坏块问题破坏性大,但并非不可预防。 首先,在Metalink.oracle.com网站,Oracle定期发布基于特定软件版本的“已知问题(known issues)说明”。对于可能导致坏块的Oracle软件BUG,在Oracle公司内部,是作为高严重级别的问题进行处理,在“已知问题(known issues)说明”中,这些BUG以严重(Noticable)问题标出(标记为*或+),部分问题,Oracle还会发布警告(Alert)通告。在文档中,Oracle会提供相应的补丁或应对措施。 Oracle提供备份恢复工具-Recovery Manager,提供了扫描文件检查坏块的功能。在Recovery Manager界面中,使用: RMAN> BACKUP CHECK LOGICAL VALIDATE DATAFILE n ; 可以检查数据文件是否包含坏块,同时并不产生实际的备份输出。 Dbv工具检查。 注:因为dbv要求file后面跟的必须是一个文件扩展名,所以如果用裸设备存储的,就必须使用ln链接裸设备到一个文件,然后再用dbv对这个链接文件进行检查。 ANALYZE TABLE tablename VALIDATE STRUCTURE CASCADE; 它执行坏块的检查,但是不会标记坏块为corrupt,检测的结果保存在USER_DUMP_DEST目录下的用户trace文件中。 利用exp工具导出整个数据库可以检测坏块 对以下情况的坏块是检测不出来的:
结合数据库性能综合考虑db_block_checksum和db_blockchecking参数。 当我们使用Recovery Manager进行实际的数据库备份时,同时也就进行了坏块检查。但要注意的是,在线使用Recovery Manager扫描坏块和备份时,需要数据库运行在归档模式(archive log),否则只能在数据库未打开的情况下进行。对于操作系统问题和硬件故障,则需要相应厂商的配合支持。同时,避免在数据库主机运行其他用户进程,避免异常停机,也会减少坏块发生的几率。 坏块故障的识别 遇到坏块问题时,数据库的异常表现通常有:
坏块故障的恢复 完整的备份恢复策略是恢复坏块最有效的方法。备份恢复策略至少应该包括定期的数据库物理备份和日志归档。其中,归档日志还可以作为判别坏块产生原因的工具。 1、当出现坏块时,使用物理备份进行文件还原,在此文件基础上使用归档日志恢复至故障时间点。以Recovery Manager为例: 1)先offline受影响的数据文件,执行以下的语句: ALTER DATABASE DATAFILE 'name_file' OFFLINE; 2)保留有坏块的数据文件,然后拷贝备份的数据文件。如果恢复的数据文件要求路径不同,执行以下的语句: ALTER DATABASE RENAME FILE 'old_name' TO 'new_name'; 3)恢复数据文件,执行以下语句: RECOVER DATAFILE 'name_of_file'; 4) Online恢复后的数据文件,执行以下的语句: ALTER DATABASE DATAFILE 'name_of_file' ONLINE; 2、在特定情况下(9i以上版本可用),还可以使用块级恢复,以加快恢复进程: RMAN> blockrecover datafile n block nnnn; 3、通过ROWID RANGE SCAN保存数据 1)先取得坏块中ROW ID的最小值,执行以下的语句: SELECT dbms_rowid.rowid_create(1,
2)取得坏块中的ROW ID的最大值,执行以下的语句:
3)建议一个临时表存储那些没有坏块的数据,执行以下的语句:
4)保存那些不存在坏块的数据到临时表中,执行以下的语句:
5)根据临时表中的数据重建表,重建表上的索引,限制。
4、使用10231诊断事件,在做全表扫描的时候跳过坏块
可以在session级别设定:
也可以在数据库级别上设定,在初始化参数中加入:event="10231 trace name context forever, level 10",然后重启数据库。
然后从存在坏块的表中取出不存在坏块的数据,执行以下的语句:
最后rename生成的corrupt_table为原来表的名字,并重建表上的索引和限制。
5、使用dbms_repair包进行恢复
使用dbms_repair标记有坏块的表,在做全表扫描的时候跳过坏块,执行以下的语句:
然后使用exp工具或者createtable as select的方法取出没有坏块数据,然后重建表,表上的索引和限制。
6、UNDO表空间坏块
1) dump undoheader(如果数据库不能open用event 1015升成trace文件,本案例的情况)找到活动事务(状态为10)和对应的undo dba地址和使用的回滚段:
或者:
2) dump回滚段内容得到相关活动事物对应的对象以便以后进行处理
3) 设置隐含参数跳过相应回滚段:
4)启动数据库,删除offline的回滚段并处理活动事物对应的对象:
处理活动事务相关的对象(rebuild index,exchange partition,drop table)等。
在没有完整备份恢复策略的情况下,可以使用应急手段进行恢复,但过程较为复杂且风险较大。
完整备份恢复策略需要合理规划和相应的资源投入。
总结
数据库坏块问题原因复杂,破坏性大。但完整的备份恢复策略,经常性的检查,有效的故障识别以及对应的恢复手段,可以帮助用户最大限度的应对数据库坏块问题所带来的风险。
(责任编辑:OracleTT) |

