数据库文件变成32k故障恢复

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

标题:数据库文件变成32k故障恢复

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

最近一个客户数据库重启系统之后,数据文件大小变为了32kb,我接手的不是第一现场(客户那边尝试了rman还原操作),查看alert日志,数据库最初报错

Wed Jun 18 13:09:23 2025
alter database open
Block change tracking file is current.
Read of datafile 'D:\APP\ADMINISTRATOR\ORADATA\ORCL\WASION08.DBF' (fno 14) header failed with ORA-01210
Hex dump of (file 14, block 1) in trace file d:\app\administrator\diag\rdbms\ORCL\ORCL\trace\ORCL_ora_11208.trc
Corrupt block relative dba: 0x03800001 (file 14, block 1)
Completely zero block found during datafile header read
Rereading datafile 14 header failed with ORA-01210
Hex dump of (file 14, block 1) in trace file d:\app\administrator\diag\rdbms\ORCL\ORCL\trace\ORCL_ora_11208.trc
Corrupt block relative dba: 0x03800001 (file 14, block 1)
Completely zero block found during datafile header read
Errors in file d:\app\administrator\diag\rdbms\ORCL\ORCL\trace\ORCL_ora_11208.trc:
ORA-01122: 数据库文件 14 验证失败
ORA-01110: 数据文件 14: 'D:\APP\ADMINISTRATOR\ORADATA\ORCL\WASION08.DBF'
ORA-01210: 数据文件标头发生介质损坏
ORA-1122 signalled during: alter database open...
Wed Jun 18 13:09:23 2025
Checker run found 1 new persistent data failures

客户那边不知道做了什么操作之后报错(初步估计是把14号文件重命名了)

Thu Jun 19 16:04:19 2025
alter database open
Thu Jun 19 16:04:21 2025
Errors in file d:\app\administrator\diag\rdbms\ORCL\ORCL\trace\ORCL_dbw0_13000.trc:
ORA-01157: ????/?????? 14 - ??? DBWR ????
ORA-01110: ???? 14: 'D:\APP\ADMINISTRATOR\ORADATA\ORCL\WASION08.DBF'
ORA-27041: ??????
OSD-04002: 无法打开文件
O/S-Error: (OS 2) 系统找不到指定的文件。
Errors in file d:\app\administrator\diag\rdbms\ORCL\ORCL\trace\ORCL_ora_12328.trc:
ORA-03113: 通信通道的文件结尾
ORA-3113 signalled during: alter database open...

根据客户反馈14号文件变成了32kb,就是被重命名的.bak文件
32k


这其中有一个bak0618是通过rman还原出来的(备份中无有效的14号文件备份,还原出来的为该文件初始化创建大小)

Thu Jul 07 16:57:05 2022
alter tablespace wasion add datafile 'D:\APP\ADMINISTRATOR\ORADATA\ORCL\WASION08.dbf' size 10g autoextend on
Completed: alter tablespace wasion add datafile 'D:\APP\ADMINISTRATOR\ORADATA\ORCL\WASION08.dbf' size 10g autoextend on

2025-06-26_101717_568


基于当前情况,可以确认该文件异常,而且没有有效的rman备份.通过分析备份脚本,发现每个备份集1个数据文件,而且没有压缩,并按照10g进行分割为多个文件
QQ20250626-095824

这些本身没有问题,脚本的后面有直接通过系统级别命令删除两天之前的备份文件
QQ20250626-100105

这里有一个问题,由于磁盘空间不足,导致部分备份不成功,但是系统级别删除操作依旧正常进行,导致以前有效的备份被删除,后面的备份又没有成功(这个是本次该文件无法还原的主要原因),慎重提醒,rman备份尽量使用rman本身的策略来管理不要使用系统命令来维护备份策略,基于这样的情况,可以使用反删除命令找出来了一些该文件的备份集,并注册到控制文件中

RMAN> list backup of datafile 14;


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


BS 关键字  类型 LV 大小       设备类型 经过时间 完成时间
------- ---- -- ---------- ----------- ------------ ----------
35251   Incr 0  10.89G     DISK        00:01:20     15-6月 -25
  备份集 35251 中的数据文件列表
  文件 LV 类型 Ckp SCN    Ckp 时间   名称
  ---- -- ---- ---------- ---------- ----
  14   0  Incr 758850903  15-6月 -25 D:\APP\ADMINISTRATOR\ORADATA\ORCL\WASION08.DBF

  备份集 副本号 2 属于备份集 35251
  设备类型 经过时间 完成时间   压缩标记
  ----------- ------------ ---------- ---------- ---
  DISK        00:01:20     26-6月 -25 NO         TAG20250615T220003

    备份集 35251 副本号 2的备份片段列表
    BP 关键字  Pc# 状态      段名称
    ------- --- ----------- ----------
    78307   1   AVAILABLE   H:\BAIDUNETDISK\202506191452\L0_ORCL_20250615_78847_VV3S3RQP_1_1
    78308   2   AVAILABLE   H:\BAIDUNETDISK\202506191452\L0_ORCL_20250615_78847_VV3S3RQP_2_1

BS 关键字  类型 LV 大小       设备类型 经过时间 完成时间
------- ---- -- ---------- ----------- ------------ ----------
35266   Incr 0  1.81G      DISK        00:00:00     17-6月 -25
  备份集 35266 中的数据文件列表
  文件 LV 类型 Ckp SCN    Ckp 时间   名称
  ---- -- ---- ---------- ---------- ----
  14      Full 759283192  17-6月 -25 D:\APP\ADMINISTRATOR\ORADATA\ORCL\WASION08.DBF

  备份集 副本号 1 属于备份集 35266
  设备类型 经过时间 完成时间   压缩标记
  ----------- ------------ ---------- ---------- ---
  DISK        00:00:00     26-6月 -25 NO         TAG20250617T220049

    备份集 35266 副本号 1的备份片段列表
    BP 关键字  Pc# 状态      段名称
    ------- --- ----------- ----------
            1   DELETED                        <---缺少一个备份集文件
    78309   2   AVAILABLE   H:\BAIDUNETDISK\202506191452\L0_ORCL_20250617_79022_5E3S94MC_2_1

尝试rman还原这些备份文件

RMAN> run
2> {
3> SET NEWNAME FOR DATAFILE 14 to 'H:\BaiduNetdisk\202506191452\14.dbf';
4> restore datafile 14;
5> }

正在执行命令: SET NEWNAME

启动 restore 于 26-6月 -25
使用通道 ORA_DISK_1

通道 ORA_DISK_1: 正在开始还原数据文件备份集
通道 ORA_DISK_1: 正在指定从备份集还原的数据文件
通道 ORA_DISK_1: 将数据文件 00014 还原到 H:\BAIDUNETDISK\202506191452\14.DBF
通道 ORA_DISK_1: 正在还原段 1 (属于 2)
通道 ORA_DISK_1: 正在读取备份片段 H:\BAIDUNETDISK\202506191452\L0_ORCL_20250615_78847_VV3S3RQP_1_1
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: restore 命令 (在 06/26/2025 08:35:53 上) 失败
ORA-19870: 还原备份片段 H:\BAIDUNETDISK\202506191452\L0_ORCL_20250615_78847_VV3S3RQP_1_1 时出错
ORA-00600: 内部错误代码, 参数: [krbvalmrange_badfno], [1], [14], [], [], [], [], [], [], [], [], []

alert日志报错

Thu Jun 26 08:25:26 2025
Checker run found 39 new persistent data failures
Thu Jun 26 08:35:51 2025
Datafile rdba reconstruction error, expected block greater than 804966, got 322047 for datafile 14
Corrupt block 804352 found during reading backup piece, 
file=H:\BAIDUNETDISK\202506191452\L0_ORCL_20250615_78847_VV3S3RQP_1_1, corr_type=4
Reread of blocknum=804352, file=H:\BAIDUNETDISK\202506191452\L0_ORCL_20250615_78847_VV3S3RQP_1_1. found valid data
Datafile rdba reconstruction error, expected block greater than 324095, got 55516 for datafile 14
Corrupt block 806400 found during reading backup piece, 
file=H:\BAIDUNETDISK\202506191452\L0_ORCL_20250615_78847_VV3S3RQP_1_1, corr_type=4
Reread of blocknum=806400, file=H:\BAIDUNETDISK\202506191452\L0_ORCL_20250615_78847_VV3S3RQP_1_1. found valid data
Errors in file C:\APP\XFF\diag\rdbms\ORCL\orcl\trace\orcl_ora_19208.trc  (incident=177):
ORA-00600: 内部错误代码, 参数: [krbvalmrange_badfno], [1], [14], [], [], [], [], [], [], [], [], []
Incident details in: C:\APP\XFF\diag\rdbms\ORCL\orcl\incident\incdir_177\orcl_ora_19208_i177.trc
Use ADRCI or Support Workbench to package the incident.
See Note 411.1 at My Oracle Support for error and packaging details.
Thu Jun 26 08:35:52 2025

后面通过工具分析以及ORA-600 krbvalmrange_badfno的错误,基本上可以确认在反删除恢复的备份集文件中部分rman的block是其他数据文件的,从而导致无法正常还原.基于这种情况,通过工具进行强制还原出来部分14号数据文件的block
QQ20250626-101208


然后再通过磁盘级别碎片,找到部分没有覆盖的block
suip

把rman备份中强制抽取的部分block和底层碎片恢复的没有覆盖的block组合到一起,通过检测确认恢复了大概2/3的数据
QQ20250626-101601

基于恢复的该文件和这个表空间的其他文件一起,使用dul工具把数据恢复到新库中,最大限度完成本次数据的抢救工作.

本次故障本不该发生,或者说发生不该如此严重:
1. rman备份采用系统级别维护策略,在备份没有成功的情况下依旧通过系统层面删除文件,导致故障文件无一份有效备份
2. 发生故障之后,没有保护现场的意识:对于32kb的数据文件所在磁盘进行了大量的写入操作(近1T的数据文件直接在本盘做了一次拷贝,还有rman默认写入到了以前文件所在位置)

ORA-01122 ORA-01210 故障恢复

联系:手机/微信(+86 17813235971) QQ(107644445)

标题:ORA-01122 ORA-01210 故障恢复

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

有朋友数据文件头出现错误ORA-01122和ORA-01210等错误,数据库无法正常open。
ORA-01210


因为平台是win,他们找我咨询win bbed,因为回老家电脑没有带,无法提供win的bbed.我通过dd部分文件头,然后在linux平台分析发现是该文件的文件头block大量坏块

bbed分析坏块情况

BBED> show all
        FILE#           0
        BLOCK#          1
        OFFSET          0
        DBA             0x00000000 (0 0,1)
        FILENAME        /tmp/30.dbf
        BIFILE          bifile.bbd
        LISTFILE
        BLOCKSIZE       8192
        MODE            Browse
        EDIT            Unrecoverable
        IBASE           Dec
        OBASE           Dec
        WIDTH           80
        COUNT           512
        LOGFILE         log.bbd
        SPOOL           No
BBED> set count 64
        COUNT           64
BBED> map
 File: /tmp/30.dbf (0)
 Block: 1                                     Dba:0x00000000
------------------------------------------------------------
BBED-00400: invalid blocktype (27)
BBED> d
 File: /tmp/30.dbf (0)
 Block: 1                Offsets:    0 to   63           Dba:0x00000000
------------------------------------------------------------------------
 1ba20000 03004400 bffd8a1d 0000000c acba0000 008f4500 00003455 fc020000
 02040000 00000000 00008001 04000000 00000000 00000000 949400b4 94514005
 <32 bytes per line>
BBED> set block +1
        BLOCK#          2
BBED> map
 File: /tmp/30.dbf (0)
 Block: 2                                     Dba:0x00000000
------------------------------------------------------------
BBED-00400: invalid blocktype (27)
BBED> d
 File: /tmp/30.dbf (0)
 Block: 2                Offsets:    0 to   63           Dba:0x00000000
------------------------------------------------------------------------
 1ba20000 04004400 bffd8a1d 0000000c a6e00000 008f4500 00003455 fc020000
 0204e81f 00000000 0000241e 05000000 00000000 00000000 11fc297f b426fe2b
 <32 bytes per line>
BBED> set block +1
        BLOCK#          3
BBED> d
 File: /tmp/30.dbf (0)
 Block: 3                Offsets:    0 to   63           Dba:0x00000000
------------------------------------------------------------------------
 1ba20000 05004400 bffd8a1d 0000000c 780a0000 008f4500 00003455 fc020000
 0204e81f 00000000 0000c001 06000000 00000000 00000000 2969a0d2 d30168a2
 <32 bytes per line>
BBED> set block +1
        BLOCK#          4
BBED> d
 File: /tmp/30.dbf (0)
 Block: 4                Offsets:    0 to   63           Dba:0x00000000
------------------------------------------------------------------------
 1ba20000 06004400 bffd8a1d 0000000c 6c5a0000 008f4500 00003455 fc020000
 0204e81f 00000000 0000f81d 07000000 00000000 00000000 7b51d409 6dc7ca4d
 <32 bytes per line>
BBED> set block +1
        BLOCK#          5
BBED> d
 File: /tmp/30.dbf (0)
 Block: 5                Offsets:    0 to   63           Dba:0x00000000
------------------------------------------------------------------------
 1ba20000 07004400 bffd8a1d 0000000c c5600000 008f4500 00003455 fc020000
 02040000 00000000 0000c001 08000000 00000000 00000000 14514005 25145200
 <32 bytes per line>
BBED> set block +1
        BLOCK#          6
BBED> d
 File: /tmp/30.dbf (0)
 Block: 6                Offsets:    0 to   63           Dba:0x00000000
------------------------------------------------------------------------
 1ba20000 08004400 bffd8a1d 0000000c 60480000 008f4500 00003455 fc020000
 0204e81f 00000000 0000c301 09000000 00000000 00000000 c2a1606a 7615130a
 <32 bytes per line>
BBED> set block +1
        BLOCK#          7
BBED> d
 File: /tmp/30.dbf (0)
 Block: 7                Offsets:    0 to   63           Dba:0x00000000
------------------------------------------------------------------------
 1ba20000 09004400 bffd8a1d 0000000c e3430000 008f4500 00003455 fc020000
 0204e81f 00000000 00000002 0a000000 00000000 00000000 00a28a28 00a28a28
 <32 bytes per line>
BBED> set block +1
        BLOCK#          8
BBED> d
 File: /tmp/30.dbf (0)
 Block: 8                Offsets:    0 to   63           Dba:0x00000000
------------------------------------------------------------------------
 1ba20000 0a004400 07fe8a1d 0000000c fc000000 008f4500 00003455 fc020000
 0205e81f 00000000 0000f41d 00000000 00000000 00000000 ffd8ffe0 00104a46
 <32 bytes per line>
BBED> set block +1
        BLOCK#          9
BBED> d
 File: /tmp/30.dbf (0)
 Block: 9                Offsets:    0 to   63           Dba:0x00000000
------------------------------------------------------------------------
 1ba20000 0b004400 07fe8a1d 0000000c 48da0000 008f4500 00003455 fc020000
 0205e81f 00000000 0000c601 01000000 00000000 00000000 b47d69d3 7fa96a6f
 <32 bytes per line>
BBED> set block +1
        BLOCK#          10
BBED> d
 File: /tmp/30.dbf (0)
 Block: 10               Offsets:    0 to   63           Dba:0x00000000
------------------------------------------------------------------------
 1ba20000 0c004400 07fe8a1d 0000000c be0f0000 008f4500 00003455 fc020000
 0205e81f 00000000 0000181d 02000000 00000000 00000000 9de3e868 4782d83a
 <32 bytes per line>
BBED> set block +1
        BLOCK#          11
BBED> d
 File: /tmp/30.dbf (0)
 Block: 11               Offsets:    0 to   63           Dba:0x00000000
------------------------------------------------------------------------
 1ba20000 0d004400 07fe8a1d 0000000c 9cd00000 008f4500 00003455 fc020000
 0205e81f 00000000 0000241e 03000000 00000000 00000000 dead1259 5919e385
 <32 bytes per line>
BBED> set block +1
        BLOCK#          12
BBED> d
 File: /tmp/30.dbf (0)
 Block: 12               Offsets:    0 to   63           Dba:0x00000000
------------------------------------------------------------------------
 1ba20000 0e004400 07fe8a1d 0000000c df450000 008f4500 00003455 fc020000
 0205e81f 00000000 00004001 04000000 00000000 00000000 31d9a292 9698828a
 <32 bytes per line>
BBED> set block +1
        BLOCK#          13
BBED> d
 File: /tmp/30.dbf (0)
 Block: 13               Offsets:    0 to   63           Dba:0x00000000
------------------------------------------------------------------------
 1ba20000 0f004400 07fe8a1d 0000000c 18790000 008f4500 00003455 fc020000
 02050000 00000000 00000002 05000000 00000000 00000000 b93f8235 5ea063b7
 <32 bytes per line>

拿block 1的rdba(04004400–倒序存储)分析[win文件拷贝到linux后使用bbed查看相差1 block]可以的出来block信息为file=1, block=262148,明显错误.

通过dul分析文件头损坏情况

Data UnLoader: 10.2.0.6.9 - Internal Only - on Tue Sep 29 22:15:22 2015
with 64-bit io functions
Copyright (c) 1994 2015 Bernard van Duijnen All rights reserved.
 Strictly Oracle Internal Use Only
DUL: Warning: Recreating file "dul.log"
Reading SCANNEDLOBPAGE.dat 1204 entries loaded and sorted 1204 entries
Reading SEG.dat 0 entries loaded
Reading EXT.dat 44 entries loaded and sorted 44 entries
Reading COMPATSEG.dat 0 entries loaded
DUL: Warning: Wrong DBA  0X00440004 (file=1, block=262148) (Ignored)
DUL: Error: While processing file# 30 block# 1
DUL: Warning: Found mismatch while checking file E:\TEMP\shebao\30.dbf
DUL: Warning: DUL osd_parameter or control.dul configuration error
DUL: Warning: Given file number(30) in control file does not match file# in dba(1)
DUL: Warning: Wrong DBA  0X00440004 (file=1, block=262148) (Ignored)
DUL: Error: While processing file# 30 block# 1
DUL>

通过bbed和dul证明文件头大量损坏,而且尚未有任何该文件的物理备份,因此恢复起来难道较大。

分析Oracle Database Recovery Check Result
通过对Oracle数据库异常恢复检查脚本(Oracle Database Recovery Check)的分析结果,我们意外的发现,人品不错,发现异常的文件创建时间为2015-09-26 19:39:33,进一步和客户沟通,这个文件存储为图片,少量丢失可以允许,优先恢复业务
Oracle-Database-Recovery-Check


有了这个结论,那处理起来就easy了,直接offline异常文件,然后分析丢失的表
从而确定时lob字典的少量extent数据分配到了file 30上
lob


为了避免查询对应lob之时出现错误,通过update 对应lob为空规避该问题

create table corrupt_lobs (corrupt_rowid rowid,table_name varchar2(100));
declare
  n number;
begin
  for cursor_lob in (select rowid r, xff_lob from xff.t_xifenfei) loop
  begin
    n:=dbms_lob.instr(cursor_lob.xff_lob,hextoraw('889911'));
  exception
    when others then
      insert into corrupt_lobs values (cursor_lob.r,'xff.t_xifenfei');
      commit;
    end;
  end loop;
end;
/
update xff.t_xifenfei
     set xff_lob = empty_blob()
     where rowid in (select corrupted_rowid from corrupt_lobs);

本次恢复是由于运气好,遇到异常文件刚好是最近加入,而且都是图片,客户允许少量丢失,如果是不允许丢失的数据文件,可能需要通过找历史的该文件的备份(Oracle 12C的第一次异常恢复—文件头坏块),在某些情况下,如果也没有此类备份,只能通过bbed重构block 1(如果有其他异常块一次处理,如果太多无法处理,最少也需要重构block 1),然后尝试open数据库或者使用dul之类工具处理(因为文件头损坏,工具可能不能识别文件无法恢复)