☰
达梦数据库实战指南:从Oracle迁移到DM8的避坑笔记
2026/9/26 1:09:02 网站建设 项目流程

开篇先说实话:达梦数据库这几年在政企和金融行业的出现频率,已经高到做技术的人没法再无视它。尤其是信创改造进入深水区之后,Oracle、SQL Server、MySQL往达梦迁移的项目一个接一个,网上相关的教程倒是不少,但大多停留在“装个库、建个表”的层面,真正到生产环境里跑一遍,才会发现从连接工具到SQL方言、从迁移工具到中间件适配,处处都是细节坑。这篇文章我不打算做那种照本宣科的官方文档复述,而是把我自己从安装到迁移、从调试到适配的真实经验摊开来讲,希望能给正在或准备上手达梦的同行一些能直接落地的参考。

先交代一下背景。我接触达梦是从一个国产化替换项目开始的,目标是把一套跑了七八年的旧系统从Oracle迁到DM8,数据库里有两百多张表、几十个存储过程,还牵扯到Nacos配置中心、数据同步链路等外围设施。整个过程大概持续了两个月,踩过的坑不少,但最后都解决了。本文会按照真实项目推进的顺序来写,从安装部署开始,到连接调试、迁移实战,再到中间件适配和进阶能力落地,每一段都附上我当时遇到的具体问题和处理方式。

1. 第一个坑就藏在安装后的模式里:SYSDBA模式下连不上自己的表

先说安装。达梦数据库的安装包在官网就能下载,Windows版和Linux版都有,个人学习用的话官方也提供了免费授权,这一点对初学者非常友好。安装过程本身不复杂,图形界面一路下一步就行,但我建议你在安装时就把几个关键参数记下来:实例名、端口号(默认5236)、字符集、页大小和大小写敏感开关。

这里必须先说清楚一个反直觉的点——达梦的权限体系和MySQL、Oracle都不太一样。很多新手装完库之后,习惯性地用SYSDBA登录,然后兴致勃勃地去建表、插数据,结果第二天重新连上发现“表不存在”。我当时也在这个问题上卡了半天,后来才搞明白:达梦里SYSDBA是一个超级管理用户,但它不像MySQL的root那样自动绑定一个同名数据库。你用SYSDBA登录时,当前默认模式是SYSDBA模式,而达梦的模式(Schema)是用来隔离对象的,不同模式下的表就是不同的表。如果你在SYSDBA模式下建表,之后用应用账号连接时,需要写模式名.表名才能访问,或者显式执行SET SCHEMA切过去。

解决办法很简单规范:建库之后,第一时间创建一个业务专用用户,它默认会有一个同名模式,以后所有业务表都建在这个模式下,应用连接串里也明确指定这个模式和用户。别图省事全用SYSDBA,不然到后面做权限管控和数据迁移的时候,你会被自己的懒惰反噬。

还有一个在安装阶段容易被忽略的选项是“字符串比较是否大小写敏感”。默认情况下达梦是大小写不敏感的,这意味着你写的SQL里WHERE name = 'Abc'和WHERE name = 'ABC'效果一样。如果你的老系统是MySQL迁移过来的,这个特性很友好;但如果老系统是Oracle且数据里本身区分大小写,那建议在初始化实例时就把大小写敏感打开。这个参数一旦实例初始化完成后就没法改了,只能重建实例,所以务必先想清楚。

安装完后建议用disql命令行工具验证一下基本状态,常用的几个命令我列一下:

# 查看数据库版本 select * from v$version; # 查看当前用户和模式 select user, sys_context('USERENV', 'CURRENT_SCHEMA') from dual; # 查看所有模式 select distinct owner from all_tables order by owner; # 查看端口是否监听 netstat -an | grep 5236

记住:达梦在语法上高度兼容Oracle的PL/SQL,但它的系统视图和部分系统函数是自成一派的。先花二十分钟把disql用顺,后面排查问题会省非常多时间。

2. Navicat到JDBC再到IDE:把达梦接进你熟悉的工具链

达梦的生态工具虽然没有MySQL那么丰富,但常用的连接方式基本都有覆盖。很多人在网上搜“navicat连接达梦数据库”,其实Navicat从16版本开始就原生支持达梦了,不需要额外装驱动,直接选数据库类型为“DM”就行。连接参数和MySQL几乎一样:主机、端口、用户名、密码。这里要注意,Navicat里的“数据库”一栏对应的是达梦的“模式”,不是实例名,连接成功后你需要下拉切换到业务模式才能看到表。

除了Navicat,还有两个场景比较高频:一个是用JDBC做应用开发,一个是直接用IDE连库做调试。

JDBC连接达梦的驱动类名是dm.jdbc.driver.DmDriver,连接URL格式为:

jdbc:dm://127.0.0.1:5236?schema=TEST_SCHEMA&compatibleMode=oracle

我强烈建议在URL里显式加上schema参数,否则应用启动后查询时经常会出现“无效的表名”或“违反语法规则”的报错,就是因为默认模式不对。compatibleMode=oracle这个参数也很关键,如果你的SQL是从Oracle迁移过来的(比如用了SYSDATE、NVL、ROWNUM这些函数),开启这个模式可以让达梦在语法解析上更贴近Oracle的语义。反之,如果从MySQL迁过来,可以设置compatibleMode=mysql,但说实话,达梦对Oracle的兼容度远高于MySQL,MySQL迁过来的SQL很多还是得手动改。

至于IDEA连接达梦,其实本质就是JDBC连接。在IDEA的数据库面板里选择“达梦”或者直接选择“Generic JDBC”,填入上面那条URL和驱动类即可。如果IDEA版本比较老没有内置达梦驱动,你可以从安装目录的dmdbms/drivers/jdbc下找到DmJdbcDriver18.jar,手动加载进去。这个JAR包同时支持JDK8和JDK11,不用担心版本不匹配的问题。

还有一个容易被坑的点是密码策略。达梦默认创建用户时如果指定了PASSWORD POLICY,可能会有复杂度要求,比如必须包含大写字母和数字。应用连接报“用户名或密码错误”时,先别怀疑网络,先去确认一下是不是密码策略导致创建的用户和我们预期的不一样。

3. 从Oracle迁到达梦:结构迁移能省事,但SQL方言必须动手改

数据迁移是国产化项目里最核心、也最容易翻车的一步。很多人觉得达梦兼容Oracle,把脚本拿过来跑一遍就行——这个想法很天真。达梦自带的迁移工具叫“数据迁移工具”(简称DTS,在安装目录的tool文件夹下),它可以连接Oracle、MySQL、SQLServer等多种数据源,把表结构、数据、甚至部分存储过程一并迁过来。

我在项目里用DTS迁移了两百多张表,整体感受是:表结构和数据基本不用愁,但要特别留意三个地方。

第一,字段类型的自动映射。Oracle的NUMBER类型到达梦默认映射成NUMERIC或DECIMAL,如果你的表里NUMBER字段没指定长度和小数位,迁移后达梦会用默认精度,可能导致之后写入超长数据报错。建议迁移前先检查源库中所有NUMBER定义,尽量在源头补全精度。另外,Oracle的VARCHAR2迁移到达梦后如果设成VARCHAR,在大小写不敏感模式下没问题,但如果你开了大小写敏感,VARCHAR2(100)和VARCHAR(100 CHAR)两种写法占的空间不一样,会导致部分行数据插入失败。

第二,自增列的处理。Oracle的自增传统上用序列加触发器实现,DTS迁移时会把这个序列和触发器也带过来,但有时触发器的顺序会乱掉,导致批量插入时自增值不连续,甚至主键冲突。我当时遇到的情况是:数据迁过去了,序列的NEXTVAL没有同步,业务系统插入新记录时说主键重复。解决方法是迁移完成后手动做一次序列重置,把序列当前值调到已迁数据最大自增ID以上:

-- 先查当前最大id select max(id) from TEST_SCHEMA.ORDERS; -- 再修改序列的步长和值(达梦支持alter sequence) alter sequence TEST_SCHEMA.SEQ_ORDERS increment by 5000 nocache; select TEST_SCHEMA.SEQ_ORDERS.nextval from dual; alter sequence TEST_SCHEMA.SEQ_ORDERS increment by 1;

第三,也是项目里最耗时的部分——存储过程和函数。达梦虽然兼容PL/SQL,但兼容不是100%。我当时踩过的典型报错包括:包内变量作用域不一致、FORALL批量绑定不支持、带默认值的函数参数在调用时被要求必须全传。这些只能靠一个过程一个过程地去跑、去改。没有什么捷径,唯一建议是迁移之前先用静态SQL跑一遍业务主流程,把动态SQL里的字符串拼接问题提前暴露出来,因为动态拼接的SQL语法错误在编译期是看不到的。

另外还要提一句“迁移表设置先删后插入”。达梦的DTS在同步数据时,默认是“先清除目标表数据,再插入新数据”,这个配置非常容易引起生产事故。如果你同时开了多个同步任务,并且目标表之间有外键约束,先删后插会导致子表删除时因外键报错。稳妥做法是把目标表外键全部禁用,同步完成后再重建,或者在DTS里改成“追加模式”,只在空表上跑。

4. Dify和Nacos适配达梦:自然语言查库与配置中心的落地细节

先说Nacos适配达梦。Nacos版本不同,适配方式差异很大。Nacos 2.2.2和2.5.4我都折腾过。

Nacos 2.2.2要把默认的derby或MySQL存储换成达梦,官方没有直接提供达梦的插件,需要自己写一个数据源插件。具体路径是:实现com.alibaba.nacos.plugin.datasource.mapper包下的多个Mapper接口(比如ConfigInfoMapper、HisConfigInfoMapper等),把原本MySQL的SQL语句改写成达梦可执行的方言,然后在application.properties里指定spring.datasource.platform=dm并加载驱动。这个工作量不小,我当时把官方MySQL插件的代码拷出来,把占位符?改成#{...}风格,把分页SQL的LIMIT ?,?改成达梦的LIMIT ? OFFSET ?,再把驱动JAR引入Nacos的plugins目录,才算跑通。

到了Nacos 2.5.4版本就好多了,官方增强了插件机制,社区也出现了比较成熟的达梦适配包,直接下载后放进plugins目录,在配置里指定数据库类型为dm就能启动。但还是有一个注意点:达梦的schema要能正常建表。Nacos启动时如果报“无效的SQL语句”,先检查它用的账号是否有建表权限,然后再检查达梦是否开启了CREATE TABLE的系统权限。Nacos启动时会自动执行初始化表结构脚本,如果数据库用户不是表空间所有者,这个初始化很容易失败。

再说Dify。Dify目前官方支持的数据库中也不包含达梦,但热搜里“dify实现自然语言查询数据库达梦数据库”“dify连接达梦数据库n2l”说明大家确实有这个需求。我在项目里试过两条路。

第一条路是让Dify通过已有的数据库连接插件走JDBC。Dify有个工具叫“Text2SQL”或“Data Source”,它通过SQLAlchemy来连接数据库。SQLAlchemy要连达梦,需要安装dmalchemy或sqlalchemy-dm这个方言包,然后在连接串里写:

dm+dmPython://username:password@localhost:5236?schema=TEST_SCHEMA

注意这里的驱动名dmPython,需要提前安装达梦的Python驱动。这个驱动在达梦安装目录的drivers/python下,也可以用pip直接装dmPython源码包。装完之后Dify里的自然语言转SQL功能就能查询到达梦的数据,实测下来基本逻辑和MySQL没区别,但遇到复杂子查询时,生成的SQL还是会有方言差异,需要在提示词里显式要求生成达梦兼容SQL。

第二条路比较适合不想碰Python驱动的场景:给Dify开发一个自定义工具,通过HTTP调用后台Java服务,由Java服务用达梦JDBC查询并返回结果。这种方式更稳定,但工程量更大。我的建议是:如果只是验证RAG效果,用第一条路;如果要做成正式功能,直接上第二条路。

5. 达梦的高级功能不是摆设:CDC和SSL的真实配置经验

最后聊两个进阶能力:CDC和SSL。这两个都是生产环境比较常被问到的点。

达梦的CDC(变更数据捕获)和MySQL的binlog方案思路类似,但实现上完全不一样。达梦的CDC基于日志挖掘,开启过程稍微繁琐。首先要把数据库设置为归档模式:

-- 以SYSDBA身份执行 alter database mount; alter database archivelog; alter database add archivelog type local, dest=/dmdata/arch, file_size=64, space_limit=4096; alter database open;

然后开启日志挖掘:

-- 开启日志挖掘 sp_apply_log_begin();

之后通过DBMS_LOGMNR包里的存储过程来捕获增量数据。最常用的方式是DBMS_LOGMNR.START_LOGMNR配合V$LOGMNR_CONTENTS视图读取变更记录:

select operation_code, table_name, sql_redo, timestamp from v$logmnr_contents where table_name = 'ORDERS' and timestamp > sysdate - interval '1' hour;

sql_redo字段返回的是SQL语句,你可以根据operation_code判断是插入(1)、删除(2)还是更新(3),再进行下一步解析。我实测下来,达梦CDC的延迟大概在秒级,性能不如Canal加MySQL的组合那么轻快,但在国产化环境下配合自研同步程序是可行的。需要提醒的是,归档日志目录一定要注意磁盘容量,有个同事在生产上忘记写清理策略,一个月后归档日志把磁盘干满了,整个实例直接hang住。

SSL方面,达梦的SSL配置和PostgreSQL有几分相似。先要生成证书和私钥,达梦支持国密算法和RSA,生成后配置在dm.ini里:

ENABLE_SSL=1 SSL_CA_CERT=/dmdata/ssl/ca.crt SSL_CERT=/dmdata/ssl/server.crt SSL_KEY=/dmdata/ssl/server.key

配置完后重启实例,客户端连接时需要带上ssl参数。JDBC连接串形如:

jdbc:dm://127.0.0.1:5236?ssl=true&trustStore=/path/truststore.jks&trustStorePassword=xxx

这里头有个坑:达梦的SSL证书格式和Java的TrustStore不是一回事儿。你给达梦服务端配置的是PEM证书,但JDBC端要的是JKS或PKCS12格式的TrustStore。需要先用keytool把服务端公钥导成truststore。我当时在这里折腾了不少时间,最后是把服务端证书导出cer文件,再执行:

keytool -import -alias dmcert -file server.cer -keystore dmtruststore.jks -storepass changeit

客户端才能正常握手。这个过程在官方文档里写得很简略,遇到证书管理不善的团队,真的会在这里卡上一天。

6. 常用命令和调试心得:给刚开始上手的人一份即抄即用清单

写到最后,把这几周项目里反复用到的命令和工具做个小结。这些命令不复杂,但胜在都是“踩坑之后验证过”的,新手可以直接抄。

首先是数据库日常维护三件套。查看会话连接数,排查应用连接泄漏:

select count(*), state from v$sessions group by state; select addr, appname, clnt_ip, state, last_recv_time from v$sessions order by last_recv_time desc;

查看表空间使用率:

select tablespace_name, total_size, free_size, (total_size - free_size) * 100 / total_size as used_pct from dba_tablespace_usage_ratio;

查看数据库是否开启了归档和SSL:

select arch_mode from v$database; select para_name, para_value from v$dm_ini where para_name in ('ENABLE_SSL', 'ARCH_INI');

然后是调试阶段会用到的一些技巧。达梦执行计划用EXPLAIN,但它的输出格式比Oracle更友好一些:

explain select * from TEST_SCHEMA.ORDERS where status = 'P';

如果你发现某条SQL走不到索引,多半是统计信息没有更新。达梦的统计信息收集命令是:

dbms_stats.gather_table_stats('TEST_SCHEMA', 'ORDERS', cascade => true);

这里要说一个比Oracle严格的地方:达梦对NULL和空字符串的处理在某些模式下会有让人意外的行为。我建议建表时把允许为空的字段统一不加NOT NULL约束,然后在应用层处理空值,这样能少掉很多莫名其妙的同步报错。还有一个高频问题是字段命名,达梦的保留字比MySQL要多,比如TYPE、LEVEL、COMMENT这类词在达梦里做列名需要加双引号。迁移前建议先把所有列名过一遍保留字清单,别等到测试环境报错了再回头改实体类,那时候成本就大了。

最后提一下达梦的免费镜像和下载问题。官方确实提供了试用版和部分免费镜像,个人学习和功能验证完全足够。我个人的建议是:先下载Windows版在本地把环境跑起来,用DTS从MySQL导几张表过去试一遍,跑通增删改查之后再上Linux生产环境。生产环境安装时选择“服务器”安装类型,别选“客户端”,否则会缺一些服务端组件,到时候又要重新装,很浪费时间。

如果是团队协作,建议人手装一个disql并写几个常用的别名脚本,比如快速登录、查模式、查表结构等。等大家习惯了达梦的这套调试方式,后面做性能优化和排障的时候效率会明显提高。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询