坏块的处理与恢复!

首先构建一个写满数据的表空间

SQL> create tablespace tb2 datafile '/u01/app/oracle/oradata/orcl/tb2.dbf' size 1m;

表空间已创建。

SQL> create user u2 identified by u2 default tablespace tb2;

用户已创建。

SQL> grant connect,resource to u2;

授权成功。

SQL> alter user u2 quota unlimited on tb2;

用户已更改。

SQL> create table u2.t as select * from dba_tables;

表已创建。

SQL> conn u2/u2
已连接。
SQL> select * from tab;

TNAME                          TABTYPE  CLUSTERID
------------------------------ ------- ----------
T                              TABLE
SQL> select count(*) from t;

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

SQL> insert into t select * from t;

已创建1537行。

SQL> /
insert into t select * from t
            *
第 1 行出现错误:
ORA-01653: 表 U2.T 无法通过 8 (在表空间 TB2 中) 扩展

SQL> commit;

提交完成。

SQL> select count(*) from t;

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


然后关闭数据库使用UE等工具修改数据文件(有时候可能需要多次修改),启动数据库查询T表可以看见数据块损坏。

SQL> startup
ORACLE 例程已经启动。

Total System Global Area  167772160 bytes
Fixed Size                  1266392 bytes
Variable Size              67112232 bytes
Database Buffers           96468992 bytes
Redo Buffers                2924544 bytes
数据库装载完毕。
数据库已经打开。
SQL> conn u2/u2
已连接。
SQL> select count(*) from t;
select count(*) from t
                     *
第 1 行出现错误:
ORA-01578: ORACLE 数据块损坏 (文件号 6, 块号 111)
ORA-01110: 数据文件 6: '/u01/app/oracle/oradata/orcl/tb2.dbf'

 

DBV工具参数详解

[oracle@linux orcl]$ dbv help=y

DBVERIFY: Release 10.2.0.4.0 - Production on 星期一 10月 10 19:27:30 2011

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

关键字      说明                    (默认值)
----------------------------------------------------
FILE        要验证的文件                 (无)
START       起始块                    (文件的第一个块)
END         结束块                      (文件的最后一个块)
BLOCKSIZE   逻辑块大小             (8192)
LOGFILE     输出日志                     (无)
FEEDBACK    显示进度               (0)
PARFILE     参数文件                 (无)
USERID      用户名/口令              (无)
SEGMENT_ID  段 ID (tsn.relfile.block) (无)
HIGH_SCN    要验证的最高块 SCN    (无)
            (scn_wrap.scn_base 或 scn)   


使用DBV检查数据文件,可以检测到快损坏:

[oracle@linux oracle]$ dbv file=/u01/app/oracle/oradata/orcl/tb2.dbf

DBVERIFY: Release 10.2.0.4.0 - Production on 星期一 10月 10 19:30:41 2011

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

DBVERIFY - 开始验证: FILE = /u01/app/oracle/oradata/orcl/tb2.dbf
页 111 标记为损坏
Corrupt block relative dba: 0x0180006f (file 6, block 111)
Bad check value found during dbv: 
Data in bad block:
 type: 6 format: 2 rdba: 0x0180006f
 last change scn: 0x0000.00074005 seq: 0x2 flg: 0x04
 spare1: 0x0 spare2: 0x0 spare3: 0x0
 consistency value in tail: 0x40050602
 check value in block header: 0xb95e
 computed block checksum: 0xbb17



DBVERIFY - 验证完成

检查的页总数: 128
处理的页总数 (数据): 109
失败的页总数 (数据): 0
处理的页总数 (索引): 0
失败的页总数 (索引): 0
处理的页总数 (其它): 18
处理的总页数 (段)  : 0
失败的总页数 (段)  : 0
空的页总数: 0
标记为损坏的总页数: 1
流入的页总数: 0
最高块 SCN            : 475145 (0.475145)


在这种情况下,如果有备份需要从备份中恢复。如果没有备份,坏块的数据肯定是要丢失得了,在这个时候是不用允许导出的

[oracle@linux oracle]$ exp system/oracle@orcl owner=u2 file=tab2.dmp

Export: Release 10.2.0.4.0 - Production on 星期一 10月 10 19:33:17 2011

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


连接到: Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
已导出 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集

即将导出指定的用户...
. 正在导出 pre-schema 过程对象和操作
. 正在导出用户 U2 的外部函数库名
. 导出 PUBLIC 类型同义词
. 正在导出专用类型同义词
. 正在导出用户 U2 的对象类型定义
即将导出 U2 的对象...
. 正在导出数据库链接
. 正在导出序号
. 正在导出簇定义
. 即将导出 U2 的表通过常规路径...
. . 正在导出表                               T
EXP-00056: 遇到 ORACLE 错误 1578
ORA-01578: ORACLE 数据块损坏 (文件号 6, 块号 111)
ORA-01110: 数据文件 6: '/u01/app/oracle/oradata/orcl/tb2.dbf'
. 正在导出同义词
. 正在导出视图
. 正在导出存储过程
. 正在导出运算符
. 正在导出引用完整性约束条件
. 正在导出触发器
. 正在导出索引类型
. 正在导出位图, 功能性索引和可扩展索引
. 正在导出后期表活动
. 正在导出实体化视图
. 正在导出快照日志
. 正在导出作业队列
. 正在导出刷新组和子组
. 正在导出维
. 正在导出 post-schema 过程对象和操作
. 正在导出统计信息
导出成功终止, 但出现警告。


处理方法:

1、跳过损坏的块

SQL> select tablespace_name,segment_type,owner,segment_name from dba_extents
  2  where file_id = 6 and 111 between block_id and block_id + blocks -1;                    --可以查看坏块对应的对象就是t表。

TABLESPACE_NAME                SEGMENT_TYPE       OWNER                          SEGMENT_NAME
------------------------------ ------------------ ------------------------------ --------------------
TB2                            TABLE              U2                             T

SQL> alter system set events='10231 trace name context forever,level 10';                 --设置内部事件,让exp跳过坏块。

系统已更改。

然后就可以导出了(可以看见还是导出了3074行数据,说明坏块没有影响到数据丢失。)

[oracle@linux oracle]$ exp system/oracle@orcl owner=u2 file=tab2.dmp

Export: Release 10.2.0.4.0 - Production on 星期一 10月 10 19:43:33 2011

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


连接到: Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
已导出 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集

即将导出指定的用户...
. 正在导出 pre-schema 过程对象和操作
. 正在导出用户 U2 的外部函数库名
. 导出 PUBLIC 类型同义词
. 正在导出专用类型同义词
. 正在导出用户 U2 的对象类型定义
即将导出 U2 的对象...
. 正在导出数据库链接
. 正在导出序号
. 正在导出簇定义
. 即将导出 U2 的表通过常规路径...
. . 正在导出表                               T导出了        3074 行
. 正在导出同义词
. 正在导出视图
. 正在导出存储过程
. 正在导出运算符
. 正在导出引用完整性约束条件
. 正在导出触发器
. 正在导出索引类型
. 正在导出位图, 功能性索引和可扩展索引
. 正在导出后期表活动
. 正在导出实体化视图
. 正在导出快照日志
. 正在导出作业队列
. 正在导出刷新组和子组
. 正在导出维
. 正在导出 post-schema 过程对象和操作
. 正在导出统计信息
成功终止导出, 没有出现警告。


2、使用rman进行恢复。
正如前面,可以看见数据文件 块存在错误。

SQL> conn u2/u2
已连接。
SQL> select count(*) from t;
select count(*) from t
                     *
第 1 行出现错误:
ORA-01578: ORACLE 数据块损坏 (文件号 6, 块号 111)
ORA-01110: 数据文件 6: '/u01/app/oracle/oradata/orcl/tb2.dbf'

使用rman进行数据文件检测

RMAN> backup validate datafile 6;

启动 backup 于 10-10月-11
使用目标数据库控制文件替代恢复目录
分配的通道: ORA_DISK_1
通道 ORA_DISK_1: sid=144 devtype=DISK
通道 ORA_DISK_1: 启动全部数据文件备份集
通道 ORA_DISK_1: 正在指定备份集中的数据文件
输入数据文件 fno=00006 name=/u01/app/oracle/oradata/orcl/tb2.dbf
通道 ORA_DISK_1: 备份集已完成, 经过时间:00:00:01
完成 backup 于 10-10月-11

查询坏块信息

SQL> conn /as sysdba
已连接。
SQL> select * from v$database_block_corruption where file# = 6;

     FILE#     BLOCK#     BLOCKS CORRUPTION_CHANGE# CORRUPTIO
---------- ---------- ---------- ------------------ ---------
         6        111          1                  0 CHECKSUM

使用rman进行修复

RMAN> list backup;


备份集列表
===================

BS 关键字  类型 LV 大小       设备类型 经过时间 完成时间  
------- ---- -- ---------- ----------- ------------ ----------
1       Full    527.85M    DISK        00:00:28     10-10月-11
        BP 关键字: 1   状态: AVAILABLE  已压缩: NO  标记: TAG20111010T203009
段名:/u01/app/oracle/flash_recovery_area/ORCL/backupset/2011_10_10/o1_mf_nnndf_TAG20111010T203009_795sbknx_.bkp
  备份集 1 中的数据文件列表
  文件 LV 类型 Ckp SCN    Ckp 时间   名称
  ---- -- ---- ---------- ---------- ----
  1       Full 477798     10-10月-11 /u01/app/oracle/oradata/orcl/system01.dbf
  2       Full 477798     10-10月-11 /u01/app/oracle/oradata/orcl/undotbs01.dbf
  3       Full 477798     10-10月-11 /u01/app/oracle/oradata/orcl/sysaux01.dbf
  4       Full 477798     10-10月-11 /u01/app/oracle/oradata/orcl/users01.dbf
  5       Full 477798     10-10月-11 /u01/app/oracle/oradata/orcl/tb1.dbf
  6       Full 477798     10-10月-11 /u01/app/oracle/oradata/orcl/tb2.dbf

BS 关键字  类型 LV 大小       设备类型 经过时间 完成时间  
------- ---- -- ---------- ----------- ------------ ----------
2       Full    6.80M      DISK        00:00:02     10-10月-11
        BP 关键字: 2   状态: AVAILABLE  已压缩: NO  标记: TAG20111010T203009
段名:/u01/app/oracle/flash_recovery_area/ORCL/backupset/2011_10_10/o1_mf_ncsnf_TAG20111010T203009_795scpjh_.bkp
  包括的控制文件: Ckp SCN: 477809       Ckp 时间: 10-10月-11
  包含的 SPFILE: 修改时间: 10-10月-11

RMAN> blockrecover datafile 6 block 111 from backupset;

启动 blockrecover 于 10-10月-11
使用通道 ORA_DISK_1

通道 ORA_DISK_1: 正在还原块
通道 ORA_DISK_1: 正在指定要从备份集还原的块
正在还原数据文件 00006 的块
通道 ORA_DISK_1: 正在读取备份片段 /u01/app/oracle/flash_recovery_area/ORCL/backupset/2011_10_10/o1_mf_nnndf_TAG20111010T203009_795sbknx_.bkp
通道 ORA_DISK_1: 已从备份片段 1 还原块
段句柄 = /u01/app/oracle/flash_recovery_area/ORCL/backupset/2011_10_10/o1_mf_nnndf_TAG20111010T203009_795sbknx_.bkp 标记 = TAG20111010T203009
通道 ORA_DISK_1: 块还原完成, 用时: 00:00:01

正在开始介质的恢复
介质恢复完成, 用时: 00:00:03

完成 blockrecover 于 10-10月-11

验证修复结果

SQL> conn u2/u2
已连接。
SQL> select count(*) from t;

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

你可能感兴趣的:(oracle,sql,数据库,application,database,disk)