Mysql迁移达梦实践

0、前言

前几天因为要搭建一个达梦的开发环境,数据从mysql中迁移,所以做了一次mysql到达梦的迁移工作(数据量不大,所以也没碰到太多问题)。看了一下网上好像也没有比较详细的mysql迁移达梦的文章,于是我把这次迁移总结一下供大家参考。对于oracle迁移达梦可以参考我之前的两篇文章:
oracle迁移达梦7手顺及注意事项
oracle迁移达梦常见问题汇总

1、概述

mysql迁移达梦主要需要完成以下工作:

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

2、迁移准备

2.1、版本选择
首先需要选择合适的数据库版本,优先选择完整安装版本(无完整安装版本的平台例外),避免数据库客户端和服务 器端存在版本不匹配带来的额外工作量,达梦在不同平台的不同版本上,安装包都会有差异, 一定要采用严格匹配的原则,除非得到达梦原厂技术人员的允许,尽量减少干扰性的问题出现。

2.2、数据库参数选择
初始化库,关键的点在于对初始化参数的设置,从mysql迁移到oracle推荐参数设置如下:
1、页大小page_size,在达梦中,页大小默认是8k,如果数据库中表存在较多大字段,建议设置成16k或者32k,否则导入数据时会报错。
2、mysql是大小写不敏感的,大小写敏感参数CASE_SENSITIVE设置成0。
3、簇大小 EXTENT_SIZE。数据文件使用的簇大小,即每次分配新的段空间时连续的页数,只能是16页或32页,缺省使用16页,从 mysql移植到 DM 使用默认值就可。
4、在dm.ini中将COMPATIBLE_MODE参数设置成4,表示兼容mysql。
5、在dm.ini中将CALC_AS_DECIMAL修改为1,表示整数相除保留小数。

2.3、其它准备事项
1、迁移前在达梦中创建对应的用户,默认会将数据迁移到SYSDBA用户下。
2、迁移前在达梦中创建对应的表空间,默认迁移到MAIN表空间下。
3、对于dts机器的内存推荐至少要大于4g,否则会出现"java heap space"之类内存不足的报错。
4、机器的CPU要多核,开12个以上的并行速度会快很多。
5、尽量考虑上SSD,机械盘的速度比较慢

3、迁移过程

3.1、制定迁移计划
1、迁移建议按照以下顺序进行:先迁移序列,再迁移表,最后迁移视图、函数等对象。
2、对于表的迁移,建议先迁移表结构(不包含索引、约束),再迁移表数据,最后迁移索引和约束。
3、数据量大的表单独进行迁移
4、对于大字段较多的表,需要修改批量的行数,以免造成迁移工具内存溢出。

3.2、建立迁移工程
使用达梦的dts迁移工具创建迁移工程,在迁移创建mysql到达梦的迁移工程即可,但是需要注意dts工具连接mysql要自己手动指定驱动包,如下图:
Mysql迁移达梦实践_第1张图片
相关的驱动包在toot/dropins/com.dameng/plugins/com.dameng.jdbc.drivers目录下面,指定完驱动后配置好驱动类名(如上图)和URL即可。

不过这里我配置完后出现了这个报错:
Mysql迁移达梦实践_第2张图片
当时反复检查后也没查出是什么原因,后来换了个版本的dts工具就搞定了。。。

3.3、迁移表
迁移表我们按照表结构=》表数据=》表约束这个顺序来。
首先是表结构:
Mysql迁移达梦实践_第3张图片
Mysql迁移达梦实践_第4张图片
如上图所示,这里要注意***在迁移工具的选项中要选择“保持对象名大小写”!***

接着迁移表数据:
Mysql迁移达梦实践_第5张图片
最后是约束:
Mysql迁移达梦实践_第6张图片
至此,表就已经迁移完成了!

这里说一下迁移表时碰到的问题:
–问题1:

错误号:   -2670

错误消息: 第10 行附近出现错误:
对象[is_show]DEFAULT约束表达式无效

---------------------------------
CREATE TABLE "FFCS"."c_table_tbl"
(
 "id" INT IDENTITY(1,1) NOT NULL,
 "title" VARCHAR(300) NULL,
 "param_out" VARCHAR(765) NULL,
 "param_in" VARCHAR(765) NULL,
 "data_source" VARCHAR(300) NULL,
 "is_show" VARCHAR(6) DEFAULT Y
 NOT NULL
)

解决方案:

CREATE TABLE "FFCS"."c_table_tbl"
(
 "id" INT IDENTITY(1,1) NOT NULL,
 "title" VARCHAR(300) NULL,
 "param_out" VARCHAR(765) NULL,
 "param_in" VARCHAR(765) NULL,
 "data_source" VARCHAR(300) NULL,
 "is_show" VARCHAR(6) DEFAULT 'Y'
 NOT NULL
)

–问题2:分区表问题
本次迁移因为表较少没碰到该问题,但这是在迁移表时十分典型的一个问题。因为达梦中要求分区表的分区列必须是主键。对于这个类型的错误需要使用复合主键,将分区键添加到主键中。

–问题3:‘0000-00-00 00:00:00’ 插入失败
因为mysql 中有’0000-00-00’ ‘0000-00-00 00:00:00’ 这样无效的日期类型数据,迁移时会报错,需要先在mysql中修改掉。

3.4、其它对象迁移
对于视图、函数、包这类对象,建议用脚本到达梦管理工具中直接执行。这里举几个本次迁移碰到的问题例子。

–问题1:视图创建报错

CREATE VIEW "FFCS"."aas_user_resource_view" ("resource_type","resource_key","operation_code","aas_user_id","aas_usergroup_id","is_direct_relate")  
AS 
select "r1"."resource_type"    AS "resource_type",
       "r1"."resource_key"     AS "resource_key",
       "r1"."operation_code"   AS "operation_code",
       "r1"."aas_user_id"      AS "aas_user_id",
       "r1"."aas_usergroup_id" AS "aas_usergroup_id",
       1                       AS "is_direct_relate"
  from "FFCS"."aas_resource_tbl" "r1"
 where "r1"."aas_user_id" is not null
union
select "r2"."resource_type"    AS "resource_type",
       "r2"."resource_key"     AS "resource_key",
       "r2"."operation_code"   AS "operation_code",
       "u"."aas_user_id"       AS "aas_user_id",
       "r2"."aas_usergroup_id" AS "aas_usergroup_id",
       0                       AS "is_direct_relate"
  from "FFCS"."aas_resource_tbl" "r2"
  join "FFCS"."aas_user_tbl" "u"
 where "u"."org_id" = "r2"."aas_usergroup_id" or
       "u"."aas_user_id" in
       (select "uug"."aas_user_id"
           from "FFCS"."aas_user_usergroup_tbl" "uug"
          where "uug"."aas_usergroup_id" = "r2"."aas_usergroup_id")

解决方案:
这里是因为mysql中支持select * from t1 join t2这种写法,而在达梦中要改成select * from t1,t2或着select * from t1 join t2 on(xxx)

CREATE VIEW "FFCS"."aas_user_resource_view" ("resource_type","resource_key","operation_code","aas_user_id","aas_usergroup_id","is_direct_relate")  
AS 
select "r1"."resource_type"    AS "resource_type",
       "r1"."resource_key"     AS "resource_key",
       "r1"."operation_code"   AS "operation_code",
       "r1"."aas_user_id"      AS "aas_user_id",
       "r1"."aas_usergroup_id" AS "aas_usergroup_id",
       1                       AS "is_direct_relate"
  from "FFCS"."aas_resource_tbl" "r1"
 where "r1"."aas_user_id" is not null
union
select "r2"."resource_type"    AS "resource_type",
       "r2"."resource_key"     AS "resource_key",
       "r2"."operation_code"   AS "operation_code",
       "u"."aas_user_id"       AS "aas_user_id",
       "r2"."aas_usergroup_id" AS "aas_usergroup_id",
       0                       AS "is_direct_relate"
  from "FFCS"."aas_resource_tbl" "r2",
   "FFCS"."aas_user_tbl" "u"
 where "u"."org_id" = "r2"."aas_usergroup_id" or
       "u"."aas_user_id" in
       (select "uug"."aas_user_id"
           from "FFCS"."aas_user_usergroup_tbl" "uug"

–问题2:函数创建报错

CREATE DEFINER=`ffcs`@`192.168.37.%` FUNCTION `judge_usergroup_is_center`(v_usergroup_id int) RETURNS int(11)
begin
  declare v_result int DEFAULT(-1);
  declare n_parent int;
  declare n_no_parent int;
  declare n_childs int;
  select count(1)
    from aas_usergroup_tbl gg
   where gg.aas_usergroup_id =
         (select g.parent_id
            from aas_usergroup_tbl g
           where g.aas_usergroup_id = v_usergroup_id) and gg.parent_id is null
     into n_parent;
     select count(1)
    from aas_usergroup_tbl gg
   where gg.aas_usergroup_id in (
    select parent_id
    from aas_usergroup_tbl gg
   where gg.aas_usergroup_id =
         (select g.parent_id
            from aas_usergroup_tbl g
           where g.aas_usergroup_id = v_usergroup_id)) into n_no_parent;
  select count(1)
    from aas_usergroup_tbl g
   where g.parent_id = v_usergroup_id  into n_childs;
   
  IF n_parent>0 THEN SET
        v_result =0;
   ELSEIF (n_no_parent >0 and n_childs>0) THEN SET
     v_result =1; 
   ELSEIF (n_no_parent >0 and n_childs=0) THEN SET
     v_result =2;
  END IF; 
  return v_result;
end

解决方法:
函数报错是因为语法区别导致的,改成如下:

CREATE or replace FUNCTION "FFCS"."judge_usergroup_is_center"(v_usergroup_id int) RETURN int is
   v_result int DEFAULT(-1);
   n_parent int;
   n_no_parent int;
   n_childs int;
 begin
  select count(1)
    into n_parent
    from aas_usergroup_tbl gg
   where gg.aas_usergroup_id =
         (select g.parent_id
            from aas_usergroup_tbl g
           where g.aas_usergroup_id = v_usergroup_id) and gg.parent_id is null
     ;
     select count(1)
     into n_no_parent
    from aas_usergroup_tbl gg
   where gg.aas_usergroup_id in (
    select parent_id
    from aas_usergroup_tbl gg
   where gg.aas_usergroup_id =
         (select g.parent_id
            from aas_usergroup_tbl g
           where g.aas_usergroup_id = v_usergroup_id));
  select count(1)
  into n_childs
    from aas_usergroup_tbl g
   where g.parent_id = v_usergroup_id ;
  IF n_parent>0 THEN SET
        v_result =0;
   ELSEIF (n_no_parent >0 and n_childs>0) THEN SET
     v_result =1; 
   ELSEIF (n_no_parent >0 and n_childs=0) THEN SET
     v_result =2;
  END IF; 
  return v_result;
end;

3.5、收尾工作
至此,迁移基本都已经完成了,最后我们需要对全库收集一次统计信息:

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

你可能感兴趣的:(国产数据库,数据库,sql,达梦)