1. 迁移前夜:先搞清楚达梦到底是个什么“梦”
第一次接触达梦数据库的MySQL老手,往往带着两种极端情绪:要么觉得“又一个国产数据库,换汤不换药”,要么觉得“文档这么厚,迁移肯定是个大工程”。我在做了几次实际迁移之后,感受更接近后者——迁移本身确实不难,三分钟能完成核心数据搬迁,但背后的兼容性改造和踩坑清单,才是真正拉开差距的地方。
先明确一个基础认知:达梦数据库(DM8)是武汉达梦推出的关系型数据库,它支持多种兼容模式,包括Oracle模式、MySQL模式、SQL Server模式等。做MySQL迁移时,关键在于初始化实例时选择正确的兼容参数,而不是装完再调。很多新手一上来就按默认配置建库,结果导入表结构时满屏报错,回头骂“达梦不好用”,其实问题出在兼容模式没选对。
这篇内容适合三类人:一是公司有国产化替代需求,需要把MySQL业务迁到达梦的DBA或后端开发;二是刚接触达梦,想了解它跟MySQL到底差在哪的数据库爱好者;三是做数据中台、异构平台整合的架构师,想快速评估成本的人。我会从工具准备、三分钟快速迁移操作、SQL兼容性改造,到常见问题排查,完整走一遍我的实操路线。
提示:本文所有操作基于 DM8 与 MySQL 5.7/8.0 环境,迁移工具使用达梦自带的 DTS(数据迁移工具),旧版本请先升级到 DM8 的最新版,避免工具本身的bug干扰判断。
2. 快速迁移的整体思路:为什么能三分钟搞定
很多人一听“三分钟迁移”,第一反应是质疑:几百万行的表,三分钟怎么可能导完?这里要区分一个概念:“三分钟完成”指的是从拿到连接信息、建库、导完表结构、开始导数据到数据校验完成,整个操作链路在输入命令和点击操作层面不超过三分钟,而不是物理传输几千万行数据只要三分钟。大表还是要等IO跑完,但等待过程中你已经被释放了,可以去喝茶。
我的迁移思路分四步:
- 建库并设为MySQL兼容模式——这一步决定了后续SQL的存活率。
- 用DTS迁移工具从MySQL导入表结构与数据——DTS原生支持异构迁移,能识别MySQL的建表语句自动转换成达梦语法。
- 检查自增列、索引、约束、注释等信息——这是最容易被忽略但最容易出问题的环节。
- 启动应用,跑通关键业务流程,抽样校验数据一致性——用业务来验证比任何校验脚本都靠谱。
之所以选择DTS而不是导出SQL再手工改,是因为达梦的DTS工具对MySQL的兼容做得已经很成熟,能自动处理大部分类型映射。你需要的不是从零写SQL,而是懂得在它转换完之后,怎么去审查和修正。
这里聊聊为什么不用Navicat等第三方工具直接迁移。Navicat支持MySQL到达梦吗?较新版本已经能连达梦了,但第三方工具更多是“能用”,DTS是“为迁移而生”。它专门处理了MySQL到达梦的保留字冲突、字符集转换、数据类型映射,批量提交策略也已经调优。我在实际对比中,同一个200万行的表,DTS的导入速度比通用工具快了不少,而且出错信息更明确,便于定位。
选DTS还有一个现实原因:达梦官网为Windows和Linux都提供了完整工具集,DTS就内嵌在达梦管理工具中。也就是说,你装完达梦,工具就有了,不需要额外部署任何迁移中间件。
3. 动手准备:三分钟内快速完成迁移的前提条件
3.1 安装达梦数据库
Windows下安装DM8很简单,下载达梦官网的 x86_win_64 安装包,双击exe,一路下一步。这里有几个注意事项:
- 安装时不要使用默认实例名DMSERVER,建议改成 dm8_mysql 这类一眼能看出用途的名字,后续排查问题方便。
- 端口默认5236,跟你本机其他服务冲突的可能性极低,但安装前还是顺手确认一下。
- 如果安装目录有中文路径,后续DTS工具连接时可能出现字符集相关怪异问题,建议统一用纯英文目录。
Linux下安装稍微多几个步骤。官方有命令行静默安装脚本,但一般建议用图形化安装(如果没有图形界面,需要安装xauth等组件或用VNC)。我个人的经验是:生产环境用静默安装,参数文件里把时区、页大小、兼容模式这些参数写好;自己测试机就直接图形界面点选,省事。
3.2 配置MySQL连接准备
迁移前确认几件事:
- MySQL服务开着,且迁移账号有权限读取你要迁移的库。建议用root或专门的迁移账号,避免权限不足导致导表失败。
- MySQL的
max_allowed_packet至少要大于最大行的单行数据量,尤其是有Text/BLOB字段的表。如果是默认配置,遇到一行几百KB的数据,DTS读取时可能报错。建议迁移前临时调大,迁移完再改回去。 - 字符集必须是utf8mb4或utf8,达梦默认字符集通常是UTF-8,两边不统一的话,中文会变成乱码。
3.3 准备JDBC驱动
DTS迁移工具是通过JDBC连接MySQL的。达梦自带连接MySQL的驱动包吗?一般不自带,需要从MySQL官网下载对应版本的JDBC驱动(mysql-connector-java),放到DTS工具指定的lib目录下。
很多人在这一步被卡住,现象是DTS选择MySQL数据源后,测试连接报「找不到驱动类」。解决办法是找到达梦安装目录下的dmdbms\tool\jdk\lib或者tool\lib,根据你的DTS版本,把mysql-connector-java.jar拷进去,重启DTS。
注意:JDBC驱动版本尽量跟你MySQL实例的大版本匹配。MySQL 8.0用最新驱动没问题,但MySQL 5.7用太新的驱动反而可能连不上。我踩过一次,MySQL 5.7 + mysql-connector-java 8.0.33 一直握手失败,换成驱动5.1.49版本就正常了。
4. 核心实操:三分钟完成MySQL到达梦的完整迁移
4.1 第一步:初始化一个兼容MySQL的数据库实例
无论是Windows图形安装还是Linux静默安装,在初始化实例时都要选兼容模式。这一步几乎决定了后续所有操作的顺畅程度。
具体在图形安装的“初始化参数”界面,有个参数叫COMPATIBLE_MODE(兼容模式),默认值是Oracle,你得改成MySQL:
- Oracle模式下,建表语法、序列、函数名都是Oracle风格,跟MySQL相差很大。
- MySQL模式下,达梦会尽量模拟MySQL的语法行为,包括
AUTO_INCREMENT、ENGINE=InnoDB这些关键字也能被接受。
有人问,能不能不给实例选兼容模式,在库里设置?不行,这个参数是初始化实例时指定,之后不能随便改的。实际生产中如果想调整,只能用dmrman工具备份还原的方式重建实例,非常麻烦。所以安装时一定要想清楚。
命令行的静默安装参数参考:
./DMInstall.bin -q # 交互式安装完成后,用 dminit 初始化实例 ./dminit PATH=/dm/data DM_NAME=dm8_mysql PORT_NUM=5236 COMPATIBLE_MODE=MySQL CHARSET=1 PAGE_SIZE=32看懂几个关键参数:
PATH=数据文件存放目录,建议单独放一块磁盘或分区,方便后续扩容和备份。DM_NAME=实例名。PORT_NUM=监听端口。COMPATIBLE_MODE=MySQL这就是核心,必须写上。CHARSET=1表示UTF-8字符集。PAGE_SIZE=32页大小,单位KB。达梦默认是8KB,但如果是数据仓库类业务,建议32KB,能减少大字段、长文本的溢页,提升性能。注意页大小初始化后也不能改。
初始化完成,启动服务:
# 前台启动 dmserver /dm/data/dm8_mysql/dm.ini # 或注册为系统服务 cd /dm/tool ./dmservice.sh看到SYSTEM IS READY的日志,说明实例启动成功了。
4.2 第二步:用DTS一键导入MySQL表结构与数据
DTS工具的位置在达梦的安装目录tool下。Windows下叫DTS.exe,Linux下通过管理工具里的“数据迁移”打开。
打开后按以下步骤配置:
- 新建迁移任务,类型选“MySQL -> 达梦”。
- 源数据源填MySQL的连接信息:IP、端口、用户名、密码、数据库名。
- 目标数据源填达梦的连接信息:IP、端口、用户名、密码,选择之前建好的兼容MySQL的库。
- 选择要迁移的模式和表,默认是全库迁移。如果只想迁部分表,取消勾选其它表即可。
- 开始迁移。
DTS会自动执行几个动作:
- 读取MySQL的表结构,转换成达梦能识别的建表语句并执行。
- 分批读取MySQL数据,写入达梦。
- 自动生成迁移日志,记录成功与失败的表、错误信息。
假设你MySQL里有 10 张表、每张表 50 万行,配置好点“开始”后,大部分时间其实是在等待传输,真正需要你动手的时间不会超过三分钟。这个“三分钟”更准确地说,是「迁移配置操作三分钟」,之后就是等进度条。
4.3 第三步:检查自增列和序列
MySQL的AUTO_INCREMENT在达梦中并不完全等同。DTS转换后,达梦的表结构会用IDENTITY或序列加触发器来实现自增。这就有个常见隐患:
- 达梦的
IDENTITY(1,1)默认是“禁止手动插入值”的。 - 如果你的业务代码里明确写了主键ID插入(比如数据回填、指定ID导入),会直接报错。
- 解决方法:把表改为
IDENTITY(1,1)允许显式插入值,或者干脆去掉自增列,改用序列。
实际业务中,我看到最稳妥的做法是:保留达梦的IDENTITY,但业务SQL尽量不手动指定主键插入。如果你的应用框架(比如JPA、MyBatis Plus)会自动生成主键并插入,那就要改表结构为手动模式。
改表语句参考:
-- 修改列标识属性为允许显式插入 ALTER TABLE tablename MODIFY id INT IDENTITY(1,1) NOT NULL WITH INSERT;这个WITH INSERT就是允许手动插入值的关键选项。没有它,你INSERT指定ID必报错。
4.4 第四步:索引、注释、约束的核对
DTS能迁移大部分索引,但不能保证100%。我建议迁移完以后跑一遍导入的建表脚本,逐表检查以下几点:
- 主键是否都带上了,漏掉主键会影响后续binlog解析和业务更新。
- 唯一索引是否都创建了,尤其是业务上有唯一性约束的字段(如手机号、订单号)。
- 外键要不要保留。如果业务代码本来就不依赖外键,建议干脆不建,提升并发写入性能。
- 注释是否丢失。达梦的列注释和表注释语法跟MySQL类似,但DTS偶尔会漏掉部分注释,尤其是列级别的中文注释。检查并补上。
- 默认值:DTS对
CURRENT_TIMESTAMP、DEFAULT 0这类默认值的转换比较稳,但对CURRENT_TIMESTAMP ON UPDATE这种MySQL特有的写法,达梦可能无法完美支持,需要手工改成触发器或应用层逻辑。
4.5 第五步:数据校验
数据校验不是可选项,是必须项。我习惯用三把尺子:
- 行数校验:逐表比对MySQL和达梦的 COUNT(*)。
- 抽样核对:每张表随机抽10条记录,比对关键字段的值。
- 业务流程验证:登录应用,走一遍新增、查询、修改、删除的核心路径,确认无报错。
很多人在第3步偷懒,结果上线第一天发现登录接口报错,一查是某条SQL的语法在达梦里不兼容。这个成本太高了,建议你花半天把核心链路完整跑一遍。
校验SQL示例:
-- 达梦端执行 SELECT table_name, num_rows FROM user_tables ORDER BY table_name; -- 与MySQL端 information_schema.tables 比对注意达梦的user_tables字段名跟Oracle类似,但如果你用的是MySQL模式,也可以用DM特有的系统视图。实际上一开始就用SELECT COUNT(*) FROM 表名比对最靠谱,系统视图的数据不一定实时刷新。
5. SQL兼容性改造:迁移之后真正要花时间的环节
很多人有个误解:迁移完数据就算结束,应用直接启动就行。实际上,SQL层面的兼容性改造才是迁移项目的重头戏,数据搬迁一晚上能搞定,SQL兼容性改造可能要花几天甚至几周。
为什么?因为达梦虽然提供了MySQL兼容模式,但不是100%照搬MySQL语法。常见差异点:
5.1 函数差异
MySQL 有很多常用函数,达梦的MySQL模式下有的支持,有的不支持,有的结果有差异。列举几个实际遇到的:
| 场景 | MySQL写法 | 达梦兼容写法/处理 |
|---|---|---|
| 判断非空 | IFNULL(a, 0) | IFNULL基本能兼容,但建议用COALESCE(a, 0)更稳 |
| 字符串拼接 | CONCAT('a', 'b') | 兼容,但注意 ` |
| 日期格式化 | DATE_FORMAT(now(), '%Y-%m-%d') | 达梦支持TO_CHAR(now(), 'YYYY-MM-DD'),两种都行,建议统一 |
| 时间戳转日期 | FROM_UNIXTIME(ts) | 达梦用TO_CHAR(TO_DATE('1970-01-01','YYYY-MM-DD') + ts/86400, 'YYYY-MM-DD') |
| 行号/分页 | LIMIT 0, 10 | 达梦MySQL模式支持LIMIT,但不能在子查询任意嵌套时乱用,必要时改用ROWNUM |
5.2 保留字冲突
MySQL里很多字段名在达梦里是保留字,比如level、comment、type、condition、timestamp等。DTS导表时如果遇到保留字,一般会自动加引号处理,但你的业务SQL如果写的是不带引号的裸字段名,到了达梦就报语法错误。
排查技巧:把业务日志里的错误SQL收集起来,用达梦的EXPLAIN逐条执行,看哪些字段需要加双引号。
5.3 事务隔离级别与锁机制
MySQL默认的 InnoDB 事务隔离级别是REPEATABLE READ,达梦默认通常是READ COMMITTED。如果你的业务重度依赖REPEATABLE READ下的间隙锁(Gap Lock)来防幻读,迁移到达梦后要重点验证并发场景,否则可能出现并发问题。
解决方案:
- 应用层加乐观锁/版本号。
- 达梦初始化参数里调整
ISO_LEVEL,但需要全局评估是否有副作用。 - 重写存在幻读风险的SQL,改用显式锁或唯一约束。
这块偏体系化,我建议在迁移评审时专门列一个「事务兼容性风险清单」,不要等到线上并发出问题再去救火。
5.4 存储过程与触发器
如果原来MySQL里写了复杂的存储过程、触发器,DTS迁移后多半需要手工调整。达梦对存储过程的支持语法跟Oracle更像,与MySQL差异较大。
常见改造点:
- MySQL的
DELIMITER语法,达梦不需要。 - MySQL的存储过程参数模式
IN/OUT写法类似,但异常处理块DECLARE ... HANDLER语法不同,需改写成达梦的EXCEPTION结构。 - 触发器中的
NEW/OLD引用在达梦中写法大致兼容,但要注意字段名冲突和系统函数差异。
如果存储过程不多,我建议手工重写而不是依赖自动转换。如果存储过程很多,建议先用DTS转一遍再逐个人工检查,至少语法错误能在编译阶段暴露出来。
5.5 字符集和排序规则
MySQL的utf8mb4_general_ci、utf8mb4_unicode_ci这类排序规则,达梦没有一一对应的概念。达梦更常用的是GB18030、UTF-8这种字符集,排序规则也不太一样。
迁移后常见现象:中文排序结果和MySQL不一致、字符串比较时大小写敏感度不同。如果业务中对排序和比较有严格依赖,需要测试后调整达梦的NLS_SORT或字段级别排序方式。
6. 常见问题与排查技巧实录
我在多次迁移实操中,积累了一些高频问题,整理成速查表,你们对照排查可以省不少时间:
| 问题现象 | 排查方向 | 解决办法 |
|---|---|---|
| DTS测试连接报“找不到驱动类” | JDBC驱动没放到DTS的lib目录 | 拷贝mysql-connector-java.jar到tool目录并重启DTS |
| 导入表结构报语法错误 | 源库表名/字段名是达梦保留字 | 在DTS中开启“自动加引号”选项;业务SQL同样处理 |
| 导入数据后中文乱码 | 字符集不一致 | 源MySQL检查SHOW VARIABLES LIKE 'character_set%',目标达梦检查SELECT * FROM v$nls_parameters,保证两边UTF-8统一 |
| 自增列插入失败 | IDENTITY默认禁止手动插入 | 使用ALTER TABLE ... MODIFY id INT IDENTITY(1,1) WITH INSERT |
| 业务SQL执行报错:不是GROUP BY表达式 | 达梦对GROUP BY的兼容性跟MySQL不同 | 改写SQL,确保SELECT列都包含在GROUP BY中,或改成聚合函数写法 |
| 大表导入速度很慢 | 未设置批量提交 | DTS导入选项里调整批量提交大小,如batch_size=1000;检查网络延迟 |
| 连接ssl错误 | MySQL 8.0默认开了SSL | JDBC连接串加useSSL=false,或达梦DTS里关闭SSL |
| 迁移完成但外键全部丢失 | DTS部分版本不迁移外键 | 手工导出原库外键关系,在达梦中补建 |
| 达梦安装Windows后服务启动失败 | 端口被占用或权限不足 | 检查5236端口占用;以管理员身份运行dmserver |
6.1 一个典型的SSL连接报错案例
有次我在迁移MySQL 8.0时,DTS报错信息是Public Key Retrieval is not allowed。这个错误很经典,原因是MySQL 8.0 默认的 caching_sha2_password 认证插件需要SSL或RSA公钥传输。
解决思路有两条:
- 在MySQL端创建一个用
mysql_native_password插件的用户,专门给DTS用。 - 在JDBC连接串里加上
allowPublicKeyRetrieval=true&useSSL=false。
我推荐第一种,因为第二种改了应用连接串会引入新的安全隐患,迁移账号用完后记得删掉。
6.2 达梦安装后替换Key(License)的操作
达梦默认有试用期,过期后你会遇到服务能启动但登录被拒或报授权错误。替换Key的操作分两步:
- 把达梦官方发的合法授权文件(通常是
dm.key)放到安装目录。 - 重启达梦服务。
Windows和Linux都支持在线替换,不需要重建实例。很多人不知道的是,替换后最好执行一个SELECT * FROM v$license;确认授权类型和到期时间,避免以为换成功实际上文件放错目录。
7. 实操心得:三分钟迁移的真相与时间规划
最后分享点个人经验。
如果你问我,三分钟迁移是真的吗?我的回答是:准备工作到位的情况下,从DTS打开到点击开始,三分钟确实够用。但这个“三分钟”背后,是对源库结构、业务SQL兼容性、达梦参数配置的充分理解。
我自己的迁移节奏通常是:
- 第1天:环境准备、实例初始化、JDBC驱动调试、DTS跑通小表。
- 第2天:全量数据导入,同步做SQL兼容性改造。
- 第3天:业务联调,数据校验,并发压测,修正隐藏问题。
一周左右基本能完成一个标准中小型MySQL应用的迁移。如果你是几十张表、单表百万级的系统,这个节奏完全可行。如果表数量大几百张,存储过程几百个,那我建议把时间预算翻倍。
有一点我想强调:不要迷信任何迁移工具的“一键完成”。DTS确实能帮你解决80%的结构和数据迁移,但剩下的20%(SQL语法兼容、自增列行为差异、字符集边界、事务语义差异、系统函数行为)永远需要人工介入。它就像一个很擅长翻译的人,能帮你把一本书从英文翻成中文,但遇到俚语和双关,翻出来总是怪怪的,你得自己再润色一遍。
另外,达梦的社区和技术支持体系这几年进步很快,碰到疑难杂症,去官方社区搜“错误码+达梦”,很多时候能看到别人踩过的坑和官方回复。别一个人死磕,该问就问,该提工单就提工单。
如果你准备的MySQL历史包袱不重(没有海量存储过程、没有诡异语法),迁到达梦之后,你会发现在达梦上写SQL其实挺顺手,事务能力、锁机制、备份恢复工具都做得扎实。这也是国产数据库这几年能顶上去的底气之一。