Oracle坏块修复(二)

2014-11-24 15:15:52 · 作者: · 浏览: 1
导出命令在执行中会报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在windows 8i中在$ORACLE_HOME/bin下可以找到,9i中似乎未随软件发布,故
在windows没有这个工具,linux下需要编译:
然后把$ORACLE_HOME/rdbms/lib加到环境变量的PATH里面,就可以直接在命令中bbed了。
BBED的缺省口令为blockedit,
For Oracle Internal Use only 请谨慎使用Oracle不做技术支持。
BBED具体的使用,参考blog:
http://blog.csdn.net/tianlesoftware/archive/2009/12/14/5006580.aspx
五.如何查找坏块所含的数据表名称和数据的rowid
关于Rowid 的相关知识参看blog:
http://blog.csdn.net/tianlesoftware/archive/2009/12/16/5020718.aspx
5.1. 首先肯定知道那个数据文件坏了,查出该文件的file_id,relative_fno,tablespace_name
利用dba_data_files可以查询file_id(整个数据库唯一序号),RELATIVE_FNO(相对一个表空间内的序号)
5.2. 找到坏块的ID(可以运行dbverify实现),假设找到的坏块ID为1234。
5.3.运行下面的查询,根据,坏块的file_id,block id查找该块对应的owner,segment_type,
segment_name等信息
select owner,file_id,segment_name, segment_type, block_id, blocks
  from dba_extents
  where file_id=13 and block_id<=1234 and (block_id + blocks- 1) >= 1234;
5.4. 根据坏块的file_id,owner,segment_name,block_id,如果是数据表的话,用下面的查询来得到对应坏块的rowid
假设owner : DAVE
segment_name: BL
file_id : 13
block_id : 162
运行下面的查询来获得该块所含的rowid(如果没有索引,可能就不能用下面的方式了):
select /*+ index(DAVE, i_test) */ rowid
from DAVE.BL
where dbms_rowid.rowid_to_absolute_fno(rowid,'DAVE','BL')=13
and dbms_rowid.rowid_block_number(rowid)=162;   
六,如何模拟坏块
DBA 的基本知识,制造坏块的方法很多的,可以用ultraedit,也可以用dd命令,同时也呆以用orapatch工具
6.1 orapatch 工具:
$orapatch open tools001.dbf write
patch>set hex --要用十六进制
patch>display 177 --orapatch以512字节为工作模式,假定想破坏第11个block即为:8k/512*11+1(file header)
patch>find 00400003 --选一个要编辑的点
patch>modify 00400002 --破坏
patch>exit
6.2 用编辑器打开 datafile 以 8192 字节为一大小(db 的block是 8192)
下面是一个 block 的开始的 20个字节和结尾的 4 个字节
06 02 00 00 08 00 c0 02 6c 43 0d 00 00 00 01 02
00 00 00 00 -- block head
06 02 6c 43 -- block tail 这里有 scn(6c 43) 的情况和 block (06)的类型 (01) 和 hea