本文基于 DM8⇄DM8 测试环境(192.168.x.223 源 / 192.168.x.224 目标),完整记录达梦数据校验软件 DMDVS(V5.2.5.4)的三大实战场景:静态数据校验 + 二次校验(RCMP)、数据代理 DVAGENT 静态校验、dschsvr 定时调度自动校验。所有 IP、端口、口令、许可编号均为示例值,请按实际环境调整。
迁移割接后最怕"数据对不上"。达梦 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 |
使用离线安装包,中文交互式安装;依赖达梦客户端动态库路径;指定 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 |
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%。
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 &
| 作业名 | 校验任务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)要解决的问题。
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。
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 表全部一致。
# 将新 key 文件复制到 bin 目录,并在控制台执行 update lic 生效
cp /dmdata/software/xxx.key /dmdata/dvs/bin/
CSL> update lic
| 有效日期 | 授权顾客名称 | 许可证编号 | 版本类型 |
| 2099-12-31 | DEVELOP USER | dm*****7 | 试用版 |
原理:DVAGENT(CMP_AGENT)与数据库同机部署,本机读数据并格式化发给 DMDVS 的 CMP,解决远程读大对象/大数据表慢的问题。只给"需要代理的库"配(本例只给源库 223 配,目标库直连)。
<?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
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 必须先启动,否则命令失败。
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 | 不一致(造数中,预期) |
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 定时触发 DMDVS 的 CMP(静态)/ DCMP(动态)校验。本例:静态校验 + 每 5 分钟 + 并行 4 + 走 223 的 agent。
ss -lntp | grep 5345
# LISTEN 0.0.0.0:5345 users:(("drsvr",pid=223052,fd=4)) ← DMDRS drsvr(exec.xml) 占用
# 故 dschsvr 端口改用 5346
<?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
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 |
① 源端 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)。
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;debug=1 可看每条 SQL;ALTER ADD JOB + TIME_MASK 六段,管理命令不带 job、add/modify 才带 job。掌握这套流程,迁移割接后的数据一致性把关就能快速自动化,配合 DMDRS 的 dcmp 动态校验可覆盖全量数据校验场景。
文章
阅读量
获赞
