跳到主要内容
数据恢复

DBRescue

Oracle DBF 表数据提取

本文使用 DBRescue 从 DBF 中提取指定表的数据。保留数据文件和同库 SYSTEM 文件,通过用户名、表名定位目标记录,提取结果写入独立目录。

下载工具查看授权Windows / Linux / macOS

恢复原理与模式

工具读取数据块和对应字典信息,再定位、解析指定表的记录,不要求原数据库实例启动。本文验证普通 DBF 路线,不能据此推断任意 ASM、压缩或损坏场景都能恢复。

DBF 数据提取与 redo 分析是两条路线。本文演示 DBF;redo 中发现对象或事件线索不等于恢复业务行,也不自动执行回滚。

恢复准备

准备同一数据库、匹配时间点的数据文件副本和 SYSTEM 数据文件,确认目标 OWNER.TABLE。需要其他数据文件时一并保留,不要在原文件上试错。另建空输出目录。

SYSTEM 必须与目标数据文件对应,不能借用其他库的 SYSTEM。用户名和表名可以从原有 DDL、运维记录或可靠数据字典记录确认;没有这些资料时,不能靠试填名称宣称找到了目标表。

自己的文件,参数从哪里找

下面是只读查询,在数据库客户端执行,不是在 DBRescue 中执行。原库还能正常查询时,请 DBA 导出这些资料;原库已经故障,就使用匹配、可启动的副本,不要为了查参数强行启动故障原库。

由有相应查询权限的 DBA 执行。RECOVERY_SAMPLE 和 SAMPLE 要换成真实 OWNER、表名,大小写按字典记录填写。

SQL

1SELECT SYS_CONTEXT('USERENV','DB_NAME') AS DB_NAME,SYS_CONTEXT('USERENV','CURRENT_SCHEMA') AS CURRENT_SCHEMA FROM DUAL;
2SELECT VALUE FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER='NLS_CHARACTERSET';
3SELECT OWNER,TABLE_NAME FROM ALL_TABLES WHERE OWNER='RECOVERY_SAMPLE' AND TABLE_NAME='SAMPLE';
4SELECT FILE#,NAME FROM V$DATAFILE;
5SELECT COLUMN_ID,COLUMN_NAME,DATA_TYPE,DATA_LENGTH,DATA_PRECISION,DATA_SCALE FROM ALL_TAB_COLUMNS WHERE OWNER='RECOVERY_SAMPLE' AND TABLE_NAME='SAMPLE' ORDER BY COLUMN_ID;

表清单确认 OWNER.TABLE,列清单用于核对结构。V$DATAFILE 给出本库数据文件路径,从中确认 SYSTEM 文件所在位置。应由管理员制作匹配时间点的副本,不能直接复制正在写入的文件当作一致备份。 字符集查询用于核对导出文字。路径相同不等于文件一定匹配,还要核对来源实例、备份时间和文件清单。

下载参数核对 SQL

没有同库 SYSTEM 或无法确认 OWNER.TABLE 时先停止。优先找已有备份、DDL 和运维记录;不要下载别人的 SYSTEM 文件,也不要猜用户名反复试。

本次测试结果

本次采集自 Oracle 19.3.0.0.0,目标 RECOVERY_SAMPLE.SAMPLE。重新提取 4096 行、4 列,与保留 NULL 的 SQL 基准比对通过,源文件哈希未变。桌面任务完成且重启后仍能查看。

使用正常关闭后的真实数据库文件和虚构测试数据,桌面为开发构建、测试授权。未制造文件损坏;隔离导入是否通过,见下方各库的实测记录,不据此推算故障库恢复率。

恢复操作实战

下面是本次桌面工具的实际操作。点击标题展开,按顺序选择文件、填写参数,再检查结果。

Oracle 19c 指定表 DBF 提取实战

演示:Windows 桌面开发构建,Oracle 19.3.0.0.0 的 sample.dbf / system01.dbf,测试授权。

1. 安装工具并激活

  1. 安装工具,激活 Oracle 或全库授权,确认运行引擎就绪。
  2. 新建恢复任务选择 Oracle。
  3. 恢复模式选择“数据文件提取”,不要进入 redo 分析。

2. 选择输入和输出

  1. 点击源文件旁的“文件”,选择 sample.dbf。
  2. 选择独立空输出目录;自己的数据文件仍应使用副本。
  3. 单文件演示只对本次目标表负责,跨文件数据应按工具支持的对应路线处理,不能只选一个 DBF 就认为整表齐全。

3. 填写参数

  1. 展开高级参数,在“对应数据库的 SYSTEM 数据文件(必选)”选择 system01.dbf,不要把 sample.dbf 选到这里。
  2. “用户 / 数据库”填写 RECOVERY_SAMPLE,“表名”填写 SAMPLE。自己的文件改为真实 OWNER 和表名。
  3. 并发数保持 1,核对文件属于同一数据库后开始。
本次实跑:Oracle 19c 指定表 DBF 提取实战参数。
本次实跑:Oracle 19c 指定表 DBF 提取实战参数。 点击图片查看原图。

4. 执行提取

  1. 点击“开始恢复”,等待任务结束并查看日志。
  2. 本次目标表提取完成;原生检查按 insert.sql 与原库 SQL 基准逐字段比对,结果为 4096 行。
  3. 如果对象未找到或记录不完整,先检查 SYSTEM、OWNER、表名和数据文件范围,不要立即改一组名字重试。

5. 查看导出记录

  1. 打开结果目录,保留 insert.sql、table.rows.tsv、recovery_report.md 和相关定位清单。
  2. 点击“查看表数据”查看 TSV。table.rows.tsv 包含物理位置和解析信息,不是可以直接导入的平面业务表。
  3. 检查生成 SQL 中的目标 OWNER.TABLE、列列表、NULL、中文、金额和日期转换。不要直接在原库执行。
本次实跑:查看提取结果,不代表已完成回灌。
本次实跑:查看提取结果,不代表已完成回灌。 点击图片查看原图。

6. 恢复后检查

  1. 本次将 insert.sql 中 ID、NAME、AMOUNT、BORN 四列解析后与原库查询结果比对,4096 行一致,未出现缺失、额外、重复或不匹配记录。
  2. 自己的文件需使用自己的参考数据,并检查报告中不支持类型、行片段和异常块;不能只数 INSERT 条数。
  3. 生成 SQL 已在实验实例的独立 schema 中执行并核对,详见下一节;未向原业务库回补。

导入测试库,再核对一次

这次实际执行了生成的 insert.sql:只把目标 schema 改为 GUIDE_LAB_107603C85C,在原实验实例的新 schema 中导入。4096 行、4 列与保留 NULL 的原库基准逐值一致,ID 没有重复。不是另建了一套 Oracle 实例,也没有改原样本表。

  1. 先审查 insert.sql 的目标用户、表名、列清单、字符集和日期转换。本例字符集为 AL32UTF8,不能直接套到其他字符集。
  2. 由测试库管理员准备独立 schema 和空表。本次原样本表仍在,用空表复制结构后加 ID 主键;故障现场原表不可用时,要用备份 DDL 或确认过的结构建表,不能省略。
  3. 把 INSERT 的目标限定为新 schema 后执行,核对下方行数,再把查询结果逐字段与原库基准比对。本次已实际执行和比对,验收后关闭了测试实例。
SQL

1SELECT COUNT(*) AS rows_total, COUNT(DISTINCT ID) AS distinct_ids
2FROM GUIDE_LAB_107603C85C.SAMPLE;
在数据库客户端里,具体怎么执行

下面使用数据库自带的命令行客户端,不是在 DBRescue 任务窗口输入命令。先安装对应客户端,让管理员准备空的隔离测试环境和账号。把练习 SQL 放到 C:/recovery-practice;路径不同就替换下面的路径。

以下是连接模板:TEST_HOST 是测试服务器地址,TEST_PORT 是实际端口,TEST_USER 是测试账号,TEST_DATABASE 是管理员给出的空测试库,Oracle 的 TEST_SERVICE 是服务名。必须替换这些字样;密码在客户端提示时输入,不写进脚本。命令找不到时,进入客户端 bin 目录再执行。

1. 先确认连接位置

1sqlplus /nolog
2CONNECT TEST_USER@//TEST_HOST:TEST_PORT/TEST_SERVICE

由管理员提供可登录的测试账号、服务名及空目标表。不要在故障原库以 SYSDBA 身份照抄。连接后用 SHOW USER 核对账号,并查询 SYS_CONTEXT 确认数据库。本文验收 schema 是只供管理员操作的 NO AUTHENTICATION schema,不能直接用它登录。

2. 再执行练习脚本

这里使用工具导出的 insert.sql,不是其他数据库的练习 SQL。先确认其中的 OWNER.TABLE 已由管理员改为准备好的空测试表,列定义、字符集、日期转换已核对,再执行整个文件并提交。

1@C:/recovery-practice/insert.sql
2COMMIT;

执行中出现报错就停止,保留第一条错误和完整输出,不要反复重跑 INSERT。成功后在同一目标库执行上面的计数查询,再按 ID 对齐逐字段核对。只有两个计数都为 4096 还不能作为完整验收。

文件执行方式已在 ESXi 的原生客户端验证:MySQL SOURCE、psql 的 \i、sqlcmd -i、SQL*Plus 与 DIsql 的 @。连接地址、账号和 Windows 路径是需要替换的模板;本节没有把命令行记录当成图形客户端截图。

本例的总行数和去重后的 ID 数均为 4096。行数相同还不够,本次另外逐字段比对了全部记录;中文、NULL、数字和日期也要一起核对。

自己的数据没有原库基准时,至少要用业务留存记录核对字段、缺失、重复和关联关系。表结构或字符集不确定,应先找 DBA 确认;不能看到生成了 INSERT 就直接向原库执行。

遇到问题时

缺少结构或元数据

确认 SYSTEM 来自同一数据库,目标 OWNER / 表名来自可靠记录。缺少 SYSTEM 或字典无法匹配时先保留全部文件,不能用其他库的系统文件替代。

没有提取出记录

检查表是否位于所选数据文件、是否跨文件或含有当前不支持的组织方式。查看恢复报告和定位结果,不要把空结果当成表本来没有数据。

显示部分完成或需要复核

检查 recovery_report.md 和 datatype_warnings.tsv 等输出。存在未重建行片段、不支持类型或异常块时,先明确缺失范围,再决定后续处理。

本例 insert.sql 已导入实验实例的独立 schema 并逐值比对通过。未执行生产回补,自己的结构、字符集、缺失和业务关联仍须确认。

解析细节和导出文件

扫描 ASM 磁盘头

识别磁盘组、磁盘编号、AU 大小,以及主副磁盘头状态,先确认文件所在的存储布局。

从 ASM 映射重组数据文件

扫描字典候选与原生分配表;按文件号和磁盘组筛选映射,再拼出目标 DBF。

有 SYSTEM 或只有 DDL,都有提取路径

保留 SYSTEM 时按字典定位用户表;缺少 SYSTEM 时可提供 DDL,配合对象号、块范围和内容筛选提取目标表。

把 redo / archivelog 变成可查证的线索

输出日志序列、SCN 区间、时间范围、日志头与 DDL 命中位置。当前不是把任意 redo 自动还原为完整业务表。

result.sql
数据提取模式的 SQL;日志模式可能只提供审查脚手架
result.tsv
提取的行或日志事件清单
asm_file.map
ASM 文件与 extent / AU 的定位映射
redo_inventory.tsv
日志序列、SCN、时间范围与头信息
redo_ddl_hits.tsv
DDL 关键词、对象线索与命中偏移
查看命令行示例
Bash

1dbrescue extract --db oracle --path /recovery/asm_disks.txt --user APP --table ORDERS --metadata /recovery/metadata --out-dir /recovery/output

SYSTEM 必须与目标数据文件对应,不能借用其他库的 SYSTEM。用户名和表名可以从原有 DDL、运维记录或可靠数据字典记录确认;没有这些资料时,不能靠试填名称宣称找到了目标表。

数据库恢复服务
Oracle 数据恢复工具 — 能力与使用说明 | ORA100