ITPub博客

首页 > 数据库 > Oracle > ORACLE坏块(ORA-01578)模拟与处理方法

ORACLE坏块(ORA-01578)模拟与处理方法

原创 Oracle 作者:wtjiang2008 时间:2008-05-19 20:04:06 0 删除 编辑
ORACLE坏块(ORA-01578)模拟与处理方法 一。.什么是数据库的坏块
首先我们来大概看一下数据库块的格式和结构——数据库的数据块有固定的格式和结构,分三层 cache layertransaction layerdata layer。在我们对数据块进行读取写入操作的时候,数据库会对要读写的数据块做一致性的检查,其中包括数据块的类型、数据块的地址信息、数据块的SCN号以及数据块的头部和尾部。如果发现其中有不一致的信息,那数据库就会标记这个数据块为坏块了。数据库的坏块分为两种,逻辑坏块和物理坏块。

二.模拟坏块
SQL> conn system
SQL> create tablespace corrupt datafile'C:corrupt.dbf' size 200k;
SQL> create table corrupt_tab tablespacecorrupt as select * from all_users;
SQL> alter table corrupt_tabmodify(user_id primary key);
SQL> selectextent_id,file_id,block_id,blocks from dba_extents

2
where owner='SYSTEM' andsegment_name='CORRUPT_TAB';


EXTENT_ID
FILE_ID
BLOCK_ID
BLOCKS
---------- ---------- ---------- ----------

0
8
17
8
上述查询说明,这个表具有一个区间EXTNET_ID 0,位于8号文件,从块号17开始,大小为8个块。
SQL> conn / as sysdba
SQL> shutdown immediate;
UE编辑器模拟出物理或逻辑坏块。




保存
SQL> startup
SQL> select count(*) fromsystem.corrupt_tab;


COUNT(*)
----------

21

SQL> select * from system.corrupt_tab;
select * from system.corrupt_tab

*
1 行出现错误:
ORA-01578: ORACLE 数据块损坏 (文件号 8, 块号 20)
ORA-01110: 数据文件 8: 'C:CORRUPT.DBF'
由于corrupt_tab表上有一个主键约束,从而使ORACLE能够通过扫描索引(而不是表)对记录进行计数。第二条查询需要读取表本身,因此会失败并报ORA-01578:错误
查看警告文件
Hex dump of (file 8, block 20) in tracefile
cracleproduct10.2.0adminpdbudumppdb_ora_2248.trc
Corrupt block relative dba: 0x02000014(file 8, block 20)
Bad check value found during buffer read
Data in bad block:

type: 6 format: 2 rdba: 0x02000014

lastchange scn: 0x0000.0009e3b6 seq: 0x2 flg: 0x04

spare1: 0x0 spare2: 0x0 spare3: 0x0

consistency value in tail: 0xe3b60602

check value in block header: 0x13b

computed block checksum: 0x5c66
Reread of rdba: 0x02000014 (file 8, block20) found same corrupted data
Sun May 18 23:11:18 2008
Corrupt Block Found

TSN = 9, TSNAME = CORRUPT

RFN = 8, BLK = 20, RDBA = 33554452

OBJN = 51436, OBJD = 51436, OBJECT = CORRUPT_TAB, SUBOBJECT =

SEGMENT OWNER = SYSTEM, SEGMENT TYPE = Table Segment
再次说明了相关文件以及数据块号,并且给出了一个重要信息OBJD = 51436(属有这个坏块的对象号为51436
SQL> selectowner,object_name,object_type from dba_objects where object_id=51436;
OWNER
OBJECT_NAME
OBJECT_TYPE
---------- ----------------------------------
SYSTEM
CORRUPT_TAB
TABLE

SQL> selectowner,segment_name,segment_type from dba_extents where file_id=8 and

20between block_id and block_id+blocks;
OWNER
OBJECT_NAME
OBJECT_TYPE
---------- ----------------------------------
SYSTEM
CORRUPT_TAB
TABLE

三..DBVERIFY实用程序
用于验证数据文件,手动备份。RNAM的镜像拷贝。不能验证日志文件。控制文件。以及RMAN的备份集。可以验证数据文件中的所有坏块。
C:>dbv file=C:CORRUPT.DBF


以上验证说明CORRUPT.DBF数据文件存在两个坏块1220
四.AYALYZE命令检查表或索引是否有坏块
SQL>analyze table validate structure;
SQL>analyze index validate structure;
SQL>analyze table validate structure cascade;
Cascade选项验证指定表及相关联的全部索引,对于大对象将是一个非常耗时的过程。

五.DBMS_REPAIR程序包
DBMS_REPAIR程序包是检查对象是否存在问题并使其再次可用的一组过程。
--创建REPAIR_CORRUPT_TAB
exec dbms_repair.admin_tables(-
table_name=>'REPAIR_CORRUPT_TAB',-
table_type=>dbms_repair.repair_table,-
action=>dbms_repair.create_action);

--检测坏块,信息存入REPAIR_CORRUPT_TAB
declare num_corrupt int;
begin
num_corrupt:=0;
dbms_repair.check_object(
schema_name=>'SYSTEM',
object_name=>'CORRUPT_TAB',
repair_table_name=>'REPAIR_CORRUPT_TAB',
corrupt_count=>num_corrupt);
dbms_output.put_line(num_corrupt);
end;
/

selectschema_name,object_name,relative_file_id,block_id,repair_description fromrepair_corrupt_tab;

--标记坏块
declare num_fix int;
begin
num_fix:=0;
dbms_repair.fix_corrupt_blocks(
schema_name=>'SYSTEM',
object_name=>'CORRUPT_TAB',
object_type=>DBMS_REPAIR.TABLE_OBJECT,
repair_table_name=>'REPAIR_CORRUPT_TAB',
fix_count=>num_fix);
end;
/

--忽略所有被标记为坏块的数据块
execdbms_repair.skip_corrupt_blocks('SYSTEM','CORRUPT_TAB');

结果
SQL> select * from system.corrupt_tab;

未选定行

SQL> select count(*) fromsystem.corrupt_tab;


COUNT(*)
----------

21
会话能够成功访问被影响的对象,不过受损的数据块中的数据将会丢失。这将导致不可预期的结果。
Alter index … rebuild online重新构建索引
DBMS_REPAIR程序包提供了一种不需要停机就可以使受损表可用的方式,但是代价却是丢失数据。决定使用这个程序包之前,需要考虑受损的范围、对业务的影响以及是否更适合采用还原与恢复的操作。

六.使用RMAN恢复坏块
RMAN备份可以在不停机的情况下进行块级的还原与恢复。并且可以用RMAN检测坏块。
SQL> conn system/oracle
SQL>=drop tablespace corrupt;
SQL> create tablespace corrupt datafile'C:corrupt.dbf' size 200k;
SQL> create table corrupt_tab tablespacecorrupt as select * from all_users;
SQL> alter table corrupt_tabmodify(user_id primary key);
SQL> selectextent_id,file_id,block_id,blocks from dba_extents

2
where owner='SYSTEM' andsegment_name='CORRUPT_TAB';

先来做一个CORRUPT2.DBF文件的备份。
RMAN> backup format 'C:corr.bak'datafile 'C:CORRUPT2.DBF' tag corr2;
SQL> conn / as sysdba
SQL> shutdown immediate;
依照前面的方法模拟出坏块。

SQL> select * from system.corrupt_tab2;
select * from system.corrupt_tab2

*
1 行出现错误:
ORA-01578: ORACLE 数据块损坏 (文件号 7, 块号 12)
ORA-01110: 数据文件 7: 'C:CORRUPT2.DBF'
已经出现坏块。此时再用RMAN备份


失败。
RMANC:CORRUPT2.DBF文件中允许的坏块增加到100,只要坏块小于100就能备份成功。并在v$backup_corruption视图中生成所有坏块的记录。如果是镜像副本,则应该是v$copy_corruption.
RMAN>run{
Set maxcorrupt for datafile 7 to 100;
Backup datafile 7;}
恢复坏块
blockrecover datafile 7 block 12 from tagCORR2;
验证
C:>dbv file=C:CORRUPT2.DBF
SQL> select * from system.corrupt_tab2;

[ 本帖最后由 wtjiang2008 于 2008-5-19 20:06 编辑 ]

ORACLE坏块(ORA-01578)模拟与处理方法.rar
(2008-05-19 20:06:57, Size: 123 KB, Downloads: 48)

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/527318/viewspace-561546/,如需转载,请注明出处,否则将追究法律责任。

下一篇: ORA-20011
请登录后发表评论 登录
全部评论

注册时间:2008-06-30

  • 博文量
    30
  • 访问量
    192985