首先构建一个写满数据的表空间
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