news 2026/10/3 14:29:27

用DMHS实现MySQL和达梦双向同步:架构、配置与踩坑全记录

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用DMHS实现MySQL和达梦双向同步:架构、配置与踩坑全记录

做数据库迁移和同步,不少人的第一反应是上应用层双写,或者套一个第三方CDC工具。但如果你正在做的项目涉及达梦数据库,而且要求Oracle或MySQL和达梦之间做准实时数据同步,那达梦官方自带的DMHS这套实时同步组件,基本是你绕不开的核心选项。这篇文章不聊PPT上的宣传指标,只记录我最近一次基于DMHS在MySQL和达梦之间搭建双向同步的完整过程:从整体架构拆解、环境准备、任务配置,到双向防循环设计以及中途踩过的各种坑。如果你正准备上手DMHS,或者已经在排障路上绕圈子,这份部署实例应该能让你少走不少弯路。

1. 整体设计与架构拆解

1.1 为什么最终选了DMHS

我在做这个项目之前,先把市面上常见的同步方案都过了一遍。应用层双写最直观,业务代码里同时写两个库,但牵扯事务一致性、失败补偿、接口超时等一系列问题,而且改造量大,几乎等于重写数据访问层。基于binlog的第三方同步工具虽然生态成熟,但面对达梦时生态支持就很尴尬,不少工具要么不支持达梦作为目标端,要么需要额外写插件。

DMHS是达梦自带的实时同步组件,走的是日志解析路线,源端读取本地日志,目标端执行装载,对业务系统来说基本无侵入。这意味着应用代码不用改,数据库账号只需要具备读取日志和写入目标库的权限。对异构数据库场景来说,这种“日志级同步”的侵入性优势非常明显。

还有一个现实因素:客户要求后期的运维边界清晰。如果是自研同步逻辑,一旦出问题,排查链路会很长;如果是DMHS,官方对达梦侧的行为有明确约束,问题定位能限定在配置和网络层面。从交付角度看,选择官方组件,后续维护和文档说明都有据可查。

1.2 单向同步到双向同步的差异

很多项目一开始只提单向需求,比如“把老系统的数据同步到新系统”。但业务一旦跑起来,两边系统都会有人操作,单向很快就满足不了。我这次的需求很明确:MySQL侧的应用继续读写,达梦侧的应用也要读写,两边数据要尽量保持一致,这就是典型的双向同步。

单向同步和双向同步并不是“把任务反过来再建一遍”这么简单,差异主要体现在三个方面:

维度单向同步双向同步
任务数量一个同步任务即可至少两个任务,方向相反
数据流向源端到目标端,单向流动两端互为源和目标,双向流动
冲突风险低,基本不会出现双写冲突高,同一记录可能被两端同时修改
防循环要求不需要额外设计必须考虑环路问题
初始实施成本较低,配置简单较高,需要逐表规划同步方向

从架构上看,双向同步的每一端都需要部署一套DMHS服务。A库上的DMHS负责把A库的变更推到B库,B库上的DMHS负责把B库的变更推到A库。两套任务独立运行,互不依赖。

但这里有一个关键细节,也是很多人容易忽视的:双向同步不等于双活双写。如果同一张表在两端都允许应用直接修改,那同步回灌产生的环路和冲突会非常难处理。我后面会在部署章节详细讲怎么通过表级方向割分来规避这个问题。

1.3 DMHS各组件的角色分工

DMHS整体上分三个主要部分:部署在源端的服务组件、部署在目标端的执行组件,以及用来管理配置和监控的控制台组件。源端组件负责读取日志、解析变更、发送数据;目标端组件负责接收数据并写入目标库;控制台组件负责创建同步任务、启停服务、查看运行状态。

用一个生活化的类比来说:源端组件像抄写员,盯着源库日志,把新发生的变更一条条抄下来;网络传输像快递链路,把抄写的内容运到目标端;目标端组件像入库员,把快递内容逐条写进目标库。控制台则像调度室,你只需要在调度室查看全局状态。

这个分工决定了部署位置:源端和目标的服务器上必须分别装好对应组件,控制台可以装在管理机上远程连接。规划网络时,要注意两端之间的端口连通性,防火墙策略需要提前放行,否则配置好了任务却连不上,排查起来相当费时间。

2. 环境准备:从达梦安装到连接链路打通

2.1 达梦数据库本身的安装要点

要搭建DMHS同步环境,前提是达梦数据库实例能正常跑起来。目前用到比较多的还是DM8,安装过程本身不算复杂,但有几个初始化参数会直接影响后续同步,必须在一开始就确认清楚。

页大小在达梦里一旦初始化完,后期没法轻易修改。页大小选择要考虑业务表行宽和实际存储场景,如果一张表的单行数据较大,页太小会导致行跨页,查询性能受影响。经验上是根据最大表行宽和并发场景综合判断,而不是统一用默认值。

字符集也一样关键。如果源端MySQL用的是UTF-8,达梦初始化时最好也选择UTF-8;如果源端是GBK,两边也要尽量对齐。字符集不一致,同步过来的中文字段非常容易出现乱码。我这次把两端都统一到了UTF-8,省掉了后续编码转换的麻烦。

大小写敏感性决定了SQL里表名和列名的匹配方式。达梦初始化时可以选择大小写不敏感,业务侧可以直接用大写表名操作。这个参数在DMHS同步任务配置时也需要注意,过滤条件里如果出现表名字段,大小写规则要跟库内实际存储一致。

初始化完成后,要确认数据库服务已经启动,默认的管理员账号能正常登录,同时记录好实例名和端口,默认端口一般是5236。还有一步容易被忽略:检查是否启用了本地归档。DMHS靠读取日志来捕获变更,如果源端达梦没有开启归档,日志被复用覆盖后,同步任务就拿不到完整的历史变更数据。这是部署DMHS前必须确认的前置条件。

2.2 连接工具与驱动的那些坑

环境准备好之后,第一件事是验证数据库连接是否正常。Navicat这类通用客户端连接达梦,需要选择对应的数据库类型并加载达梦驱动。如果驱动没配好,或者类型选错,通常会报连接失败或驱动类找不到。

实际排查中我发现,大部分连接问题并不是密码错误,而是服务名选错、实例未启动、驱动版本不匹配。比如报“用户名或密码错误”且错误码是-2501,很多人第一反应是去重置密码,但有时候只是客户端没有正确指定目标实例。建议排查顺序是这样:

排查项具体操作常见结果
服务是否启动在达梦服务器上检查数据库服务进程未启动则启动服务
端口是否连通telnet到目标端口,比如5236不通则检查防火墙
实例名是否匹配确认连接配置里的实例名与dminit创建时一致不一致则报错或连错实例
驱动版本使用与数据库版本匹配的JDBC驱动版本太老可能连不上
账号权限确认账号具备同步所需权限权限不足则无法创建任务

达梦驱动一般跟随安装包提供,在安装目录的jdbc子目录下能找到对应的jar包。Java项目引入时,如果公司Maven私服没有坐标,可以直接用系统依赖方式把本地jar包引入工程,简单直接。Spring Boot项目接入时还需要注意Druid连接池和达梦驱动的兼容性,我遇到过Druid对达梦的DbType识别不准的情况,需要手动指定连接参数。

2.3 DMHS安装与授权注意事项

DMHS的安装包同样来自达梦官方渠道,安装时注意版本要和数据库版本匹配,不同版本之间的协议细节有差异,混用容易出现同步中断或解析失败。安装完成后,还需要配置授权文件,也就是常说的key。

授权文件有有效期,到期后同步服务会停止工作。我在实际项目中遇到过授权到期后任务中断的情况,重启服务无效,查日志才定位到是授权过期。这里给大家一个建议:把授权到期时间记录到运维日历里,提前一个月安排更新;同时了解授权更新流程,避免到期当天手忙脚乱。

DMHS服务启动前,最好先检查安装路径下的配置模板,确认监听的端口、日志目录、工作目录等参数。日志目录尤其重要,排障时如果日志目录在系统盘且空间不足,同步任务会异常退出。我习惯把日志和临时数据单独放到数据盘,并配置好日志轮转。

3. 部署实操:从单向任务到双向同步的实现

3.1 历史数据初始化:同步的前提

DMHS解决的是增量同步,已经存在于源库里的历史数据不会自动同步过来。所以你需要在启动DMHS任务之前,先把源库的历史数据迁移到目标库,业界通常叫“基线导入”。

我这次的处理方式是:先对MySQL侧的业务表做逻辑备份,然后在达梦侧恢复。这里要注意字符集和表结构的兼容性,MySQL的自增列、时间类型、字符串类型在达梦里的表达方式有差异。比如MySQL的datetime类型到达梦后,如果建表语句不调整,可能会因为精度或默认值问题导致数据导入失败。

基线导入完成后,一定要做行数校验和关键字段抽样比对。用“同一条记录在原库和目标库内容一致”来验证迁移质量,不要只看总数对得上就放开手配置同步。数据质量问题如果拖到增量同步阶段才暴露,定位成本会成倍上升。

在正式配置DMHS任务之前,还要记录一个时间点:基线导入完成的时间。这个时间点是增量同步的起点参考。如果DMHS支持从某个日志位置开始解析,那就把起点定位在基线完成的时刻附近,尽量避免漏数据或重复数据。

3.2 配置同步任务:对象、连接和过滤条件

配置同步任务时,需要把同步对象明确到表级。不需要同步的表不要一股脑全部加进来,每加一张表,后续的监控和冲突处理就多一份负担。我这次只选择了业务核心表,比如订单主表、订单明细表,其他配置表另作处理。

配置结构大致是这个思路,以MySQL到达梦方向为例:

同步方向:MySQL -> 达梦 源端连接:源MySQL库的连接信息 目标端连接:目标达梦库的连接信息 同步对象: - 表 orders,同步时排除某些无业务价值的字段 - 表 order_items,按时间条件过滤数据 冲突策略:目标端已存在相同主键记录时,根据业务选择跳过或覆盖

这只是配置思路示例,具体参数名以你手里的DMHS版本模板为准。核心要表达的是:在创建任务之前,把同步对象、过滤条件、冲突策略都想清楚,而不是建完任务发现问题再回来改。

过滤条件是个好东西。如果业务上只需要同步最近一年的订单,可以在任务里加时间过滤条件,减少无效数据传输。但过滤条件也需要定期检查,曾经遇到一个任务配置了时间过滤,业务数据延迟写入导致部分记录绕过过滤条件,两边数据对不齐,排查了很久才发现是过滤条件与业务行为不匹配。

3.3 双向同步的防循环设计

双向同步最核心的技术难点是防止数据“回灌”。假设A库和B库都部署了同步任务,A库的一条数据变更被任务1同步到B库后,B库里会生成新的日志。这条日志如果不加区分,又被任务2捕获回A库,A库再次变更,再同步到B库,数据就像乒乓球一样在两个库之间来回跳,形成无限循环。

规避环路的设计思路,我实际用过三种,按推荐程度排序:

第一种是表级方向割分。每张表在规划时只指定一个同步方向,比如订单表只做MySQL到达梦同步,商品表只做到达梦到MySQL同步。两端应用分别只写各自负责的表,两边数据最终都能看到全量数据,但同一张表的变更只走一条链路,从根本上不会产生环回。

第二种是行级方向标记。如果业务上必须有同一张表双向同步,可以在表里增加一个来源标记字段,源端应用写入时维护该字段,同步任务通过过滤条件跳过本端标记的数据。比如标记值为A的数据只允许从A同步到B,B侧任务读取时过滤掉标记为A的记录,这样B侧应用产生的变更写的是标记B,不会把A同步过来的数据再次同步回去。

第三种是依赖DMHS自身控制能力。不同版本对环路控制的支持不一样,需要仔细看官方文档确认参数行为。如果版本支持,可以试试在任务上开启回环控制相关配置。

我最终采用的是表级方向割分方案。虽然需要和业务确认每张表的归属方向,前期沟通成本高一点,但运行期的数据一致性和可维护性最好,排障时思路清晰,不会出现两边数据反复覆盖的问题。

3.4 启动、监控与数据验证

任务配置完成后,启动前先检查日志目录权限和磁盘空间,避免运行一段时间后日志把盘写满。启动同步任务后,不要马上认为万事大吉,先用一条测试数据跑一遍完整链路。

我当时的验证步骤是:在MySQL侧往订单表插入一条新记录,然后在达梦侧观察是否在预期时间内出现对应记录。确认正向同步正常后,再在达梦侧修改一条记录的备注字段,观察MySQL侧是否出现同步修改。两边都验证通过,再把应用流量逐步切过来。

监控方面,DMHS控制台可以查看同步任务的状态,比较直观的指标是同步延迟。我建议设置一个延迟阈值,比如超过一分钟就告警。延迟突然飙升往往意味着源端归档没有及时生成,或者网络链路有问题。可以把状态查询做成定时脚本,将结果推送到运维群,这样出了问题不用等到业务侧反馈才后知后觉。

4. 常见问题与排查技巧实录

4.1 连接报错“用户名或密码错误”的真相

这个报错我见得太多了,尤其是用Navicat连接达梦时,客户端提示用户名或密码错误,错误码-2501。大部分情况下用户第一反应是改密码,但真正原因可能是客户端和服务端字符集不一致导致提示信息显示异常,也可能是连接配置中的服务名与实际实例不匹配。

之前接手一个环境,用户拿着报错截图来找我,说密码怎么改都对不上。我坐过去一看,连接配置里的服务名写了一个不存在的实例,系统实际实例名是另一个,Navicat拿着错误的服务名去连接,自然报凭据错误。把服务名改正后,同一组账号密码直接就通过了。

遇到这类报错,我建议大家按顺序检查:先确认实例是不是真的启动了;再用命令行工具在服务器本地连接测试;最后才轮到排查网络、驱动、账号权限。本地能连而远程连不上,问题基本在网络或防火墙;本地都连不上,问题大概率在数据库配置。

4.2 字符集引发的“乱码连环坑”

字符集问题在异构数据库同步里出现的频率非常高。创建达梦实例时如果没有选对字符集,同步过来的中文数据很可能变成乱码。更隐蔽的是客户端本身的字符集设置也会影响显示,我在热词里看到有人把“用户名或密码错误”认成了乱码,其实那只是客户端把UTF-8内容按GBK渲染了。

乱码在MySQL和达梦两侧的排查思路不一样。MySQL侧要检查连接参数里的characterEncoding和表字段字符集;达梦侧要检查实例字符集和客户端连接字符集。两端不一致时,同步过来的中文在沿途每个环节都可能被转码一次,越转越乱。

经验是:达梦实例初始化阶段就把字符集定为UTF-8,应用连接串显式指定字符集,不要依赖数据库默认值。如果已经建好的实例字符集不对,最干净的做法是逻辑导出数据、重新建实例、再导入数据。调整实例字符集的代价比较大,所以初始化阶段就要定好。

4.3 双向同步的数据冲突处理

双向同步跑起来之后,最头疼的问题是同一张表在两个库同时被更新。比如MySQL侧把订单状态改成已发货,业务人员又在达梦侧把同一订单的备注改了,两个方向的同步任务都生效,最终哪个值被覆盖取决于时间顺序和任务执行顺序。

这里我强烈建议,在业务层面尽量把同一实体在两个端的写入时间错开。如果无法错开,可以引入最后更新时间戳字段,同步时用时间戳判断,保留更新的值。但这不是万能的,极端情况下时钟偏差会导致错误覆盖。

更稳妥的思路还是表级方向割分。把双向同步设计成业务上应用侧单边写,另一端只读,这样数据只在固定方向流动,冲突概率降到最低。双向同步的可用性优势主要体现在读扩展和容灾上,而不要贪心让两端同时承担写压力。

4.4 同步延迟飙升和日志导致的坑

同步延迟上升时,我一般先查源端日志归档情况。如果达梦侧没有开启归档,或者日志空间配置太小,日志很快被覆盖,DMHS解析不到完整变更,任务会表现异常甚至中断。这个坑在测试环境不容易暴露,因为数据量小,生产环境跑一两天就会爆发。

如果确认归档没问题,再看两端的时间同步。服务器时钟偏差会直接影响同步速度判断,甚至影响基于时间的过滤条件判断。生产环境强烈建议所有服务器都配置NTP时间同步。

还有一次,我排查一个同步延迟越来越大的问题,查到最后发现是源端表没有主键。DMHS在日志中逐行变更解析时,没有主键的表无法高效定位变更目标,导致同步性能断崖式下降。这给我们的启示是:同步对象的表尽量都有主键,没有主键的表要么改造业务,要么加强监控。

现象可能原因优先排查方向
连接报错类提示服务名或驱动问题实例状态、连接配置
中文乱码字符集不一致实例字符集、连接参数
同步延迟高归档未开或表无主键归档配置、表结构
双向数据被覆盖冲突策略未设计好同步方向规划、时间戳字段
任务突然中断授权过期或日志空间满授权有效期、磁盘空间

5. 实操心得与后续扩展建议

整套环境跑通后,我对DMHS的看法更务实了。它确实能解决异构数据库之间的增量同步问题,但前提是前期规划做得足够细。表的方向归属、过滤条件、冲突策略,这些设计工作占整个项目比重的四成都不夸张。

我个人体会比较深的一点是,双向同步一定要先以单向同步为基础跑稳。先搭一条MySQL到达梦的单向链路,通过数据和延迟验证,确认整条链路没有问题了,再叠加反向链路。一次直接把两条链路都搭好,出了问题时很难判断是正向链路的问题还是反向链路的干扰。

另外,数据校验应该做成定期任务。每天凌晨业务低峰期对比两端表行数和关键字段校验值,哪怕只是抽查核心表,也能尽早发现同步遗漏。同步链路越复杂,越需要靠数据比对来兜底,不能只依赖同步任务自身的状态监控。

如果需要做数据一致性校验,也可以关注一下达梦自带的校验工具或通用比对方案。成本不高,收益明显。

这个项目结束之后,我还在想能不能把同步任务再做细致一点,比如按业务类型拆成多个任务,这样某个任务出问题只影响对应的业务子集,不会导致全库同步停摆。后续如果要做达梦和Oracle之间的同步,思路也是共通的,核心还是想清楚同步对象、方向和冲突处理这三件事。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/3 14:27:47

基于Hadoop的健康饮食推荐系统实战全流程解析

说实话,刚拿到这个题目的时候,我第一反应是"这又是一道标准的大数据毕设题"。但真做下来才发现,"基于Hadoop的健康饮食推荐系统"远比想象中复杂:它既要处理Hadoop生态的搭建和MapReduce离线任务,又…

作者头像 李华
网站建设 2026/10/3 14:27:42

OpenHarmony上Flutter ListView垂直列表性能优化实践

直接进入正文。1. 为什么要在 OpenHarmony 上专门谈 ListView 垂直列表性能先说结论:Flutter 在 OpenHarmony 上的适配已经能跑起来,但“能跑”和“跑得顺”之间隔着一条河,而 ListView 就是那条河上最容易翻船的地方。信息流、商品列表、聊天…

作者头像 李华
网站建设 2026/10/3 14:26:02

Flutter鸿蒙多语言适配实战:flutter_auto_localizations迁移与语言切换方案

如果你在一个同时维护 Flutter 和鸿蒙双端工程的技术团队里,大概率已经遇见过这种场景:Android/iOS 上跑得挺顺的国际化流程,迁移到鸿蒙设备上却开始闹脾气——要么语言包加载不出来,要么切换系统语言之后界面纹丝不动。坐标里再叠…

作者头像 李华
网站建设 2026/10/3 14:25:43

PostgreSQL JDBC报错排查:从IO error到连接池配置

1. 别被报错文案骗了:"An IO error occurred while sending to the backend"的真实含义先简单交代一下场景。这几天在帮一个团队排查线上 PostgreSQL 间歇性报错,应用日志里反复出现一行异常:org.postgresql.util.PSQLException: A…

作者头像 李华
网站建设 2026/10/3 14:25:36

折叠式共源共栅(FC)的噪声机制与版图实现铁律

1. 为什么折叠式共源共栅(Folded Cascode)不是“高级版共源放大器”的简单叠加?在IC设计新人的直觉里,“折叠式共源共栅”听起来像是把共源级和共栅级“叠起来用”,再加个“折叠”二字显得高大上。我带过三届校招新人&…

作者头像 李华
网站建设 2026/10/3 14:25:06

InsightFace-REST:开箱即用的人脸识别HTTP服务部署指南

简介:本资源是一个基于Python构建的人脸识别RESTful服务开源项目,面向计算机视觉初学者、AI开发者及后端工程师,提供开箱即用的人脸检测、特征提取与比对能力,适用于安防验证、考勤系统、身份核验等轻量级部署场景。压缩包共102个…

作者头像 李华