Oracle 11g 基于RMAN实现坏块介质恢复(blockrecover)
2017-07-14 13:54
495 查看
测试环境:
数据库:11.2.0.4
OS:Centos 6.5
对于物理损坏的数据块,我们可以通过RMAN块介质恢复(BLOCK MEDIA RECOVERY)功能来完成受损块的恢复,而不需要恢复整个数据库或所有文件来修复这些少量受损的数据块。恢复整个数据库或数据文件那不是大炮用来打蚊子,有点不值得!但前提条件是你得有一个可用的RMAN备份存在,因此,无论何时备份就是一切。本文演示了产生坏块即使用RMAN实现坏块恢复的全过程。
1.创建演示环境
--创建用于演示的data file
SQL> create tablespace mytest datafile '/data1/orcl/datafile/mytest01.dbf' size 20M autoextend on;
Tablespace created.
--基于新的数据文件创建对象mytest
SQL> conn test/test;
Connected.
SQL> create table mytest tablespace mytest as select * from dba_objects;
Table created.
SQL> col file_name format a60
SQL> select file_id,file_name from dba_data_files where tablespace_name='MYTEST';
FILE_ID FILE_NAME
---------- ------------------------------------------------------------
8 /data1/orcl/datafile/mytest01.dbf
SQL>
--表对象mytest上的信息,包含对应的文件信息,头部块,总块数
SQL> select segment_name , header_file , header_block,blocks from dba_segments where segment_name = 'MYTEST' and owner='TEST';
SEGMENT_NAME
--------------------------------------------------------------------------------
HEADER_FILE HEADER_BLOCK BLOCKS
----------- ------------ ----------
MYTEST
8 130 1408
SQL
--首先使用rman备份对应的数据文件
RMAN> backup datafile 8 format '/u01/datafile_8__%d_%T_%s_%p' tag=helath;
Starting backup at 2017/07/13 16:20:33
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=00008 name=/data1/orcl/datafile/mytest01.dbf
channel ORA_DISK_1: starting piece 1 at 2017/07/13 16:20:34
channel ORA_DISK_1: finished piece 1 at 2017/07/13 16:20:37
piece handle=/u01/datafile_8__ORCL_20170713_68_1 tag=HELATH comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:03
Finished backup at 2017/07/13 16:20:37
Starting Control File and SPFILE Autobackup at 2017/07/13 16:20:37
piece handle=/u01/control_c-1459318340-20170713-02 comment=NONE
Finished Control File and SPFILE Autobackup at 2017/07/13 16:20:40
RMAN>
2、单块数据块损坏的恢复处理
--下面使用了linux自带的dd命令来损坏单块数据块
orcl:/data1/orcl/datafile@db1>dd of=/data1/orcl/datafile/mytest01.dbf bs=8192 conv=notrunc seek=130 <<EOF
> Corrupted block!
> EOF
记录了0+1 的读入
记录了0+1 的写出
18字节(18 B)已复制,0.0002196 秒,82.0 kB/秒
--清空buffer cache
SQL> alter system flush buffer_cache;
System altered
--查询表对相 mytest收到 ORA-01578
SQL> select count(*) from mytest;
select count(*) from mytest
*
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 8, block # 130)
ORA-01110: data file 8: '/data1/orcl/datafile/mytest01.dbf'
--查询视图v$database_block_corruption,提示有坏块,注意该视图可能不会返回任何数据,如无返回,先执行backup validate
SQL> select * from v$database_block_corruption;
FILE# BLOCK# BLOCKS CORRUPTION_CHANGE# CORRUPTIO
---------- ---------- ---------- ------------------ ---------
8 130 1 0 CORRUPT
--也可以使用dbv工具来校验坏块,参考:http://blog.csdn.net/shiyu1157758655/article/details/56666350
--下面使用blockrecover来恢复坏块
RMAN> blockrecover datafile 8 block 130;
Starting recover at 2017/07/13 17:12:48
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=52 device type=DISK
searching flashback logs for block images until SCN 12073138
finished flashback log search, restored 1 blocks
starting media recovery
media recovery complete, elapsed time: 00:02:08
Finished recover at 2017/07/13 17:16:05
--再次查询表mytest正常
SQL> select count(*) from mytest;
COUNT(*)
----------
95338
SQL>
3、多块数据块损坏的恢复处理
--下面使用linux dd命令对不连续块损坏
orcl:/home/oracle@db1>dd of=/data1/orcl/datafile/mytest01.dbf bs=8192 conv=notrunc seek=133 <<EOF
> New corrupted block!
> EOF
记录了0+1 的读入
记录了0+1 的写出
21字节(21 B)已复制,0.0510806 秒,0.4 kB/秒
orcl:/home/oracle@db1>dd of=/data1/orcl/datafile/mytest01.dbf bs=8192 conv=notrunc seek=143 <<EOF
> New corrupted block!
> EOF
记录了0+1 的读入
记录了0+1 的写出
21字节(21 B)已复制,0.0639114 秒,0.3 kB/秒
orcl:/home/oracle@db1>dd of=/data1/orcl/datafile/mytest01.dbf bs=8192 conv=notrunc seek=182 <<EOF
> New corrupted block!
> EOF
记录了0+1 的读入
记录了0+1 的写出
23字节(23 B)已复制,0.178737 秒,0.1 kB/秒
orcl:/home/oracle@db1>
SQL> alter system flush buffer_cache;
System altered
-下面提示块133被损坏,注意我们损坏了多块数据块,但查询时,从块号最小的开始提示,如133被修复后还有坏块则继续提示133之后的坏块
SQL> select count(*) from mytest;
select count(*) from mytest
*
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 8, block # 133)
ORA-01110: data file 8: '/data1/orcl/datafile/mytest01.dbf'
--查询视图v$database_block_corruption
SQL> select * from v$database_block_corruption;
FILE# BLOCK# BLOCKS CORRUPTION_CHANGE# CORRUPTIO
---------- ---------- ---------- ------------------ ---------
8 133 1 0 CORRUPT
8 143 1 0 CORRUPT
8 182 1 0 CORRUPT
SQL>
--下面使用backup validate来校验数据文件
RMAN> backup validate datafile 8 format '/u01/data_file8_%d_%T_%s_%p';
Starting backup at 2017/07/14 08:06:05
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=52 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=00008 name=/data1/orcl/datafile/mytest01.dbf
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:07
List of Datafiles
=================
File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
---- ------ -------------- ------------ --------------- ----------
8 FAILED 0 1051 2560 12070446
File Name: /data1/orcl/datafile/mytest01.dbf
Block Type Blocks Failing Blocks Processed
---------- -------------- ----------------
Data 0 1349
Index 0 0
Other 3 160
validate found one or more corrupt blocks
See trace file /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_2370.trc for details
Finished backup at 2017/07/14 08:06:16
RMAN>
--再次查询v$database_block_corruption,表明有3个损坏的块
SQL> select * from v$database_block_corruption;
FILE# BLOCK# BLOCKS CORRUPTION_CHANGE# CORRUPTIO
---------- ---------- ---------- ------------------ ---------
8 133 1 0 CORRUPT
8 143 1 0 CORRUPT
8 182 1 0 CORRUPT
--下面直接使用blockrecover corruption list来恢复,如下所有刚刚被校验的坏块都会被恢复
RMAN> blockrecover corruption list;
Starting recover at 2017/07/14 13:04:13
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=52 device type=DISK
searching flashback logs for block images until SCN 12073138
finished flashback log search, restored 0 blocks
channel ORA_DISK_1: restoring block(s)
channel ORA_DISK_1: specifying block(s) to restore from backup set
restoring blocks of datafile 00008
channel ORA_DISK_1: reading from backup piece /u01/datafile_8__ORCL_20170713_68_1
channel ORA_DISK_1: piece handle=/u01/datafile_8__ORCL_20170713_68_1 tag=HELATH
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:35
Finished recover at 2017/07/14 13:09:11
--校验结果
SQL> select count(*) from mytest;
COUNT(*)
----------
95338
SQL>
4、后记
a、对于受损的数据块,仅仅坏块上的数据无法被查询或读取,其余正常块的数据依旧可以使用。
b、对于受损的表对象进行聚合等相关运算时收到错误提示,因为坏块上的数据无法被统计。如果你聚合的是索引列,索引未损坏的情形则可正常返回。
c、可以基于RMAN可用的备份文件实现块介质恢复,其数据文件无需offline,开销最小,影响最小。
d、对于多个数据块的损坏,先执行backup validate校验数据库或相应的数据文件以便标记受损的坏块后,填充v$database_block_corruption以及后续恢复。
e、对于使用backup validate 校验后的情形,坏块恢复时可以直接使用blockrecover corruption list一次性恢复所有的坏块。
f、缺省情况下,存在坏块的数据文件无法成功备份,也会导致自动备份脚本失败。
select dbms_rowid.rowid_object(rowid) object_id,dbms_rowid.rowid_relative_fno(rowid) file_id,
dbms_rowid.rowid_block_number(rowid) block_id,owner,object_name,object_id
from mytest where dbms_rowid.rowid_block_number(rowid)=163 and rownum<=2;
对于物理损坏的数据块,我们可以通过RMAN块介质恢复(BLOCK MEDIA RECOVERY)功能来完成受损块的恢复,而不需要恢复整个数据库或所有文件来修复这些少量受损的数据块。恢复整个数据库或数据文件那不是大炮用来打蚊子,有点不值得!但前提条件是你得有一个可用的RMAN备份存在,因此,无论何时备份就是一切。本文演示了产生坏块即使用RMAN实现坏块恢复的全过程。
测试环境:
数据库:11.2.0.4
OS:Centos6.5
1.创建演示环境
--创建用于演示的data file
SQL> create tablespace mytest datafile '/data1/orcl/datafile/mytest01.dbf' size 20M autoextend on;
Tablespace created.
--基于新的数据文件创建对象mytest
SQL> conn test/test;
Connected.
SQL> create table mytest tablespace mytest as select * from dba_objects;
Table created.
SQL> col file_name format a60
SQL> select file_id,file_name from dba_data_files where tablespace_name='MYTEST';
FILE_ID FILE_NAME
---------- ------------------------------------------------------------
8 /data1/orcl/datafile/mytest01.dbf
SQL>
--表对象mytest上的信息,包含对应的文件信息,头部块,总块数
SQL> select segment_name , header_file , header_block,blocks from dba_segments where segment_name = 'MYTEST' and owner='TEST';
SEGMENT_NAME
--------------------------------------------------------------------------------
HEADER_FILE HEADER_BLOCK BLOCKS
----------- ------------ ----------
MYTEST
8 130 1408
SQL
--首先使用rman备份对应的数据文件
RMAN> backup datafile 8 format '/u01/datafile_8__%d_%T_%s_%p' tag=helath;
Starting backup at 2017/07/13 16:20:33
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=00008 name=/data1/orcl/datafile/mytest01.dbf
channel ORA_DISK_1: starting piece 1 at 2017/07/13 16:20:34
channel ORA_DISK_1: finished piece 1 at 2017/07/13 16:20:37
piece handle=/u01/datafile_8__ORCL_20170713_68_1 tag=HELATH comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:03
Finished backup at 2017/07/13 16:20:37
Starting Control File and SPFILE Autobackup at 2017/07/13 16:20:37
piece handle=/u01/control_c-1459318340-20170713-02 comment=NONE
Finished Control File and SPFILE Autobackup at 2017/07/13 16:20:40
RMAN>
2、单块数据块损坏的恢复处理
--下面使用了linux自带的dd命令来损坏单块数据块
orcl:/data1/orcl/datafile@db1>dd of=/data1/orcl/datafile/mytest01.dbf bs=8192 conv=notrunc seek=130 <<EOF
> Corrupted block!
> EOF
记录了0+1 的读入
记录了0+1 的写出
18字节(18 B)已复制,0.0002196 秒,82.0 kB/秒
--清空buffer cache
SQL> alter system flush buffer_cache;
System altered
--查询表对相 mytest收到 ORA-01578
SQL> select count(*) from mytest;
select count(*) from mytest
*
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 8, block # 130)
ORA-01110: data file 8: '/data1/orcl/datafile/mytest01.dbf'
--查询视图v$database_block_corruption,提示有坏块,注意该视图可能不会返回任何数据,如无返回,先执行backup validate
SQL> select * from v$database_block_corruption;
FILE# BLOCK# BLOCKS CORRUPTION_CHANGE# CORRUPTIO
---------- ---------- ---------- ------------------ ---------
8 130 1 0 CORRUPT
--也可以使用dbv工具来校验坏块,参考:http://blog.csdn.net/shiyu1157758655/article/details/56666350
--下面使用blockrecover来恢复坏块
RMAN> blockrecover datafile 8 block 130;
Starting recover at 2017/07/13 17:12:48
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=52 device type=DISK
searching flashback logs for block images until SCN 12073138
finished flashback log search, restored 1 blocks
starting media recovery
media recovery complete, elapsed time: 00:02:08
Finished recover at 2017/07/13 17:16:05
--再次查询表mytest正常
SQL> select count(*) from mytest;
COUNT(*)
----------
95338
SQL>
3、多块数据块损坏的恢复处理
--下面使用linux dd命令对不连续块损坏
orcl:/home/oracle@db1>dd of=/data1/orcl/datafile/mytest01.dbf bs=8192 conv=notrunc seek=133 <<EOF
> New corrupted block!
> EOF
记录了0+1 的读入
记录了0+1 的写出
21字节(21 B)已复制,0.0510806 秒,0.4 kB/秒
orcl:/home/oracle@db1>dd of=/data1/orcl/datafile/mytest01.dbf bs=8192 conv=notrunc seek=143 <<EOF
> New corrupted block!
> EOF
记录了0+1 的读入
记录了0+1 的写出
21字节(21 B)已复制,0.0639114 秒,0.3 kB/秒
orcl:/home/oracle@db1>dd of=/data1/orcl/datafile/mytest01.dbf bs=8192 conv=notrunc seek=182 <<EOF
> New corrupted block!
> EOF
记录了0+1 的读入
记录了0+1 的写出
23字节(23 B)已复制,0.178737 秒,0.1 kB/秒
orcl:/home/oracle@db1>
SQL> alter system flush buffer_cache;
System altered
-下面提示块133被损坏,注意我们损坏了多块数据块,但查询时,从块号最小的开始提示,如133被修复后还有坏块则继续提示133之后的坏块
SQL> select count(*) from mytest;
select count(*) from mytest
*
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 8, block # 133)
ORA-01110: data file 8: '/data1/orcl/datafile/mytest01.dbf'
--查询视图v$database_block_corruption
SQL> select * from v$database_block_corruption;
FILE# BLOCK# BLOCKS CORRUPTION_CHANGE# CORRUPTIO
---------- ---------- ---------- ------------------ ---------
8 133 1 0 CORRUPT
8 143 1 0 CORRUPT
8 182 1 0 CORRUPT
SQL>
--下面使用backup validate来校验数据文件
RMAN> backup validate datafile 8 format '/u01/data_file8_%d_%T_%s_%p';
Starting backup at 2017/07/14 08:06:05
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=52 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=00008 name=/data1/orcl/datafile/mytest01.dbf
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:07
List of Datafiles
=================
File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
---- ------ -------------- ------------ --------------- ----------
8 FAILED 0 1051 2560 12070446
File Name: /data1/orcl/datafile/mytest01.dbf
Block Type Blocks Failing Blocks Processed
---------- -------------- ----------------
Data 0 1349
Index 0 0
Other 3 160
validate found one or more corrupt blocks
See trace file /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_2370.trc for details
Finished backup at 2017/07/14 08:06:16
RMAN>
--再次查询v$database_block_corruption,表明有3个损坏的块
SQL> select * from v$database_block_corruption;
FILE# BLOCK# BLOCKS CORRUPTION_CHANGE# CORRUPTIO
---------- ---------- ---------- ------------------ ---------
8 133 1 0 CORRUPT
8 143 1 0 CORRUPT
8 182 1 0 CORRUPT
--下面直接使用blockrecover corruption list来恢复,如下所有刚刚被校验的坏块都会被恢复
RMAN> blockrecover corruption list;
Starting recover at 2017/07/14 13:04:13
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=52 device type=DISK
searching flashback logs for block images until SCN 12073138
finished flashback log search, restored 0 blocks
channel ORA_DISK_1: restoring block(s)
channel ORA_DISK_1: specifying block(s) to restore from backup set
restoring blocks of datafile 00008
channel ORA_DISK_1: reading from backup piece /u01/datafile_8__ORCL_20170713_68_1
channel ORA_DISK_1: piece handle=/u01/datafile_8__ORCL_20170713_68_1 tag=HELATH
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:35
Finished recover at 2017/07/14 13:09:11
--校验结果
SQL> select count(*) from mytest;
COUNT(*)
----------
95338
SQL>
4、后记
a、对于受损的数据块,仅仅坏块上的数据无法被查询或读取,其余正常块的数据依旧可以使用。
b、对于受损的表对象进行聚合等相关运算时收到错误提示,因为坏块上的数据无法被统计。如果你聚合的是索引列,索引未损坏的情形则可正常返回。
c、可以基于RMAN可用的备份文件实现块介质恢复,其数据文件无需offline,开销最小,影响最小。
d、对于多个数据块的损坏,先执行backup validate校验数据库或相应的数据文件以便标记受损的坏块后,填充v$database_block_corruption以及后续恢复。
e、对于使用backup validate 校验后的情形,坏块恢复时可以直接使用blockrecover corruption list一次性恢复所有的坏块。
f、缺省情况下,存在坏块的数据文件无法成功备份,也会导致自动备份脚本失败。
select dbms_rowid.rowid_object(rowid) object_id,dbms_rowid.rowid_relative_fno(rowid) file_id,
dbms_rowid.rowid_block_number(rowid) block_id,owner,object_name,object_id
from mytest where dbms_rowid.rowid_block_number(rowid)=163 and rownum<=2;
数据库:11.2.0.4
OS:Centos 6.5
对于物理损坏的数据块,我们可以通过RMAN块介质恢复(BLOCK MEDIA RECOVERY)功能来完成受损块的恢复,而不需要恢复整个数据库或所有文件来修复这些少量受损的数据块。恢复整个数据库或数据文件那不是大炮用来打蚊子,有点不值得!但前提条件是你得有一个可用的RMAN备份存在,因此,无论何时备份就是一切。本文演示了产生坏块即使用RMAN实现坏块恢复的全过程。
1.创建演示环境
--创建用于演示的data file
SQL> create tablespace mytest datafile '/data1/orcl/datafile/mytest01.dbf' size 20M autoextend on;
Tablespace created.
--基于新的数据文件创建对象mytest
SQL> conn test/test;
Connected.
SQL> create table mytest tablespace mytest as select * from dba_objects;
Table created.
SQL> col file_name format a60
SQL> select file_id,file_name from dba_data_files where tablespace_name='MYTEST';
FILE_ID FILE_NAME
---------- ------------------------------------------------------------
8 /data1/orcl/datafile/mytest01.dbf
SQL>
--表对象mytest上的信息,包含对应的文件信息,头部块,总块数
SQL> select segment_name , header_file , header_block,blocks from dba_segments where segment_name = 'MYTEST' and owner='TEST';
SEGMENT_NAME
--------------------------------------------------------------------------------
HEADER_FILE HEADER_BLOCK BLOCKS
----------- ------------ ----------
MYTEST
8 130 1408
SQL
--首先使用rman备份对应的数据文件
RMAN> backup datafile 8 format '/u01/datafile_8__%d_%T_%s_%p' tag=helath;
Starting backup at 2017/07/13 16:20:33
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=00008 name=/data1/orcl/datafile/mytest01.dbf
channel ORA_DISK_1: starting piece 1 at 2017/07/13 16:20:34
channel ORA_DISK_1: finished piece 1 at 2017/07/13 16:20:37
piece handle=/u01/datafile_8__ORCL_20170713_68_1 tag=HELATH comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:03
Finished backup at 2017/07/13 16:20:37
Starting Control File and SPFILE Autobackup at 2017/07/13 16:20:37
piece handle=/u01/control_c-1459318340-20170713-02 comment=NONE
Finished Control File and SPFILE Autobackup at 2017/07/13 16:20:40
RMAN>
2、单块数据块损坏的恢复处理
--下面使用了linux自带的dd命令来损坏单块数据块
orcl:/data1/orcl/datafile@db1>dd of=/data1/orcl/datafile/mytest01.dbf bs=8192 conv=notrunc seek=130 <<EOF
> Corrupted block!
> EOF
记录了0+1 的读入
记录了0+1 的写出
18字节(18 B)已复制,0.0002196 秒,82.0 kB/秒
--清空buffer cache
SQL> alter system flush buffer_cache;
System altered
--查询表对相 mytest收到 ORA-01578
SQL> select count(*) from mytest;
select count(*) from mytest
*
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 8, block # 130)
ORA-01110: data file 8: '/data1/orcl/datafile/mytest01.dbf'
--查询视图v$database_block_corruption,提示有坏块,注意该视图可能不会返回任何数据,如无返回,先执行backup validate
SQL> select * from v$database_block_corruption;
FILE# BLOCK# BLOCKS CORRUPTION_CHANGE# CORRUPTIO
---------- ---------- ---------- ------------------ ---------
8 130 1 0 CORRUPT
--也可以使用dbv工具来校验坏块,参考:http://blog.csdn.net/shiyu1157758655/article/details/56666350
--下面使用blockrecover来恢复坏块
RMAN> blockrecover datafile 8 block 130;
Starting recover at 2017/07/13 17:12:48
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=52 device type=DISK
searching flashback logs for block images until SCN 12073138
finished flashback log search, restored 1 blocks
starting media recovery
media recovery complete, elapsed time: 00:02:08
Finished recover at 2017/07/13 17:16:05
--再次查询表mytest正常
SQL> select count(*) from mytest;
COUNT(*)
----------
95338
SQL>
3、多块数据块损坏的恢复处理
--下面使用linux dd命令对不连续块损坏
orcl:/home/oracle@db1>dd of=/data1/orcl/datafile/mytest01.dbf bs=8192 conv=notrunc seek=133 <<EOF
> New corrupted block!
> EOF
记录了0+1 的读入
记录了0+1 的写出
21字节(21 B)已复制,0.0510806 秒,0.4 kB/秒
orcl:/home/oracle@db1>dd of=/data1/orcl/datafile/mytest01.dbf bs=8192 conv=notrunc seek=143 <<EOF
> New corrupted block!
> EOF
记录了0+1 的读入
记录了0+1 的写出
21字节(21 B)已复制,0.0639114 秒,0.3 kB/秒
orcl:/home/oracle@db1>dd of=/data1/orcl/datafile/mytest01.dbf bs=8192 conv=notrunc seek=182 <<EOF
> New corrupted block!
> EOF
记录了0+1 的读入
记录了0+1 的写出
23字节(23 B)已复制,0.178737 秒,0.1 kB/秒
orcl:/home/oracle@db1>
SQL> alter system flush buffer_cache;
System altered
-下面提示块133被损坏,注意我们损坏了多块数据块,但查询时,从块号最小的开始提示,如133被修复后还有坏块则继续提示133之后的坏块
SQL> select count(*) from mytest;
select count(*) from mytest
*
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 8, block # 133)
ORA-01110: data file 8: '/data1/orcl/datafile/mytest01.dbf'
--查询视图v$database_block_corruption
SQL> select * from v$database_block_corruption;
FILE# BLOCK# BLOCKS CORRUPTION_CHANGE# CORRUPTIO
---------- ---------- ---------- ------------------ ---------
8 133 1 0 CORRUPT
8 143 1 0 CORRUPT
8 182 1 0 CORRUPT
SQL>
--下面使用backup validate来校验数据文件
RMAN> backup validate datafile 8 format '/u01/data_file8_%d_%T_%s_%p';
Starting backup at 2017/07/14 08:06:05
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=52 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=00008 name=/data1/orcl/datafile/mytest01.dbf
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:07
List of Datafiles
=================
File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
---- ------ -------------- ------------ --------------- ----------
8 FAILED 0 1051 2560 12070446
File Name: /data1/orcl/datafile/mytest01.dbf
Block Type Blocks Failing Blocks Processed
---------- -------------- ----------------
Data 0 1349
Index 0 0
Other 3 160
validate found one or more corrupt blocks
See trace file /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_2370.trc for details
Finished backup at 2017/07/14 08:06:16
RMAN>
--再次查询v$database_block_corruption,表明有3个损坏的块
SQL> select * from v$database_block_corruption;
FILE# BLOCK# BLOCKS CORRUPTION_CHANGE# CORRUPTIO
---------- ---------- ---------- ------------------ ---------
8 133 1 0 CORRUPT
8 143 1 0 CORRUPT
8 182 1 0 CORRUPT
--下面直接使用blockrecover corruption list来恢复,如下所有刚刚被校验的坏块都会被恢复
RMAN> blockrecover corruption list;
Starting recover at 2017/07/14 13:04:13
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=52 device type=DISK
searching flashback logs for block images until SCN 12073138
finished flashback log search, restored 0 blocks
channel ORA_DISK_1: restoring block(s)
channel ORA_DISK_1: specifying block(s) to restore from backup set
restoring blocks of datafile 00008
channel ORA_DISK_1: reading from backup piece /u01/datafile_8__ORCL_20170713_68_1
channel ORA_DISK_1: piece handle=/u01/datafile_8__ORCL_20170713_68_1 tag=HELATH
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:35
Finished recover at 2017/07/14 13:09:11
--校验结果
SQL> select count(*) from mytest;
COUNT(*)
----------
95338
SQL>
4、后记
a、对于受损的数据块,仅仅坏块上的数据无法被查询或读取,其余正常块的数据依旧可以使用。
b、对于受损的表对象进行聚合等相关运算时收到错误提示,因为坏块上的数据无法被统计。如果你聚合的是索引列,索引未损坏的情形则可正常返回。
c、可以基于RMAN可用的备份文件实现块介质恢复,其数据文件无需offline,开销最小,影响最小。
d、对于多个数据块的损坏,先执行backup validate校验数据库或相应的数据文件以便标记受损的坏块后,填充v$database_block_corruption以及后续恢复。
e、对于使用backup validate 校验后的情形,坏块恢复时可以直接使用blockrecover corruption list一次性恢复所有的坏块。
f、缺省情况下,存在坏块的数据文件无法成功备份,也会导致自动备份脚本失败。
select dbms_rowid.rowid_object(rowid) object_id,dbms_rowid.rowid_relative_fno(rowid) file_id,
dbms_rowid.rowid_block_number(rowid) block_id,owner,object_name,object_id
from mytest where dbms_rowid.rowid_block_number(rowid)=163 and rownum<=2;
对于物理损坏的数据块,我们可以通过RMAN块介质恢复(BLOCK MEDIA RECOVERY)功能来完成受损块的恢复,而不需要恢复整个数据库或所有文件来修复这些少量受损的数据块。恢复整个数据库或数据文件那不是大炮用来打蚊子,有点不值得!但前提条件是你得有一个可用的RMAN备份存在,因此,无论何时备份就是一切。本文演示了产生坏块即使用RMAN实现坏块恢复的全过程。
测试环境:
数据库:11.2.0.4
OS:Centos6.5
1.创建演示环境
--创建用于演示的data file
SQL> create tablespace mytest datafile '/data1/orcl/datafile/mytest01.dbf' size 20M autoextend on;
Tablespace created.
--基于新的数据文件创建对象mytest
SQL> conn test/test;
Connected.
SQL> create table mytest tablespace mytest as select * from dba_objects;
Table created.
SQL> col file_name format a60
SQL> select file_id,file_name from dba_data_files where tablespace_name='MYTEST';
FILE_ID FILE_NAME
---------- ------------------------------------------------------------
8 /data1/orcl/datafile/mytest01.dbf
SQL>
--表对象mytest上的信息,包含对应的文件信息,头部块,总块数
SQL> select segment_name , header_file , header_block,blocks from dba_segments where segment_name = 'MYTEST' and owner='TEST';
SEGMENT_NAME
--------------------------------------------------------------------------------
HEADER_FILE HEADER_BLOCK BLOCKS
----------- ------------ ----------
MYTEST
8 130 1408
SQL
--首先使用rman备份对应的数据文件
RMAN> backup datafile 8 format '/u01/datafile_8__%d_%T_%s_%p' tag=helath;
Starting backup at 2017/07/13 16:20:33
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=00008 name=/data1/orcl/datafile/mytest01.dbf
channel ORA_DISK_1: starting piece 1 at 2017/07/13 16:20:34
channel ORA_DISK_1: finished piece 1 at 2017/07/13 16:20:37
piece handle=/u01/datafile_8__ORCL_20170713_68_1 tag=HELATH comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:03
Finished backup at 2017/07/13 16:20:37
Starting Control File and SPFILE Autobackup at 2017/07/13 16:20:37
piece handle=/u01/control_c-1459318340-20170713-02 comment=NONE
Finished Control File and SPFILE Autobackup at 2017/07/13 16:20:40
RMAN>
2、单块数据块损坏的恢复处理
--下面使用了linux自带的dd命令来损坏单块数据块
orcl:/data1/orcl/datafile@db1>dd of=/data1/orcl/datafile/mytest01.dbf bs=8192 conv=notrunc seek=130 <<EOF
> Corrupted block!
> EOF
记录了0+1 的读入
记录了0+1 的写出
18字节(18 B)已复制,0.0002196 秒,82.0 kB/秒
--清空buffer cache
SQL> alter system flush buffer_cache;
System altered
--查询表对相 mytest收到 ORA-01578
SQL> select count(*) from mytest;
select count(*) from mytest
*
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 8, block # 130)
ORA-01110: data file 8: '/data1/orcl/datafile/mytest01.dbf'
--查询视图v$database_block_corruption,提示有坏块,注意该视图可能不会返回任何数据,如无返回,先执行backup validate
SQL> select * from v$database_block_corruption;
FILE# BLOCK# BLOCKS CORRUPTION_CHANGE# CORRUPTIO
---------- ---------- ---------- ------------------ ---------
8 130 1 0 CORRUPT
--也可以使用dbv工具来校验坏块,参考:http://blog.csdn.net/shiyu1157758655/article/details/56666350
--下面使用blockrecover来恢复坏块
RMAN> blockrecover datafile 8 block 130;
Starting recover at 2017/07/13 17:12:48
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=52 device type=DISK
searching flashback logs for block images until SCN 12073138
finished flashback log search, restored 1 blocks
starting media recovery
media recovery complete, elapsed time: 00:02:08
Finished recover at 2017/07/13 17:16:05
--再次查询表mytest正常
SQL> select count(*) from mytest;
COUNT(*)
----------
95338
SQL>
3、多块数据块损坏的恢复处理
--下面使用linux dd命令对不连续块损坏
orcl:/home/oracle@db1>dd of=/data1/orcl/datafile/mytest01.dbf bs=8192 conv=notrunc seek=133 <<EOF
> New corrupted block!
> EOF
记录了0+1 的读入
记录了0+1 的写出
21字节(21 B)已复制,0.0510806 秒,0.4 kB/秒
orcl:/home/oracle@db1>dd of=/data1/orcl/datafile/mytest01.dbf bs=8192 conv=notrunc seek=143 <<EOF
> New corrupted block!
> EOF
记录了0+1 的读入
记录了0+1 的写出
21字节(21 B)已复制,0.0639114 秒,0.3 kB/秒
orcl:/home/oracle@db1>dd of=/data1/orcl/datafile/mytest01.dbf bs=8192 conv=notrunc seek=182 <<EOF
> New corrupted block!
> EOF
记录了0+1 的读入
记录了0+1 的写出
23字节(23 B)已复制,0.178737 秒,0.1 kB/秒
orcl:/home/oracle@db1>
SQL> alter system flush buffer_cache;
System altered
-下面提示块133被损坏,注意我们损坏了多块数据块,但查询时,从块号最小的开始提示,如133被修复后还有坏块则继续提示133之后的坏块
SQL> select count(*) from mytest;
select count(*) from mytest
*
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 8, block # 133)
ORA-01110: data file 8: '/data1/orcl/datafile/mytest01.dbf'
--查询视图v$database_block_corruption
SQL> select * from v$database_block_corruption;
FILE# BLOCK# BLOCKS CORRUPTION_CHANGE# CORRUPTIO
---------- ---------- ---------- ------------------ ---------
8 133 1 0 CORRUPT
8 143 1 0 CORRUPT
8 182 1 0 CORRUPT
SQL>
--下面使用backup validate来校验数据文件
RMAN> backup validate datafile 8 format '/u01/data_file8_%d_%T_%s_%p';
Starting backup at 2017/07/14 08:06:05
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=52 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=00008 name=/data1/orcl/datafile/mytest01.dbf
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:07
List of Datafiles
=================
File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
---- ------ -------------- ------------ --------------- ----------
8 FAILED 0 1051 2560 12070446
File Name: /data1/orcl/datafile/mytest01.dbf
Block Type Blocks Failing Blocks Processed
---------- -------------- ----------------
Data 0 1349
Index 0 0
Other 3 160
validate found one or more corrupt blocks
See trace file /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_2370.trc for details
Finished backup at 2017/07/14 08:06:16
RMAN>
--再次查询v$database_block_corruption,表明有3个损坏的块
SQL> select * from v$database_block_corruption;
FILE# BLOCK# BLOCKS CORRUPTION_CHANGE# CORRUPTIO
---------- ---------- ---------- ------------------ ---------
8 133 1 0 CORRUPT
8 143 1 0 CORRUPT
8 182 1 0 CORRUPT
--下面直接使用blockrecover corruption list来恢复,如下所有刚刚被校验的坏块都会被恢复
RMAN> blockrecover corruption list;
Starting recover at 2017/07/14 13:04:13
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=52 device type=DISK
searching flashback logs for block images until SCN 12073138
finished flashback log search, restored 0 blocks
channel ORA_DISK_1: restoring block(s)
channel ORA_DISK_1: specifying block(s) to restore from backup set
restoring blocks of datafile 00008
channel ORA_DISK_1: reading from backup piece /u01/datafile_8__ORCL_20170713_68_1
channel ORA_DISK_1: piece handle=/u01/datafile_8__ORCL_20170713_68_1 tag=HELATH
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:35
Finished recover at 2017/07/14 13:09:11
--校验结果
SQL> select count(*) from mytest;
COUNT(*)
----------
95338
SQL>
4、后记
a、对于受损的数据块,仅仅坏块上的数据无法被查询或读取,其余正常块的数据依旧可以使用。
b、对于受损的表对象进行聚合等相关运算时收到错误提示,因为坏块上的数据无法被统计。如果你聚合的是索引列,索引未损坏的情形则可正常返回。
c、可以基于RMAN可用的备份文件实现块介质恢复,其数据文件无需offline,开销最小,影响最小。
d、对于多个数据块的损坏,先执行backup validate校验数据库或相应的数据文件以便标记受损的坏块后,填充v$database_block_corruption以及后续恢复。
e、对于使用backup validate 校验后的情形,坏块恢复时可以直接使用blockrecover corruption list一次性恢复所有的坏块。
f、缺省情况下,存在坏块的数据文件无法成功备份,也会导致自动备份脚本失败。
select dbms_rowid.rowid_object(rowid) object_id,dbms_rowid.rowid_relative_fno(rowid) file_id,
dbms_rowid.rowid_block_number(rowid) block_id,owner,object_name,object_id
from mytest where dbms_rowid.rowid_block_number(rowid)=163 and rownum<=2;
相关文章推荐
- 基于RMAN实现坏块介质恢复(blockrecover)
- 基于RMAN实现坏块介质恢复(block recover)
- 基于RMAN实现坏块介质恢复(blockrecover)
- oracle 11g 如何实现坏块检查、恢复?
- Oracle 基于 RMAN 的不完全恢复(incomplete recovery by RMAN)
- ORACLE 11G没有备份文件参数文件在异机通过rman备份恢复找回被误删的数据
- Oracle 12C Study--RMAN新特性-基于表时间点恢复
- Oracle 11g R2 rac通过rman 恢复到单实例数据库
- ORACLE 11G 中采用rman备份异机恢复数据库详细过程
- Oracle 基于 RMAN 的不完全恢复(incomplete recovery by RMAN)
- Oracle技术之手动实现表空间基于时间点的恢复
- 基于RMAN的Oracle备份和恢复
- ORACLE 11G 中没有参数文件和控制文件如何通过rman恢复数据库
- ORACLE使用RMAN对SYSTEM表空间进行介质恢复
- Oracle技术之手动实现表空间基于时间点的恢复
- Oracle 学习之RMAN(十四)恢复实战--基于时间点恢复
- Oracle技术之使用rman进行表空间基于时间点的恢复
- oracle 11g RMAN 异机恢复(linux to windows)
- ORACLE 11G rman恢复数据库实战纪实
- ORACLE模拟一个数据文件坏块并使用RMAN备份来恢复