跳到主要内容
数据恢复
返回数据恢复DBRescue · SQL Server

DBRescue 使用说明

SQL Server MDF 表数据恢复

本文介绍使用 DBRescue 提取 SQL Server MDF 表数据的方法。准备好 MDF 文件、表结构和数据页参数,选择文件后即可执行。恢复结果另存,不修改原文件。

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

恢复原理

SQL Server 的表记录保存在数据页中。DBRescue 直接读取 MDF,通过指定的分配单元定位目标记录,再按 schema.tsv 中的列顺序和类型解析字段,整个过程无需启动原数据库。

当前支持单个 MDF 中的未压缩记录,可提取整数、字符、二进制、decimal、datetime2 等字段。数据导出为 TSV,保留对应页号、槽号和校验状态。decoded_rows.sql 为核对用的注释内容,不包含可直接执行的 INSERT。

文件在本地处理,结果写入独立目录,不修改源 MDF,不写回数据库。当前不支持 LDF 日志恢复及误删回滚。

恢复准备

执行前准备以下文件和参数。建议先复制 MDF,使用副本操作:

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

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

先连接 MDF 对应的原数据库或匹配的可查询副本,把 dbo.sample 换成真实目标表。以下查询需要读取相应系统目录的权限。

SQL

1SET NOCOUNT ON;
2SELECT @@VERSION AS version, DB_NAME() AS current_database;
3SELECT name,page_verify_option_desc FROM sys.databases WHERE database_id=DB_ID();
4SELECT c.column_id,c.name,t.name AS type_name,c.max_length,c.precision,c.scale FROM sys.columns c JOIN sys.types t ON c.user_type_id=t.user_type_id WHERE c.object_id=OBJECT_ID(N'dbo.sample') ORDER BY c.column_id;
5SELECT p.index_id,p.partition_number,a.type_desc,a.allocation_unit_id FROM sys.partitions p JOIN sys.allocation_units a ON a.container_id=p.hobt_id WHERE p.object_id=OBJECT_ID(N'dbo.sample') AND a.type=1;

page_verify_option_desc 是原库的页校验设置。列清单给出顺序、类型、长度、精度和小数位,不能只抄列名。 allocation_unit_id 清单用于让 DBA 核对目标索引和分区。它、OBJECT_ID()、普通 index_id 都不能直接填进工具的 Object / Index 字段;工具这里要求页分配组件值。本例 222 / 256 只对样本有效,自己的页组件仍须结合目标数据页确认。

下载参数核对 SQL

没有结构或页组件资料时,先把 MDF 副本、版本、表设计、索引和分区资料交给 DBA 核对。不要把页校验改成 NONE 来绕过失败,也不要猜两个数字继续。

恢复准备
文件 / 参数说明
MDF 副本不再被数据库写入的 MDF 文件副本,另建一个空目录存放恢复结果。
schema.tsv对应表的结构文件,列顺序、类型须与实际记录布局一致。Excel 或重命名后的 SQL 文件不能代替。
Object / Index目标数据页的分配单元组件,不是普通 OBJECT_ID 或索引编号。本文测试值仅用于随包 MDF。
PAGE_VERIFY填写原库的 CHECKSUM、TORN_PAGE_DETECTION 或 NONE 设置。不清楚时先确认,不要随意选择 NONE。

只有 MDF、没有结构和页参数,当前无法执行这条恢复流程。压缩、加密、多文件及复杂类型需要另行确认,购买前请先联系。

测试环境与恢复结果

演示环境为 SQL Server 2022(16.0.4305.5)。测试库正常分离后,保留 MDF 和原库查询结果,在 Windows 桌面开发构建中使用测试授权执行恢复。表中共 4096 行、8 个字段。

恢复后将 TSV 与原库结果逐字段比对,4096 行一致,27 个目标数据页校验通过,源 MDF 的 SHA-256 未变。随后在独立 SQL Server 容器中按 8 列类型导入,再查询比对也通过。本次未模拟损坏,记录的事务状态仍需核对。

恢复实战

测试文件已打包,可以先下载跟着操作一遍,无需安装 SQL Server。点击下方标题展开,包含安装、选文件、填参数及恢复后检查。

SQL Server MDF 表数据恢复实战

SQL Server · 桌面工具操作实战

本文演示使用 DBRescue,从 SQL Server MDF 文件中提取表数据的过程。使用一份包含 4096 行数据的测试文件,恢复完成后,与原库查询结果逐字段比对。工具不修改源文件,恢复结果单独保存。

本次演练环境与适用范围

演示时间:2026 年 10 月 16 日。SQL Server 版本为 16.0.4305.5,数据库正常分离后采集 MDF。截图使用 Windows 桌面开发构建和测试授权,没有进行真实购买、生产授权签发及数据回灌。本次验证的是正常分离文件的记录提取,不是损坏文件恢复率。

下载工具和本文测试文件

本文测试文件已打包,包含 MDF、表结构、页参数和参考数据。下载解压后即可跟着操作,不需要安装 SQL Server。 正式提取需要 SQL Server 或全库授权,测试包不包含授权码。已有会员权益的用户先领取授权,无需重复购买。 使用自己的 MDF 时,表结构和参数都要重新准备,不能套用本文的 222 / 256。材料不齐先确认是否适用,再购买授权。

下载 DBRescue下载本文测试文件(约 560 KB)
演示环境信息
操作环境
Windows x64 · DBRescue 桌面开发构建(测试授权)
恢复文件
单个 MDF 副本 + 对应表的原生 schema.tsv
恢复方式
指定数据页分配单元,提取目标表记录
样本结果
4,096 行;任务状态 completed

1恢复准备

  1. 下载 practice.zip,右键选择“全部解压缩”。
  2. 打开解压目录,确认 input 下有 MDF、schema.tsv 和 baseline.json;根目录有 sample-settings.json 和三个 ps1 脚本。
  3. 在 input 同级目录下新建 output 文件夹,恢复结果放在这里。脚本与 input 保持原有位置,不要单独挪走。

baseline.json 是原库查询结果,供恢复后比对,不用选进工具。MDF 不需要附加到 SQL Server,直接选择文件即可。使用自己的文件时,要保留副本,并确认文件不再被数据库写入。

测试包需要完整解压。output 由你新建,三个脚本放在根目录:

1input/
2 recovery-sample.mdf
3 schema.tsv
4 baseline.json
5sample-settings.json
6Check-Recovery.ps1
7Verify-Sample.ps1
8Inspect-Sample.ps1
9output/ (create this empty folder)

2打开工具

  1. 下载当前电脑系统对应的 DBRescue 安装包,安装后打开。
  2. 在授权区域填入 SQL Server 或全库授权码,点击激活,确认授权有效。本文使用测试授权,不提供授权码。离线电脑使用工具中的离线请求、响应流程。
  3. 找到“新建恢复任务”,数据库类型选择 SQL Server,恢复模式选择“数据文件提取”。

界面版本不同时,入口文案可能略有区别。开始前确认引擎已就绪。购买前预览只能用于检查记录,不能代替完整导出。

3选择 MDF 文件

  1. 点击“源文件或目录”右侧的“文件”,选择 input 目录下的 recovery-sample.mdf。这里不选目录,也不选 LDF。
  2. 点击“输出目录”右侧的“选择”,选中刚建好的 output 文件夹。
  3. 需要检查文件读取情况,可以点击“检查源文件”。检查完成后,继续配置下面的参数。

源路径结尾应为 recovery-sample.mdf,输出路径应为 output。输出目录不能放在 input 里面,也不能放在程序或配置目录内。

4填写恢复参数

  1. 展开“用户、表与高级参数”。
  2. 点击“对应表的 schema.tsv(必选)”右侧的“文件”,选择 input/schema.tsv。
  3. “原数据库的 PAGE_VERIFY 设置”选择 CHECKSUM。
  4. “数据页分配单元 Object 组件”填写 222,“数据页分配单元 Index 组件”填写 256。
  5. 并发数保持 1,用户名和表名不用填写。参数填写完成后如下图:

这两个数字来自本次样本的页分配单元信息,不是普通 OBJECT_ID 或索引编号,只适用于本文 MDF。schema.tsv 中列名与类型以制表符分隔,练习时直接选择随包文件即可。

这几个参数从哪里来

本文的 222 / 256 和 CHECKSUM 来自测试文件的采集记录,已经写入解压目录下的 sample-settings.json。可以用记事本直接打开,也可以在 PowerShell 执行下面两行。输入解压目录的完整路径,不要输入 input 子目录。

POWERSHELL

1$practiceFolder = Read-Host 'Extracted practice folder'
2Get-Content -LiteralPath (Join-Path $practiceFolder 'sample-settings.json') -Raw -Encoding UTF8

找到 allocationUnitObjectComponent、allocationUnitIndexComponent、pageVerify,分别对应界面的 Object、Index 和 PAGE_VERIFY。这里只说明测试包的参数来源,不代表工具能自动识别其他 MDF 的表名和参数。

查看样本结构文件内容

1id int
2name varchar(100)
3small smallint
4big bigint
5active bit
6tiny tinyint
7code char(3)
8payload varbinary(4)
选择文件并填写恢复参数,点击开始恢复。
选择文件并填写恢复参数,点击开始恢复。 点击图片可查看原图。

5执行恢复

  1. 确认 MDF、schema.tsv、输出目录都已选好,校验方式为 CHECKSUM,Object / Index 为 222 / 256。
  2. 点击“开始恢复”,等待任务结束,运行中不要更换输入文件。
  3. 本次任务状态为 completed。日志显示 decoded_rows 为 4096、data_pages 为 27、skipped_slots 为 0,即读取 27 个目标数据页,提取 4096 行记录。

任务失败时先看日志,不要反复提交,也不要随意切换成 NONE。日志中的 TRANSACTION_STATE_UNKNOWN 表示事务状态未知,提取完成不等于记录都已提交。

6查看恢复数据

  1. 恢复完成后,点击“查看表数据”。
  2. 结果文件选择 decoded_rows.tsv,查看恢复出的字段和值。本次中文、表情、整数和空值均可在预览中看到,如下图:
  3. 点击“打开结果目录”,可以看到 decoded_rows.tsv、decoded_rows.sql、slot_locator.tsv 和 desktop-engine.log 等文件。

本次界面只预览前 50 行,完整数据在 TSV 文件中。decoded_rows.sql 是供核对的注释内容,不包含可直接执行的 INSERT,不能拿它直接回灌业务库。

打开 decoded_rows.tsv,查看本次恢复出的记录。
打开 decoded_rows.tsv,查看本次恢复出的记录。 点击图片可查看原图。

7数据比对

  1. 点击“打开结果目录”,找到这次生成的 decoded_rows.tsv。检查脚本已经放进测试包,参考数据会自动从 input/baseline.json 读取,不需要手动选择。

随后又在独立 SQL Server 容器中执行了本例的类型导入,逐字段核对通过,具体操作见下方“导入测试库”。没有向原业务库回补。

  1. 打开解压后的测试包目录,确认能看到 Check-Recovery.ps1 和 input 文件夹。
  2. 点击资源管理器的地址栏,输入 powershell,按回车,在当前目录打开 PowerShell。
  3. 执行下面这一行。弹出文件选择窗口后,进入本次任务的结果目录,选择 decoded_rows.tsv,点击打开。
  4. 脚本先比对 4096 行、8 个字段,再统计重复 ID、页面校验和事务状态。关闭选择窗口即可取消,不修改任何文件。
POWERSHELL

1.\Check-Recovery.ps1

下面是本次实际运行输出。第一行出现 PASS 才表示与本文样本基准一致;系统策略不允许执行时,不要关闭安全策略,请检查脚本并使用获准的环境。

1PASS: 4096 rows; 8 columns match the supplied baseline.
2Rows: 4096
3Duplicate ID groups: 0
4Page checks:
5VERIFIED_PAGE_CHECKSUM: 4096
6Transaction states:
7TRANSACTION_STATE_UNKNOWN: 4096

4096 行都带有 VERIFIED_PAGE_CHECKSUM,重复 ID 为 0,但事务状态全部是 TRANSACTION_STATE_UNKNOWN。这表示页面校验通过,不能据此认定记录都已提交。该脚本按练习表的 id 检查重复,不能直接用于任意业务表。

先保留 MDF 副本、结构文件、任务日志和原始导出。下节继续验证样本在独立 SQL Server 中的导入;生产回补仍要确认事务、目标表结构、重复记录和业务关联。

导入测试库,再核对一次

SQL Server 也做了实际导入:在 ESXi 实验机的新容器中,按 8 列原类型建表并写入导出的 4096 行。按数字 ID 对齐后,全部字段与原库基准一致,包含中文、表情、二进制和 1584 个 NULL。容器没有外部网络,验收后已停止。

  1. 连接独立的 SQL Server 测试环境。下载下方 SQL,先确认它创建的是 guide_lab_107603c85c 测试库,不能把目标改成原业务库。
  2. 打开并执行完整脚本。脚本包含本例的建表和 4096 行虚构数据;目标库已存在时就停止,换一套空测试环境,不要直接 DROP。
  3. 待测试库状态为 ONLINE 后再查询,核对下方两个计数。还要按数值 ID 对齐,逐字段与练习包 baseline.json 比对,不能只比较两份查询的显示顺序。

下载本例导入 SQL(仅供练习)

SQL

1USE guide_lab_107603c85c;
2SELECT COUNT(*) AS rows_total, COUNT(DISTINCT id) AS distinct_ids
3FROM dbo.sample;
在数据库客户端里,具体怎么执行

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

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

1. 先确认连接位置

1sqlcmd -S tcp:TEST_HOST,TEST_PORT -U TEST_USER -d master -b -Q "SELECT @@SERVERNAME AS server_name, DB_NAME() AS current_database;"

这条命令只打印服务器和当前库,不导入数据。确认服务器是隔离测试环境。证书或权限报错时先让管理员解决,不要跳过身份确认。

2. 再执行练习脚本

回到 PowerShell,使用同一套服务器和账号执行下面的 -i 命令。脚本会新建 guide_lab_107603c85c,不能把它改成业务库名。随后连接该库,等状态为 ONLINE 再核对数据。

1sqlcmd -S tcp:TEST_HOST,TEST_PORT -U TEST_USER -d master -b -f 65001 -i "C:\recovery-practice\import-sample.sql"

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

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

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

页校验通过不等于事务已提交。恢复结果仍保留 TRANSACTION_STATE_UNKNOWN,测试库可以读出数据也不代表可以覆盖原业务表。

换成自己的 MDF 时

表结构、页参数和校验设置都要重新确认,不能沿用测试包里的值。

  • MDF 文件副本
  • 对应表的 schema.tsv
  • 目标页的 Object / Index 组件
  • 原库 PAGE_VERIFY 设置
只有 MDF,其他信息没有怎么办?

本文的 schema.tsv 和 222 / 256 只适用于测试文件,不能用于其他 MDF。

schema.tsv 中的列顺序、类型要与目标表实际记录布局一致。可以使用建表 SQL 或表设计资料核对,但当前工具不能自动把任意建表 SQL 转成结构文件。

Object / Index 填写目标数据页的分配单元组件,不是普通 OBJECT_ID 或索引编号。PAGE_VERIFY 按原库设置填写。

只有 MDF、没有上述信息时,目前不能直接开始恢复。先准备数据库版本、故障经过、文件清单和表结构资料,找熟悉 SQL Server 页结构的 DBA 确认。

导出后,按自己的业务数据检查缺失、重复、事务状态和关联关系。本文没有进行数据回灌,测试比对通过也不代表业务库可以直接上线。

常见问题

开始恢复按钮不可用

检查运行环境/引擎是否就绪、授权是否有效、是否仍有任务运行。再核对源文件和输出目录是否已选。缺少结构文件、页组件或校验方式时,提交也会被拒绝。

提示结构文件无效或格式不支持

练习时重新选 input/schema.tsv,不要选 JSON、Excel 或重命名的 SQL。自己的表不能套练习结构;先核对真实列顺序、类型及工具支持范围。

任务失败或没有读出记录

先保留日志。练习时核对 MDF、schema.tsv 是否来自同一个解压包,参数是否为 CHECKSUM / 222 / 256。不要为绕过错误而改成 NONE。自己的文件出现校验或布局错误,应停止并核查文件完整性和支持范围。

比对脚本报行数、重复 ID 或字段不一致

Row count mismatch:检查是否选中了旧任务或只有部分记录的预览文件。Value mismatch:检查字段值、结构或文件是否被修改。Duplicate id:发现重复 ID,保留导出文件和日志。以上任一错误都不能按验证通过处理。

本次恢复结果

本次重新恢复后的检查结果如下:

1database: mssql
2taskStatus: completed
3rows: 4096
4columns: 8
5dataPagesChecksumVerified: 27
6sourceUnchanged: true
7transactionVisibility: unknown
8sqlExecution: comment-only

4096 行、8 个字段逐值一致,27 个目标数据页校验通过,MDF 恢复前后的 SHA-256 一致。关闭工具重新打开,任务和结果预览仍可查看。以上均为测试授权下的提取验证。

解析细节和导出文件

读取 MDF 数据页

按数据页分配单元读取未压缩记录,使用提供的表结构解析列值。输出中保留页校验结果及事务状态,便于检查异常记录。

查看导出文件

TSV 保存字段值,slot_locator.tsv 保存记录位置,SQL 文件保存供核对的注释。任务结束后检查日志及导出文件,不自动写回数据库。

decoded_rows.tsv
解码后的列值、页校验结果与事务状态
decoded_rows.sql
供人工核对的 SQL 注释,不自动执行
slot_locator.tsv
每条记录的页号、槽号与原始位置
RECOVERY_COMMITTED
本次输出已完成写入的标记
查看命令行示例
Bash

1mssql-rescue mdf dump-table --file /recovery/database.mdf --schema /recovery/schema.tsv --object-id <allocation-object-component> --index-id <allocation-index-component> --page-verify checksum --out-dir /recovery/output --json

缺少表结构或页参数时,先准备数据库版本、故障经过和文件清单,联系确认后再购买。

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