注册
搭建DMHS单向和双向同步
专栏/技术分享/ 文章详情 /

搭建DMHS单向和双向同步

夏雨雨雨雨雨 2026/08/28 112 0 0
摘要

搭建DMHS单向和双向同步

本次搭建的是 dm8 - dm8 的 dmhs单向和双向同步,首先介绍单向同步的搭建过程,接着在此基础上修改搭建为双向同步,加深理解。

搭建DMHS单向同步

这里搭建的是 dm8 - dm8 的 dmhs 单向同步,使用两个虚拟机分别作为源端和目的端。

一、前期准备工作

先给出所需内容的一览表如下:

目录 内容
源端IP 192.168.229.187
目的端IP 192.168.229.186
KEY文件 dmhsXXX.key
源端xml文件 dmhs_cpt.xml
目的端xml文件 dmhs_exec.xml
dmhs安装包 dmhs_XXX.bin
归档日志配置文件 dmarch.ini
自动调优工具 dm.sql
性能监控工具 nmon.dat
监控脚本 monitor_damp.sh
SQL日志的配置文件 sqllog.ini
调试所需的工具包 symbols.zip
接口的压缩包 dmdci.zip

需要两个dm8的虚拟机,建议先安装一台安装上dm8的虚拟机模板,接下来需要dm8的同步可以直接克隆,只需要修改IP地址,减少重复性操作。

修改IP地址:

#查看当前网卡名称 ip addr #编辑网卡配置文件 sudo vi /etc/sysconfig/network-scripts/ifcfg-ens33 #修改配置内容 BOOTPROTO=static # 把 dhcp 改成 static ONBOOT=yes # 确保是 yes,表示开机自启 IPADDR=192.168.229.187 # 固定 IP,两个dm8虚拟机不一样 NETMASK=255.255.255.0 # 子网掩码,一般是这个 GATEWAY=192.168.229.2 # 网关,通常是 .1 或 .2,看你的环境 DNS1=114.114.114.114 # DNS 服务器(也可以填 8.8.8.8) #重启网络服务 sudo systemctl restart network #验证是否生效 ip addr | grep inet

修改完后,可以获得两个固定的IP地址的虚拟机。

新建传输其余文件的目录:

mkdir /opt/dm

接着,其他文件通过xftp传输至你新建的目录下

这样,所有前期需要的内容已准备完毕

二、安装dmhs

两边的dm8虚拟机都需要安装dmhs,步骤一致,也可以在之前提到的模板中直接安好,看自身的使用用途。

2.1 给dmhs安装包执行权限

前期已将安装包传入,在两个虚拟机内都安装好dmhs。

赋予所有用户对安装的读、写和执行权利:

chmod 777 dmhs_XXX.bin

更改安装包属组和属主:

chown dmdba:dinstall dmhs_XXX.bin

这里不需要加-R,-R 为递归更改,为子文件和子目录更改

2.2 开始安装

切换到dmdba用户下执行,下面为具体的安装步骤:

./dmhs_XXX.bin -i Extract install files.......... 1.英文(English) 2.简体中文(简体中文) 安装语言[2.简体中文(简体中文)]:2 1.免费试用达梦数据实时同步 2.使用已申请的Key文件 验证许可证文件[1.免费试用达梦数据实时同步]:2 输入Key文件路径:/opt/dm/dmhsXXX.key 1.标准版 2.企业版 3.自定义 安装类型[1.标准版]:1 1.服务器 2.配置助手 3.手册 所需磁盘空间:352 MB 安装目录: [/home/dmdba/dm/dmhs] 正在安装 正在创建快捷方式 安装成功 服务器配置 1.英文(English) 2.简体中文(简体中文) 语言[2.简体中文(简体中文)]:2 请输入mgr端口号 (1000-65535)[5345]:5345 请输入信息收集间隔 时间(1-60)秒[3]:3 请输入检查点间隔时间(10-65536)秒[60]:60 请输入站点id(0-65536):1 Please login as root user:copy /home/dmdba/dm/dmhs/bin/dmhs_serverd to /etc/rc.d/init.d 达梦数据实时同步 V4.0 安装完成 更多安装信息,请查看安装日志文件: /home/dmdba/dm/dmhs/log/install.log

这样,dmhs同步软件就算安装完成了。

三、源端

3.1 开启逻辑附加日志

修改dm.ini:

ARCH_INI = 1 --开启归档 RLOG_APPEND_LOGIC = 1 -- 开启逻辑附加日志

修改完日志需要重启数据库:

cd /home/dmdbda/dm/dmdbms/bin ./dmserverd restart

3.2 创建目录和辅助表

源端需要创建目录:

/dbbak/dmhs_dict

打开管理工具

cd /home/dmdba/dm/dmdbms/tool ./manager

进入管理工具后,会出现可视化的界面,在里面找到scripts目录,执行里面的脚本:

#我们可以在scripts目录下看到很多版本的脚本,我们这次是dm8的同步,选择ddl_sql_dm8.sql [root@localhost dmhs]# cd scripts/ [root@localhost scripts]# ls ddl_sql_db2.sql ddl_sql_dm7.sql ddl_sql_pg.sql dmhs_grant.sql root ddl_sql_dm6_v2.sql ddl_sql_dm8.sql delete_data_before_7day.sql dmhs_manager.sql setenv.sh ddl_sql_dm6_v3.sql ddl_sql_ora.sql dmhs_cdb_grant.sql readme.txt

image.png

image.png

image.png

验证是否真的执行成功:

SQL >SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'SYSDBA' AND TABLE_NAME LIKE 'DMHS_%'; #输出应包含 #DMHS_DDL_SQL #DMHS_TRXID_TABLE

image.png

3.3 放入配置文件

将用xftp传输的.xml配置文件和key放到dmhs/bin/目录下:

cp dmhs.cpt.xml dmhs.key /home/dmdba/dm/dmhs/bin/

将dmhs.ctp.xml改为dmhs.xml

mv dmhs.ctp.xml dmhs.xml
[root@localhost ~]# cd /home/dmdba/dm/dmhs/bin [root@localhost bin]# ls clear_log dmhs_veri libdmhs_ld_dm8.so script DDL dmhs_veri_agent_dm8 libdmhs_lic_dll.so service_template dmhs_0_0.ini dmhs_veri_local_dm8 libdmhs_lic.so SQL dmhs_2_0.ini dmhs.xml libdmhs_net.so stat dmhs_bak.conf ERR libdmhs_pub.so symbols dmhs.conf ld_tableid_2.dat libdmhs_sdo2dmgeo.so TemplateDmhsGuardService dmhs_console libcpt_dm8.so libdmhs_ucvt.so TemplateDmhsGuardServiceHA dmhs_cpt.tmp libcpt_dsc.so libdmhs_xml.so TemplateDmhsService dmhs_dict_chk libdmhs_api.so libdmuts.so trace dmhs_exe.tmp libdmhs_bool_parse.so libexec_ins_dm8.so TRX dmhs_guard libdmhs_cvt.so log TSK dmhs.key libdmhs_dm_obj.so pids UDT dmhs_server libdmhs_exec.so _REPLACE_SELF_DMHS_HOME veri_xml_crt dmhs_serverd libdmhs_exp.so _REPLACE_SELF_DMHS_PROG_DIR

3.4 配置后台启动脚本

可以看到脚本启动服务模板下很多服务:

[root@localhost bin]# cd service_template/ [root@localhost service_template]# ls AgentDb2Service AgentMssService DmhsGuardService TemplateDmhsAgentService AgentDm6Service AgentMysqlService DmhsService TemplateDmhsService AgentDm7Service AgentOraService DmhsStatService AgentDm8Service AgentPgService DmhsWebService AgentKingbaseService DmhsAgentService DmService

将脚本里的路径改为实际路径:

cd /home/dmdba/dm/dmhs/bin/service_template/ cp DmhsService ../dmhs_serverd vi dmhs_serverd # 修改以下四项路径: # DMHS_HOME=/home/dmdba/dm/dmhs # DMHS_BIN=/home/dmdba/dm/dmhs/bin # DMHS_CONF=/home/dmdba/dm/dmhs/bin/dmhs.xml # DMHS_PATH=/home/dmdba/dm/dmhs/bin:/home/dmdba/dm/dmdbms/bin ./dmhs_serverd start

3.5 源端执行装载命令

./dmhs_console DMHS >connect DMHS >COPY 0 "SCH.NAME IS NOT NULL" DICT|LSN (从当前开始同步) DMHS >start cpt

3.6 插入数据

将源端与目的端都配置完成和控制台启动后,再插入数据验证。

将当前用户切换为 TEST 用户,插入数据:

INSERT INTO CLASS VALUES (1, '高一(1)班', 1, '张明', 45, 'A栋101', DATE '2025-09-01'); INSERT INTO CLASS VALUES (2, '高一(2)班', 1, '李红', 42, 'A栋102', DATE '2025-09-01'); INSERT INTO CLASS VALUES (3, '高一(3)班', 1, '王芳', 48, 'A栋103', DATE '2025-09-02'); INSERT INTO CLASS VALUES (4, '高二(1)班', 2, '赵强', 50, 'B栋201', DATE '2024-09-01'); INSERT INTO CLASS VALUES (5, '高二(2)班', 2, '孙丽', 47, 'B栋202', DATE '2024-09-01'); INSERT INTO CLASS VALUES (6, '高二(3)班', 2, '周梅', 44, 'B栋203', DATE '2024-09-02'); INSERT INTO CLASS VALUES (7, '高三(1)班', 3, '吴刚', 52, 'C栋301', DATE '2023-09-01'); INSERT INTO CLASS VALUES (8, '高三(2)班', 3, '郑洁', 49, 'C栋302', DATE '2023-09-01'); INSERT INTO CLASS VALUES (9, '高三(3)班', 3, '陈静', 46, 'C栋303', DATE '2023-09-02'); INSERT INTO CLASS VALUES (10, '高三(4)班', 3, '刘洋', 40, 'C栋304', DATE '2023-09-02');

四、目的端

4.1 放入配置文件

将用xftp传输的.xml配置文件和key文件放到软件目录下:

cp dmhs.exec.xml dmhs.key /home/dmdba/dm/dmhs/bin/

将dmhs.exec.xml改为dmhs.xml

mv dmhs.exec.xml dmhs.xml

4.2 配置后台启动脚本

cd /home/dmdba/dm/dmhs/bin/service_template/ cp DmhsService ../dmhs_serverd vi dmhs_serverd # 修改以下四项路径: # DMHS_HOME=/home/dmdba/dm/dmhs # DMHS_BIN=/home/dmdba/dm/dmhs/bin # DMHS_CONF=/home/dmdba/dm/dmhs/bin/dmhs.xml # DMHS_PATH=/home/dmdba/dm/dmhs/bin:/home/dmdba/dm/dmdbms/bin ./dmhs_serverd start

4.3 目的端启动执行线程

./dmhs_console DMHS >connect DMHS >start exec

五、dmhs.xml配置文件

5.1 源端dmhs.xml

在原来传输进来的xml配置文件上的DDL处增加了用户USER,原先传输的逻辑是源端和目的端都有相同的用户和模式,不需要再次传输,而且当源端增加时,也无需再次向目的端传输,目的端也无需这些新用户。

此处为了测试是否联通,增加了USER。

需要注意:是否创建了字典目录;发送的目的端IP是否正确;发送的源端填本机IP。

<?xml version="1.0" encoding="GB2312"?> <dmhs> <base> <lang>ch</lang> <mgr_port>5345</mgr_port> <chk_interval>3</chk_interval> <ckpt_interval>60</ckpt_interval> <siteid>1</siteid> </base> <cpt> <db_type>dm8</db_type> <db_server>127.0.0.1</db_server> #发送端ip <db_user>SYSDBA</db_user> #设成初始化数据库时的密码 <db_pwd>SYSDBA</db_pwd> <db_port>5236</db_port> <idle_time>10</idle_time> #需要创建此目录 <dict_dir>/dbbak/dmhs_dict</dict_dir> <ddl_mask>TABLE:VIEW:PROCEDURE:FUNCTION:TRIGGER:INDEX:CHECK:SEQUENCE:PACKAGE:TYPE:SYNONYM:OP:USER</ddl_mask> <parse_thr>1</parse_thr> <arch> <clear_interval>600</clear_interval> <clear_flag>0</clear_flag> </arch> <send> #目的端ip <ip>192.168.229.186</ip> <mgr_port>5345</mgr_port> <data_port>5346</data_port> <level>0</level> <trigger>1</trigger> <constraint>1</constraint> <identity>1</identity> <net_turns>0</net_turns> <filter> <enable> <item>*.*</item> </enable> <disable> </disable> </filter> <map> <item></item> </map> </send> </cpt> </dmhs>

5.2 目的端dmhs.xml

这里捕获模块IP填本机IP,注意站点需要与源端区别开。

<?xml version="1.0" encoding="GB2312"?> <dmhs> <base> <lang>ch</lang> <mgr_port>5345</mgr_port> <chk_interval>2</chk_interval> <ckpt_interval>45</ckpt_interval> #站点与源端区分开 <siteid>2</siteid> </base> <recv> <data_port>5346</data_port> <exec> <check_index>0</check_index> <db_type>dm8</db_type> #填本机IP <db_server>127.0.0.1</db_server> <db_user>SYSDBA</db_user> #设成初始化数据库时的密码 <db_pwd>SYSDBA</db_pwd> <db_port>5236</db_port> <db_name></db_name> <exec_mode>1</exec_mode> <exec_thr>16</exec_thr> <exec_sql>512</exec_sql> <exec_trx>5000</exec_trx> <exec_rows>250</exec_rows> <exec_policy>2</exec_policy> <msg_col_size>8000</msg_col_size> <level>0</level> <affect_row>0</affect_row> <tag> <schema>NUSP</schema> <sql>update NUSP.DY_DOWNLOAD_SIGNAL set DOWNLOAD_FLAG=0,MODIFY_TIME=sysdate where table_name_eng=lcase('%s');</sql> <before_commit>0</before_commit> </tag> </exec> </recv> </dmhs>

六、验证单向同步是否成功

在187源端执行新建用户、表和插入数据后,可以浏览数据看到:

image.png

可以在186目的端查询到数据,同步成功

image.png

改为 DMHS双向同步

一、整体架构理解

双向同步 = 两个方向相反的单向同步任务的组合

任务 方向 说明
任务一 187 → 186 源端187捕获,发送给186执行(已搭建好)
任务二 186 → 187 源端186捕获,发送给187执行(需要新增)

二、开启归档和逻辑附加日志

2.1 两个方向都需要开启归档和逻辑日志

在两台服务器上都要执行:

# 修改 dm.ini vi /home/dmdba/dm/dmdbms/data/DAMENG/dm.ini ARCH_INI = 1 # 开启归档 RLOG_APPEND_LOGIC = 1 # 开启逻辑附加日志 # 重启数据库生效 cd /home/dmdba/dm/dmdbms/bin ./dmserverd restart

三、创建目录和辅助表

源端已经创建过目录和辅助表,现在需要在目的端也创建。

目的端也需要创建目录:

/dbbak/dmhs_dict

打开管理工具

cd /home/dmdba/dm/dmdbms/tool ./manager

进入管理工具后,会出现可视化的界面,在里面找到scripts目录,执行里面的脚本:

image.png

image.png

image.png

三、修改配置文件

需要修改186和187的.xml配置文件,主要是分为接收方和发送方,IP地址需要改动,其余基本不变.

3.1 187(原先的源端)修改

主要增加了接收模块:

<?xml version="1.0" encoding="GB2312"?> <dmhs> <base> <lang>ch</lang> <mgr_port>5345</mgr_port> <chk_interval>3</chk_interval> <ckpt_interval>60</ckpt_interval> <siteid>1</siteid> <!-- ← 站点ID=1 --> </base> <cpt> <!-- ← 捕获模块:负责发送数据到186 --> <db_type>dm8</db_type> <db_server>127.0.0.1</db_server> <db_user>SYSDBA</db_user> <db_pwd>SYSDBA</db_pwd> <db_port>5236</db_port> <dict_dir>/dbbak/dmhs_dict</dict_dir> <ddl_mask>TABLE:VIEW:PROCEDURE:FUNCTION:TRIGGER:INDEX:CHECK:SEQUENCE:PACKAGE:TYPE:SYNONYM:OP</ddl_mask> <send> <ip>192.168.229.186</ip> <!-- ← 发往186 --> <mgr_port>5345</mgr_port> <data_port>5346</data_port> <filter> <enable><item>TEST.*</item></enable> </filter> </send> </cpt> <recv> <!-- ← 接收模块:负责接收来自186的数据 --> <data_port>5346</data_port> <exec> <db_type>dm8</db_type> <db_server>127.0.0.1</db_server> <db_user>SYSDBA</db_user> <db_pwd>SYSDBA</db_pwd> <db_port>5236</db_port> <exec_mode>1</exec_mode> <exec_thr>16</exec_thr> <exec_sql>512</exec_sql> <exec_trx>5000</exec_trx> <exec_rows>250</exec_rows> <exec_policy>2</exec_policy> </exec> </recv> </dmhs>

3.2 186(原先的目的端)修改

主要增加了发送模块:

<?xml version="1.0" encoding="GB2312"?> <dmhs> <base> <lang>ch</lang> <mgr_port>5345</mgr_port> <chk_interval>3</chk_interval> <ckpt_interval>60</ckpt_interval> <siteid>2</siteid> <!-- ← 站点ID=2,与187不同 --> </base> <cpt> <!-- ← 捕获模块:负责发送数据到187 --> <db_type>dm8</db_type> <db_server>127.0.0.1</db_server> <db_user>SYSDBA</db_user> <db_pwd>SYSDBA</db_pwd> <db_port>5236</db_port> <dict_dir>/dbbak/dmhs_dict</dict_dir> <ddl_mask>TABLE:VIEW:PROCEDURE:FUNCTION:TRIGGER:INDEX:CHECK:SEQUENCE:PACKAGE:TYPE:SYNONYM:OP</ddl_mask> <send> <ip>192.168.229.187</ip> <!-- ← 发往187 --> <mgr_port>5345</mgr_port> <data_port>5346</data_port> <filter> <enable><item>TEST.*</item></enable> </filter> </send> </cpt> <recv> <!-- ← 接收模块:负责接收来自187的数据 --> <data_port>5346</data_port> <exec> <db_type>dm8</db_type> <db_server>127.0.0.1</db_server> <db_user>SYSDBA</db_user> <db_pwd>SYSDBA</db_pwd> <db_port>5236</db_port> <exec_mode>1</exec_mode> <exec_thr>16</exec_thr> <exec_sql>512</exec_sql> <exec_trx>5000</exec_trx> <exec_rows>250</exec_rows> <exec_policy>2</exec_policy> </exec> </recv> </dmhs>

四、启动双向同步

4.1 在 187 上启动服务

187与之前的相比,在启动“发送方”(CPT)之前,必须确保“接收方”(EXEC)已经准备好,并且完成了数据的“初始化对齐”。

  1. start exec 必须先执行:exec 是负责把数据写入目标库的“执行器”。它启动后,会在目标库里创建一些供自己使用的辅助表(比如记录哪些事务已经执行过了)。只有这些辅助表建好了,数据来了才有地方可去,初始化才不会报错。
  2. COPY ... REG 紧随其后:COPY 命令用于把源端的存量数据(表结构和历史数据)初始化到目标端。在双向同步里,必须配合 REG 参数来使用。
  3. 最后启动 cpt:数据装载完成后,再启动源端的“捕获器”(CPT),它就开始从当前时刻抓取新的变更进行同步了。如果顺序反过来,cpt 先启动了,它可能会把一些还没准备好的中间状态日志也抓走,导致数据不一致。
su - dmdba cd /home/dmdba/dm/dmhs/bin # 配置后台启动脚本(如果还没配置) cp service_template/DmhsService dmhs_serverd vi dmhs_serverd # 修改以下四项路径: # DMHS_HOME=/home/dmdba/dm/dmhs # DMHS_BIN=/home/dmdba/dm/dmhs/bin # DMHS_CONF=/home/dmdba/dm/dmhs/bin/dmhs.xml # DMHS_PATH=/home/dmdba/dm/dmhs/bin:/home/dmdba/dm/dmdbms/bin # 启动服务 ./dmhs_serverd start # 进入控制台 ./dmhs_console # 在控制台中执行,注意执行顺序 DMHS > connect DMHS > start exec # 启动执行(接收来自186的数据) DMHS > COPY 0 "SCH.NAME IS NOT NULL" DICT|LSN|REG # 初始化装载 DMHS > start cpt # 启动捕获

4.2 在 186 上启动服务

186也需要执行与187相同的命令:

su - dmdba cd /home/dmdba/dm/dmhs/bin # 配置后台启动脚本 cp service_template/DmhsService dmhs_serverd vi dmhs_serverd # 同样修改四项路径 # 启动服务 ./dmhs_serverd start # 进入控制台 ./dmhs_console # 在控制台中执行,注意执行顺序 DMHS > connect DMHS > start exec # 启动执行(接收来自187的数据) DMHS > COPY 0 "SCH.NAME IS NOT NULL" DICT|LSN|REG # 初始化装载 DMHS > start cpt # 启动捕获

双向同步增加了REG:

REG 参数的核心作用:防止“数据回环”。

在双向同步中,最怕的就是数据 “ 一去一回 ” 形成死循环。比如:187 插入一条数据,cpt 捕获并同步到 186。186 的 cpt 也捕获到了这条“由A库发来的”插入操作,如果不加区分,它又会把它同步回 187。如此往复,数据就永远停不下来了。

REG (REGISTER) 参数就是为了打破这个循环。它的核心作用是打标记:当 COPY 命令配合 REG 执行时,它会在目标端的辅助表里 “登记” 这个初始化事务,打上一个“已由我处理过”的标记。

五、验证双向同步是否成功

5.1 在 187 上插入数据,检查 186

#在 187 上插入 INSERT INTO TEST.CLASS VALUES (11, '高一(5)班', 1, '王磊', 38, 'A栋105', DATE '2025-09-03'); COMMIT; #在 186 上查询,应该能看到这条新数据 SELECT * FROM TEST.CLASS WHERE CLASS_ID = 11;

5.2 在 186 上插入数据,检查 187

# 在 186 上插入 INSERT INTO TEST.CLASS VALUES (12, '高一(6)班', 1, '李娜', 41, 'A栋106', DATE '2025-09-03'); COMMIT; #在 187 上查询,应该能看到这条新数据 SELECT * FROM TEST.CLASS WHERE CLASS_ID = 12;

image.png

image.png

5.3 查看同步状态

在任意一台的 DMHS 控制台中:

DMHS > show status
DMHS> state MGR: Execute TYPE VID SITEID EXEC/CPT IP PORT DBNAME ------- --- ------ --------------- ---- ------ Capture 0 2 192.168.229.187 5347 Execute 0 0 127.0.0.1 0 Execute 0 1 192.168.229.187 5347
评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服