基于RMAN实现坏块介质恢复(blockrecover)

      对于物理损坏的数据块,我们可以通过RMAN块介质恢复(BLOCK MEDIA RECOVERY)功能来完成受损块的恢复,而不需要恢复整个数据库或所有文件来修复这些少量受损的数据块。恢复整个数据库或数据文件那不是大炮用来打蚊子,有点不值得!但前提条件是你得有一个可用的RMAN备份存在,因此,无论何时备份就是一切。本文演示了产生坏块即使用RMAN实现坏块恢复的全过程。

 

1、创建演示环境

SQL> select * from v$version where rownum<2;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production

--创建用于演示的data file
SQL> create tablespace tbs_tmp datafile '/u02/database/usbo/oradata/tbs_tmp.dbf' size 10m autoextend on;

SQL> conn scott/tiger;

--基于新的数据文件创建对象tb_tmp
SQL> create table tb_tmp tablespace tbs_tmp as select * from dba_objects;

SQL> col file_name format a60
SQL> select file_id,file_name from dba_data_files where tablespace_name='TBS_TMP';

   FILE_ID FILE_NAME
---------- ------------------------------------------------------------
         6 /u02/database/usbo/oradata/tbs_tmp.dbf

--表对象tb_tmp上的信息,包含对应的文件信息,头部块,总块数
SQL> select segment_name , header_file , header_block,blocks
  2  from dba_segments
  3  where segment_name = 'TB_TMP' and owner='SCOTT';

SEGMENT_NAME                   HEADER_FILE HEADER_BLOCK     BLOCKS
------------------------------ ----------- ------------ ----------
TB_TMP                                   6          130       1152

--首先使用rman备份对应的数据文件
$ $ORACLE_HOME/bin/rman target /
RMAN> backup datafile 6 tag=health;

Starting backup at 2013/08/28 17:03:15
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=24 device type=DISK
channel ORA_DISK_1: starting full datafile backup set
channel ORA_DISK_1: specifying datafile(s) in backup set
input datafile file number=00006 name=/u02/database/usbo/oradata/tbs_tmp.dbf
channel ORA_DISK_1: starting piece 1 at 2013/08/28 17:03:16
channel ORA_DISK_1: finished piece 1 at 2013/08/28 17:03:17
piece handle=/u02/database/usbo/fr_area/USBO/backupset/2013_08_28/o1_mf_nnndf_HEALTH_91vh6ntb_.bkp tag=HEALTH comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01
Finished backup at 2013/08/28 17:03:17
RMAN> exit

2、单块数据块损坏的恢复处理

--下面使用了linux自带的dd命令来损坏单块数据块
[oracle@linux1 ~]$ dd of=/u02/database/usbo/oradata/tbs_tmp.dbf bs=8192 conv=notrunc seek=130 <<EOF
> Corrupted block!
> EOF
0+1 records in
0+1 records out
17 bytes (17 B) copied, 0.000184519 seconds, 92.1 kB/s

--清空buffer cache
SQL> alter system flush buffer_cache;

--查询表对相 tb_tmp,收到ORA-01578
SQL> select count(*) from tb_tmp;
select count(*) from tb_tmp
*
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 6, block # 130)
ORA-01110: data file 6: '/u02/database/usbo/oradata/tbs_tmp.dbf'

--查询视图v$database_block_corruption,提示有坏块,注意该视图可能不会返回任何数据,如无返回,先执行backup validate
SQL> select * from v$database_block_corruption;

     FILE#     BLOCK#     BLOCKS CORRUPTION_CHANGE# CORRUPTIO
---------- ---------- ---------- ------------------ ---------
         6        129          1                  0 CORRUPT

--也可以使用dbv工具来校验坏块,参考: http://blog.csdn.net/robinson_0612/article/details/6530890   

--下面使用blockrecover来恢复坏块
RMAN> blockrecover datafile 6 block 130;

Starting recover at 2013/08/28 17:22:25
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=24 device type=DISK

channel ORA_DISK_1: restoring block(s)
channel ORA_DISK_1: specifying block(s) to restore from backup set
restoring blocks of datafile 00006
channel ORA_DISK_1: reading from backup piece /u02/database/usbo/fr_area/USBO/backupset/2013_08_28/o1_mf_nnndf_HEALTH_91vh6ntb_.bkp
channel ORA_DISK_1: piece handle=/u02/database/usbo/fr_area/USBO/backupset/2013_08_28/o1_mf_nnndf_HEALTH_91vh6ntb_.bkp tag=HEALTH
channel ORA_DISK_1: restored block(s) from backup piece 1
channel ORA_DISK_1: block restore complete, elapsed time: 00:00:01

starting media recovery
media recovery complete, elapsed time: 00:00:03

Finished recover at 2013/08/28 17:22:31

--再次查询表tb_emp正常
SQL> select count(*) from tb_tmp;

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

3、多块数据块损坏的恢复处理

--下面使用linux dd命令对不连续块损坏
[oracle@linux1 ~]$ dd of=/u02/database/usbo/oradata/tbs_tmp.dbf bs=8192 conv=notrunc seek=133 <<EOF
> New corrupted block!
> EOF
0+1 records in
0+1 records out
21 bytes (21 B) copied, 0.000182835 seconds, 115 kB/s
[oracle@linux1 ~]$ dd of=/u02/database/usbo/oradata/tbs_tmp.dbf bs=8192 conv=notrunc seek=143 <<EOF
> New corrupted block!
> EOF
0+1 records in
0+1 records out
21 bytes (21 B) copied, 0.000115527 seconds, 182 kB/s
[oracle@linux1 ~]$ dd of=/u02/database/usbo/oradata/tbs_tmp.dbf bs=8192 conv=notrunc seek=153 <<EOF
> New corrupted block!
> EOF
0+1 records in
0+1 records out
21 bytes (21 B) copied, 0.000335781 seconds, 62.5 kB/s

SQL> alter system flush buffer_cache;

--下面提示块133被损坏,注意我们损坏了多块数据块,但查询时,从块号最小的开始提示,如133被修复后还有坏块则继续提示133之后的坏块
SQL> select count(*) from scott.tb_tmp;
select count(*) from scott.tb_tmp
*
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 6, block # 133)
ORA-01110: data file 6: '/u02/database/usbo/oradata/tbs_tmp.dbf'

--查询视图v$database_block_corruption无任何记录
SQL> select * from v$database_block_corruption;

no rows selected

--下面使用backup validate来校验数据文件
RMAN> backup validate datafile 6;

Starting backup at 2013/08/29 09:42:04
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=22 device type=DISK
channel ORA_DISK_1: starting full datafile backup set
channel ORA_DISK_1: specifying datafile(s) in backup set
input datafile file number=00006 name=/u02/database/usbo/oradata/tbs_tmp.dbf
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01
List of Datafiles
=================
File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
---- ------ -------------- ------------ --------------- ----------
6    FAILED 0              223          1408            838489       --字段Status为FAILED
  File Name: /u02/database/usbo/oradata/tbs_tmp.dbf
  Block Type Blocks Failing Blocks Processed
  ---------- -------------- ----------------
  Data       0              1029
  Index      0              0
  Other      3              156             --有3个Blocks Failing

validate found one or more corrupt blocks
See trace file /u02/database/usbo/diag/rdbms/usbo/usbo/trace/usbo_ora_27874.trc for details
Finished backup at 2013/08/29 09:42:06

--再次查询v$database_block_corruption,表明有3个损坏的块
SQL> select * from v$database_block_corruption;

     FILE#     BLOCK#     BLOCKS CORRUPTION_CHANGE# CORRUPTIO
---------- ---------- ---------- ------------------ ---------
         6        153          1                  0 CORRUPT
         6        143          1                  0 CORRUPT
         6        133          1                  0 CORRUPT

--下面直接使用blockrecover corruption list来恢复,如下所有刚刚被校验的坏块都会被恢复
RMAN> blockrecover corruption list;  

Starting recover at 2013/08/29 10:05:24
using channel ORA_DISK_1

channel ORA_DISK_1: restoring block(s)
channel ORA_DISK_1: specifying block(s) to restore from backup set
restoring blocks of datafile 00006
channel ORA_DISK_1: reading from backup piece /u02/database/usbo/fr_area/USBO/backupset/2013_08_28/o1_mf_nnndf_HEALTH_91vh6ntb_.bkp
channel ORA_DISK_1: piece handle=/u02/database/usbo/fr_area/USBO/backupset/2013_08_28/o1_mf_nnndf_HEALTH_91vh6ntb_.bkp tag=HEALTH
channel ORA_DISK_1: restored block(s) from backup piece 1
channel ORA_DISK_1: block restore complete, elapsed time: 00:00:01

starting media recovery
media recovery complete, elapsed time: 00:00:03

Finished recover at 2013/08/29 10:05:28

--校验结果
SQL> select count(*) from scott.tb_tmp;

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

4、坏块的对象定位与影响

--下面我们查询块号为163上的对象
SQL> select dbms_rowid.rowid_object(rowid) object_id,dbms_rowid.rowid_relative_fno(rowid) file_id,
  2  dbms_rowid.rowid_block_number(rowid) block_id,owner,object_name,object_id
  3  from scott.tb_tmp where dbms_rowid.rowid_block_number(rowid)=163 and rownum<=2;

 OBJECT_ID    FILE_ID   BLOCK_ID OWNER        OBJECT_NAME                     OBJECT_ID
---------- ---------- ---------- ------------ ------------------------------ ----------
     74555          6        163 SYS          GV_$QUEUEING_MTH                     2439
     74555          6        163 PUBLIC       GV$QUEUEING_MTH                      2440

--使用上面的方法,我们损块块163,173,此处不再列出

a、对于坏块对象无法进行聚合汇总等操作
SQL> select count(*) from scott.tb_tmp;
select count(*) from scott.tb_tmp
*
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 6, block # 163)
ORA-01110: data file 6: '/u02/database/usbo/oradata/tbs_tmp.dbf'

b、对于坏块上的记录无法被查询
--我们使用基于之前查询到的OBJECT_ID来查询
SQL> select owner,object_name,object_id from scott.tb_tmp where object_id in(2439,2440);
select owner,object_name,object_id from scott.tb_tmp where object_id in(2439,2440)
                                              *
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 6, block # 163)
ORA-01110: data file 6: '/u02/database/usbo/oradata/tbs_tmp.dbf'

--如下面的查询,位于损坏块上的数据无法被查询到,但对于未损坏的依旧可以查询。下面的查询时块161上的对象
SQL> select owner,object_name,object_id from scott.tb_tmp
  2  where dbms_rowid.rowid_block_number(rowid)=161 and rownum<3;

OWNER                          OBJECT_NAME                     OBJECT_ID
------------------------------ ------------------------------ ----------
PUBLIC                         GV$RECOVERY_LOG                      2285
SYS                            GV_$ARCHIVE_GAP                      2286

--Author : Robinson Cheng
--Blog   : http://blog.csdn.net/robinson_0612

c、定位受损块所对应的对象
SQL> run get_obj_name_from_corrupt_block
  1  SELECT tablespace_name,
  2         segment_type,
  3         owner,
  4         segment_name,
  5         partition_name
  6    FROM dba_extents
  7*  WHERE file_id = &file_id AND &block_id BETWEEN block_id AND block_id + blocks - 1
Enter value for file_id: 6
Enter value for block_id: 133
old   7:  WHERE file_id = &file_id AND &block_id BETWEEN block_id AND block_id + blocks - 1
new   7:  WHERE file_id = 6 AND 133 BETWEEN block_id AND block_id + blocks - 1

TABLESPACE_NAME                SEGMENT_TYPE       OWNER          SEGMENT_NAME      PARTITION_NAME
------------------------------ ------------------ -------------- ----------------- -----------------
TBS_TMP                        TABLE              SCOTT          TB_TMP 

d、对于损坏的数据文件,缺省情况下,不能对其进行备份,如下
RMAN> backup datafile 6 tag='corruption';                                                    

Starting backup at 2013/08/29 10:37:32
using channel ORA_DISK_1
channel ORA_DISK_1: starting full datafile backup set
channel ORA_DISK_1: specifying datafile(s) in backup set
input datafile file number=00006 name=/u02/database/usbo/oradata/tbs_tmp.dbf
channel ORA_DISK_1: starting piece 1 at 2013/08/29 10:37:32
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03009: failure of backup command on ORA_DISK_1 channel at 08/29/2013 10:37:33
ORA-19566: exceeded limit of 0 corrupt blocks for file /u02/database/usbo/oradata/tbs_tmp.dbf 

--需要设定允许损坏块的数量之后才能进行备份
RMAN> run{
2> set maxcorrupt for datafile 6 to 2;
3> backup datafile 6 tag='corruption';
4> }

executing command: SET MAX CORRUPT

Starting backup at 2013/08/29 10:41:24
using channel ORA_DISK_1
channel ORA_DISK_1: starting full datafile backup set
channel ORA_DISK_1: specifying datafile(s) in backup set
input datafile file number=00006 name=/u02/database/usbo/oradata/tbs_tmp.dbf
channel ORA_DISK_1: starting piece 1 at 2013/08/29 10:41:25
channel ORA_DISK_1: finished piece 1 at 2013/08/29 10:41:26
piece handle=/u02/database/usbo/fr_area/USBO/backupset/2013_08_29/o1_mf_nnndf_CORRUPTION_91xf6o18_.bkp tag=CORRUPTION comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01
Finished backup at 2013/08/29 10:41:26       

--查看备份信息如下,应在修复坏块后重新备份以避免由于保留策略导致先前可用的备份被aged out
RMAN> list backup summary;

List of Backups
===============
Key     TY LV S Device Type Completion Time     #Pieces #Copies Compressed Tag
------- -- -- - ----------- ------------------- ------- ------- ---------- ---
1       B  F  A DISK        2013/08/28 17:03:17 1       1       NO         HEALTH
3       B  F  A DISK        2013/08/29 10:41:25 1       1       NO         CORRUPTION

5、后记
a、对于受损的数据块,仅仅坏块上的数据无法被查询或读取,其余正常块的数据依旧可以使用。
b、对于受损的表对象进行聚合等相关运算时收到错误提示,因为坏块上的数据无法被统计。如果你聚合的是索引列,索引未损坏的情形则可正常返回。
c、可以基于RMAN可用的备份文件实现块介质恢复,其数据文件无需offline,开销最小,影响最小。
d、对于多个数据块的损坏,先执行backup validate校验数据库或相应的数据文件以便标记受损的坏块后,填充v$database_block_corruption以及后续恢复。
e、对于使用backup validate 校验后的情形,坏块恢复时可以直接使用blockrecover corruption list一次性恢复所有的坏块。
f、缺省情况下,存在坏块的数据文件无法成功备份,也会导致自动备份脚本失败。

 

相关参考
    中小型数据库 RMAN CATALOG 备份恢复方案(一)

    中小型数据库 RMAN CATALOG 备份恢复方案(二)

    中小型数据库 RMAN CATALOG 备份恢复方案(三)

    RMAN 数据库克隆文件位置转换方法

    基于RMAN的异机数据库克隆(rman duplicate)

    基于 RMAN 的同机数据库克隆

    基于用户管理的同机数据库克隆

    基于RMAN从活动数据库异机克隆(rman duplicate from active DB)

    RMAN duplicate from active 时遭遇 ORA-17627 ORA-12154

    Oracle 冷备份

    Oracle 热备份

    Oracle 备份恢复概念

    Oracle 实例恢复

    Oracle 基于用户管理恢复的处理

    SYSTEM 表空间管理及备份恢复

    SYSAUX表空间管理及恢复

    Oracle 基于备份控制文件的恢复(unsing backup controlfile)

    RMAN 概述及其体系结构

    RMAN 配置、监控与管理

    RMAN 备份详解

    RMAN 还原与恢复

    RMAN catalog 的创建和使用

    基于catalog 创建RMAN存储脚本

    基于catalog 的RMAN 备份与恢复

    RMAN 备份路径困惑

    自定义 RMAN 显示的日期时间格式

    只读表空间的备份与恢复

    Oracle 基于用户管理的不完全恢复

    理解 using backup controlfile

    使用RMAN实现异机备份恢复(WIN平台)

    使用RMAN迁移文件系统数据库到ASM

    基于Linux下 Oracle 备份策略(RMAN)

    Linux 下RMAN备份shell脚本

    使用RMAN迁移数据库到异机

    RMAN 提示符下执行SQL语句

    Oracle 基于 RMAN 的不完全恢复(incomplete recovery by RMAN)

    rman 还原归档日志(restore archivelog)

时间: 2024-08-18 07:38:09

基于RMAN实现坏块介质恢复(blockrecover)的相关文章

Oracle中通过RMAN修复坏块

通过dbv和rman blockrecover对Oracle数据库坏块进行修复. (1)rman备份时alert.log报如下错误: Fri Jul  2 12:41:36 2010 Hex dump of (file 12, block 2718618) in trace file /u01/app/oracle/admin/bi/udump/bi_ora_31213.trc Corrupt block relative dba: 0x03297b9a (file 12, block 2718

使用 DBMS_REPAIR 修复坏块

       对于Oracle数据块物理损坏的情形,在我们有备份的情况下可以直接使用备份来恢复.对于通过备份恢复,Oracel为我们提供了很多种方式,冷备,基于用户管理方式,RMAN方式等等.对于这几种方式我们需要实现基于数据库以及文件级别的恢复.RMAN同时也提供了基于块介质方式的恢复.也就是说我们根本不需要还原数据文件,而是直接从备份文件基于块来提取以实现联机恢复.可参考基于RMAN实现坏块介质恢复(blockrecover) .这是比较理想的情形.如果没有任何备份怎么办?我们可以使用Ora

Oracle RMAN高级恢复概述(二) 基于RMAN 的恢复主题

1.只读表空间的恢复 在默认情况下,即使丢失了只读的数据文件,RMAN也不会在执行完全恢复数据库还原操作时还原只读的数据文件. 要在完全恢复期间还原只读的数据文件,就必须在restore 命令中使用check readonly 参数,如: Restore database check readonly; 注意,执行recover tablespace或recover datafile命令时,RMAN的工作情况是不一样的. 使用这两个命令时,不管表空间是否为只读状态都会执行恢复操作. 2.归档重做

[20150601]rman备份出现坏块.txt

[20150601]rman备份出现坏块.txt --昨天看链接: http://www.jydba.net/磁盘损坏造成RMAN备份文件有坏块的恢复案例/ --提到如果备份片存在坏块的恢复案例,他使用的参数,我自己从来没见过. alter system set event='19548 trace name context forever', '19549 trace name context forever' scope=spfile; -- oerr ora 19548,oerr ora

Oracle坏块问题处理 Oracle坏块修复 Oracle坏块怎么办

Oracle数据库出现坏块现象是指:在Oracle数据库的一个或多个数据块(一个数据块的容量在创建数据库时由db_block_size参数指定,缺省为8K)内出现内容混乱的现象.由于正常的数据块都有固定的合法内容格式,坏块的出现,导致数据库进程无法正常解析数据块的内容,进而使数据库进程报错乃至挂起,并级联导致整个数据库实例出现异常. 一.坏块分类 物理坏块:也可以称为介质坏块,指的是块格式本身是坏的,块内的数据没有任何意义. 逻辑坏块:指的是块内的数据在逻辑是存在问题.比如说索引块的索引值没有按

Oracle实例恢复和介质恢复

Oracle恢复基础概述  一.恢复解决方案 错误类型及解决方案 错误分类 恢复解决方案 介质失败 如果是少量的块损坏,使用块介质恢复:如果是大量的块.数据文件.表空间的损坏,可能需要对损坏的数据文件或者表空间执行完全恢复:如果是归档Redo日志文件或者联机Redo日志文件的丢失,那么只需要不完全恢复方式. 逻辑损坏 如果是程序员错误导致出现的问题,可通过补丁应用修复问题.对于无法修复的问题,也可采用介质恢复手段来恢复数据. 用户错误 根据不同用户错误,选择不同的Flashback技术恢复,使用

Oracle 9i数据坏块的处理实例

笔者在一台生产用测试库上SELECT一个表时出现ORA-01578,一个块损坏,以前学习过块损坏怎么处理,到还真没遇到过,今天总算让我遇到了,还是一台生产用测试库,就不用很紧张了. 数据库版本是9.2.0.4,Oracle9i的RMAN有一个blockrecover命令,可以在线修复坏块,以下就是使用RMAN修复坏块的过程. SQL> conn owi/owi Connected. SQL> select * from dpa_history; select * from dpa_histor

[20150811]模拟坏块处理.txt

[20150811]模拟坏块处理.txt --如果存在备份,修复坏块还是相对简单的.在11g下: select * from V$DATABASE_BLOCK_CORRUPTION; --在rman下执行: blockrecover corruption list; --如果数据块没有使用,没有分配data_object_id而出现坏块,如何恢复呢?一般采用的方法建立新对象的方法,格式化这个数据块. --具体测试如下: 1.建立测试环境: SCOTT@test> @ver1 PORT_STRIN

一道面试题:遇到大规模Oracle坏块该怎么处理?

最近一两个月,一直有场景化运维.场景化大数据分析的声音围绕在耳畔,以Gdevops全球敏捷运维峰会杭州站上新炬网络执行副总裁程永新的"一切没有场景驱动的运维平台建设都是假大空!"最为振聋发聩.我们一直在谈技术,谈原理,谈内核,总以为"懂了"这些的人,就势必能广阔天地大有所为.   技术固然重要,但偏离了业务/应用场景的技术,无法呈现业务价值的技术就非常不重要.   技术也应该是场景驱动的,对于运维技术人员来说,离开场景学习的所谓高深技术,只是浪费时间.所以新同事进入