DBRescue
PostgreSQL 数据文件表记录提取
本文演示从 PostgreSQL 关系文件提取表记录。需要对应的 schema.tsv;保留完整 PostgreSQL 15 PGDATA 时,也可以由工具读取系统目录辅助识别结构。
恢复原理与模式
工具按关系文件的 heap 页解析记录。启用校验时,结合分段编号和每段页数核对页面;解码结果保留 xmin、xmax 和可见性信息,不代表事务已确认。
本文使用“数据文件提取”。WAL 路线输出分析材料,不应当作已恢复的业务行或已经执行的回滚。
恢复准备
练习包包含 input/base/5/16384 和 input/schema.tsv,根目录有基准和比对脚本。本次没有分发完整 PGDATA,按 schema.tsv 路线操作。自己的文件要保留关系文件与分段对应关系,确认校验和分段设置,结果另存。
不能用另一个库的系统目录或样本 schema.tsv 替代。目录不全、版本不匹配,或无法确认分段和校验设置时先停止。本文的 0 / 131072 只用于已经确认的标准首段样本。
自己的文件,参数从哪里找
下面是只读查询,在数据库客户端执行,不是在 DBRescue 中执行。原库还能正常查询时,请 DBA 导出这些资料;原库已经故障,就使用匹配、可启动的副本,不要为了查参数强行启动故障原库。
在关系文件所属的数据库执行。把 public.sample 换成实际 schema 和表名;文件名 16384 不能直接当作表名。
1SELECT version(), current_database(), current_user;2SHOW data_checksums;3SHOW block_size;4SHOW segment_size;5SELECT pg_relation_filepath('public.sample'::regclass);6SELECT a.attnum, a.attname, t.typname, a.attisdropped FROM pg_attribute a LEFT JOIN pg_type t ON t.oid=a.atttypid WHERE a.attrelid='public.sample'::regclass AND a.attnum>0 ORDER BY a.attnum;pg_relation_filepath 返回关系文件路径。保留同一关系的分段;.1、.2 是后续段,不是另外两张表。data_checksums 决定是否启用页校验,block_size、segment_size 用来核对分段参数。 列清单按 attnum 排序,typname 是本次 int4、text、int2、int8、bool、timestamp 的来源。attisdropped 出现 t 时不能简单跳过后继续照抄结构,要先确认物理布局。查询结果本身不是 schema.tsv,工具需要的结构文件只有按实际顺序排列的字段名、TAB、支持的类型。 本例实际查询为 on、8192、1GB,对应工具的校验版本 1、每段 131072 页;首段编号 0,.1 是编号 1。其他文件按实际查询和分段确认,不能照抄。
下载参数核对 SQL只有孤立关系文件,又没有结构、分段和校验资料时,先收集资料。完整 PGDATA 也必须与关系文件来自同库、匹配版本,不能借用其他实例的目录。
本次测试结果
本次使用 PostgreSQL 15.19 的关系文件 base/5/16384。4096 行、6 列与 SQL 基准逐值一致,源文件未改变,页面校验通过。桌面显示 review-required,事务可见性仍未知。
使用正常关闭后的真实数据库文件和虚构测试数据,桌面为开发构建、测试授权。未制造文件损坏;隔离导入是否通过,见下方各库的实测记录,不据此推算故障库恢复率。
恢复操作实战
下面是本次桌面工具的实际操作。点击标题展开,按顺序选择文件、填写参数,再检查结果。
PostgreSQL 15 关系文件提取实战
演示:Windows 桌面开发构建、PostgreSQL 15.19 采集文件、测试授权;本次使用 schema.tsv 路线。
1. 安装工具并激活
- 安装对应系统的工具,激活 PostgreSQL 或全库授权。
- 确认引擎就绪,在新建任务中选择 PostgreSQL。
- 模式选择“数据文件提取”。
2. 选择输入和输出
- 点击“文件”,选择本次关系文件 base/5/16384。自己的文件要先确认对应关系及分段,不要只看文件名猜测表。
- 选择独立空输出目录,不要放在 PGDATA 内。
- 可以检查源文件,但这一步不证明记录已成功解析。
3. 填写参数
- 展开高级参数,选择本次 schema.tsv。单关系文件模式不用填写用户名和表名。
- 如使用匹配的 PostgreSQL 15 完整 PGDATA,元数据栏应选择目录,而不是随意选一个系统文件。
- 本次原库启用校验,选择“已开启(版本 1)”;首段编号 0,每段页数 131072。这些值已经由本次采集设置确认,其他文件不能照抄。

4. 执行提取
- 核对关系文件、结构、校验版本、分段编号和输出目录后,点击开始恢复。
- 等待任务结束,看日志是否出现校验错误或解析失败。
- 本次导出 4096 行,状态为 review-required,仍需复核事务可见性。
5. 查看导出记录
- 点击“查看表数据”,选择 decoded_rows.tsv。
- 本次核对 id、name、small、big、active、stamp 六列;另外保留 block、item、xmin、xmax 和 checksum_status。
- 打开结果目录保留 decoded_rows.tsv、SQL 注释、定位和任务日志;目录模式要逐一查看文件子结果。

6. 恢复后检查
- 本次 4096 行、6 列与 SQL 查询基准逐值比对通过,源文件哈希一致。
- NULL 与空字符串不能混为一项,日期、布尔值和大整数不要让电子表格自动转换后再比。
- 页面校验通过不等于事务已提交。自己的数据仍需核对 xmin/xmax、可见性、缺失和业务关联。
使用本文练习包时,完整解压,保留根目录的 Check-Sample.ps1、baseline.json 和 settings.json。打开解压目录,在资源管理器地址栏输入 powershell,执行下面两行,按提示粘贴本次导出 TSV 的完整路径(去掉路径两端引号)。脚本仅适用于本文样本,不修改文件。
1$resultFile = Read-Host 'Exported TSV full path'2.\Check-Sample.ps1 -ResultFile $resultFile本次实际输出:PASS: 4096 rows; 6 columns match. Transaction state is not established. 只证明样本字段一致,不证明事务或业务恢复。脚本受系统策略阻止时,请使用获准的执行环境,不关闭安全策略。
导入测试库,再核对一次
又在 ESXi 实验机上初始化了一套独立的 PostgreSQL 15.19 实例,导入这次提取的 4096 行。按 int4、text、int2、int8、bool、timestamp 建表,查询结果与原库基准逐字段一致,包含 245 个 NULL,ID 没有重复。临时实例验收后已停止。
- 先连接独立的 PostgreSQL 测试环境,创建并连接一个空数据库,编码使用 UTF8。不要在原业务库执行。
- 下载下方 SQL,打开后确认目标是本例的 sample 表,再执行完整脚本。表已存在就换一个空测试库,不要覆盖原表。
- 查询总行数和去重 ID,再按练习包 baseline.json 核对全部字段。布尔值、大整数和微秒时间都要保留,不能先交给电子表格自动转换。
1SELECT COUNT(*) AS rows_total, COUNT(DISTINCT id) AS distinct_ids2FROM sample;在数据库客户端里,具体怎么执行
下面使用数据库自带的命令行客户端,不是在 DBRescue 任务窗口输入命令。先安装对应客户端,让管理员准备空的隔离测试环境和账号。把练习 SQL 放到 C:/recovery-practice;路径不同就替换下面的路径。
以下是连接模板:TEST_HOST 是测试服务器地址,TEST_PORT 是实际端口,TEST_USER 是测试账号,TEST_DATABASE 是管理员给出的空测试库,Oracle 的 TEST_SERVICE 是服务名。必须替换这些字样;密码在客户端提示时输入,不写进脚本。命令找不到时,进入客户端 bin 目录再执行。
1. 先确认连接位置
1psql --host=TEST_HOST --port=TEST_PORT --username=TEST_USER --dbname=TEST_DATABASE --set=ON_ERROR_STOP=1登录后输入 \conninfo,确认当前数据库、用户和连接地址。下面的 \i 在 psql 提示符中执行,不是在 PowerShell 中执行。
2. 再执行练习脚本
确认当前测试库为空,打开并检查脚本后,用 \i 读取整个文件;路径有空格时保留引号。
1\i 'C:/recovery-practice/import-sample.sql'执行中出现报错就停止,保留第一条错误和完整输出,不要反复重跑 INSERT。成功后在同一目标库执行上面的计数查询,再按 ID 对齐逐字段核对。只有两个计数都为 4096 还不能作为完整验收。
文件执行方式已在 ESXi 的原生客户端验证:MySQL SOURCE、psql 的 \i、sqlcmd -i、SQL*Plus 与 DIsql 的 @。连接地址、账号和 Windows 路径是需要替换的模板;本节没有把命令行记录当成图形客户端截图。
本例的总行数和去重后的 ID 数均为 4096。行数相同还不够,本次另外逐字段比对了全部记录;中文、NULL、数字和日期也要一起核对。
这里验证的是样本记录能否按指定类型写回测试库。decoded_rows.sql 仍是工具生成的核对用注释,下方下载文件是针对本例另外准备的导入脚本,不是工具已支持任意表自动回灌。xmin、xmax 和事务可见性还要另行判断。
遇到问题时
缺少结构或元数据
schema.tsv 不匹配时先核对列顺序、类型和原表定义。PGDATA 目录缺失或不是同一套文件时,不能强行套用目录识别结果。
没有提取出记录
先查关系文件、分段号、每段页数及 checksum 设置。出现校验错误不要关闭校验来绕过,应保留原副本和日志调查。
显示部分完成或需要复核
目录任务要看每个文件的状态,不能只看总行数。失败文件、过滤未匹配和需要复核的项都要列出;review-required 不表示事务可见性已确认。
本例已在独立 PostgreSQL 实例完成类型导入和逐值比对。工具 SQL 仍为核对用注释;事务可见性和生产业务回补没有因此获得验证。
解析细节和导出文件
按数据库与关系文件定位
通过 database OID 与 relfilenode 定位数据,可从数据目录或指定关系文件开始。
DDL 转为提取所需字段信息
将建表语句转换为 schema.tsv,并记录 relations.tsv,保留表结构与文件对应关系。
批量分析 WAL,保留事件与审查计划
单文件或目录模式保留事件记录;回滚输出是审查脚手架,不等同于可直接执行的完整恢复脚本。
失败位置能回查到具体文件
批量结果之外保留逐文件输出和错误日志,便于区分已处理文件、失败文件与待补充的结构信息。
- result.sql
- 数据提取模式的 SQL;日志模式可能只提供审查脚手架
- result.tsv
- 提取的行或日志事件清单
- schema.tsv
- 由 DDL 生成的字段与类型信息
- relations.tsv
- 关系文件定位清单
- pg_wal_rollback_plan.sql
- WAL 回滚审查计划
查看命令行示例
1dbrescue extract --db pg --path /recovery/data --user app --table public.orders --out-dir /recovery/output