在KylinV10上使用DTS进行mysql8迁移至DM8

前言:

MySQL 到 DM 的移植主要有以下几个方面的工作:

  • 1.分析待移植系统,确定移植对象。
  • 2.通过数据迁移工具 DTS 完成常规数据库对象及数据的迁移。
  • 3.通过人工完成 MSQL 的移植。
  • 4.移植完成后对移植的结果进行校验,确保移植的完整性和正确性。
  • 5.对应用系统进行移植、测试和优化。

一、分析待移植系统,确定移植对象

  • 操作系统:ky10.x86_64 GUN/Linux
  • mysql版本:8.0.32
  • DM版本:64 V8 0x7000c
  • 应用开发平台:java
  • 应用开发接口: JDBC

统计 MySQL 数据中的对象以及表数据量

--根据指定用户统计用户下的对象数目
// 表数目
SELECT
	count(*) TABLES,
	table_schema
FROM
	information_schema.TABLES
WHERE
	table_schema = '数据库名称'
GROUP BY
	table_schema;
 
// 存储过程 
SELECT
	count(1) PROCEDURES
FROM
	information_schema.Routines t1
WHERE
	db = '数据库名称'
	and 
	t1.ROUTINE_TYPE = 'PROCEDURE';

// 函数
SELECT
	count(1) FUNCTIONS
FROM
	information_schema.Routines t1
WHERE
	db = '数据库名称'
	and 
	t1.ROUTINE_TYPE = 'FUNCTION';

查询结果:

表数目 :TABLES:381
存储过程数目:PROCEDURES:28
函数数目:FUNCTIONS:24

mysql 8.0开始删除了proc表,mysql8.0之前使用proc表

// 存储过程 
SELECT
	count(1) PROCEDURES
FROM
	MySQL.proc
WHERE
	db = '数据库名称'
AND `type` = 'PROCEDURE';

// 函数
SELECT
	count(1) FUNCTIONS
FROM
	MySQL.proc
WHERE
	db = '数据库名称'
AND `type` = 'FUNCTION' 

mysql与dm之间实例和表空间的区别

梳理一下大体的区别,在迁移时,做好mysql与dm中实例与表空间的对应关系;
从 MySQL 移植到DM,要求先创建好待使用的用户和这个用户的表空间, 不要把数据移植到系统默认的管理员 SYSDBA 用户下和 MAIN 表空间下

  • MySQL:单实例多库,
  • DM7 以上:单库多实例
  • 从MySQL 迁移到达梦的时候就需要针对 MySQL 中的每一个库在达梦里面创建一个用户和表空间来对应。

例如 MySQL 中有一个库 test,达梦里面先创建一个表空间 tab_test,然后创建一个用户 test,指定默认表空间为 tab_test。
迁移 MySQL 中 test 库的数据的时候,用 root 用户连接 MySQL,指定当前
库为 test;用 test 用户连接达梦,这样就把 MySQL test 库中的数据迁移到了达梦test 用户中。

  • 我们在做MySQL 移植的时候要先分析本次移植需要从源库中移植哪一个库 或者哪几个库的数据,然后为每一个库,分别在达梦中创建独立的表空间和用户;
  • 大多数情况下,我们需要移植的数据所在的 MySQL 实例里面有多个库,并不是所有的库都需要移植,所以再移植准备阶段,一定要和相关技术负责人员沟通明确清楚。

二、通过数据迁移工具 DTS 完成常规数据库对象及数据的迁移

通过达梦数据库数据迁移同步工具 DTS 将原系统中结构化数据迁移到国产
化数据库,DTS支持:

  • DM 数据库之间模式、表、序列、视图、存储过程/函数、包、触发器、对象权限的迁移;
  • 主流大型数据库 Oracle、SQLServer、MySQL、DB2、PostgreSQL、Informix、Kingbase、Sybase的模式、表、视图、序列、索引迁移到 DM;
  • DM 的模式、表、视图、序列、索引迁移到主流大型数据库 Oracle、SQLServer、MySQL;
  • ODBC 数据源、JDBC 数据源的模式、表、视图迁移到 DM;
  • DM 数据库模式、表、序列、视图、存储过程/函数、包、触发器、对象权限迁移到 XML 文件,SQL 脚本文件;
  • DM 数据库的表、视图数据迁移到文本文件,Excel 文件,Word 文件;
  • 指定格式的文本文件,Excel 文件,Word 文件,XML 文件和 SQL 脚本文件迁移到 DM 数据库。

开始迁移

打开dts工具

cd到DM 数据库安装目录下 tool 文件夹,执行./dts

cd /dm8/tool
./dts

在这里插入图片描述
在这里插入图片描述

在dts上新建迁移工程

在这里插入图片描述
在这里插入图片描述

新建迁移任务

在这里插入图片描述

扫描二维码关注公众号,回复: 16146602 查看本文章

选择迁移方式

在这里插入图片描述

连接迁移数据源

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
从数据源复制对象,包括模式及模式对象,目录,公共同义词或者上下
文(目的模式选择自己要用的模式)。
在这里插入图片描述

选择迁移对象

在这里插入图片描述

设置转换策略

在这里插入图片描述
在这里插入图片描述

执行迁移任务

在这里插入图片描述
在这里插入图片描述

三、通过人工完成 MSQL 的移植

因为上面我们是全部对象直接全选,默认导入的dm的,肯定存在语法转换上的问题,我们可以通过查看失败对象和日志来人工完成失败对象的移植。

对系统中的表和视图,可以使用达梦 DTS 工具进行迁移。如果还用到了自
定义类型、存储过程、函数、触发器等,需要导出源端数据库上的定义,手动去修改sql脚本,再到dm执行:

首先,可以先从 MySQL 导出用户对象 sql 脚本,MySQL 导出存储过程及函
数的执行命令:

MySQLdump-hhostname-uusername-ppassword-ntd-Rdatabasename>prorandfu
nc.sql

然后,将导出的 sql 脚本,经人工修改之后,再导入到达梦数据库中运行。

数据迁移常见问题

  • 1.无效的数据类型

请核查字段定义中的 int 类型,是否有精度,如果有,请直接去掉。即 int(10)需要改成 int,去掉精度。(达梦数据库的 int 类型,不需要、也不能设置精度)。

create table test1(v1 int(10),v2 varchar(20));
需要更改成
create table test1(v1 int,v2 varchar(20);
  • 2.TIMESTAMP

类型 在 MySQL中时间类型TIMESTAMP 默认default 设 置 为
“ 0000-00-0000:00:00 ” , 而在 DM 中 TIMESTAMP 类型数据不能为
“0000-00-0000:00:00”,在 DM 中是不合法的,必须在
‘0001-01-0100:00:00.000000’
到’9999-12-3123:59:59.999999’之间。 可通过修改直接修改 MySQL 中的业务表数据后进行数据迁移或通过DTS的使用 SQL 进行迁移数据。

  • 3.DEFAULT

设置 对于字段的 default 设置,默认的字符或字符串默认值,需要添加单引号’',如 achar(10) default ‘abc’。

  • 4.TEXT 类型

对于 text 字段类型,若在多条 SQL 中存在对 text 字段类型的 distinct 处理,可根据具体情况决定是否将 text 字段类型改变为 varchar 类型,或对查询结果进行其他方式的过滤。

  • 5.精度放大 3 倍

在 2019-9-18 以前的 DM 迁移工具中,如果 MySQL 源端的表字符集为utf8,迁移到达梦的时候 CHAR、VARCHAR
类型的精度会自动放大三倍。如果不能接收这种精度的放大,有两个办法:
1.把 MySQL 的表定义导出成文本,手动修改为 DM 语法。
2.去官网下载 2019-9-18 以后的版本。

  • DATE_FORMAT()函数

以 date_format 函数为例,MySQL 中的 date_format 函数可以在 DM 数据库 中使用 to_char 或 to_date 函数改写,改写后在达梦中可以达到相同的效果,示例如下:

--MySQL
select date_format(sysdate(), '%Y 年%m 月') from dual
-- DM
select translate(to_char(sysdate, 'yyyy-mm#'),'-#','年月') from dua
--MySQL
select DATE_ FORMAT(C_ FIRST_TIME,'%Y-%m-%d %H') FROM DUAL;
-- DM
select TO_CHAR(C_FIRST_TIME, 'YYYY- MM- DD HH24') FROM DUAL;
  • IF()函数

MySQL 中的 if()函数在当前测试版本 DM 中不支持,需采用 casewhen 进行替代,后续新版本可能会支持。

  • CONVERT()函数
    DM 的 convert()函数中的 type 在前,value 在后,而 MySQL 数据库中 convert()函数则恰恰相反,对于 cast()函数的用法则一致,测试示例如下:
--MySQL
CONVERT(
	CASE WHEN TEMP_STA.c_data_value & lt;0 
	THEN NULL
	ELSE TEMP_STA.c_data_value
	END,SIGNED
	) AS "ONLINEUSER",
-- DM
CONVERT( 
	INTEGER,CASE WHEN TEMP_STA.c_data_value <0 
	THEN NULL
	ELSE TEMP_STA.c_data_value 
	END
	) AS "ONLINEUSER"
  • CAST()函数

DM 中的 cast()函数的用法虽然和 MySQL 一致,但使用效果存在不同,MySQL 中对于数值类型的 value 转 char 类型没有限制,DM 中则存在限制,会报“数据转换失败”等报错,可将 cast(数值类型的 valueaschar)转换为 cast(数值类型的valueasvarchar),对于unsigned类型可以根据实际情况做对应改变或确定是否有必要进行转换。

  • FIND_IN_SET()函数

MySQL 字符串函数 find_in_set(str1,str2)函数就是查询字段(strlist)中包含(str)的结果,返回结果为 null 或记录,也就是返回 str2 中 str1 所在的位置索引,str2必须以","分割开。同 like 相比,like 是广泛的模糊匹配,字符串中没有分隔符,而 Find_IN_SET 是精确匹配,字段值以英文”,”分隔,Find_IN_SET 查询的结果要小于 like 查询的结果。而在 DM 中没有对应的函数,需要编写自定义函数,如下:

CREATE
OR REPLACE FUNCTION SYSDBA.FIND_ IN_SET (
	piv_str1 varchar2,
	piv_str2 varchar2,
	p_sep varchar2 := ','
) RETURN NUMBER IS l_idxnumber := 0;
-- 用于计算 piv_str2 中分隔符的位置
strvarchar2 (500);
-- 根据分隔符截取的子字符串
piv_strvarchar2 (500) := piv_str2;
-- 将 piv_str2 赋值给 piv_str
resnumber := 0;
-- 返回结果
BEGIN
	-- 如果 piv_str 中没有分割符,直接判断 piv_str1 和 piv_str 是否相等,相等 res=1
	IF instr(piv_str,
		p_sep,
		1) = 0 THEN
		IF piv_str = piv_str1 THEN
			res := 1;
END IF;
ELSE
-- 循环按分隔符截取 piv_str
LOOP l_idx := instr(piv_str,
p_sep);
-- 当 piv_str 中还有分隔符时
		IF l_idx > 0 THEN
-- 截取第一个分隔符前的字段 str
str := substr(piv_str,
		1,
		l_idx - 1);
-- 判断 str 和 piv_str1 是否相等,相等 res=1 并结束循环判断
		IF str = piv_str1 THEN
			res := 1;

EXIT;
END IF;

piv_str := substr(
	piv_str,
	l_idx + LENGTH(p_sep)
);
ELSE
-- 当截取后的 piv_str 中不存在分割符时,判断 piv_str 和 piv_str1 是否相等,相
等 res = 1
IF piv_str = piv_str1 THEN
	res := 1;
END
IF;
-- 无论最后是否相等,都跳出循环
EXIT;
END
IF;
END
LOOP
;
-- 结束循环
END
IF;
-- 返回 res
RETURN res;
END FIND_ IN_SET;
  • GROUP_CONCAT 函数

对于 group_concat 函数,可以采用 DM 的 LISTAGG 函数进行替换,如下为MySQL 和 DM 中的函数应用和效果,如下:

-- MySQL
SELECT
	group_concat(
		ifnull(OPEN_STEP, '10')
		ORDER BY
			ID ASC SEPARATOR '、、'
	)
FROM
	ZHZB_DEV.BID_PACKAGE BP; 10、、10、、10、、10、、10、、10、、10、、10、、10、、10、、10、、10、、10、、10、、 10、、10.... SELECT
		group_concat(
			ifnull(OPEN_STEP, '10')
			ORDER BY
				ID ASC SEPARATOR '、、'
		)
	FROM
		ZHZB_DEV.BID_PACKAGE BP
	GROUP BY
		AGENT_ ID;

-- DM
SELECT
	LISTAGG (
		ifnull("BP"."OPEN_STEP", '10'),
		' 、 、 '
	) WITHIN GROUP (ORDER BY "BP"."ID" ASC)
FROM
	ZHZB_DEV.BID_PACKAGE BP;

SELECT
	LISTAGG (
		ifnull("BP"."OPEN_STEP", '10'),
		' 、 、 '
	) WITHIN GROUP (ORDER BY "BP"."ID" ASC)
FROM
	ZHZB_DEV.BID_PACKAGE BP
GROUP BY
	"BP"."AGENT_ID";
  • DATE_ADD 函数

date_add 函数若对添加时间间隔的表达式进行求值,可采用 DM 的
TIMESTAMPADD 函数进行替代,例子如下:

--MySQL
select DATE_ADD(sysdate(), INTERVAL 1 YEAR);
--2020-07-02 11:24:18
-- DM
select TIMESTAMPADD(SQL_TSI_YEAR, 1,sysdate());
--2020-07-02 11:27:56.000000
  • 其他函数

对于 MySQL 独有的函数或基于 MySQL 语法创建的自定义函数,在 DM 中需要基于 DM 的 SQL 语法进行改写,实现相同的功能。

  • 时间间隔表达式

对 于 类 似 date_format(("S"."CREATE_TIME" + interval 1 year),'%Y')
date_format((now() + interval -(1) year),'%Y'))的时间间隔表达式,对于 interval 关键词后的正数需添加单引号’',如 interval ‘1’ year,对于负数,需改写,如 interval ‘-1’。

关于DM 数据库参数

  • 页大小 PAGE_SIZE
    在 DM 数据库中,页大小可以为 4KB、8KB、16KB 或者 32KB,从 MySQL 移植到 DM,建议设置页大小为16KB,一旦创建好了数据库,在该库的整个生命周期内,页大小都不能够改变。除了每个字段的最大长度限制外,每条记录总长度不能大于页面大小的一半。如果系统中存在或者以后可能存在含有较长的字符串类型的表,可以按需调整,最大为32KB(也可以设置为 8KB)。页大小设置越大,最后数据文件的物理大小就会越大,系统运行时,每次从磁盘调入内存的数据单位也就越大,所以此处要慎重。
  • 簇大小 EXTENT_SIZE
    数据文件使用的簇大小,即每次分配新的段空间时连续的页数,只能是 16 页或 32 页,缺省使用 16 页,从 MySQL 移植到 DM 使用默认值就可。
  • 大小写敏感 CASE_SENSITIVE
    DM为了兼容不同的数据库,在初始化数据库的时候有一个参数字符串比较大小写敏感,用于确定数据库对象及数据是否区分大小写,默认为区分,不可更改。建议 MySQL 和 SQLSERVER 迁移过来的系统,使用大小写不敏感
  • 字符集 CHARSET
    建议采用默认值 GB18030,如果需要国际字符可以采用 Unicode,GB18030 数字字母占 1 个字节,普通汉字占 2 个字节,部分繁体及少数民族文字占 4 字节,Unicode 在达梦中采用 UTF-8 编码格式,欧洲的字母字符占 1 到 2个字节,亚洲的大部分字符占 3 个字节,附加字符为 4 个字节。如果只存储中文和字母数字,一般来说 GB18030 更节省空间一些。

在 INI 参数的 compatibility 部分,还有其它的一些参数,在涉及到之前,尽
量保持默认值,在移植准备的环节,先只调整这个参数就可以了,其它参数,在移植过程中再具体分析。

compatibility : COMPATIBLE_ MODE

是否兼容其他数据库模式。

  • 0 :不兼容,
  • 1: 兼容 SQL92 标准,
  • 2 :兼容 ORACLE ,
  • 3 :兼 容 MS SQL SERVER ,
  • 4 :兼容 MySQL ,
  • 5 :兼 容 DM6,
  • 6:兼容 Teradata
    从 MySQL 移植到 DM 时,修改值为 4;

统计达梦数据基础信息

--统计页大小
select page; --统计编码格式
select unicode; --统计大小写敏感参数
select case_sensitive;

移植完成后对移植的结果进行校验,确保移植的完整性和正确性

统计达梦数据中的对象以及表数据量

--根据指定用户统计用户下的各对象类型和数目
SELECT
	object_type count *
FROM
	all_objects
WHERE
	owner = ‘OA8000_DM2015’
GROUP BY
	Object_type;

--统计指定用户下所有的对象,并记录到新的记录表中
CREATE TABLE dm_objects(obj_owner varchar(100),
obj_name varchar(100),
obj_type
varchar(50));

INSERT
	INTO
	dm_objects
SELECT
	owner,
	object_name,
	object_type
FROM
	all_objects
WHERE
	owner = 'OA8000_DM2015';

--统计每个表的数据量到表数据记录表
CREATE TABLE dm_tables(tab_owner varchar(100),
tab_name varchar(100),
tab_count int);

DECLARE
BEGIN
	FOR rec IN (
	SELECT
		owner,
		object_name
	FROM
		all_objects
	WHERE
		owner = 'OA8000_DM2015'
		AND object_type = 'TABLE') loop
EXECUTE IMMEDIATE 'insert into dm_tables select ''' | |
rec.owner | | ''',''' | | rec.object_name | | ''',count(*) from ' | | rec.owner | | '.' | |
rec.object_name;
END loop;
END;

SELECT
	*
FROM
	dm_tables;

对比达梦数据库中对象和 MySQL 库中对象以及数据量差异

-- 比对表数据量,找出数据量不相等的表
SELECT
	a.tab_owner,
	a.tab_name,
	a.tab_count-b.tab_count
FROM
	MySQL_tables a,
	dm_tables b
WHERE
	a.tab_owner = b.tab_owner
	AND a.tab_name = b .tab_name
	AND a.tab_count-b.tab_count <> 0
;

更新统计信息
数据核对完成无问题后, 应进行一次全库的统计信息更新工作。 统计信
息更新脚本示例如下:

DBMS_STATS.GATHER_SCHEMA_STATS(
'HNSIMIS',
-- HNSIMIS 为模式名
100,
FALSE,
'FOR ALL COLUMNS SIZE AUTO');

更新统计信息的目的在于大批量迁移数据后,可能会导致数据库优化器根据
错误的统计信息得到错误的查询计划,严重影响查询性能。
数据备份
再对数据更新完统计信息后,在数据量不大,磁盘空间足够的情况下应进行
一次数据备份工作。数据备份有两种方式:正常停止数据库后,拷贝备份 data
文件夹;或者开启归档日志后,进行物理备份。

猜你喜欢

转载自blog.csdn.net/qq_37432174/article/details/130453166