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

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

孙莹 2026/07/23 82 0 0
摘要

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

一、为什么做这个工具

做达梦运维的同行大概都遇到过这样的至暗时刻:实例怎么都 open 不了,控制文件、REDO、归档链路某个环节出了问题,DMRMAN 也救不回来。手里只剩下几个 .DBF 文件,但业务数据就静静地躺在里面——看得见,却拿不出来

dmdul 就是为这个场景准备的:它不连接实例、不修改任何原始文件,直接读取离线的 SYSTEM.DBF、可选的 dm.ctl 以及用户表空间 DBF,把数据库对象定义和表数据抽取出来。

⚠️ 先把话说在前面:dmdul 不是常规备份恢复工具,不能也不打算替代 DMRMAN、归档恢复、闪回或 dexp。它定位于"官方手段都走不通时的最后一根救命稻草"。所有导出的 DDL 和数据,都必须先在隔离测试库验证后再使用

二、它能做什么

从离线物理文件,一路走到官方 dimp 可以直接装载的逻辑 DMP:

SYSTEM.DBF / dm.ctl / 用户表空间 DBF
              │
              ▼
     Standard Bootstrap(两阶段字典下载)
              │
              ▼
       数据字典恢复(用户/表/列/索引/分区…)
              │
     ┌────────┼────────┬────────┐
     ▼        ▼        ▼        ▼
    DDL      SQL      CSV      DMP ──▶ dimp ──▶ 达梦数据库

核心能力清单:

  • 离线字典恢复:从 page 0 锚点进入 SYSOBJECTS / SYSINDEXES,沿 storage root → internal refs → leaf chain 下载系统字典;失败时回退按页流式扫描。
  • 参数自动识别:页大小、簇大小、字符集(UTF-8 / GB18030 / EUC-KR)、大小写敏感标志、实例名,结合 dm.ctl 恢复库名。
  • 对象全覆盖:用户、角色授权、表、字段、索引、约束、注释、分区、视图、序列、过程/函数/包、触发器、同义词、对象授权。序列会沿运行态定位器恢复安全的 LAST_NUMBER,避免从初始值重新发号。
  • 完整数据类型:定长/变长字符与二进制、精确/近似数值、9 位时间戳、时区类型、13 种 INTERVAL、ROWID、BFILE、JSON/JSONB。
  • 复杂行与大对象:显式 2-bit NULL metadata、ALTER TABLE 历史短行、21 字节 LOB locator、行外 CLOB/BLOB 流式读取、Long Row 页链。
  • 三种导出格式:INSERT SQL(默认)、CSV、原生逻辑 DMP(单文件含元数据+数据,dimp 直接装载,支持 FULL / OWNER / SCHEMAS / TABLES 四级)。
  • 残留数据救援:recover table 可尝试读取 DELETE / DROP / TRUNCATE 后尚未被覆盖的残留页(孤儿页恢复带一致性校验和物理来源证据,降低误归属)。

三、可诊断的分层数据定位

抽数据不是"暴力全盘扫描"。dmdul 采用分层策略,并把每一步都记进日志:

1. storage root / internal refs / leaf chain 生成 page plan
2. 计划完整时,仅用 ReadAt 精确读取计划页
3. root 损坏/断链时,回退同 group 按 storage_id 扫描
4. 再不行,按段范围(header_file/block/blocks)读取
5. 只有 recover table 才做全文件残留页扫描

每次卸载,控制台和 dul.log 都会告诉你实际读了哪些页:

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

一眼就能看出这张表走的是精确直读还是兜底扫描,恢复结果心里有底。

四、性能:千万行大表实测

近期做了一轮千万行级的压力测试和优化。测试环境:达梦 DM8、单表 1000 万行 / 13 列 / 2.13 GiB 表空间、4 核 4GiB 主机、冷缓存停库快照。

场景 早期版本 最新 v0.5.8
SQL 卸载(4 核) 内存溢出被杀 87 秒
DMP 卸载(4 核) 内存溢出被杀 116 秒
SQL 卸载(8 核) 49 秒

关键点:

  • 自动多核并行:page plan 直读阶段按页批次并行解码,worker 数自动取 min(CPU 核数, 8),无需任何配置。普通行页内自包含,按页并行天然安全;LOB/Long Row 页链由锚点行所属 worker 整链跟随,绝不拆链。
  • 输出确定性:单一 writer 按批次序合并,并行输出与单线程逐字节一致(3.75 GiB SQL 输出 MD5 双重验证过)。
  • 有界内存:引入在飞字节背压阀,即使大 LOB 表的 SQL/CSV 导出,峰值内存也由额度决定,与 LOB 总量无关,不会把低配机器撑爆。
  • 自适应:低配机自动降级(单核走顺序路径、小表不起并发),高配机吃满到 8 核。

导出的 DMP 经官方 dimp SHOW=Y 验证,能正确识别全部行数。

五、快速上手

D:\> dmdul.exe

DMDUL> set data_dir D:\recovery\dameng;
DMDUL> set system D:\recovery\dameng\SYSTEM.DBF;
DMDUL> set control D:\recovery\dameng\dm.ctl;
DMDUL> show parameter;
DMDUL> bootstrap;
DMDUL> list user;
DMDUL> list table HR_TEST;
DMDUL> set data_format dmp;
DMDUL> unload user HR_TEST;
DMDUL> unload database;
DMDUL> exit;

bootstrap 后会生成可人工审查、修改的磁盘字典 dmdul_dict/*.tsv,再次启动可直接 load dictionary,无需重复扫描。DROP/TRUNCATE 场景可以加载故障前保存的字典来补齐表结构。

导出的 DMP 用官方工具装载:

dimp SYSDBA/password FILE=HR_TEST.dmp SHOW=Y NOLOGFILE=Y dimp SYSDBA/password FILE=HR_TEST.dmp NOLOGFILE=Y

六、适用场景

场景 说明
数据库无法 open 实例起不来,但 DBF 文件可读
常规恢复失败 控制文件/ROLL/REDO/归档异常,DMRMAN 无法完成
只剩数据文件 从 SYSTEM.DBF + 表空间文件抢救对象和数据
部分数据块损坏 大部分页可读时按页扫描恢复
DROP/TRUNCATE 后救援 原数据块未被覆盖时尝试残留页恢复
需要离线导出 DDL 用户、表、视图、序列、过程、触发器、授权等

七、开源地址

  • GitHub:https://github.com/greatfinish/dmdul
  • Gitee(国内访问):https://gitee.com/sun-ying1119/dmdul
  • 提供 Windows / Linux x64 预编译包,MIT 协议,Go 编写、单文件、零依赖。

最后再强调一次:离线恢复结果受达梦版本、页大小、字符集、表类型、行格式和损坏程度影响,dmdul 是极端故障下的兜底方案,不保证与故障前数据库在事务一致性层面完全一致。请务必在隔离测试库充分验证后再用于任何生产恢复。

欢迎试用、提 Issue、贡献失败案例和测试样例。也欢迎各位达梦同行交流离线恢复的实战经验 🙌

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服