今天一个恢复行业的朋友让我帮忙看一个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的信息
- 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``'' |
- 这种情况需要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导出数据完成本次恢复任务