现在的位置: 首页 > 综合 > 正文

ORACLE坏块总结

2013年10月18日 ⁄ 综合 ⁄ 共 3409字 ⁄ 字号 评论关闭
Oracle数据库出现坏块现象是指:在Oracle数据库的一个或多个数据块(一个数据块的容量在创建数据库时由db_block_size参数指定,缺省为8K)内出现内容混乱的现象。由于正常的数据块都有固定的合法内容格式,坏块的出现,导致数据库进程无法正常解析数据块的内容,进而使数据库进程报错乃至挂起,并级联导致整个数据库实例出现异常。

 

一.坏块的产生原因

 

坏块产生的原因大致有以下几种:

1.1硬件问题

Oracle进程在处理一个数据块时,首先将其读入物理内存空间,在处理完成后,再由特定进程将其写回磁盘;如果在这个过程中,出现内存故障,CPU计算失误,都会导致内存数据块的内容混乱,最后反映到写回磁盘的数据块内容有误。同样,如果存储子系统出现异常,数据块损坏也就随之出现了。

 

1.2操作系统BUG

由于Oracle进程对数据块的读写,都是以操作系统内核调用(system call)的方式完成的,如果操作系统在内核调用存在问题,必然导致Oracle进程写入非法的内容。

 

1.3操作系统的I/O错误或缓冲问题

 

1.4内存或paging问题

 

Oracle软件BUG

Oracle软件特定版本上,可能出现导致数据块的内容出现异常BUG。

 

1.5非Oracle进程扰乱Oracle共享内存区域

如上文所述,在当数据块的内容被读入主机的物理内存时,如果其他非Oracle进程,对Oracle使用的共享内存区域形成了扰乱,最终导致写回磁盘的数据块内容混乱。

 

1.6异常关机,掉电,终止服务

异常关机,掉电,终止服务使进程异常终止,而破坏数据块的完整性,导致坏块产生。

注:这也是为什么突然断电会导致数据库无法启动

 

由上可见,坏块的形成原因复杂。当出现坏块时,为了找到确切的原因,需要大量的分析时间和排查操作,甚至需要多次重现才能找出根本原因。但当故障发生在生产系统上,我们为了减少停机时间,会尽快实施应急权变措施以保证系统的可用性,这样就破坏了故障现场,对根本原因的分析因而也更加困难了。

 

二.坏块的预防

 

坏块问题破坏性大,但并非不可预防。

 

2.1在Metalink.oracle.com网站,Oracle定期发布基于特定软件版本的“已知问题(known issues)说明”。对于可能导致坏块的Oracle软件BUG,在Oracle公司内部,是作为高严重级别的问题进行处理,在“已知问题(known issues)说明”中,这些BUG以严重(Noticable)问题标出(标记为*或+),部分问题,Oracle还会发布警告(Alert)通告。在文档中,Oracle会提供相应的补丁或应对措施。

 

2.2Oracle提供备份恢复工具-Recovery Manager,提供了扫描文件检查坏块的功能。

在Recovery Manager界面中,使用:

RMAN> BACKUP CHECK LOGICAL VALIDATE DATAFILE n ;

 

可以检查数据文件是否包含坏块,同时并不产生实际的备份输出。

 

2.3Dbv工具检查

注:因为dbv要求file后面跟的必须是一个文件扩展名,所以如果用裸设备存储

的,就必须使用ln链接裸设备到一个文件,然后再用dbv对这个链接文件进行检

查。

 

ANALYZE TABLE tablename VALIDATE STRUCTURE CASCADE

它执行坏块的检查,但是不会标记坏块为corrupt,检测的结果保存在USER_DUMP_DEST目录下的用户trace文件中。

 

2.4利用exp工具导出整个数据库可以检测坏块

对以下情况的坏块是检测不出来的:

 HWM以上的坏块是不会发现的

 索引中存在的坏块是不会发现的

 数据字典中的坏块是不会发现的

 

结合数据库性能综合考虑db_block_checksum和db_blockchecking参数。

 

当我们使用Recovery Manager进行实际的数据库备份时,同时也就进行了坏块

检查。但要注意的是,在线使用Recovery Manager扫描坏块和备份时,需要数

据库运行在归档模式(archive log),否则只能在数据库未打开的情况下进行。

 

对于操作系统问题和硬件故障,则需要相应厂商的配合支持。同时,避免在数

据库主机运行其他用户进程,避免异常停机,也会减少坏块发生的几率。

 

坏块故障的识别

遇到坏块问题时,数据库的异常表现通常有:

报告ORA-01578错误。

报告Ora-1110错误。

报告ORA-00600错误,其中,第一个参数为2000-8000,Cache layer 2000 – 4000,Transaction layer 4000 – 6000,Datalayer 6000 - 8000。

Trace文件中出现Corrupt block dba: 0x160c5958 . found。

分析对象失败。

后台进程,如DBWR,LGWR出现长时间异常等待,如“LGWR wait for redo copy”。

 

 

四.Oracle数据块损坏恢复总结

 

可以用DBV命令来检测是否有坏块:

 

在恢复前使用DBV命令检查数据文件是否存在坏块

dbv file=d:\oracle\oradata\mydb\RONLY.DBF blocksize=8192

 

查看数据坏块所在数据文件号及块号可以对表进行一次全表扫描,如:

select count(*) from tablename;

 

 

 

4.1没有备份的情况下:

4.1.1、使用exp/imp恢复

在这种情况下肯定会造成数据的丢失,在这种情况下应采取将数据导出然后重建表再进行导入的方法,来尽量恢复损坏数据块中的数据,但是在有坏块的情况下是不允许导出的,如下命令:

Exp test/test file=t.dmp tables=t;

 

导出命令在执行中会报ORA-01578错误,在这错误提示中会提示那个文件号的文件以及这个文件中的哪个块被损坏,如:ORA—01578:ORACLE数据块损坏(文件号4,块号35)

针对以上的提示首先查询那些对象被损坏:

 

Select tablespace_name,segment_type,owner,segment_name From dba_extents Where file_id=4 and 35 between block_id and block_id+blocks-1;

 

如果被损坏的块是索引,通常可以通过索引重建来解决,如果损坏的是数据(segment_type为table),那么通过设置如下内部事件使得Exp操作跳过坏块。

Alter session set events=’10231 trace name context forever,level 10’;

 

然后重新执行导出命令,导出相关的表,然后执行Drop Table命令删除相关表,之后重建表最后导入数据。

 

4.1.2、使用DBMS_REPAIR恢复

用DBMS_REPAIR当然也会丢失数据。这里不做详细的介绍,有兴趣的可以查看oracle的在线文档

 

 

4.2使用Rman进行恢复:

首先要存在Rman的最新备份集,然后执行如下命令:

RMAN>backup validate datafile 4;

 

检查4号数据文件是否存在坏块

执行查询:

select * from v$database_block_corruption where file#=4;

 

如果4号文件存在坏块的话,那么将在结果集中有所显示,会显示损坏的块号,根据显示结果执行如下命令进行恢复:

RMAN>blockrecover datafile 4 block 35 from backupset;

 

该命令执行后即可恢复坏块,并且不会造成数据丢失,但是要求数据库必须要运行在归档模式下,否则RMAN无法发挥作用,而且通过RMAN做过最新的数据库备份

 

 

4.3使用bbed恢复

使用bbed恢复时必须有数据文件的拷贝。

bbed就是英文block browse edit的缩写,用来直接查看和修改数据文件数据的一个工具。

 

BBED在windows8i中在$ORACLE_HOME/bin下可以找到,9i中似乎未随软件发布,故

在windows没有这个工具,linux下需要编译:

然后把$ORACLE_HOME/rdbms/lib加到环境变量的PATH里面,就可以直接在命令中bbed了。

BBED的缺省口令为blockedit,

For Oracle Internal Use only请谨慎使用Oracle不做技术支持。

抱歉!评论已关闭.