oracle坏块修复步骤(索引坏块rebuild和表表坏块用rman,dbms_repair恢复)

1.确认坏块部分是表还是索引

select owner,segment_name,segment_type,block_id

from dba_extents

where block_id <= &block_id

and block_id + blocks -1 > &block_id

and file_id=&file_id;

1.1如果是索引,rebuild即可

alter index rebuild online   ----实质上是扫描表而不是扫描现有的索引块来实现索引的重建.

alter index rebuild         ----只扫描现有的索引块来实现索引的重建。

rebulid index online说明:

rebuild index online在执行期间不会阻塞DML操作,但在开始和结束阶段,需要请求模式为4的TM锁。因此,如果在rebuild index online开始前或结束时,有其它长时间的事物在运行,很有可能就造成大量的锁等待。也就是说在执行前仍会产生阻塞, 应该避免排他锁.

而rebuild index在执行期间会阻塞DML操作, 但速度较快.

普通情况下建立索引或者rebuild索引时,oracle会对基表加share锁,由于share锁和row-X是不兼容的,也就是说,在建立索引期间,无法对基表进行DML操作。 是否加online,要看系统需求。因为不加online时rebuild会阻塞一切DML操作。

当对索引进行rebuild时:如果不加online选项,oracle则直接读取原索引的数据;

当添加online选项时:oracle是直接扫描表中的数据,索引在重建时,查询仍然可以使用旧索引。

实际上,oracle在rebuild时,在创建新索引过程中,并不会删除旧索引,直到新索引rebuild成功。
从这点可以知道rebuild比删除索引然后重建索引的一个好处是不会影响原有的SQL查询,但也正由于此,用rebuild方式建立索引需要相应表空间的空闲空间是删除重建方式的2倍。

1.2 如果是表

A.有rman备份

rman>block recover datafile file# block block#

B.把受损数据块标记成"software corrupt" -软件损坏

oracle在扫描时跳过这些块,然后通过CTAS方法把数据抢救出来

1)把数据块标记成"corrupt"

如果遇到ORA-1578错误,说明数据块已经被标识为"software corrupt";

如果遇到ORA-600,就需要使用DBMS_REPAIR包把数据块标识成"software corrupt",这时再扫描到这个数据块时会抛出ORA-1578错误。

2)扫描是跳过"software corrupt"数据块

可以使用dbms_repair.skip_corrupt_blocks跳过坏块;

或者使用10231事件,可以从视图dba_tables.skip_corrupt字段可以看出表是否设置了这个标志,如果使用CTAS方法重建表,最好是在session、实例级别设置10231事件,如果通过exp方式重建表,则需要在实例级别设置或者使用dbms_repair包,可以参照如下步骤:

a.使用诊断事件10231,跳过坏块检查

SQL> alter session set events '10231 trace name context forever,level 10';

b.创建一个临时表tab_tmp的表中除坏块的数据都检索出来

SQL>create table tab_tmp as select * from tab;

SQL>alter session set events '10231 trace name context off';

c.更名原表,并把 tab_tmp 更名为 tab

SQL>alter table tab rename to tab_bak;

SQL>alter table tab_tmp to tab;

d.在tab上重新创建索引、约束、授权、 trigger等对象

e.利用表之间的业务关系,把坏块中的数据补足。

f.如果要删除之前的表空间,或者表

alter database datafile '/ora01/oradata/tbs_data01.dbf' offline drop;

alter tablespace tbs1 including contents;

删除表:drop table table1 pruge;

2.如何检测坏块

1.1 dbv

检测物理逻辑坏块:dbv file=/u01/oracle/users.dbf blocksize-8192

[oracle@std lib]$ dbv file=/u02/app/oradata/PSDB/livan_tbs01.dbf

DBVERIFY: Release 10.2.0.4.0 - Production on Thu Feb 5 12:50:05 2015

Copyright (c) 1982, 2007, Oracle. All rights reserved.

DBVERIFY - Verification starting : FILE = /u02/app/oradata/PSDB/livan_tbs01.dbf

Page 12 is marked corrupt

Corrupt block relative dba: 0x0180000c (file 6, block 12)

Bad check value found during dbv:

Data in bad block:

type: 6 format: 2 rdba: 0x0180000c

last change scn: 0x0000.0007d460 seq: 0x5 flg: 0x06

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

consistency value in tail: 0xd4600605

check value in block header: 0x4d5c

computed block checksum: 0x1607

DBVERIFY - Verification complete

Total Pages Examined : 38400

Total Pages Processed (Data) : 4

Total Pages Failing (Data) : 0

Total Pages Processed (Index): 0

Total Pages Failing (Index): 0

Total Pages Processed (Other): 11

Total Pages Processed (Seg) : 0

Total Pages Failing (Seg) : 0

Total Pages Empty : 38384

Total Pages Marked Corrupt : 1 --发现坏块

Total Pages Influx : 0

Highest block SCN : 513120 (0.513120)

1.2 rman

检测物理坏块:backup validaite datafie '/u01/oracle/users.dbf';

检测物理逻辑坏块:backup check logical validate datafile '/u01/oracle/users.dbf';

[oracle@std lib]$ rman target /

Recovery Manager: Release 10.2.0.4.0 - Production on Thu Feb 5 12:54:21 2015

Copyright (c) 1982, 2007, Oracle. All rights reserved.

connected to target database: PSDB (DBID=1410134833)

RMAN> backup check logical validate database;

Starting backup at 05-FEB-15

using target database control file instead of recovery catalog

allocated channel: ORA_DISK_1

channel ORA_DISK_1: sid=141 devtype=DISK

channel ORA_DISK_1: starting full datafile backupset

channel ORA_DISK_1: specifying datafile(s) in backupset

input datafile fno=00001 name=/u02/app/oradata/PSDB/system01.dbf

input datafile fno=00006 name=/u02/app/oradata/PSDB/livan_tbs01.dbf

input datafile fno=00003 name=/u02/app/oradata/PSDB/sysaux01.dbf

input datafile fno=00005 name=/u02/app/oradata/PSDB/example01.dbf

input datafile fno=00002 name=/u02/app/oradata/PSDB/undotbs01.dbf

input datafile fno=00004 name=/u02/app/oradata/PSDB/users01.dbf

channel ORA_DISK_1: backup set complete, elapsed time: 00:00:25

channel ORA_DISK_1: starting full datafile backupset

channel ORA_DISK_1: specifying datafile(s) in backupset

including current control file in backupset

including current SPFILE in backupset

channel ORA_DISK_1: backup set complete, elapsed time: 00:00:02

Finished backup at 05-FEB-15

  

rman的检查结果放在v$database_block_corruption

SQL> select file#,block#,blocks from v$database_block_corruption;

FILE#     BLOCK#     BLOCKS

----------  ----------   ----------

6         12          1

1.3 使用exp工具验证坏块

[oracle@std lib]$ exp livan/livan file=/home/oracle/livan_table.dmp tables=test

Export: Release 10.2.0.4.0 - Production on Thu Feb 5 13:00:27 2015

Copyright (c) 1982, 2007, Oracle. All rights reserved.

Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production

With the Partitioning, OLAP, Data Mining and Real Application Testing options

Export done in US7ASCII character set and AL16UTF16 NCHAR character set

server uses AL32UTF8 character set (possible charset conversion)

About to export specified tables via Conventional Path ...

. . exporting table TEST

EXP-00056: ORACLE error 1578 encountered

ORA-01578: ORACLE data block corrupted (file # 6, block # 12)

ORA-01110: data file 6: '/u02/app/oradata/PSDB/livan_tbs01.dbf'

Export terminated successfully with warnings.

1.4 使用dbms_repair.check_object检验坏块

(1)创建repair表,用于记录需要被修复的表:

SQL>

begin

dbms_repair.admin_tables (

table_name => 'repair_table',

table_type => dbms_repair.repair_table,

action => dbms_repair.create_action,

tablespace => 'livan_tbs');

end;

/

PL/SQL procedure successfully completed.

(2)创建Orphan Key表,用于记录在表块损坏后那些孤立索引,也就是指向坏块的那些索引:

begin 

dbms_repair.admin_tables ( 

     table_name => 'ORPHAN_KEY_TABLE', 

     table_type => dbms_repair.orphan_table, 

     action => dbms_repair.create_action, 

     tablespace => 'USERS'); 

end; 

(3)检查坏块,检测对象上受损的情形,并返回受损块数

SQL> set serveroutput on

SQL>

declare num_corrupt int;

begin

     num_corrupt := 0;

     dbms_repair.check_object (

     schema_name => 'livan',

     object_name => 'test',

     repair_table_name => 'repair_table',

     corrupt_count => num_corrupt);

     dbms_output.put_line('number corrupt: ' || to_char (num_corrupt));

end;

/

number corrupt: 1

PL/SQL procedure successfully completed.

SQL> select relative_file_id,block_id,corrupt_type,object_name

from repair_table;

RELATIVE_FILE_ID   BLOCK_ID   CORRUPT_TYPE   OBJECT_NAME

----------------      ----------    ------------       ----------------
12                  6148                         TEST

1.5 使用analyze命令检验坏块

此命令会锁表

SQL> analyze table test validate structure cascade online;  --在线分析表test验证结构级联;

analyze table test validate structure cascade online

*

ERROR at line 1:

ORA-01578: ORACLE data block corrupted (file # 6, block # 12)

ORA-01110: data file 6: '/u02/app/oradata/PSDB/livan_tbs01.dbf'

=====================================================

使用dbv查看坏块,dbv file=xxx.dbf

DBVERIFY: Release 11.2.0.1.0 - Production on Tue Aug 16 11:31:47 2016

Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.

Keyword Description (Default)

----------------------------------------------------

FILE File to Verify (NONE)

START Start Block (First Block of File)

END End Block (Last Block of File)

BLOCKSIZE Logical Block Size (8192)

LOGFILE Output Log (NONE)

FEEDBACK Display Progress (0)

PARFILE Parameter File (NONE)

USERID Username/Password (NONE)

SEGMENT_ID Segment ID (tsn.relfile.block) (NONE)

HIGH_SCN Highest Block SCN To Verify (NONE)

(scn_wrap.scn_base OR scn)

或者使用视图v$database_block_corruption;

1)执行以下语句看哪个段坏了

select b.segment_name, b.segment_type

from dba_extents a, dba_segments b

where a.file_id =&FNO

and &BLOCK between a.block_id and a.block_id + a.blocks - 1

and a.segment_name = b.segment_name

and a.owner = b.owner;

这里的&FNO指的是 file#,&BLOCK 指的是 block#

2)如果是物理坏块,分几种情况:

a)如果是文件系统且做了raid的,在messages里会显示具体哪个磁盘出问题了,更换磁盘,系统会自动恢复磁盘。---raid相当于冗余

b)如果是文件系统且没做raid,但有备份和归档,在messages里会显示具体哪个磁盘出问题了,更换磁盘,然后用数据文件备份和归档、在线日志恢复到最后的时间点。

c)如果是文件系统且没做raid,没有备份,那么就要按下面的步骤3里的操作恢复好坏块后,再更换磁盘。

d)如果是asm管理磁盘阵列,将亮红灯的磁盘拔掉,换个新的,系统会自动恢复磁盘。

3)如果是逻辑坏块,就看是索引坏块还是表坏块。

如果是索引坏块,那么直接删除索引,重建索引就好。

如果是表坏块,分三种情况:

A.有rman备份,利用rman备份恢复坏块。

命令:block recover datafile file# block block# from backupset;

B.没有rman备份,只有exp备份,且备份可用,那么删除这个表,重新导入。

C.如果没有备份,以表tab03为例,按下面的步骤处理:

a.以 tab03的 owner 连入 oracle

b.使用诊断事件10231,跳过坏块检查

SQL> alter system set events '10231 trace name context forever,level 10';

c.创建一个临时表tab_tmp的表中除坏块的数据都检索出来

SQL>create table tab_tmp as select * from tab03;

SQL>alter session set events '10231 trace name context off';

D、更名原表,并把tab_tmp更名为tab03

SQL>alter table tab03 rename to tab03_bak;

SQL>alter table tab_tmp to tab03;

E、在tab03上重新创建索引、约束、授权、trigger等对象

F、利用表之间的业务关系,把坏块中的数据补足。

G,如果要删除之前的表空间,或者表

alter database datafile '/ora01/oradata/tbs_data01.dbf' offline drop;

alter tablespace tbs1 including contents;

删除表,drop table table1 pruge;

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Running Sun丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值