记录block 0损坏,数据文件大量坏块,使用不当数据库版本恢复等各种操作之后的故障处理

联系:手机/微信(+86 17813235971) QQ(107644445)QQ咨询惜分飞

标题:记录block 0损坏,数据文件大量坏块,使用不当数据库版本恢复等各种操作之后的故障处理

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

今天一个恢复行业的朋友让我帮忙看一个oracle故障,说是vmdk文件被加密(加密破坏的很少),然后他从里面恢复出来了oracle的数据库文件,客户那边拿到数据文件然后说有三个文件头(被重命名为.bak)损坏了,无法打开数据库,让我这边给他们分析处理.分析他们说的被破坏文件,确实有损坏(初步看是block 0)
block0


使用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错误
rename


对于这些情况,通过修复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"

正常打开的数据库,没有明显坏块,出现这个错误,理论上不太应该,怀疑是客户的版本问题,查询组件版本
v1


确认该数据库版本可能是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导出数据完成本次恢复任务