注册
【开源分享】dmdul:达梦数据库离线恢复与数据抽取工具
专栏/技术分享/ 文章详情 /

【开源分享】dmdul:达梦数据库离线恢复与数据抽取工具

孙莹 2026/08/21 758 1 0
摘要

本文已更新至 dmdul v0.8.0。新版补充了 DMASM 多数据库自动发现、两阶段离线坏页诊断,以及 DM8 HUGE/HFS 列存储表的字典、DDL 和数据恢复能力。

一、为什么做这个工具

做达梦运维时,最棘手的情况往往不是误删一张表,而是数据库已经无法正常 open:控制文件、ROLL、REDO 或归档链路出现问题,DMRMAN 也无法完成常规恢复。此时手里可能只剩下一组 .DBF 文件,甚至只剩下离线 DMASM 成员盘,但业务数据仍然存在于物理介质中。

dmdul 就是为这类场景准备的。它不连接数据库实例,也不修改原始介质,可以从两类离线来源读取数据:

  1. 文件系统中的 SYSTEM.DBF、可选的 dm.ctl、用户表空间 DBF,以及 HUGE 表需要的 HFS 目录;
  2. 离线 DMASM 成员裸盘或 VMware *-flat.vmdk,无需启动 DMASMSVR,也无需先执行 asmcmd cp

使用边界: dmdul 不是常规备份恢复工具,不能替代 DMRMAN、归档恢复、闪回、dexp 或达梦原厂恢复流程。它定位于常规手段无法继续时的离线只读救援。所有导出结果都必须先在隔离测试库中验证。

二、从离线介质到可导入数据

当前能力链有两条输入路径。文件系统 DBF 可以直接进入字典恢复;DMASM 成员盘则先恢复磁盘组目录、INODE、AU 映射、副本和条带,再把其中的数据库文件作为只读逻辑 DBF 使用。两条路径最终共用同一套 bootstrap、字典和数据解析器。

文件系统离线快照                           离线 DMASM 成员盘
SYSTEM.DBF / 用户 DBF / HFS                裸设备 / *-flat.vmdk
          |                                         |
          |                                         v
          |                              DMASM 元数据与 AU 映射
          |                              INODE / 副本 / 条带
          |                                         |
          |                                         v
          |                                  ASM 逻辑 DBF
          |                                         |
          +-------------------+---------------------+
                              |
                              v
                    统一只读离线数据源
                  DBF + 可选的 HFS 根目录
                              |
                              v
              Standard Bootstrap + SYSTEM 物理预检
                              |
                              v
                       Dictionary Recovery
                              |
                   +----------+----------+
                   |          |          |
                   v          v          v
             DDL / SQL    dmfldr      Native DMP
                             |             |
                             v             v
                           dmfldr          dimp
                             |             |
                             +------+------+
                                    |
                                    v
                              隔离达梦测试库

目前的核心能力包括:

  • Standard Bootstrap:SYSTEM.DBF 中恢复 SYSOBJECTSSYSINDEXES 等系统字典,优先沿 storage root -> internal refs -> leaf chain 下载字典数据;
  • 可修改磁盘字典: bootstrap 后生成 dmdul_dict/*.tsv。字典可以人工审核和修订,再通过 load dictionary; 复用;
  • 数据库对象恢复: 支持用户、模式、角色与授权、表、字段、索引、约束、注释、分区、视图、序列、过程、函数、包、触发器和同义词;
  • 复杂行与类型解析: 支持显式 2-bit NULL metadata、ALTER TABLE 历史短行、时区与 INTERVAL 类型、ROWID、BFILE、JSON/JSONB、行外 CLOB/BLOB 和 Long Row;
  • 可诊断的数据页定位: 正常卸载从 storage root 构建 page plan,只有根页损坏、页链断裂或字典不足时才逐级 fallback;
  • 三种数据输出: 默认输出 INSERT SQL,也可以生成 dmfldr 文本与控制文件,或生成由官方 dimp 识别的原生 DMP;
  • 残留数据救援: recover table 可以尝试读取 DELETEDROPTRUNCATE 后尚未被覆盖的残留页,并记录物理来源证据。

三、v0.8.0:HUGE 列存储表不再只看 DBF

普通行表的数据位于 DBF 的段和数据页中。HUGE 表建立在混合表空间上,完整 section 的列数据位于 Huge File System(HFS)目录,尚未整理的事务增量则位于普通 DBF 中的内部辅助表。

因此,只扫描 MAIN.DBF 会漏掉 HFS 主体数据;只读取 HFS 文件又会漏掉新增、删除和更新增量。v0.8.0 按下面的关系恢复逻辑行:

SYSTEM.DBF 字典
      |
      +-- HUGE 主表
      +-- 表$AUX   section 位置、列号、偏移和行数
      +-- 表$RAUX  尚未进入完整 section 的尾部行
      +-- 表$DAUX  逻辑删除范围
      +-- 表$UAUX  更新后的列值
      |
      v
HFS/SCH#########/TAB####/COL####_##########.dta
      |
      v
HFS section + RAUX - DAUX + UAUX
      |
      v
统一逻辑行 -> SQL / dmfldr / DMP

bootstrap 会识别 HUGE 主表及四类辅助对象,并把 HUGE 标志、SECTIONFILESIZEWITH DELTA 和辅助表 ID 写入 dmdul_dict/tables.tsv。DDL 可以恢复已经验证的存储属性:

CREATE HUGE TABLE SYSDBA.DMDUL_HUGE_SIMPLE ( ID INT NOT NULL, VAL VARCHAR(20), TAG CHAR(1) ) STORAGE(SECTION(1024), FILESIZE(16), WITH DELTA, ON MAIN);

数据卸载按 section 流式读取 .dta,不会把整个 HFS 文件一次性装入内存;随后读取 RAUX、DAUX 和 UAUX,合并为表的最终逻辑结果。

当前已经完成以下实机验证:

  • 一个完整 HFS section 加 RAUX,共恢复 1499 行;
  • RAUX-only 小表恢复 100 行,SQL 与 dmfldr 回灌双向 MINUS=0
  • 两个完整 section 加 RAUX 共恢复 2500 行,SQL 回灌双向 MINUS=0
  • DAUX 删除与 UAUX 更新合并后,SQL 回灌双向 MINUS=0
  • 表级 DMP 由官方 dimp REMAP_SCHEMA 导入 1499 行,与同快照 SQL 回灌表双向 MINUS=0

这项能力仍然有明确边界。当前验证范围是未压缩、未加密的单一 HFS path,已验证 HFS 列类型为非空 INT 和可空/非空 VARCHAR/CHAR。压缩、加密、未验证的可空定长列或类型会在输出第一行前明确失败,不会生成看似成功但内容不可信的结果。DMASM 裸盘路径当前只映射 DBF,HFS 目录仍需另外提供。

四、DMASM:从裸盘直接发现数据库文件

DMASM 支持不是把裸盘当成普通 DBF 全盘搜索。dmdul 会解析磁盘头、目录、INODE、描述 AU、数据 AU、副本数组和条带规则,再按 ASM 文件逻辑偏移读取 DBF。

目前已验证的能力包括:

  • 非镜像和镜像磁盘组;
  • NORMAL/HIGH 副本选择与损坏副本回退;
  • 多成员盘、多磁盘组和条带读取;
  • 单文件与整套 DBF 的流式复制;
  • 多数据库候选发现、唯一候选自动选择和候选文件集持久化。

执行 set asm_disk 后,工具会立即扫描全部磁盘组的 INODE 目录,列出每个 SYSTEM.DBF 候选及其数据库名、字符集、页大小和对应 DBF 集合。只有一个候选时会自动选中;存在多个数据库时不会猜测,必须使用 set system <ASM path>; 明确选择。

候选证据会保存到:

dmdul_dict/asm_databases.tsv
dmdul_dict/asm_datafiles.tsv

如果其他工具需要普通 DBF,可以使用 cp

DMDUL> cp +NORM4/data/MIRRORDB/SYSTEM.DBF /recovery/dbf/SYSTEM.DBF;
DMDUL> cp datafile /recovery/dbf;

复制过程使用固定大小缓冲区,先写临时文件,完成同步后再改名,并输出字节数、耗时和 SHA-256。DMASM 解析仍属于实验性能力,成员盘必须来自同一时点且已经停止写入。工具当前不重放 DMASM 元数据事务。

五、两阶段页检查:先自动预检,再按需全库扫描

恢复流程不要求用户在 bootstrap 前重复执行检查命令。v0.7.3 起,bootstrap; 会先自动完成 SYSTEM 文件的纯物理预检,再尝试恢复字典。

阶段 入口 范围 字典依赖 何时执行
第一阶段 bootstrap; 自动执行 完整 SYSTEM.DBF 不依赖 每次从当前快照重建字典时自动执行
第二阶段 check pages; 全部或指定 DBF 物理检查不依赖;对象归属依赖当前会话字典 SYSTEM 预检告警、整库恢复、介质可疑或需要审计报告时

第一阶段发现坏页时,bootstrap 会尽量继续读取仍可用的字典,并以 SUCCESS_WITH_WARNINGS 提示进入第二阶段。如果字典无法建立,check pages; 仍能完成纯物理扫描,但无法可靠归属的坏页会标记为 UNATTRIBUTED

第二阶段会生成三份报告:

output/check_summary.md
output/check_bad_pages.tsv
output/check_affected_objects.tsv

报告包含文件、页号、绝对字节偏移、损坏类型、storage ID、可能受影响的对象和归属置信度。独立检查只使用当前会话通过 bootstrap 或显式 load dictionary 加载的字典,不会偷偷套用目录中残留的旧字典。

六、正常卸载不依赖全文件暴力扫描

对于普通表,数据定位按下面的顺序执行:

1. 根据 storage root、internal refs 和 leaf chain 生成 page plan
2. page plan 完整时,仅用 ReadAt 读取计划页
3. 根页损坏或断链时,扫描同 group 文件并匹配 storage_id
4. storage_id 回退仍失败时,按段范围读取
5. 只有 recover table 才允许全文件残留页扫描

每次卸载都会记录实际路径:

planned pages: 12
direct pages read: 12
fallback pages scanned: 0
fallback reason: none

这些信息不仅用于观察性能,也用于判断恢复证据强弱。出现 fallback 时,应结合原因、失败行数、坏页报告和目标库核对结果共同评估。

七、快速上手

1. 文件系统 DBF

最短流程是把 dmdul.exeSYSTEM.DBF、全部用户表空间 DBF 和可选的 dm.ctl 放在同一个可写目录。目标包含 HUGE 表时,还要放入同一快照的完整 HFS 根目录,例如 HMAIN/

D:\recovery> dmdul.exe

DMDUL> list datafile;
DMDUL> bootstrap;
DMDUL> list user;
DMDUL> list table HR_TEST;
DMDUL> describe HR_TEST.EMP_INFO;
DMDUL> set data_format dmp;
DMDUL> unload user HR_TEST;
DMDUL> exit;

dm.ctl 仅作为 group/file/表空间映射的增强核对来源。恢复目录存在同名 DBF 时,工具优先读取用户准备的离线副本,不会跟随控制文件中的原绝对路径回到在线文件。

2. 离线 DMASM 成员盘

DMDUL> set data_dir /recovery/asm-work;
DMDUL> set asm_disk /dev/dmasm/ext4a,/dev/dmasm/ext4b,/dev/dmasm/norm4a,/dev/dmasm/norm4b;
DMDUL> list asmfile;

唯一数据库候选会自动选中。如果输出多个候选,先核对数据库名、页大小、字符集和完整 DBF 集合,再选择目标:

DMDUL> set system +NORM4/data/MIRRORDB/SYSTEM.DBF;
DMDUL> list datafile;
DMDUL> bootstrap;
DMDUL> unload user ASMTEST;

独立 check pages; 当前扫描文件系统 data_dir。需要对 ASM 中全部逻辑 DBF 做第二阶段检查时,先执行 cp datafile <directory>;,再切换到复制目录检查。

3. 选择输出格式

# 默认:可审查的 INSERT SQL
DMDUL> set data_format sql;
DMDUL> unload table HR_TEST.EMP_INFO;

# 分隔文本 + 每表 dmfldr 控制文件
DMDUL> set data_format fldr;
DMDUL> unload user HR_TEST;

# 达梦原生逻辑 DMP
DMDUL> set data_format dmp;
DMDUL> unload table HR_TEST.EMP_INFO;
DMDUL> unload user HR_TEST;
DMDUL> unload schema HR_TEST;
DMDUL> unload database;

默认输出位于启动目录的 output/。DMP 对应达梦 TABLES / OWNER / SCHEMAS / FULL 四种互斥逻辑级别,可由官方 dimp 导入。FLDR 模式会为每张非空表生成 .txt.ctl,先执行 _ddl.sql 建表,再调用:

dmfldr USERID=SYSDBA/password@127.0.0.1:5236 CONTROL="'HR_TEST_EMP_INFO_data.ctl'"

CONTROL 外层双引号用于把内部单引号原样交给 dmfldr,不是排版错误。

八、千万行测试与资源控制

项目曾使用 DM8 单表 1000 万行、13 列、约 2.13 GiB 表空间、4 核 4 GiB 主机做专项测试。下表记录的是 v0.5.8 阶段的实测,不是对 v0.8.0 的重新跑分:

场景 早期实现 优化后
SQL 卸载(4 核) 内存溢出退出 87 秒
DMP 卸载(4 核) 内存溢出退出 116 秒
SQL 卸载(8 核) 未测试 49 秒

这些改进已经保留在当前版本中:page plan 按批次并行解码,worker 根据 CPU 和任务规模自适应;writer 按序合并,保证并行与顺序输出确定;在飞字节背压限制大 LOB 和大表的峰值内存;DMP 使用缓冲写、worker 侧预编码和多 phase 输出。

实际速度仍会受到磁盘介质、页分布、行宽、LOB 比例、fallback 程度和输出格式影响,不能把这组数据当作所有生产库的性能承诺。

九、适用场景与安全边界

场景 dmdul 可以做什么
数据库无法 open 从仍可读的离线文件尝试恢复字典、DDL 和表数据
常规恢复链路失败 在保留官方恢复优先级的前提下,提供只读物理抽取路径
只剩 DBF 从 SYSTEM 和用户表空间文件恢复对象及数据
只剩 DMASM 成员盘 解析已验证的 DMASM 布局,直接读取或复制逻辑 DBF
部分页损坏 定位坏页、尝试对象归属,并继续抽取其他可读页
DROP / TRUNCATE 后救援 原数据页未被覆盖时尝试残留恢复
HUGE 列存储表 合并 HFS section 与 RAUX/DAUX/UAUX,输出 DDL 和逻辑数据

离线抽取不等于事务一致性恢复。普通 unload 已收紧为 slot-only,但 slot-only 不等于 committed-only;未提交事务的最终可见性仍需要完整事务状态和 Undo 证据。损坏页、断链、多版本残留以及未验证的存储格式也可能降低结果可信度。

请始终保留原始介质的只读副本,优先尝试官方恢复路径。导出后至少核对对象数量、表行数、关键列、分区分布、LOB 长度与哈希,再决定如何使用结果。

十、项目地址

  • GitHub:<https://github.com/greatfinish/dmdul>
  • Gitee:<https://gitee.com/sun-ying1119/dmdul>
  • v0.8.0 Release:<https://github.com/greatfinish/dmdul/releases/tag/v0.8.0>
  • 标准恢复流程:<https://github.com/greatfinish/dmdul/blob/main/docs/recovery-workflow.md>
  • DMASM 裸盘恢复:<https://github.com/greatfinish/dmdul/blob/main/docs/dmasm-raw-recovery.md>
  • HUGE 列存储恢复:<https://github.com/greatfinish/dmdul/blob/main/docs/huge-tables.md>

项目使用 Go 编写,提供 Windows x64 和 Linux x64 预编译包,采用 MIT 许可证。

欢迎试用和提交 Issue,也欢迎提供可脱敏的失败案例、存储格式差分样本与导入验证结果。离线恢复工具的可靠性,最终来自可重复的物理证据和回灌核对,而不是对未知格式的大胆猜测。

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服