注册
达梦 DMDVS 数据校验实战
专栏/技术分享/ 文章详情 /

达梦 DMDVS 数据校验实战

Gyyyyy 2026/09/23 214 0 0
摘要

达梦 DMDVS 数据校验实战:静态校验 · 二次校验 · DVAGENT · 定时调度

本文基于 DM8⇄DM8 测试环境(192.168.x.223 源 / 192.168.x.224 目标),完整记录达梦数据校验软件 DMDVS(V5.2.5.4)的三大实战场景:静态数据校验 + 二次校验(RCMP)、数据代理 DVAGENT 静态校验、dschsvr 定时调度自动校验。所有 IP、端口、口令、许可编号均为示例值,请按实际环境调整。


一、DMDVS 能解决什么问题

迁移割接后最怕"数据对不上"。达梦 DMDVS(数据校验软件)支持对 DM6/DM7/DM8、Oracle、SQL Server、MySQL、DB2、PostgreSQL、Kafka 等做源/目标数据一致性校验,返回逐表报告(源/目标行数、相同/不同行数、校验结果 SAME/DIFF)。

核心思路只有三步:

cmp add db 注册源/目标库 → cmp job 建校验作业(模式.表==模式.表) → show report 看结果

💡 本文环境:源库 192.168.x.223:5636、目标库 192.168.x.224:5536(非默认端口);同机已有 DMDRS 占用 5345,因此定时调度 dschsvr 改用 5346 避免端口冲突。

端口规划(同机多服务):

节点 服务 程序 配置文件 端口(示例)
224 DMDVS 校验服务 dvsvr dvs.xml 5349
223 DVAGENT 数据代理 dvagent agent.xml 5350
224 定时调度服务 dschsvr dsched.xml 5346
224 DMDRS 目标(已占用) drsvr exec.xml 5345

二、安装部署 DMDVS

使用离线安装包,中文交互式安装;依赖达梦客户端动态库路径;指定 license:

./dmdvs_rev<版本号>_x86_rh6_64_<日期>.bin -i # 指定安装目录 → /dmdata/dvs/ # 许可证文件 → /dmdata/software/dmdvs<授权号>.key(提示:试用版有效期/版本类型) # 依赖环境配置 -数据库动态库路径 → /dmdata/dmdbms/bin # DVS配置-IP → 本机对外IP;DVS配置-端口 → 5349;DVS配置-站点号 → 1 # 安装成功

⚠️ DVS 配置 IP 不允许设置为 127.0.0.1。

生成服务脚本并启动(dvsvr):

cd /dmdata/dvs/bin/service_template cp TemplateService ../DvsService vi ../DvsService # INSTALL_HOME=/dmdata/dvs/ # PROG_DIR=/dmdata/dvs/bin # CONF_PATH=/dmdata/dvs/bin/dvs.xml # NEED_LIB_PATH=/dmdata/dmdbms/bin # EXEC_PROG_NAME=dvsvr # SERVICE_TYPE_NAME="dvs server" ./DvsService start ./DvsService status # DvsService (pid xxxxx) is running...

💡 安装目录 /dmdata/dvs/、依赖库 /dmdata/dmdbms/bin、端口 5349、站点号 1、License 为试用授权均以实际环境为准。

添加两端数据库信息(drcsl 控制台):

CSL> cmp add db dm8 db_src "192.168.x.223" 用户名 口令 5636
命令执行成功
CSL> cmp add db dm8 db_dst "192.168.x.224" 用户名 口令 5536
命令执行成功
CSL> show db
| 数据库类型 | 数据库信息名 |     服务器名    | 用户名 | 端口号 | 数据库数据代理IP | 数据库数据代理端口号 |
|     DM8    |    DB_DST    | 192.168.x.224 | 用户  |  5536  |                  |                    0 |
|     DM8    |    DB_SRC    | 192.168.x.223 | 用户  |  5636  |                  |                    0 |

三、场景一:静态数据校验 + 二次校验

1. 首次静态校验(数据静止)

CSL> cmp job jobname=cmp_test1 db_src db_dst "TEST_USR.*==TEST_USR.*"
| 作业名 | 校验任务ID | 源数据库名 | 目标数据库名 | 表一致数 | 表差异数 | 表失败数 | 表停止数 |     校验状态    |
| CMP_TEST |      1     |   DB_SRC   |    DB_DST    |     3    |     0    |     0    |     0    | 校验成功 - 一致 |
|         已校验的表个数      |    需校验的表总个数    |  校验任务进度(%)  |
|           3             |           3            |      100.00      |
|         校验表组         | 源表行数 | 目标表行数 | 相同行数 | 不同行数 | 总耗时(ms) |       校验结果      |
| TEST_USR.T1==TEST_USR.T1 | 400000 | 400000 | 400000 | 0 | 1772 | 校验成功 - 数据一致 |
| TEST_USR.T2==TEST_USR.T2 | 199996 | 199996 | 199996 | 0 |  799 | 校验成功 - 数据一致 |
| TEST_USR.T3==TEST_USR.T3 | 300000 | 300000 | 300000 | 0 | 1204 | 校验成功 - 数据一致 |

✓ 3 张静态表全部一致,任务耗时 3 秒,进度 100%。

2. 动态造数(模拟数据持续变化)

CREATE TABLE TEST_USR.T_TEST_DYNAMIC ( ID BIGINT PRIMARY KEY, NAME VARCHAR(64), AMOUNT NUMBER(12,2), CHECK_TIME TIMESTAMP(6), REMARK VARCHAR(255)); -- 存储过程:每秒插 1 行 / 每 10s 删最早 1 条 / 每 15s 更新最新 1 行 nohup disql TEST_USR/口令@192.168.x.223:5636 \ -e "CALL TEST_USR.SP_GEN_TEST_DATA();" > gen_test_data.log 2>&1 &

3. 数据持续变化时静态校验 → 出现差异行

| 作业名  | 校验任务ID | 表总个数 | 表一致数 | 表差异数 |
| CMP_TEST1 |      2     |    4    |     3    |      1     |
|         校验表组         | 源表行数 | 目标表行数 | 相同行数 | 不同行数 | 校验结果 |
| TEST_USR.T1==TEST_USR.T1 | 500000 | 500000 | 500000 | 0 | 校验成功 - 数据一致   |
| TEST_USR.T2==TEST_USR.T2 | 199996 | 199996 | 199996 | 0 | 校验成功 - 数据一致   |
| TEST_USR.T3==TEST_USR.T3 | 300000 | 300000 | 300000 | 0 | 校验成功 - 数据一致   |
| T_TEST_DYNAMIC==T_TEST_DYNAMIC | 2758 | 2757 | 2757 | 1 | 校验成功 - 数据不一致 |

⚠️ 动态表在持续增删改时,静态校验"取快照对比"必然在时间点上差 1~2 行(先读源、后读目标期间数据又变了),不是真实数据丢失。这正是二次校验(rcmp)要解决的问题。

4. 二次校验 rcmp:旧版本不支持,换新版本 bin 解决

CSL> rcmp job jobname=cmp_test1 tab="TEST_USR.T_TEST_DYNAMIC==TEST_USR.T_TEST_DYNAMIC"
CSL[ERROR]: DRS-2802 非法的控制台命令
CSL> show version
| V5.0.4.3-Build(2025.02.20-182015_trunc_sp26)_64 |   ← 旧版本无 rcmp 命令

💡 DVS V5.0.4.3(2025.02 构建)控制台没有实现 rcmp;rcmp 是 V5.2.x 才新增。解决:重新替换新版本 bin → V5.2.5.4。

5. 新版本下二次校验成功

CSL> rcmp job jobname=cmp_test1
CMP[INFO]: [INPUT CMD: RCMP JOB jobname=cmp_test1]
CMP[INFO]: CMP JOB NAME IS: CMP_TEST1, TASK ID IS: 2
命令执行成功
CSL> show report cmp_test1
|       作业名       | 校验任务ID | 表总个数 | 表一致数 | 表差异数 |
|      CMP_TEST1     |      2     |    4    |    4    |    0    |
| TEST_USR.T_TEST_DYNAMIC==TEST_USR.T_TEST_DYNAMIC | 1 | 1 | 1 | 0 | 校验成功 - 数据一致 |

✓ rcmp 对差异行按主键精确定位复校后,动态表差异行校验一致(1 vs 1,diff=0),4/4 表全部一致。

6. 更换 License(key)操作

# 将新 key 文件复制到 bin 目录,并在控制台执行 update lic 生效 cp /dmdata/software/xxx.key /dmdata/dvs/bin/ CSL> update lic | 有效日期 | 授权顾客名称 | 许可证编号 | 版本类型 | | 2099-12-31 | DEVELOP USER | dm*****7 | 试用版 |

四、场景二:数据代理 DVAGENT 静态校验

原理:DVAGENT(CMP_AGENT)与数据库同机部署,本机读数据并格式化发给 DMDVS 的 CMP,解决远程读大对象/大数据表慢的问题。只给"需要代理的库"配(本例只给源库 223 配,目标库直连)。

1. 源库 223 配置 DVAGENT

<?xml version="1.0" encoding="GB18030"?> <dvs> <base> <mgr_port>5350</mgr_port> <siteid>10002</siteid> </base> <agent> <debug>0</debug> <char_trim_space>1</char_trim_space> </agent> </dvs>
# DvagentService 脚本关键项 # INSTALL_HOME=/dmdata/dvs/ PROG_DIR=/dmdata/dvs/bin # CONF_PATH=/dmdata/dvs/bin/agent.xml # EXEC_PROG_NAME=dvagent SERVICE_TYPE_NAME="dvagent server" chmod +x DvagentService ./DvagentService start # Starting DvagentService: [ OK ] ps -ef | grep dvagent # dvagent ... -noconsole ss -lntp | grep 5350 # LISTEN 0.0.0.0:5350 ... dvagent

2. DMDVS(224)为源库绑定代理

CSL> cmp add agent db_src "192.168.x.223" 5350
# 若改端口:cmp alter agent db_src agent_ip="192.168.x.223" agent_port=5350
# 解除:cmp remove agent db_src
CSL> show db   ← 添加 agent 后 DB_SRC 出现代理信息
| 数据库类型 | 数据库信息名 | 服务器名 | 数据库数据代理IP | 数据库数据代理端口号 |
|     DM8    |    DB_DST    | 192.168.x.224 |                  |                    0 |
|     DM8    |    DB_SRC    | 192.168.x.223 | 192.168.x.223 | 5350 |

⚠️ cmp add agent 前 DVAGENT 必须先启动,否则命令失败。

3. 执行静态校验(命令与普通静态一致,源库自动走 agent)

CSL> cmp job jobname=cmp_agent_test db_src db_dst "TEST_USR.*==TEST_USR.*"
| 作业名 | 校验任务ID | 表一致数 | 表差异数 | 校验状态 |
| CMP_AGENT_TEST | 3 | 3 | 1 | 校验成功 - 不一致(动态表正常) |
| TEST_USR.T1==TEST_USR.T1 | 500000 | 500000 | 500000 | 0 | 一致 |
| TEST_USR.T2==TEST_USR.T2 | 199996 | 199996 | 199996 | 0 | 一致 |
| TEST_USR.T3==TEST_USR.T3 | 300000 | 300000 | 300000 | 0 | 一致 |
| T_TEST_DYNAMIC==T_TEST_DYNAMIC | 15883 | 15882 | 15882 | 1 | 不一致(造数中,预期) |

4. 证明真的走了 agent(223 agent 日志)

tail -100f /dmdata/dvs/bin/log/agent_202609.log
2026-09-16 15:39:43 AGENT[INFO]: -------------------------------开始数据代理 CMP_AGENT_TEST(4)src -------------------------------
2026-09-16 15:39:43 AGENT[INFO]: 查询时间统计: src tab_name: TEST_USR.T1 fetch data begin
2026-09-16 15:39:43 AGENT[INFO]: 查询时间统计: src tab_name: TEST_USR.T_TEST_DYNAMIC fetch data end, total time:81(ms)
...
2026-09-16 15:39:45 AGENT[INFO]: -------------------------------结束数据代理 CMP_AGENT_TEST(4)src -------------------------------

💡 校验时 223 的 agent 日志出现"CMP_AGENT_TEST(4)src 开始/结束数据代理"及逐表取数耗时 → 确认源库数据确实经 DVAGENT 读取。如需看每条 SQL:agent.xml 的 debug=1 重启即可打印。


五、场景三:定时调度自动校验(dschsvr)

用独立的定时调度服务 dschsvr 定时触发 DMDVS 的 CMP(静态)/ DCMP(动态)校验。本例:静态校验 + 每 5 分钟 + 并行 4 + 走 223 的 agent。

1. 端口冲突排查:5345 已被 DMDRS 占用

ss -lntp | grep 5345 # LISTEN 0.0.0.0:5345 users:(("drsvr",pid=223052,fd=4)) ← DMDRS drsvr(exec.xml) 占用 # 故 dschsvr 端口改用 5346

2. dsched.xml 配置 + 启动

<?xml version="1.0" encoding="GB18030"?> <sche> <base> <mgr_port>5346</mgr_port> <!-- 避开 DVS 5349 / DRS 5345 --> </base> <sched> <name>sched_drs</name> </sched> </sche>
# DschService 脚本关键项 # INSTALL_HOME=/dmdata/dvs/ PROG_DIR=/dmdata/dvs/bin # CONF_PATH=/dmdata/dvs/bin/dsched.xml # EXEC_PROG_NAME=dschsvr SERVICE_TYPE_NAME="sched server" ./DschService start # Starting DschService: [ OK ] ps -ef | grep dschsvr # dschsvr ... -noconsole ss -tunlp | grep 5346 # LISTEN 0.0.0.0:5346 ... dschsvr

3. 添加定时静态校验 job(每 5 分钟 + PARALLEL|4)

CSL> alter sched_drs add job cmp_dyn_5min \
"2026-9-16 16:10:00" "2027-1-1 00:00:00" "0 */5 * * * *" \
cmp "192.168.x.224:5349" "db_src db_dst" \
"TEST_USR.T_TEST_DYNAMIC==TEST_USR.T_TEST_DYNAMIC" \
"GROUP|5|PARALLEL|4|USERULE|NULL|OMITDATA|0|FAST|0|GROUP_FUNC|0|COL_CMP|0"
MGR[INFO]: 成功添加调度任务 jobname:cmp_dyn_5min
调度任务添加成功
CSL> show sched           ← 添加后:空闲,调度次数 0
| 序号 | 调度任务名 | 状态 | 调度次数 | 成功次数 | 失败次数 | 调度类型 |  调度规则  | 是否启用 |
|  1 | cmp_dyn_5min | 空闲 |  0 | 0 | 0 | CMP | 0 */5 * * * * | YES |

参数说明:

参数 值 说明
任务名 cmp_dyn_5min 调度任务名称
启动-结束 2026-9-16 ~ 2027-1-1 生效区间
TIME_MASK 0 */5 * * * *秒 分 时 日 月 周 → 每 5 分钟触发
功能 cmp 静态校验(dcmp 为动态)
DMDVS 192.168.x.224:5349 DMDVS 服务地址
DB 信息 db_src db_dst 两端库信息名(db_src 已绑 agent)
表组 T_TEST_DYNAMIC==… 只校动态表
掩码 PARALLEL|4 等 并发表组数 4

4. 到点自动触发 —— 完整证据链

① 源端 223 agent 日志(16:10:00 定时任务自动触发取数):

2026-09-16 16:10:00 AGENT[INFO]: -------------------------------开始数据代理 JOB_1(5)src -------------------------------
2026-09-16 16:10:00 AGENT[INFO]: 查询时间统计: src tab_name: TEST_USR.T_TEST_DYNAMIC fetch data end, total time:58(ms)
2026-09-16 16:10:00 AGENT[INFO]: -------------------------------结束数据代理 JOB_1(5)src -------------------------------

② 调度服务状态(16:10 后):工作 + 调度次数 1

| 1 | cmp_dyn_5min | 工作 | 1 | 0 | 0 | CMP |

③ DMDVS 端自动生成作业 JOB_1,报告数据一致:

|  作业名  | 源数据库名 | 目标数据库名 | 校验表组 | 校验掩码 |
| JOB_1    | DB_SRC     | DB_DST       | TEST_USR.T_TEST_DYNAMIC==... | PARALLEL|4|GROUP|5|... |
| TEST_USR.T_TEST_DYNAMIC==TEST_USR.T_TEST_DYNAMIC | 17932 | 17932 | 17932 | 0 | 校验成功 - 数据一致 |

✓ 三端证据闭环:16:10:00 定时触发 → 223 agent 开始取数(JOB_1)→ DMDVS 生成作业 JOB_1 并校验通过(17932 vs 17932,diff=0,耗时 71ms)。

5. 调度任务管理

CSL> alter sched_drs disable cmp_dyn_5min        # 暂停(不带 job 关键字)
CSL> alter sched_drs enable cmp_dyn_5min         # 恢复
CSL> alter sched_drs delete cmp_dyn_5min         # 删除
CSL> alter sched_drs clear his cmp_dyn_5min      # 清空该任务历史
CSL> alter sched_drs modify job cmp_dyn_5min "start_time=..."   # 改参数(这个才带 job)
CSL> show sched_drs schedule job                 # 查看所有任务(或直接 show sched)
CSL> show sched_drs schedule his cmp_dyn_5min    # 查看执行历史(含错误原因)

💡 enable/disable/delete/clear his 后直接跟任务名,不带 job 关键字;仅 add job / modify job 带 job 关键字。


六、经验总结与踩坑记录

# 经验 / 坑 要点
1 版本差异导致命令不存在 V5.0.4.3(2025.02)无 rcmp;V5.2.5.4(2026.06)才有。执行前先 help / show version 确认,避免 DRS-2802
2 动态数据表静态校验必现 diff 持续增删改的表,静态校验两次快照时间点不同会差 1~2 行,属正常。追平后用 rcmp 二次校验(按主键定位差异行)或改走 dcmp 动态校验
3 DVAGENT 部署位置 与"被代理的数据库"同机,只给需要的库配(源库配、目标直连);add agent 前 DVAGENT 必须先启动,否则命令失败
4 端口规划(同机多服务) DVS 5349 / DVAGENT 5350 / DMDRS 5345 / DSCH 5346;DMDRS 若占 5345,dschsvr 必须换端口
5 调度管理命令别带 job enable/disable/delete/clear his 后直接跟任务名;仅 add job / modify job 带 job
6 License 管理 试用 key 可换正式/其他 key,bin 目录放 key 后 update lic 生效;换 bin 后 key 需重新放置
7 证明走 agent / 定时触发 看被代理库所在机 log/agent_yyyyMM.log(开始/结束数据代理、逐表 fetch 耗时);debug=1 可打印全部 SQL
8 mem_size 警告 dvs.xml 默认 mem_size 16G 超出系统空闲内存会有 WARN,仅提示,按机器实际调整

七、关键命令速查

cmp add db dm8 <名> "IP" 用户名 口令 端口          # 注册库
cmp alter db <名> [user= | pwd= | port=..]
show db
cmp add agent <名> "IP" 5350                        # 绑数据代理
cmp alter agent <名> agent_port=5350
cmp remove agent <名>
cmp job jobname=x db_src db_dst "SCH.*==SCH.*"      # 建静态校验作业
cmp job jobname=x                                   # 复用作业重跑
rcmp job jobname=x [task_id] [tab="pair"]           # 二次校验(V5.2+)
show cmp_task x | show report x | show detail x "sch.tab"
alter sched_drs add job <名字> "起" "止" "TIME_MASK" \
  cmp ["作业名"] "DMDVS:5349" "db_src db_dst" "pair" "MASK"
# dcmp 动态:... dcmp "DMDVS:5349" "源DMDRS:5345/cpt名" "sch.*"
alter sched_drs disable|enable|delete <任务名>
show sched | show sched_drs schedule job
show sched_drs schedule his <任务名>
0 */5 * * * *    每 5 分钟
0 0 0 * * *      每天 0 点
0 30 21 * * *    每天 21:30
*/5 * * * * *    每 5 秒(慎用)

八、总结

本文完整走通了 DMDVS 从部署到三大场景的闭环:

安装(bin + License + 依赖库)→ 注册数据库(cmp add db)
    → 场景一:静态校验 + 动态差异 + rcmp 二次校验(版本坑:V5.0.4.3 无 rcmp → 换 V5.2.5.4)
    → 场景二:DVAGENT 数据代理(同机取数提速,agent 日志证明走代理)
    → 场景三:dschsvr 定时调度(TIME_MASK 每 5 分钟 + 三端证据闭环)

核心要点可归纳为三句话:

  • 校验上:数据静止用 cmp job,数据在变先 cmp 后 rcmp 二次校验,动态追平场景直接走 dcmp;
  • 提速上:大表远程读慢给库配 DVAGENT(同机取数),是否走代理看库端 agent 日志,debug=1 可看每条 SQL;
  • 自动化上:dschsvr 定时调度 ALTER ADD JOB + TIME_MASK 六段,管理命令不带 job、add/modify 才带 job。

掌握这套流程,迁移割接后的数据一致性把关就能快速自动化,配合 DMDRS 的 dcmp 动态校验可覆盖全量数据校验场景。

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服