从单机安装、数据清洗到周期增量同步的完整实践
摘要: 本文介绍 DMDIS 的产品定位、单机部署、DM8 数据源配置、增量数据读取、字段清洗、作业编排和周期调度过程。实践以
HOTEL.PERSON_INFO为源表,将处理后的数据写入目标表,并通过数据库查询核对清洗结果和统计数据。文末结合实际报错,总结字符串替换顺序和列转换变量引用问题的定位方法。
关键词: DMDIS、DM8、数据集成、数据清洗、增量同步、CDC、作业调度
DMDIS 是达梦提供的专业实时数据集成软件,集数据迁移、数据同步、清洗转换和数据整合于一体。它通过可视化方式连接数据库、文件及其他数据源,将数据抽取、传输、处理和装载组织成可执行的转换与作业。
DMDIS 常用于数据库升级替代、异构数据同步、数据仓库或数据中心建设、周期性报表数据准备,以及需要集中编排和监控的数据处理任务。
单机模式适合学习和小型项目;规模更大或可靠性要求更高时,应根据实际产品版本和项目要求规划集群部署。
本次示例以 DM8 的 HOTEL.PERSON_INFO 为源表,将数据清洗后写入 HOTEL.旅客信息一览表,并生成总人数、男性人数和女性人数统计。
转换链覆盖以下内容:
DMDIS 用于连接不同数据源,并通过可视化转换和作业完成数据抽取、清洗、映射、装载与调度。本次采用单机部署,整体数据流如下:
DM8 源表
↓
增量读取
↓
清洗与列转换
↓
增量装载
↓
统计作业
| 项目 | 本次配置 | 验收标准 |
|---|---|---|
| DMDIS | V5.2.0.1 单机模式,管理端口 8800 | Web 页面可访问,服务进程正常 |
| 源端 | 192.168.80.**:5236,HOTEL.PERSON_INFO |
源表可读取,增量字段可识别 |
| 目标端 | DM8 目标库,HOTEL.旅客信息一览表 |
姓名、年龄、联系方式、性别清洗正确 |
| 调度 | 作业绑定 perMinute 周期调度 |
执行历史连续成功,验证后可停用 |
| 统计 | HOTEL.旅客信息统计表 |
总人数 4、男性 2、女性 2 |
安装前先确认 CPU 架构、安装介质和校验文件,再准备 dinstall 用户组、dmdis 用户及独立软件目录。安装、运行和后续维护尽量统一使用 dmdis,避免目录属主混乱。
lscpu | grep -E '^CPU\(s\)|^Architecture|^Model name'
getent group dinstall
# root 执行
useradd -g dinstall -m -d /home/dmdis -s /bin/bash dmdis
passwd dmdis
mkdir -p /home/dmdis/software /home/dmdis/tmp
chown -R dmdis:dinstall /home/dmdis
chmod 755 /home/dmdis /home/dmdis/software
# 将安装包及校验文件放入 /home/dmdis/software 后核验
cd /home/dmdis/software
sha256sum dmdis_rev226131_x86_linux_64_20260703.bin
图 1:CPU、安装包、用户组、dmdis 用户和目录准备记录
切换到 dmdis 用户,以字符方式启动安装程序。本次选择单机模式,使用随安装包提供的运行环境,并将管理端口设置为 8800。
su - dmdis
cd /home/dmdis/software
chmod +x dmdis_rev226131_x86_linux_64_20260703.bin
./dmdis_rev226131_x86_linux_64_20260703.bin -i
# 本次实际版本目录
/home/dmdis/dmdis5/20260804094943527000
安装结束后应记录实际生成的版本目录,后续启停脚本以该目录为准。安装向导中的目录、端口和元数据库选项应以当前安装介质与现场规划为准,不要在旧版本目录上直接覆盖安装。
服务启动后,从进程、监听端口和 HTTP 响应三个角度进行验证。HTTP 302 跳转到登录页说明 Web 服务已正常响应,不属于错误。
ps -ef | grep '/home/dmdis/dmdis5/20260804094943527000' | grep -v grep
ss -lntp | grep ':8800 '
curl -I http://127.0.0.**:8800/
# 维护时使用实际安装目录下的脚本
/home/dmdis/dmdis5/20260804094943527000/standalone/standalone_service_stop.sh
图 2:DMDIS 服务进程及 8800 端口 HTTP 响应验证
先用结构简单的部门表验证源库、目标库的连通性和装载方向。源端写入 10、20、30 三条部门数据,目标端保持空表,便于观察首次装载结果。
图 3:源端 DMDIS_DEPT_DEMO 测试数据
图 4:源端数据与目标端空表结构检查
在 DMDIS 的“数据源”中新增 DM8 连接,填写服务器地址、端口、用户名和密码。测试连接成功后,展开模式和表,确认 DMDIS 能够读取列定义。
源端连接命名为 DM_SRC_DRSSRC,目标端另建独立连接,避免在转换中选错数据方向。
图 5:DM_SRC_DRSSRC 数据源及表字段读取结果
创建工程 DMDIS_DM_SYNC,用于集中保存数据源、函数、转换、作业和调度。工程描述写明同步方向,便于后续检查和交接。
图 6:DMDIS_DM_SYNC 工程及同步方向说明
在转换中加入增量表组件,选择源端 PERSON_INFO。除业务字段外,保留 CDC_ID 和 CDC_OPT,用于标识增量顺序和变更类型。
首次运行前,应确认源表主键、增量影子表或变更捕获状态正常。
| 字段 | 用途 | 处理方式 |
|---|---|---|
CDC_ID |
增量记录顺序 | 只用于增量控制,不写入目标业务列 |
CDC_OPT |
变更操作类型 | 由增量组件传递给装载端 |
ID |
身份证号 / 业务标识 | 映射为“身份证号” |
NAME |
姓名 | 繁体转简体后写入“姓名” |
AGE |
原始年龄 | 作为函数兜底参数,输出计算后的“年龄” |
PHONE |
联系方式 | 空值统一处理 |
GENDER |
性别 | 英文值转换为男 / 女 |
图 7:增量表组件的 CDC 字段和业务字段
创建 inferAgeFromID 函数:身份证号满足 18 位规则时,从出生年份计算年龄;格式不满足时返回原 AGE。
保存函数后先执行解析检查,再在列转换中调用。
function inferAgeFromID(id, fallbackAge) {
if (id == null) return fallbackAge;
var text = String(id);
if (text.length != 18) return fallbackAge;
var birthYear = parseInt(text.substring(6, 10));
if (isNaN(birthYear)) return fallbackAge;
return new Date().getFullYear() - birthYear;
}
图 8:inferAgeFromID 自定义函数解析成功
清洗组件处理三类数据:
female / male 转换为“女”/“男”。字符串替换按顺序执行,因此必须先处理 female,再处理 male。
图 9:姓名、联系方式和性别清洗规则
风险提示: 如果先将
male替换为“男”,female会被部分匹配为“fe男”。更稳妥的做法是先处理female,或改用完整值匹配。
列转换中将英文列名映射为中文列名。年龄列使用表达式 inferAgeFromID(身份证号, 年龄),输出类型设为 Integer。
CDC_ID、CDC_OPT 继续传给增量装载组件,但不映射到目标业务字段。
图 10:列转换中的字段类型、中文名和年龄表达式
作业“作业-旅客信息更新与统计”由三个步骤组成:
PERSON_INFO 清洗转换;guestCountTotal、guestCountMale、guestCountFemale 三个变量;步骤之间使用成功连线,任一步失败时停止后续统计。
TRUNCATE TABLE HOTEL."旅客信息统计表";
INSERT INTO HOTEL."旅客信息统计表"("统计项目", "统计值")
VALUES ('1、总人数', ${guestCountTotal});
INSERT INTO HOTEL."旅客信息统计表"("统计项目", "统计值")
VALUES ('2、男性人数', ${guestCountMale});
INSERT INTO HOTEL."旅客信息统计表"("统计项目", "统计值")
VALUES ('3、女性人数', ${guestCountFemale});
图 11:转换、变量设置和 SQL 脚本组成的作业链
创建 perMinute 周期调度,用于快速观察增量同步。随后在作业调度页将该调度绑定到“作业-旅客信息更新与统计”,保存并启用。
图 12:perMinute 周期调度配置
图 13:作业与 perMinute 调度绑定
风险提示: 每分钟调度仅用于实验验证。确认功能后应禁用调度,避免持续产生无意义的执行记录和日志。
先手工运行作业并观察当前状态,确认转换和统计步骤均成功,再启用周期调度。
运行历史中应连续出现成功记录;失败时先打开该次日志,定位到具体步骤。
图 14:作业进入运行状态
图 15:每分钟作业执行历史连续成功
最终验收不能只看 DMDIS 页面“成功”,还要回到数据库比对源表、目标表和统计表。
源端 4 条记录经过转换后,应满足以下结果:
SELECT ID, NAME, AGE, NVL(PHONE, '<NULL>') AS PHONE, GENDER
FROM HOTEL.PERSON_INFO
ORDER BY ID;
SELECT "身份证号", "姓名", "年龄",
NVL("联系方式", '<NULL>') AS "联系方式",
"性别"
FROM HOTEL."旅客信息一览表"
ORDER BY "身份证号";
SELECT "统计项目", "统计值"
FROM HOTEL."旅客信息统计表"
ORDER BY "统计项目";
图 16:源表、清洗目标表和统计表最终一致性验证
| 环节 | 处理记录 |
|---|---|
| 现象 | 女性数据写入目标表后变为“fe男”,女性统计为 0。 |
| 原因 | 先执行 male→男,female 中包含 male,发生部分字符串替换。 |
| 验证 | 直接查询目标表和统计表,确认异常集中在 female 数据。 |
| 解决 | 将 female→女 放在 male→男 之前,或使用完整值匹配;保存后重新触发真实增量。 |
| 风险 | 仅在源表把 female 更新为相同的 female 不会产生新的 CDC 差异,修正规则后可能看不到重跑效果。 |
| 复盘 | 字符串规则应检查包含关系、大小写和空值;修改规则后必须设计可识别的增量测试。 |
图 17:错误替换顺序导致 female 被转换为 fe男
| 环节 | 处理记录 |
|---|---|
| 现象 | 列转换保存或运行时提示“未定义的变量:年龄”。 |
| 原因 | 表达式引用了当前步骤中不存在的中文名,或 AGE 在前一步被删除。 |
| 验证 | 从上游组件重新加载列信息,检查 AGE / 年龄 是否仍在输入列中。 |
| 解决 | 保留 AGE 作为中间列,并在列转换中使用 inferAgeFromID(身份证号, 年龄),输出类型设为 Integer。 |
| 风险 | 直接删除原 AGE 会失去身份证号异常时的兜底值。 |
| 复盘 | 自定义函数的参数名、输入列名和目标列名要分层检查,不混用源字段与中文别名。 |
本次实践完成了 DMDIS 单机部署、DM8 数据源配置、增量读取、数据清洗、字段映射、目标装载、统计作业和周期调度的完整闭环。
验证过程中,既要关注 DMDIS 页面中的运行状态,也要回到数据库侧核对源表、目标表和统计表。对于数据清洗规则,还应重点检查字符串替换顺序、输入列是否存在、字段类型是否匹配以及增量测试是否能够真正产生 CDC 变化。
THE END
达梦社区地址:https://eco.dameng.com
文章
阅读量
获赞
