MySQL 迁移至达梦 DM9 完整改造指南|99% SQL 零改动

摘要

📌 在信创国产化落地过程中,MySQL 迁移到达梦 DM9 是政务、金融、企业系统最常见的场景之一。很多开发者迁移时踩坑不断:SQL 语法报错、函数不兼容、分页异常、自增主键失效、中文乱码、排序行为不一致等问题层出不穷。

本文结合多个生产项目实战经验,整理一套从环境准备、全量迁移、语法兼容、代码改造、压测验证到上线割接 的完整流程。依托达梦高 MySQL 兼容特性,实现99% 原有业务 SQL 无需改动,仅针对少数特殊语法、函数、配置做微调,大幅降低迁移成本与风险。全文附带可直接复用的配置、SQL 对照、避坑方案、报错解决,看完即可落地生产环境。

核心结论:达梦 DM9 深度兼容 MySQL 语法与使用习惯,优先开启 MySQL 兼容模式,能最大程度做到 SQL 零改动。

🔧 前置认知:MySQL 与达梦 DM9 核心差异

迁移前先理清二者底层区别,做到心中有数,避免盲目迁移。

1. 基础特性对比

对比项 MySQL 5.7/8.0 达梦 DM9
内核架构 开源关系型数据库 完全自主研发国产数据库
默认事务隔离级别 读已提交 读已提交
大小写敏感 Linux 下表名默认区分大小写,字段不区分 可通过参数手动开关大小写敏感
关键字数量 保留字较少 多达 1287 个,极易出现关键字冲突
主流兼容方向 通用开源 SQL 语法 同时兼容 MySQL、Oracle 双语法体系
自增主键 仅支持 AUTO_INCREMENT 支持 AUTO_INCREMENT / IDENTITY 两种写法
分页语法 仅支持 LIMIT 同时支持 LIMITROWNUM 两种写法

2. 迁移整体思路

  1. 数据库实例层面:开启MySQL 兼容模式,全局适配 MySQL 语法、函数、执行行为;
  2. 结构迁移:批量迁移表、索引、约束、视图、存储过程、触发器;
  3. 数据迁移:全量数据同步 + 数据完整性校验;
  4. 应用层改造:替换驱动、调整连接串、配置 MyBatis-Plus 方言、处理少量特殊 SQL;
  5. 功能 & 性能测试:业务功能回归、压力测试、修复兼容性问题;
  6. 灰度割接:流量逐步切换,平稳完成上线运维。

📦 一、达梦 DM9 环境准备(适配 MySQL 模式)

1.1 前置说明

达梦 DM9 安装流程沿用标准 Linux 部署规范,创建专用运行用户dmdba、配置系统权限、注册系统服务等基础操作本文不再赘述,核心重点为创建 MySQL 兼容模式数据库实例

1.2 创建 MySQL 兼容模式实例(关键步骤)

达梦支持在执行dminit创建实例时直接指定兼容模式,推荐该方式,一步到位适配 MySQL。 切换至dmdba用户,进入达梦安装目录下的bin文件夹执行命令:

复制代码
# 创建兼容 MySQL 模式的数据库实例
./dminit \
path=/opt/dmdbms/data \
db_name=mysql2dm \
instance_name=DMSERVER \
port_num=5236 \
charset=1 \
case_sensitive=0 \
COMPATIBLE_MODE=4

参数详解

  • path:数据库数据文件存放路径
  • db_name:数据库名称,可自定义
  • instance_name:数据库实例名
  • port_num:服务端口,默认 5236
  • charset=1:指定字符集为 UTF-8,charset=0为 GBK,统一使用 UTF-8 避免中文乱码
  • case_sensitive=0:关闭大小写敏感,和 MySQL 默认行为保持一致
  • COMPATIBLE_MODE=4:核心兼容参数,4代表启用 MySQL 兼容模式;补充:0 = 默认、1=Oracle、2=SQL Server、3=PostgreSQL、4=MySQL

1.3 已有实例补充开启 MySQL 兼容(应急方案)

若数据库实例已创建,未提前指定兼容模式,可修改达梦核心配置文件dm.ini临时开启全局兼容:

  1. 停止达梦服务

    systemctl stop DmServiceDMSERVER

  2. 编辑dm.ini文件(路径:/opt/dmdbms/data/DMSERVER/dm.ini),新增 / 修改以下参数:

    开启MySQL全局兼容模式

    COMPATIBLE_MODE = 4

    完全模拟MySQL GROUP_CONCAT函数行为

    GROUP_CONCAT_COMPATIBLE = 1

    模拟MySQL NULL值排序规则

    ORDER_BY_NULLS_COMPATIBLE = 1

  3. 重启达梦服务使配置生效

    systemctl start DmServiceDMSERVER
    systemctl status DmServiceDMSERVER

1.4 客户端连接测试

使用 DBeaver、达梦管理工具 DM Management Tool 进行连接验证:

  • 连接地址:127.0.0.1
  • 端口:5236
  • 数据库名:mysql2dm
  • 账号:SYSDBA
  • 密码:SYSDBA(生产环境必须修改默认密码) 连接测试通过,代表数据库环境准备完成。

🚀 二、数据库结构 & 数据全量迁移(两种主流方案)

本文提供官方 DTS 工具迁移(推荐)SQL 脚本迁移两种方案,分别适配大数据量集群、小体量单库场景。

方案一:达梦自带 DTS 迁移工具(首选,零代码、高成功率)

DM DTS 是达梦官方配套数据迁移工具,原生适配 MySQL 到达梦的迁移场景,可自动转换字段类型、表结构、索引、约束、数据,是生产环境首选方案。

2.1.1 工具位置
  • Windows 客户端:达梦数据库客户端 → DM 数据迁移工具 (DTS)
  • Linux 图形环境:达梦安装目录tool文件夹下启动 DTS
2.1.2 完整迁移步骤
  1. 打开 DTS 工具,新建迁移工程 ,迁移类型选择 MySQL → 达梦 DM
  2. 配置源端 MySQL 信息:填写 MySQL 服务地址、端口、数据库名、账号、密码,点击「测试连接」;
  3. 配置目标端达梦信息:填写 DM9 服务地址、端口、数据库名、账号、密码,点击「测试连接」;
  4. 选择迁移对象:按需勾选表、视图、函数、存储过程、触发器、事件等数据库对象;
  5. 字段类型映射:DTS 会自动完成类型转换,无需手动干预,主流映射规则如下:

| MySQL 数据类型 | 达梦 DM9 对应类型 | | ---- | ---- | ---- | | TINYINT | TINYINT | | INT / INTEGER | INT | | BIGINT | BIGINT | | VARCHAR (n) | VARCHAR (n) | | TEXT / LONGTEXT | TEXT / CLOB | | DATETIME | DATETIME | | DATE | DATE | | TIMESTAMP | TIMESTAMP |

  1. 确认配置后点击开始迁移,等待结构与数据同步完成;
  2. 迁移收尾:手动核对表数量、字段数量、数据总行数、索引、主键、外键、唯一约束。

💡 避坑提示:迁移前建议将 MySQL 设置为只读或暂停业务写入,避免迁移过程中新增数据导致两端数据不一致;千万级大表建议分批次迁移。

方案二:SQL 脚本手动迁移(适合小库、单表调试)

仅适用于少量数据表、测试环境迁移,通过导出 MySQL 原生 SQL 脚本,在达梦客户端直接执行。

2.2.1 MySQL 导出 SQL 脚本

使用 Navicat、DBeaver 等工具,导出表结构 + 数据脚本,导出格式选择兼容ANSI标准

2.2.2 脚本适配与执行

MySQL 建表脚本存在专属引擎、字符集配置,达梦无法识别,需要手动删减;同时关键字表名 / 字段建议添加双引号。

原 MySQL 脚本

复制代码
CREATE TABLE `user_info` (
  `id` int AUTO_INCREMENT PRIMARY KEY,
  `username` varchar(30) NOT NULL,
  `create_time` datetime
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

适配后达梦可执行脚本

复制代码
CREATE TABLE "user_info" (
  "id" int AUTO_INCREMENT PRIMARY KEY,
  "username" varchar(30) NOT NULL,
  "create_time" datetime
);

核心修改点:

  1. 删除 ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 等 MySQL 专属配置;
  2. 标识符使用双引号包裹,规避关键字冲突。

📝 三、SQL 语法兼容详解(99% 语句零改动)

开启COMPATIBLE_MODE=4 MySQL 兼容模式后,常规增删改查、联表、排序、分组 SQL 均可直接运行。下面分类说明完全兼容、轻微差异、必须改造的语法与函数。

3.1 完全兼容(无需任何修改)

3.1.1 DDL 表结构语句

建表、删表、改表结构、新增 / 删除索引、主键、唯一约束全部兼容;AUTO_INCREMENT自增语法和 MySQL 完全一致。

复制代码
-- MySQL 原生写法,达梦直接执行
CREATE TABLE t_test(
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50)
);
3.1.2 DML 增删改查语句

基础 CRUD 语法 100% 兼容,无需调整:

复制代码
-- 新增数据
INSERT INTO t_test(name) VALUES ('test');
-- 条件查询
SELECT * FROM t_test WHERE id > 10;
-- 数据更新
UPDATE t_test SET name='dm9' WHERE id=1;
-- 数据删除
DELETE FROM t_test WHERE id=1;
3.1.3 LIMIT 分页语法

达梦 MySQL 兼容模式下,完整支持 MySQL 风格LIMIT分页,业务分页 SQL 无需改动:

复制代码
-- 取前10条数据
SELECT * FROM t_test LIMIT 10;
-- 分页:偏移20条,取10条(MySQL经典分页写法)
SELECT * FROM t_test LIMIT 20,10;
3.1.4 基础运算符与逻辑判断

and/or/not、大小于、等于、inlike模糊查询、between and区间查询等全部兼容。

3.2 函数兼容(仅少量特殊函数需改造)

开启 MySQL 兼容模式后,绝大多数 MySQL 常用函数可直接使用,仅 JSON 解析等小众函数需要调整。

3.2.1 完全兼容的 MySQL 函数(直接使用)
  • 字符串函数:CONCATSUBSTRINGLENGTHTRIMUPPERLOWER
  • 日期函数:NOW()CURDATE()CURRENT_DATEDATE_ADDDATE_SUB
  • 判空函数:IFNULL()(MySQL 专属函数,兼容模式原生支持)
  • 聚合函数:SUMCOUNTMAXMINAVG

示例:

复制代码
-- IFNULL 判空,完全兼容
SELECT IFNULL(name,'空') FROM t_test;
-- 获取当前系统时间
SELECT NOW();
-- 字符串拼接
SELECT CONCAT(name,'_suffix') FROM t_test;
3.2.2 GROUP_CONCAT 分组拼接函数

GROUP_CONCAT是 MySQL 高频分组函数,开启 MySQL 兼容模式后可直接使用

复制代码
-- MySQL原生SQL,达梦无需修改
SELECT GROUP_CONCAT(name SEPARATOR ',') FROM t_test GROUP BY id;

补充:未开启兼容模式时,达梦需使用WM_CONCAT,迁移场景无需考虑。

3.2.3 需替换的特殊函数
MySQL 函数 达梦兼容写法 补充说明
DATE_FORMAT(dt,'%Y-%m-%d') DATE_FORMAT(dt,'%Y-%m-%d') / TO_CHAR(dt,'YYYY-MM-DD') 兼容模式下原生支持,二选一即可
FROM_UNIXTIME() FROM_UNIXTIME() DM9 高版本完全兼容
JSON_EXTRACT() JSON_VALUE() JSON 解析函数,达梦标准写法

3.3 排序与 NULL 值规则

MySQL 默认规则:升序时NULL值排在最前,降序时NULL值排在最后。 达梦开启ORDER_BY_NULLS_COMPATIBLE = 1后,排序行为与 MySQL 完全一致,无需修改 SQL。

3.4 关键字冲突(高频坑点)

达梦关键字数量远多于 MySQL,orderuserstatuslevel等 MySQL 常用标识符,在达梦中属于系统关键字,直接使用会报语法错误。

统一解决方案

  1. SQL 语句层面:使用双引号包裹表名、字段名(达梦标准标识符);
  2. 应用代码层面:MyBatis/MyBatis-Plus 实体类、Mapper 注解中添加双引号;
  3. 长期优化:尽量不使用数据库保留字作为表名、字段名。

示例:

复制代码
-- order 为关键字,必须用双引号包裹
SELECT * FROM "order" WHERE "status" = 1;

🛠️ 四、SpringBoot 应用层完整改造(核心落地步骤)

数据库迁移完成后,SpringBoot 项目仅需修改驱动依赖、数据源连接串、MyBatis-Plus 配置,原有业务代码、SQL 无需改动。

4.1 替换 Maven 驱动依赖

移除原 MySQL 驱动,引入达梦适配 JDK17 + 的 JDBC 驱动:

复制代码
<!-- 移除原有 MySQL 驱动 -->
<!--
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
-->

<!-- 达梦 DM9 JDBC 驱动(适配 JDK17 及以上) -->
<dependency>
    <groupId>com.dameng</groupId>
    <artifactId>DmJdbcDriver18</artifactId>
    <version>8.1.3.192</version>
</dependency>

4.2 修改 application.yml 数据源配置

核心修改:驱动类、连接 URL、连接探测语句,同时删除 MySQL 专属参数。

复制代码
spring:
  datasource:
    # 达梦驱动类全限定名
    driver-class-name: dm.jdbc.driver.DmDriver
    # 达梦连接地址,指向MySQL兼容实例
    url: jdbc:dm://127.0.0.1:5236/mysql2dm?schema=PUBLIC&useUnicode=true&characterEncoding=utf8
    username: SYSDBA
    password: YourPwd@123
    type: com.zaxxer.hikari.HikariDataSource
    hikari:
      minimum-idle: 5
      maximum-pool-size: 30
      idle-timeout: 30000
      max-lifetime: 1800000
      connection-timeout: 30000
      # 达梦强制要求:连接探测必须使用 DUAL 虚拟表
      connection-test-query: SELECT 1 FROM DUAL

⚠️ 关键避坑:

  1. 达梦不支持 MySQL 连接参数 rewriteBatchedStatements=true,务必删除,该参数无效且会引发异常;
  2. 密码包含 @、# 等特殊符号时,建议使用单引号包裹密码;
  3. 连接探测语句必须写 SELECT 1 FROM DUAL,否则 Hikari 连接池持续报错。

4.3 MyBatis-Plus 配置修改(分页、方言核心配置)

原有 MySQL 方言必须替换为达梦方言,否则分页、逻辑删除、SQL 生成都会异常。

4.3.1 插件配置类
复制代码
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.baomidou.mybatisplus.annotation.DbType;

@Configuration
@MapperScan("com.xxx.mapper") // 替换为自己项目的mapper路径
public class MyBatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 分页插件:明确指定数据库类型为 DbType.DM(达梦)
        PaginationInnerInterceptor pageInterceptor = new PaginationInnerInterceptor(DbType.DM);
        pageInterceptor.setOverflow(true); // 页码溢出返回第一页
        interceptor.addInnerInterceptor(pageInterceptor);
        // 乐观锁插件
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        // 防全表更新/删除插件(生产环境必开)
        interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
        return interceptor;
    }
}
4.3.2 全局方言配置(yml)
复制代码
mybatis-plus:
  global-config:
    db-config:
      dialect: com.baomidou.mybatisplus.extension.plugins.inner.DmDialect

4.4 实体类 & Mapper 适配(关键字处理)

若表名、字段名是达梦关键字,在 MP 注解中使用双引号包裹;非关键字场景无需任何修改。

复制代码
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@Data
@TableName("\"order\"") // 关键字表名,添加双引号
public class Order {
    // 自增主键,AUTO模式和MySQL行为一致
    @TableId(type = IdType.AUTO)
    private Integer id;

    @TableField("\"status\"") // 关键字字段,添加双引号
    private Integer status;
}

4.5 批量插入性能优化

MyBatis-Plus 原生saveBatch在达梦中会循环单条插入,性能极差。建议使用自定义 SQL 注入器 实现批量插入,业务调用代码保持不变。 相关代码参考:自定义CustomSqlInjector、扩展BaseMapper增加insertBatchSomeColumn方法,前文已有完整实现,此处不再重复。

✅ 五、功能回归 & 数据校验(迁移必做环节)

应用改造完成并正常启动后,必须执行多轮验证,保证迁移后功能、数据完全一致。

5.1 基础连通性验证

  1. 项目正常启动,无驱动、连接、方言相关报错;
  2. 单条查询、列表查询接口正常返回数据;
  3. 新增、修改、删除操作正常,数据可正常落库。

5.2 业务 SQL 全量回归测试

重点覆盖核心业务场景:

  • 分页查询、多条件模糊查询、多表联查;
  • 分组统计、GROUP_CONCAT字符串拼接;
  • 日期函数、判空函数、JSON 解析场景;
  • 事务场景(达梦完整支持 Spring 声明式事务)。

5.3 数据一致性校验

  1. 全表行数对比:MySQL 表总行数 = 达梦表总行数;
  2. 抽样校验:随机抽取多条数据,核对字段内容、时间、字符串、数字是否完全一致;
  3. 大表校验:千万级数据表优先核对主键、索引、核心业务字段。

5.4 中文乱码校验

执行中文新增、查询操作,确认无乱码。若出现乱码排查两点:

  1. 达梦实例创建参数 charset=1(UTF-8);
  2. 连接 URL 中配置 useUnicode=true&characterEncoding=utf8

🚀 六、生产环境调优 & 上线割接

6.1 达梦数据库生产参数调优(适配 MySQL 业务)

修改dm.ini配置文件,根据服务器硬件与业务并发优化参数,修改后重启服务生效:

复制代码
# 数据缓冲区,8G内存建议设为2048,16G及以上建议4096
BUFFER = 2048
# 最大会话连接数,根据业务并发调整
MAX_SESSIONS = 500
# 慢SQL阈值,执行超过1秒的SQL记录日志
LOG_MIN_DURATION_STATEMENT = 1000
# 开启MySQL兼容全套参数
COMPATIBLE_MODE = 4
GROUP_CONCAT_COMPATIBLE = 1
ORDER_BY_NULLS_COMPATIBLE = 1

6.2 应用生产配置收紧

  1. 关闭 MyBatis SQL 控制台日志,减少磁盘 IO;
  2. 基于线上并发,优化 Hikari 连接池参数;
  3. 重置数据库默认账号密码,使用强密码策略;
  4. 配置防火墙,仅允许应用服务器访问数据库 5236 端口。

6.3 灰度割接方案(零停机上线,生产标准流程)

  1. 双写阶段:应用同时写入 MySQL 和达梦,读取流量仍走 MySQL,持续 1~3 天,观察数据同步状态;
  2. 读流量切换:逐步将查询流量切到达梦,写入保留双写,监控日志、报错、接口响应耗时;
  3. 停用旧库写入:确认运行稳定后,停止向 MySQL 写入,全量读写切换至达梦;
  4. 下线旧库:稳定运行 7~15 天无异常后,下线原 MySQL 数据库。

❌ 七、迁移高频报错 & 一键解决方案

报错现象 根因 解决方案
表 / 视图不存在、无效标识符 表名 / 字段名命中达梦关键字 使用双引号包裹标识符
Hikari 连接探测失败 探测语句不符合达梦规范 改为 SELECT 1 FROM DUAL
分页查询总条数为 0、分页失效 MyBatis-Plus 未配置达梦方言 / 分页类型 配置DmDialect,分页插件指定DbType.DM
AUTO_INCREMENT 自增失效 数据库未开启 MySQL 兼容模式 设置COMPATIBLE_MODE=4并重启服务
中文乱码 字符集配置错误 实例使用 UTF-8,连接串指定编码参数
批量插入速度极慢 使用 MP 原生 saveBatch(循环单条插入) 改用自定义InsertBatchSomeColumn批量方法
IFNULL/GROUP_CONCAT 函数不存在 未开启 MySQL 兼容 开启COMPATIBLE_MODE=4并重启服务
启动报驱动类找不到 驱动依赖缺失 / 版本不匹配 引入DmJdbcDriver18对应版本驱动

📚 八、总结

  1. 核心逻辑 :MySQL 迁移达梦 DM9,开启 MySQL 兼容模式 是实现 99% SQL 零改动的核心,优先在创建实例时指定COMPATIBLE_MODE=4
  2. 标准迁移流程:搭建兼容实例 → DTS 迁移结构与数据 → 改造应用驱动 / 连接串 / MP 方言 → 功能数据校验 → 灰度上线;
  3. 改造范围:仅需替换驱动、修改连接配置、适配 MP 方言,原有业务 SQL、Java 代码基本无需调整;
  4. 重点风险防控:关键字冲突、连接探测语句、批量插入性能、中文乱码四大问题为迁移高频坑点,提前规避。

达梦 DM9 对 MySQL 生态兼容性成熟,中小项目 1~2 天即可完成全量迁移,大型系统采用分库分表、灰度切换的方式,可有效控制迁移风险。

专注 SpringBoot + 国产数据库信创实战,持续更新达梦、人大金仓、openGauss 迁移与适配教程,点赞 + 收藏 + 关注,后续分享 Oracle 迁移达梦、达梦高可用集群搭建实战。

相关推荐
weixin_489690021 小时前
【IDEA 2025.2.4】 Maven 仅能手动 Reload All Maven Projects 问题解决
java·maven·intellij-idea
golang学习记1 小时前
Intellij IDEA 2026重磅更新!开发体验大升级
java·ide·intellij-idea
弹简特1 小时前
【Java项目-轻聊】05-AI赋能设计接口文档
java·开发语言
AI行业学习1 小时前
.NET Framework 3.5 SP1 完整离线包(2029.5.29)
开发语言·windows·.net
cany10001 小时前
C++ -- 队列std::queue
开发语言·c++
skywalk81631 小时前
根据言律的语法,能否用racket进行开发呢?主要探讨是否可行。 racket在这里:E:\Program Files\Racket\Racket.exe
开发语言·原型模式
达达爱吃肉1 小时前
claude 接入deepseek 运行报错
java·服务器·前端
OctShop大型商城源码1 小时前
OctShop对比JAVA商城源码_OctShop大型专业级多用户商城源码
java·开发语言·商城系统·小程序商城·octshop
l1t1 小时前
DeepSeek总结的使用实体-组件-系统和基于存在性处理进行Python编程15-17
开发语言·数据库·python