从 MySQL 迁移到 DM

原有的系统或开发习惯为 MySQL 的用户,可以参考文档《DM DBA 手记之 MySQL 移植到 DM》

有 MySQL 语法直接转 DM 语法的工具吗

可以使用 DM 数据迁移工具 (DTS),进行 MySQL 到 DM 的迁移,MySQL 和 DM 数据库的语法兼容性不高。关于语法,对于表、视图或游标等对象的创建语法存在不同,需要基于 DM 数据库的语法进行改写;部分 MySQL 数据库自带的系统包、函数、存储过程在 DM 数据库中也不支持,同样需要手动改写或重建相同功能的对应对象。关于数据,MySQL 中的某些数据,在 DM 中可能会被判定为不合法,需要进行修改。

在迁移数据之前,需要修改 DM 数据库参数,修改兼容参数为兼容 MySQL 数据库 COMPATIBLE_MODE=4 ,重启数据库服务使其生效即可。

ini 参数

  • 选择迁移方式时,选择【MySQL-->DM】,如下图所示:

选择迁移方式

  • 填写源端及目的端数据库信息(源端 MySQL,目的端 DM),保证数据库都能正常连接,如下图所示:

数据库信息

数据库信息

  • 指定需要迁移的对象,MySQL 数据库到 DM 数据库的迁移,只能迁移表和视图,如下图所示:

选择迁移对象

  • 选择迁移对象,可迁移的对象包括表和视图,如下图所示:

选择迁移对象

  • 点击【完成】,即可完成迁移,可在完成迁移向导中看到迁移的详细信息,如下图所示:

完成迁移

至此,MySQL 到 DM 的数据迁移完成,但在迁移时只能迁移 MySQL 的表和视图,其他对象无法进行迁移,需要手动改写或者重新创建来完成数据对象的正常使用。

  • MySQL 中时间类型 TIMESTAMP 默认 default 设置为 0000-00-00 00:00:00
  • DM 中 TIMESTAMP 类型数据不能为 0000-00-0000:00:00,在 DM 中是不合法的,必须在 0001-01-01 00:00:00.0000009999-12-31 23:59:59.999999 之间,所以可通过直接修改 MySQL 中的业务表数据后进行数据迁移。
注意

在迁移过程中可能会遇到一些语法不谦容的问题,如多表的联合查询语法、含有特殊函数的 SQL 语句等,需根据实际情况进行解决,MySQL 对于外键等对象的处理逻辑同 DM 存在诸多不同,需因地制宜。

迁移 MySQL 是否需要下载驱动

可利用 DM 数据库自带的数据迁移工具迁移 MySQL,工具如下所示:

选择迁移方式

连接数据源

连接目的端

指定迁移对象

选择迁移对象

迁移完成

快速设置使得在 mybatis 下对象不用添加双引号

有两种方法,一是修改数据库大小写敏感,二是用 DTS 工具迁移过程中,去掉“保持对象名大小写”的勾选
具体如下:
【解决方法】

  • 设置大小写不敏感,此方法会影响查询结果集,因为其对结果集匹配也不区分大小写,需要根据业务自行评估是否可行。
  • 在 mysql 数据库中,对象名默认是小写,达梦对象名默认是大写,在用达梦 DTS 工具迁移的时候,去掉“保持对象名大小写”的勾选,使对象名自动转换成大写,在 mybatis 查询的时候,即不需要加双引号强调小写。

去掉保持对象名大小写

数据迁移出现乱码

可能的原因是原数据的字符集和现在的 DM 数据初始化的字符集不一致,例如:MySQL 用的是 UTF8MB4 字符集,迁移到 DM 数据库后中文乱码,DM 数据库目前不支持 UTF8MB4

DTS 从 MySQL 迁移到 DM,char 长度是原来的 3 倍

【问题原因 1】

老版本 DTS 工具为保证数据成功迁移,会为不同字符集的目标库中 char 字段自动扩大 3 倍。

【解决方法 1】

新版本已经优化该问题,请升级更新 DM 数据库版本。

查看 DTS 版本,如下图所示:

旧版本

MySQL 中表结构,如下图所示:

表结构

迁移过程,如下图所示:

迁移日志

迁移后 DM 数据库表结构,如下图所示:

迁移后表结构

【问题原因 2】

MySQL 中 varchar(1) 可以存一个汉字,DM 数据库是以字节为单位。gb18030 字符集,varchar(2) 才可以存一个汉字;UTF-8 字符集,varchar(3) 才可以存一个汉字。此种情况下,为了保证汉字可以完整的被存储,扩大字段是合理的。

UNSUPPORTED MAJOR.MINOR VERSION 52.0

【问题描述】

DTS 连接 MySQL 错误:COM/MYSQL/CJ/JDBC/DRIVER:UNSUPPORTED MAJOR.MINOR VERSION 52.0

【解决方法】

JDK 版本不匹配,把启动 DTS 的 JDK 版本调整一下,调整参数位置:数据库安装路径下 Tool 目录 dts.ini../jdk/bin

MySQL 存储过程改为 DM

【问题描述】

DM 数据库存储过程创建临时表,如下所示:

begin
set @x=1;
EXECUTE IMMEDIATE 'set @x=10;';
select @x;
end;

在 MySQL 中,可以使用 @ 定义 session 级别变量,然后在动态 SQL 中对变量进行赋值。DM 数据库是否支持这种方式。

【解决方法】

设置 MS_PARSE_PERMIT=1,然后重启数据库生效后,可以通过 @ 定义 session 级别变量。

begin
set @x=1;
EXECUTE IMMEDIATE 'select 10' into @x;
select @x;
end;

动态 SQL 中对变量进行赋值需要修改。

MySQL 的二进制数据怎么导入

可以用 DM 数据迁移工具 DTS,DTS 在数据库安装路径 Tool 目录下。

数据迁移工具显示界面不完整,无法勾选“自定义 url”框

【问题描述】

从 MYSQL 迁移到 DM 数据库,数据迁移工具显示界面不完整,无法勾选“自定义 url”框:

指定驱动

【解决方法】

  • 方法一:调正分辨率--缩放与布局--调正稍微比现在出现问题的值小一些,然后重启 DTS 工具。
  • 方法二:如果尝试方法一还是无法解决,请从达梦云适配中心下载试用下载最新的达梦数据库。

MySQL 的 FIND_IN_SET 在达梦中如何转换

请参考:MySQL 的 FIND_IN_SET 在达梦中如何转换

如何让迁移到 DM 的表名大小写和 MySQL 保持一致

【问题描述】

从 MySQL 迁移到 DM 数据库后,表名都变成大写了,怎么能保持表名和 MySQL 中的大小写一致?

【解决方法】

如果达梦数据库初始化的时候设置的是大小写敏感就会自动转大写,如果想保持小写,可以在迁移过程中勾选“保持对象名大小写”

保持对象名大小写

DTS 工具点击“刷新”按钮不报错但是选不到数据库

DTS 界面信息

【问题解答】:

指定驱动,自定义 URL
例如:

驱动路径:mysql-connector-java-8.0.11.jar
驱动类名:com.mysql.cj.jdbc.Driver
URL:jdbc:mysql://localhost:3306/<database_name>?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true

从 MyQL 迁移到达梦报错:约束表达式无效

1.在 MySQL 中时间类型 TIMESTAMP 默认 default 设置为“0000-00-00 00:00:00”,而在 DM 中 TIMESTAMP 类型数据必须在 '0001-01-01 00:00:00.000000' 到 '9999-12-31 23:59:59.999999'之间,“0000-00-0000:00:00”在 DM 中是不合法的。

若源表表定义中存在 TIMESTAMP(0) DEFAULT 'CURRENT_TIMESTAMP()',则采用如下解决办法:
复制表定义,将 DEFAULT 'CURRENT_TIMESTAMP()'修改为 DEFAULT SYSDATE,手动创建表。
之后重新使用 DTS 迁移数据,注意要选中该类表,点击【转换】,取消勾选【表定义】,即可正常进行迁移。

更多详细信息请参考文档《DM DBA 手记之 MySQL 移植到 DM》

2.可能是驱动不对,在指定的驱动确定是否和 MySQL 版本一致。

MySQL 迁移至达梦如何指定迁移至达梦保持表名、列名都大写

DTS 迁移工具中把 “保持对象大小写” 取消勾选。

mysql 迁移到达梦报错:unknown initial character

从错误的提示信息中发现字符集设置出现问题,连接 mysql 数据库时报此错误:

【问题说明】:

//String url = "jdbc:mysql://localhost:3306/db_cjky" //如果使用这句就会报错。
Unknown initial character set index '255' received from server. Initial client character set can be forced via the 'characterEncoding' property.

或者报错如下:

unknown initial character set index'45'received from server. initial client character set can be foreced via the 'characterencoding' property

【解决方法】:

更换为合适的驱动版本,自定义 url 连接串,在 url 连接串中添加参数:

String url = "jdbc:mysql://localhost:3306/db_cjky?useUnicode=true&characterEncoding=utf8";//改成这句,就可以了

更换 mysql 驱动

DTS 迁移时设置数据类型映射

DTS 在某些情况下需设置数据类型映射,以 mysql 的 char 转成 varchar2 为例
1.添加自定义映射类型
自定义类型映射
2.创建迁移任务时不勾选默认数据类型映射
不勾选默认
3.选择需要迁移的表,使用预览表功能查看列映射选项,发现数据类型发生了映射
预览数据映射

DTS 迁移时,报错:“非法 IDENTITY 列类型”

【问题说明】
DTS 迁移 MYSQL 数据库到达梦数据库,在迁移表结构时,出现"ORIGIN_URL_ID" SMALLINT IDENTITY(2,1) NOT NULL, 非法 IDENTITY 列类型

【解决方法】
达梦数据库也有自增函数 IDENTITY(2,1),但是只支持 INT ,BIGINT 两种字段类型,需手动修改映射关系为字段 int 或者手动修改 SMALLINT 为 INT 类型再进行建表。

从 MySQL 移植达梦,char 类型达梦会自动空格补齐

【问题说明】
从 MySQL 移植达梦,char 类型在 MySQL 不会自动空格补齐,达梦会自动空格补齐。可能会导致 hibernate 不会自动过滤 char 类型中的空格,查询不到数据;

【解决方法】
如下三种方法修改 char 类型为 varchar2 类型。

  • 在 DTS 迁移时,映射 char 类型为 varchar2 类型;
  • 生成批量修改 char 为 varchar2
select 'alter table '||a.TABLE_NAME||' modify '||a.COLUMN_NAME||' VARCHAR2('||data_length||');' from all_tab_columns a where a.data_type='CHAR' AND OWNER='用户名';
  • 通过 rtrim 函数把数据右边的空格清除掉
update 表名 set 列名1=rtrim(列名1);

mysql 迁移 DM 错误提示:非法 IDENTITY 列类型

【问题说明】

利用 DTS 从 MySQL 迁移 DM 出现报错:非法 IDENTITY 列类型。

【问题解决】

查看相关创建表 SQL 语句:

创建表 SQL

发现 IDENTITY 自增列类型错误,IDENTITY 自增列的数据类型只能为 INT 或 BIGINT。
将自增列类型 DECIMAL(20,0) 修改为 BIGINT 即可。

达梦的 md5 函数加密后的值和 mysql 数据库 md5 函数加密后的值不同,该如何解决

【问题描述】

在 Mysql 数据库中,密码是调用数据库的 md5 函数加密后存储到数据库中,迁移到达梦数据库后,发现达梦的 md5 函数加密后的值和 mysql 数据库 md5 函数加密后的值不同。例如:

select md5('abc');  ---DM 数据库中 MD5 函数对 abc 加密后的值查询结果为 0x900150983CD24FB0D6963F7D28E17F72
select md5('abc');  ---mysql 数据库中 MD5 函数对 abc 加密后的值查询结果为 900150983CD24FB0D6963F7D28E17F72

【问题解决】

可利用 to_char() 函数进行转换,例如:

select to_char(md5('abc')); --DM 数据库中转换后的 abc 加密后的值为 900150983CD24FB0D6963F7D28E17F72

mysql 迁移至达梦,提示 streaming result set 报错

【问题描述】

具体报错信息如下:

报错截图

【问题解决】

报错原因是 JDBC 还没有处理完 resultSet 结果集,又使用同一个 connection 提交了新的 query。
ResultSet 的 JDBC 实现过程:默认情况下,ResultSet 会一次性返回结果集并保存在内存中。这也是最有效率且最容易实现的一种方式。但是当 ResultSet 含有大量数据(很多行、或者包含大对象的情况下)时,JVM 可能无法分配 ResultSet 要求的内存。
因此尝试调整读取行数:

调整读取行数

重新迁移成功。

使用 dts 迁移 mysql 数据至 dm 中,源端报错:连接数据库失败

【问题描述】

具体报错信息如下:

报错信息

【问题解决】

查看源端 URL 配置:

URL 配置

修改 URL:jdbc:mysql://localhost:3306/db_cjky?useUnicode=true&characterEncoding=utf8"

修改 URL

MySQL 迁移到 DM 报错:错误的日期时间类型格式

【问题解决】

检查 MySQL 中的数据,如下:

源端数据

原因是 DM 数据库中不允许日期和月份为 0,所以迁移过来会出现报错。有两种解决办法:

  • 在目标端将改类型修改为 varchar 类型的字段,可以迁移成功;
  • 在源端将数据为 0000-00-00 的日期改为 0000-01-01 或者 0001-01-01 也可以迁移成功。

MySQL 迁移到 DM 报错:列[NAMES]长度超出定义

【问题解决】

经排查,该表的 NAMES 字段存放的是中文,UTF8 编码。
报错原因:MySQL 中 varchar(1) 可以存一个汉字,DM 数据库是以字节为单位。若是 gb18030 字符集,varchar(2) 才可以存一个汉字;若是 UTF-8 字符集,varchar(3) 才可以存一个汉字。该 NAMES 在 MYSQL 的长度为 10,在迁移过程中,达梦数据库建表的 NAMES 字段长度也是 10,那么就会导致当该字段中文字符超过 4 个的时候,就会出现无法存下的问题。
解决方法:在此种情况下,为了保证汉字可以完整的被存储,可通过如下两种方法解决:
方法一:扩大字段长度。如 MySQL 表中的 NAMES 字段长度为 10,那么建议在达梦建表的时候该 NAMES 字段长度为 30。
方法二:重新初始化达梦数据库实例,并设置参数 length_in_char=1,即 VARCHAR 类型对象的长度以字符为单位。

MySQL 迁移到 DM8,VARCHAR 类型字段内容不完整,且结尾有乱码

【问题解决】

该问题是由于字符串截断造成的乱码或数据不完整。MySQL 中 VARCHAR 类型长度计算规则:
5.0.3 版本以下,varchar 按照字节存储,存一个汉字需要三个字节,varchar(10)可存储 3 个汉字。
5.0.3 版本及以上,varchar 按照字符存储,varchar(10)可存储 10 个汉字。
DM 默认为以字节为单位,varchar(10) 可存储 3 个中文字符,这样 MYSQL5.0.3 版本及以上版本迁移到 DM 中,可能会发生字符截断的问题。若设置参数 LENGTH_IN_CHAR=Y 后变为按照字符长度计算长度。
解决措施:
1.重新初始化实例,设置参数 LENGTH_IN_CHAR=Y,重新迁移数据。
2.如果在初始化库时,如果没有将 LENGTH_IN_CHAR 设置为 1,而是通过修改字段长度来解决此问题的情况下,如果后续有其他表从 MYSQL 迁移过来的需求,而恰好有字符长度不够的问题,一方面可以直接修改字段长度,另一方面也可以将对应的字段类型修改为 varchar(10 char)(10 为实际 mysql 字段长度)。这样 DM 中实际存储的中文字符长度与 MYSQL 是一致的。

DTS 做 MYSQL 到 DM 的表结构迁移时,报错 AUTO_INCREMENT

【问题描述】

通过 DTS 做 MYSQL 到 DM 表结构迁移,在 MYSQL 表结构默认值使用 AUTO_INCREMENT 函数来做自增长,会报错 AUTO_INCREMENT。

【问题解决】

达梦数据库当前通过 IDENTITY(1,1)函数设置自增长,等效于 mysql 的 AUTO_INCREMENT。
在进行等价改写的时候,需要先通过如下 SQL 确定 mysql 数据库的自增设置:

show variables like 'auto_inc%'; -- 查看当前数据库的自增长设置

查询出两个参数 auto_increment_increment(每次自增的值),auto_increment_offset(初始值)。以下图查询结果为例,初始值为 1,自增长值也为 1:
查询结果

然后,对表结构中的当前值 AUTO_INCREMENT 进行改写。以下图为例,该表结构的字段 work_record_id 应该等价改写为 work_record_id int(11) NOT NULL IDENTITY(51801,1):

改写函数

MySQL 迁移到 DM 报错:Access denied for user 'root'@'localhost' (using password: YES)

【问题描述】

迁移环境:麒麟 V10 系统,DM8 数据库,宝塔面板下的 Mysql 数据库。
在使用 DTS 达梦迁移工具时,登陆 Mysql 数据库进行数据迁移到 DM 过程中,在有驱动,登陆 Mysql 数据库账户为 root(一般情况下 root 账户具有最高权限),且密码正确的情况下,报错[1045]:Access denied for user 'root'@'localhost' (using password: YES)。

【问题解决】

出现拒绝访问的情况是因为 mysql 权限问题导致的。
可进入宝塔面板 mysql 设置里修改 my.ini 文件配置,windows 环境 可进入 MySQL 的安装路径(以默认安装路径为例)C:\Program Files\MySQL\MySQL Server 5.1\,找到 my.ini 配置文件(此文件为 MySQL 的常规参数,每次启动服务都会先加载此文件),在 my.ini 配置文件的最后一行加入 skip_grant_tables,此语句可以忽略登录检查。配置完成后重启数据库,点击 DTS 迁移工具刷新即可刷新出数据库列表。

Mysql 迁移到 DM,报错:不支持该数据类型

【问题描述】

Mysql 迁移到 DM,报错:不支持的数据类型,时间列内容多了一个 T,如'2021-04-08T16:44:40'。报错信息如下图所示:

报错信息

【问题解决】

选择正确的驱动包和驱动类名,如下图所示:

选择正确的驱动包

VARCHAR 类型数据以字符为单位且兼容 mysql 的库,varchar 类型的数据结尾部分有乱码

【问题解决】

问题原因:导致乱码的原因是插入的数据超出了定义的长度,但是并未报“-6169: 列[.......]长度超出定义”。
处理办法:
1)查看参数是否有 MY_STRICT_TABLES:SELECT *FROM V$DM_INI WHERE PARA_NAME ='MY_STRICT_TABLES';
2)如果存在 MY_STRICT_TABLES 参数,则将其值修改为 1,然后重启数据库:SP_SET_PARA_VALUE(2,'MY_STRICT_TABLES',1);
3)更新有乱码的数据。
4)如果不存在则需要升级数据库版本,再执行上述操作。

Mysql 迁移 user 表到达梦后,发现无法查询表内容和插入数据

【问题描述】:

Mysql 迁移 user 表到达梦数据库成功,迁移过程无报错。通过管理工具可看到 user 表:

image.png

但执行以下 SQL 语句无法查询表内容和插入数据,报错:语法分析出错。

select * from MY.USER;

INSERT INTO MY.USER(USER_ID,NAME,PASSWORD) VALUES ('1000008','大奔',"hj12345678');

【问题解决】:

  1. USER 在 DM 数据库中属于关键字,在进行 SQL 查询时,需要用双引号括起来。
  2. 在插入语句失败时,需要检查表结构,了解是否含有自增列等特殊定义的字段。

根据以上分析,发现 USER 表中含有自增列,因此修改查询和插入语句如下:

image.png

image.png

注意

1.因为存在自增列,所以需要设置参数SET IDENTITY_INSERT为ON。
2.当一个连接结束,IDENTITY_INSERT 属性将被自动还原为 OFF。

Mysql 迁移表到 DM 数据库报错:此列列表已索引

【问题描述】:

Mysql 迁移表到 DM 数据库报错:此列列表已索引,报错截图如下:

image.png

【问题分析】:

在 DM 数据库中查询该表,发现除了报错的索引迁移失败,其他的都迁移成功了。

image.png

image.png

【问题解决】:

Mysql 支持对同一字段建多个单列索引,而达梦不支持。根据上述问题分析和报错信息可知,STUDENT_NAME 列有两个单列索引 INDEX_N 和 INDEX_NA,因此在达梦下针对字段再建一个索引则会报错。

避免报错可在 mysql 下执行 drop index index_na on student; 删除索引,或者用其他字段索引或者联合索引代替,对于同一字段建单列索引和联合索引则不受影响,可以正常迁移。

year 字段类型迁移后数据丢失

【问题描述】:

Mysql 迁移 time 表到达梦数据库时,原 year 字段类型迁移后变成 char 字段类型,且原数据丢失。

MySQL 中表信息如下:

image.png

image.png

使用达梦数据迁移工具 dts 将 MySQL 数据库中的数据迁移到达梦数据库:

image.png

image.png

数据对比:

MySQL 数据库中原始数据如下:

image.png

迁移完成后达梦数据库中显示 time 表数据如下:

image.png

image.png

原 year 数据类型数据丢失,且在达梦数据库中原 year 数据类型变成 char 数据类型。

【问题分析】:

达梦数据库不支持 year 字段类型,在迁移过程中自动将 year 数据类型替换成为 char 字段类型。

【问题解决】:

在 mysql 下直接修改原字段类型之后再重新迁移。

步骤一:在 MySQL 中修改原字段类型。

image.png

image.png

步骤二:利用 DTS 迁移 time 表。

image.png

步骤三:迁移结果对比。

  • MySQL 数据库中数据显示如下:

image.png

  • 迁移完成后,达梦数据库中查找 time 表数据如下:

image.png

image.png

即修改 mysql 下 time 表原字段为 char 数据类型,再重新迁移到达梦数据库后,time 表数据迁移成功。

微信扫码
分享文档
扫一扫
联系客服