联系:手机/微信(+86 17813235971) QQ(107644445)
标题:记录block 0损坏,数据文件大量坏块,使用不当数据库版本恢复等各种操作之后的故障处理
作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]
今天一个恢复行业的朋友让我帮忙看一个oracle故障,说是vmdk文件被加密(加密破坏的很少),然后他从里面恢复出来了oracle的数据库文件,客户那边拿到数据文件然后说有三个文件头(被重命名为.bak)损坏了,无法打开数据库,让我这边给他们分析处理.分析他们说的被破坏文件,确实有损坏(初步看是block 0)

使用oracle自带的dbv进行检测
C:\Users\XFF>dbv file=H:\BaiduNetdisk\D\SYSTEM06.DBF.bak DBVERIFY: Release 11.2.0.4.0 - Production on 星期五 7月 3 21:06:28 2026 Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved. DBV-00107: 未知标头格式 (85) (1311029317)
由于block 0损坏,oracle自带的dbv无法检测,使用obet的dbv功能进行检测(obet实现对数据文件坏块检测功能)
=============================================== DBV (Data Block Verification) Report Started: 2026-07-03 21:04:22 Block Size: 8192 bytes Target File: ALL files in listfile =============================================== File #1: H:\BaiduNetdisk\D\SYSTEM06.DBF.bak (12801 blocks) - Started: 2026-07-03 21:04:22 File #1: rfile=19 (0x00000013) header_block_num=12800 (0x00003200) filesize_status:OK file 1, block 0: rdba error (expected 0, got 4083969), bad block File #1 completed: 0 all zero, 0 soft corrupted, 0 tailchk error, 0 checksum error, 1 rdba error File #1: H:\BaiduNetdisk\D\TSP_XXXXS06.DBF.bak (4194303 blocks) - Started: 2026-07-03 21:04:22 File #1: rfile=24 (0x00000018) header_block_num=4194302 (0x003FFFFE) filesize_status:OK file 1, block 0: rdba error (expected 0, got 1367117), bad block File #1 completed: 0 all zero, 0 soft corrupted, 0 tailchk error, 0 checksum error, 1 rdba error File #1: H:\BaiduNetdisk\D\TSP_XXXXS07.DBF.bak (1933313 blocks) - Started: 2026-07-03 21:04:42 File #1: rfile=25 (0x00000019) header_block_num=1933312 (0x001D8000) filesize_status:OK file 1, block 0: rdba error (expected 0, got 2445572), bad block File #1 completed: 0 all zero, 0 soft corrupted, 0 tailchk error, 0 checksum error, 1 rdba error DBV completed at: 2026-07-03 21:04:51 =============================================== DBV Summary: Total blocks checked: 6140414 Total all zero blocks found: 0 Total all rdba error blocks found: 3 Total all tailchk error blocks found: 0 Total all soft corrupted blocks found: 0 Total all checksum error blocks found: 0 Total bad blocks found: 3 Execution time: 29.00 seconds ===============================================
通过检测确认这三个数据文件就是block 0损坏其他的数据块是ok的.检查其他数据文件发现有一个数据文件有近2w个坏块
DBVERIFY: Release 11.2.0.4.0 - Production on 星期五 7月 3 12:55:08 2026 Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved. DBVERIFY - 开始验证: FILE = H:\BAIDUNETDISK\ORCL\TSP_XXXX.DBF 页 409601 标记为损坏 Corrupt block relative dba: 0x01864001 (file 6, block 409601) Bad header found during dbv: Data in bad block: type: 219 format: 1 rdba: 0xdf6e738f last change scn: 0xd7ed.50be2d8b seq: 0x44 flg: 0x52 spare1: 0x39 spare2: 0x92 spare3: 0xb5c5 consistency value in tail: 0x6e7debc9 check value in block header: 0x6d54 block checksum disabled ……………… DBVERIFY - 验证完成 检查的页总数: 4194302 处理的页总数 (数据): 1842107 失败的页总数 (数据): 0 处理的页总数 (索引): 2143604 失败的页总数 (索引): 0 处理的页总数 (其他): 13763 处理的总页数 (段) : 0 失败的总页数 (段) : 0 空的页总数: 437 标记为损坏的总页数: 194391 流入的页总数: 2 加密的总页数 : 0 最高块 SCN : 1869110545 (9.1869110545)
对于这个文件,由于客户有部分rman备份,尝试通过备份找出来这个文件历史文件
RMAN> run
2> {
3> set newname for datafile 'D:\APP\ADMINISTRATOR\ORADATA\ORCL\TSP_XXXX.DBF'
4> to 'H:\BaiduNetdisk\orcl\TSP_XXXX.DBF_rman';
5> restore datafile 6;
6> }
正在执行命令: SET NEWNAME
启动 restore 于 03-7月 -26
使用通道 ORA_DISK_1
通道 ORA_DISK_1: 正在开始还原数据文件备份集
通道 ORA_DISK_1: 正在指定从备份集还原的数据文件
通道 ORA_DISK_1: 将数据文件 00006 还原到 H:\BaiduNetdisk\orcl\TSP_XXXX.DBF_rman
通道 ORA_DISK_1: 正在读取备份片段 H:\BAIDUNETDISK\BACKDB\FULLDB_ORCL_20250704_TC3TM4LJ_1_1.BAK.RESTORED0
通道 ORA_DISK_1: ORA-19870: 还原备份片段 H:\BAIDUNETDISK\BACKDB\FULLDB_ORCL_20250704_TC3TM4LJ_1_1.BAK.RESTORED0 时出错
ORA-19599: 块编号 1065697 已在 backup piece H:\BAIDUNETDISK\BACKDB\FULLDB_ORCL_20250704_TC3TM4LJ_1_1.BAK.RESTORED0 中损 坏
故障转移到上一个备份
通道 ORA_DISK_1: 正在开始还原数据文件备份集
通道 ORA_DISK_1: 正在指定从备份集还原的数据文件
通道 ORA_DISK_1: 将数据文件 00006 还原到 H:\BaiduNetdisk\orcl\TSP_XXXX.DBF_rman
通道 ORA_DISK_1: 正在读取备份片段 H:\BAIDUNETDISK\BACKDB\FULLDB_ORCL_20250703_T33TJG9L_1_1.BAK
通道 ORA_DISK_1: ORA-19870: 还原备份片段 H:\BAIDUNETDISK\BACKDB\FULLDB_ORCL_20250703_T33TJG9L_1_1.BAK 时出错
ORA-19599: 块编号 95352 已在 backup piece H:\BAIDUNETDISK\BACKDB\FULLDB_ORCL_20250703_T33TJG9L_1_1.BAK 中损坏
故障转移到上一个备份
通道 ORA_DISK_1: 正在开始还原数据文件备份集
通道 ORA_DISK_1: 正在指定从备份集还原的数据文件
通道 ORA_DISK_1: 将数据文件 00006 还原到 H:\BaiduNetdisk\orcl\TSP_XXXX.DBF_rman
通道 ORA_DISK_1: 正在读取备份片段 H:\BAIDUNETDISK\BACKDB\FULLDB_ORCL_20250702_SQ3TGRTU_1_1.BAK
通道 ORA_DISK_1: 段句柄 = H:\BAIDUNETDISK\BACKDB\FULLDB_ORCL_20250702_SQ3TGRTU_1_1.BAK 标记 = TAG20250702T000518
通道 ORA_DISK_1: 已还原备份片段 1
通道 ORA_DISK_1: 还原完成, 用时: 00:28:56
完成 restore 于 03-7月 -26
RMAN> exit
运气还不错,从备份里面找一份好的该文件的备份,然后通过使用该文件好的block替换最初损坏的block,实现该文件无坏块(由于这个文件比较靠前,而且已经写满,所以只差3天左右数据可能改变很小,因此可以采用这种替代方法最大限度恢复数据).数据文件检测和明显坏块处理完成,接下来开始打开数据库操作.
由于我这边的数据文件路径和原库的不一致,修改ctl中的datafile 路径报ORA-17503错误

对于这些情况,通过修复block 0,然后尝试重命名数据文件成功
SQL> alter database rename file 'D:\APP\ADMINISTRATOR\ORADATA\ORCL\TSP_XXX06.DBF' to 'H:\BaiduNetdisk\orcl\TSP_XXX06.DBF' 2 ; 数据库已更改。 SQL> alter database rename file 'D:\APP\ADMINISTRATOR\ORADATA\ORCL\TSP_XXX07.DBF' to 'H:\BaiduNetdisk\orcl\TSP_XXX07.DBF' 2 ; 数据库已更改。 SQL> alter database rename file 'D:\APP\ADMINISTRATOR\ORADATA\ORCL\SYSTEM06.DBF' to 'H:\BaiduNetdisk\orcl\SYSTEM06.DBF' 2 ; 数据库已更改。
然后尝试打开数据库成功
SQL> recover database; 完成介质恢复。 SQL> alter database open; 数据库已更改。
尝试expdp导出数据,结果报UDE-22303
C:\Users\XFF>expdp "'/ as sysdba'" full=y dumpfile=expdp_0703_%U.dmp DIRECTORY=expdp_dir logfile=expdp_0703.log parallel=4 compression=all EXCLUDE=STATISTICS,AUDIT Export: Release 11.2.0.4.0 - Production on 星期五 7月 3 13:10:12 2026 Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved. 连接到: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production With the Partitioning, OLAP, Data Mining and Real Application Testing options UDE-22303: 操作产生了 ORACLE 错误 22303 OCI-22303: 未找到类型 "SYS"."KU$_STATUS1020"
正常打开的数据库,没有明显坏块,出现这个错误,理论上不太应该,怀疑是客户的版本问题,查询组件版本

确认该数据库版本可能是11.2.0.1而不是我现在看到的数据文件头为11.2.0.4,查询WRM$_DATABASE_INSTANCE,确认数据库之前版本是11.2.0.1.对于这种情况,直接简单的把compatible从11.2.0.4修改为11.2.0.0肯定不行,因为ctl,dbf,redo里面都写了11.2.0.4的信息
1. ctl报版本不匹配
SQL> startup mount pfile='i:/pfile.txt'; ORACLE 例程已经启动。 Total System Global Area 3206836224 bytes Fixed Size 2180024 bytes Variable Size 654314568 bytes Database Buffers 2533359616 bytes Redo Buffers 16982016 bytes ORA-00201: ?????? 11.2.0.4.0 ? ORACLE ?? 11.2.0.0.0 ??? ORA-00202: ????: ''H:\BAIDUNETDISK\ORCL\CONTROL01.CTL''
2. 这种情况需要rectl,然后报dbf版本不对
CREATE CONTROLFILE REUSE DATABASE "ORCL" NORESETLOGS NOARCHIVELOG * 第 1 行出现错误: ORA-01503: CREATE CONTROLFILE ?? ORA-01130: ??????? 11.2.0.4.0 ? ORACLE ?? 11.2.0.0.0 ??? ORA-01110: ???? 1: 'H:\BAIDUNETDISK\ORCL\SYSTEM01.DBF'
这种情况,dbf中的版本信息无法通过重建解决,只能使用obet工具修改,每个文件类似修改(Oracle数据块编辑工具( Oracle Block Editor Tool)-obet)
OBET> set file 25 filename set to: H:\BAIDUNETDISK\ORCL\TSP_XXXX07.DBF (file#25) OBET> set offset 24 offset set to: 24 OBET> m 0000 Confirm modification: File: H:\BAIDUNETDISK\ORCL\TSP_XXXX07.DBF Block: 1 Offset: 24 (file offset: 0x00002018) Original value: 0004 New value: 0000 Confirm? (Y/YES to proceed): y Verification successful: Data written correctly. Modified 2 bytes at offset 0x00002018 successfully. OBET> sum apply Confirm applying checksum: File: H:\BAIDUNETDISK\ORCL\TSP_XXXX07.DBF Block: 1 Offset in block: 16 (file offset: 0x00002010) Original value: 0x94C3 New value: 0x94C7 Confirm? (Y/YES to proceed): y Verification successful: Stored checksum matches calculated value (0x94C7). Checksum applied successfully. OBET>
然后重建ctl报redo版本不兼容ORA-00331
CREATE CONTROLFILE REUSE DATABASE "ORCL" NORESETLOGS NOARCHIVELOG * 第 1 行出现错误: ORA-01503: CREATE CONTROLFILE 失败 ORA-00331: 日志版本 0.0.0.0.0 与 ORACLE 版本 11.2.0.0.0 不兼容 ORA-01517: 日志成员: 'H:\BAIDUNETDISK\ORCL\REDO01.LOG'
采用resetlogs方式重建(不读取redo信息),重建ctl成功,然后直接打开数据库
37 CHARACTER SET AL32UTF8 38 ; 控制文件已创建。 SQL> alter database open resetlogs; 数据库已更改。
然后expdp导出数据完成本次恢复任务
