作者归档:惜分飞

年前几例Oracle数据库被加密为.wman的数据库故障恢复

年前连续恢复了4个Oracle数据库被勒索加密的case(大小分别为80g,160G,680G,1600G),扩展名是.[[dawsones@cock.li]].wman和[[YATESNET@cock.li]].wman,其中有些库是所有数据文件均被加密并且修改扩展名
1


还有些数据库只是不部分文件扩展名被改变,部分文件保持以前扩展名
2

但是他们都有一个共同的特点,就是这些数据文件均为前面63个block损坏(obet实现对数据文件坏块检测功能)

File #1: D:\app\Administrator\oradata\orcl\BHDATA.DBF (1540353 blocks) - Started: 2026-02-11 14:57:12
File #1: rfile=270931750 (0x10261726)  header_block_num=3344637312 (0xC75B1D80)  filesize_status:NO
file 1, block 0: rdba error (expected 0, got 2951434), bad block
file 1, block 1: rdba error (expected 1, got 298248), bad block
file 1, block 2: rdba error (expected 2, got 1732212), bad block
file 1, block 3: rdba error (expected 3, got 2259600), bad block
file 1, block 4: rdba error (expected 4, got 1628690), bad block
………………
file 1, block 54: rdba error (expected 54, got 1652119), bad block
file 1, block 55: rdba error (expected 55, got 3661515), bad block
file 1, block 56: rdba error (expected 56, got 2412272), bad block
file 1, block 57: rdba error (expected 57, got 3848900), bad block
file 1, block 58: rdba error (expected 58, got 3415387), bad block
file 1, block 59: rdba error (expected 59, got 3649462), bad block
file 1, block 60: rdba error (expected 60, got 1651981), bad block
file 1, block 61: rdba error (expected 61, got 99182), bad block
file 1, block 62: rdba error (expected 62, got 513782), bad block
file 1, block 63: rdba error (expected 63, got 269316), bad block
  File #1 completed: 0 all zero, 0 soft corrupted, 0 tailchk error, 0 checksum error, 64 rdba error

由于被损坏的数据库都是11g版本(而且不是从低版本升级上来的),也就是说实际业务数据是从block 128开始的(block 1为datafile header,block 2-127为数据块分配的位图信息),因此对于这个故障直接通过自研的Oracle数据文件勒索加密恢复工具对文件头进行重构
QQ20250113-220625


然后直接打开数据库,导出数据,但是由于这些库中有大量的xml类型,使得导出有点麻烦,特别是遇到了expdp导出xml列报ORA-22924故障处理,还有一些诡异问题(expdp导出正常,impdp导入报错)进行额外处理

. . 导出了 "ZLCHS"."保险结算记录"                            196.8 MB  463090 行
ORA-31693: 表数据对象 "ZLCHS"."保险结算记录" 无法加载/卸载并且被跳过, 错误如下:
ORA-29913: 执行 ODCIEXTTABLEFETCH 调出时出错
ORA-00600: 内部错误代码, 参数: [qmcxeRemap82], [], [], [], [], [], [], [], [], [], [], []
发表在 勒索恢复 | 标签为 , , | 留下评论

文件系统损坏导致数据库异常故障处理

有客户做了双机rose,由于某种故障导致共享存储在两个主机之间相互频繁挂载(甚至出现了同时挂载的情况),使得该文件系统发生损坏
ntfs


修复双机故障之后,数据库启动ORA-01122 ORA-01110 ORA-01200错误
ora-1200

初步看这个报错,block差距有点大,文件头中记录为419840个block,现在实际有的block数量为384000,使用obet查看文件头记录block number情况

OBET> p kcvfh.kcvfhhdr
File: E:\TEMP\20260219\SYSTEM01.DBF
Size: 8192 bytes
Block: 1
Offset: 20

struct kcvfhhdr, 76 bytes                   @20
   ub4 kccfhswv                            @20      0x00000000
   ub4 kccfhcvn                            @24      0x0B200400
   ub4 kccfhdbi                            @28      0x85D98FAB
   text kccfhdbn[8]                        @32-39   XXXX
   ub4 kccfhcsq                            @40      0x00091079
   ub4 kccfhfsz                            @44      0x00066800 <<--16转换为10进制为419840
   s_blkz kccfhbsz                         @48      0x00
   ub2 kccfhfno                            @52      0x0001
   ub2 kccfhtyp                            @54      0x0003
   ub4 kccfhacid                           @56      0x00000000
   ub4 kccfhcks                            @60      0x00000000
   text kccfhtag[32]                       @64-95

<kcvfh.kcvfhhdr structure printed successfully>

对于这种情况,以前有过很多次处理经验(一般办法2个:1>修改文件头的block数量记录;2>修改现在的文件大小和实际文件有匹配),以前类似的处理记录:
bbed处理ORA-01200故障
记录一次ORA-01200完美恢复
ORA-01122 ORA-01200故障处理
处理完成system文件异常之后,sysaux文件继续异常

SQL> recover datafile 1;
完成介质恢复。
SQL> recover datafile 2;
ORA-00283: 恢复会话因错误而取消
ORA-01110: 数据文件 2: 'Z:\APP\ADMINISTRATOR\ORADATA\XXXX\SYSAUX01.DBF'
ORA-01122: 数据库文件 2 验证失败
ORA-01110: 数据文件 2: 'Z:\APP\ADMINISTRATOR\ORADATA\XXXX\SYSAUX01.DBF'
ORA-01200: 149760 的实际文件大小小于 153600 块的正确大小

类似处理该故障之后,由于文件系统故障导致不少文件出现大量连续坏块(全0或者记录了其他文件内容的坏块),这种是由于文件系统元数据异常导致,通过文件系统层面恢复继续无法正常处理,对于这样的情况,通过碎片扫描工具按照oracle block级别的文件重组(其实就是基于rdba信息进行重组),获取正确的数据块信息然后重新重组成数据文件
QQ20260220-005159


然后打开数据库,顺利导出数据,实现客户数据最大限度恢复

发表在 非常规恢复 | 标签为 , , | 留下评论

expdp导出xml列报ORA-22924故障处理

expdp导出xml列类型表报错

连接到: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
启动 "SYS"."EXPDP_TBA1":  "/******** AS SYSDBA" tables=XFF.XML_TAB dumpfile=XML_TAB.dmp
    DIRECTORY=expdp_dir logfile=expdp_XML_TAB.log EXCLUDE=STATISTICS job_name=expdp_tba1
正在使用 BLOCKS 方法进行估计...
处理对象类型 TABLE_EXPORT/TABLE/TABLE_DATA
使用 BLOCKS 方法的总估计: 13.12 GB
处理对象类型 TABLE_EXPORT/TABLE/TABLE
处理对象类型 TABLE_EXPORT/TABLE/INDEX/INDEX
处理对象类型 TABLE_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
处理对象类型 TABLE_EXPORT/TABLE/CONSTRAINT/REF_CONSTRAINT
ORA-31693: 表数据对象 "XFF"."XML_TAB" 无法加载/卸载并且被跳过, 错误如下:
ORA-29913: 执行 ODCIEXTTABLEPOPULATE 调出时出错
ORA-22924: 快照太旧
已成功加载/卸载了主表 "SYS"."EXPDP_TBA1"
******************************************************************************
SYS.EXPDP_TBA1 的转储文件集为:
  D:\XML_TAB.DMP
作业 "SYS"."EXPDP_TBA1" 已经完成, 但是有 1 个错误 (于 星期六 2月 14 09:01:26 2026 elapsed 0 00:04:15 完成)

一般对于这些问题的解决思路是找出来异常的行的rowid,然后导出跳过异常行或者把对应的xml列置空,关键就是如何找出来该记录,这里自己写了一个plsql来找出来异常rowid

SQL> declare
  2  page number;
  3  len number;
  4  c varchar2(10);
  5  charpp number := 8132/2;
  6  n number;
  7  v_sqlerrm varchar2(100);
  8  begin
  9  n := 0;
 10  for r in (select rowid rid from XFF.XML_TAB order by rowid) loop
 11  begin
 12  select dbms_lob.getlength (xmltype.getclobval(XML_COL)) into c from XFF.XML_TAB     where rowid = r.rid;
 13  v_sqlerrm := SQLERRM;
 14  insert into result values (n, r.rid, 'good', page, v_sqlerrm);
 15  commit;
 16  exception
 17  when others then
 18  dbms_output.put_line ('Error on rowid ' ||r.rid||' page '||page);
 19  dbms_output.put_line (sqlerrm);
 20  v_sqlerrm := SQLERRM;
 21  insert into result values (n, r.rid, 'bad',page,v_sqlerrm);
 22  commit;
 23  end;
 24  end loop;
 25  end;
 26  /
Error on rowid AAASO1AAKAAAH5bAAC page
ORA-22924: 快照太旧
ORA-06512: 在 "SYS.XMLTYPE", line 138
Error on rowid AAASO1AAKAAAIPtAAZ page
ORA-22924: 快照太旧
ORA-06512: 在 "SYS.XMLTYPE", line 138
Error on rowid AAASO1AAKAAAIRfAAU page
ORA-22924: 快照太旧
ORA-06512: 在 "SYS.XMLTYPE", line 138
Error on rowid AAASO1AAKAAAIS9AAW page
ORA-22924: 快照太旧
ORA-06512: 在 "SYS.XMLTYPE", line 138
Error on rowid AAASO1AAKAAAIT7AAW page
ORA-22924: 快照太旧
ORA-06512: 在 "SYS.XMLTYPE", line 138
Error on rowid AAASO1AAKAAAIT/AAG page
ORA-22924: 快照太旧
ORA-06512: 在 "SYS.XMLTYPE", line 138

PL/SQL 过程已成功完成。

然后expdp导出数据跳过这些异常的rowid的par文件

directory=expdp_dir
dumpfile=expdp_XFF.XML_TAB.dmp
logfile=expdp_XFF.XML_TAB.log
tables=XFF.XML_TAB
query="XFF.XML_TAB:WHERE rowid not IN  ('AAASO1AAKAAAH5bAAC','AAASO1AAKAAAIPtAAZ','AAASO1AAKAAAIT7AAW',
'AAASO1AAKAAAIT/AAG', 'AAASO1AAKAAAIRfAAU','AAASO1AAKAAAIS9AAW')"
job_name=exp_1

数据可以正常到导出
expdp


也可以通过update语句直接把异常的xml值直接置空

update XFF.XML_TAB
set XML_COL = XMLType.createXML('')
where rowid in (select checked_rowid from result where status='bad');
发表在 逻辑备份/恢复 | 标签为 | 留下评论