新手使用DTS迁移,往往不知道从哪里下手,有哪些注意事项,出现报错问题不知道怎么处理,本文整理了迁移前的信息收集工作,如何快速做好准备工作,以及连接过程和迁移过程最常见的几种报错问题,并提供了解决思路,希望帮助新手快速学习利用DTS迁移。
数据迁移从准备阶段开始,就需要收集源库与目的库的信息,其中包含几个重要参数是实例级,仅在实例初始化阶段可以修改,而且会对数据迁移有重大影响,因此我们需要先收集信息为迁移做好准备,避免不必要的麻烦,以下是需要收集的信息表格:
调研项 调研情况
数据库版本/驱动版本
字符集编码
大小写是否敏感
是否以字节为单位
用户/模式
用户权限
表空间(数据、索引)
数据对象个数
大字段表个数
收集了源端的参数信息之后,我们要对目的端进行实例初始化,其中几个参数较为重要。
**1)PAGE_SIZE:**页大小默认为8K,建议设置成32K,一条记录的长度,受到页大小的限制,不可以超过页大小的一半,所以建议一开始规划页大小为32K;
**2)EXTENT_SIZE:**簇大小默认为16页,建议设置成32页;
3)CASE_SENSITIVE:默认是大小写敏感,源端为Oracle情况下,建议保持默认大小写敏感即可;参数1是敏感,0是不敏感;
4)BLANK_PAD_MODE:空格填充参数,是否要兼容Oracle进行设置,即在BLANK_PAD_MODE=0的情况下,’A’和’A ’被认为是相同的值,参数为1的情况下,认为是两个不同的值,根据现场具体应用的需求进行设置,此为初始化参数,只能在初始化时候指定,后续不可以修改,需要提前做好评估,但是源端为Oracle数据库时候,建议设置为1;
**5)CHARSET:**字符集编码,可选GB18030、UTF-8,默认为GB18030,如果只存储中文和字母数字,使用GB18030更节省空间,最好是与源库一致。
**6)LENGTH_IN_CHAR:**VARCHAR 类型对象的长度是否以字符为单位,默认是以字节为单位,此参数和字符集编码结合使用,所能存储的字符个数有所不同,详见如下表格:
**7)COMPATIBLE_MODE:**兼容参数,置为2为兼容Oracle参数,在dm.ini中可以进行配置,如果默认0的情况下,达梦视null不等同于空字符串,用户可能会插入空串,会导致is null查不出全部数据,所以视情况而定是否需要修改;
如果客户环境已经完成实例建立,以上参数可以用SQL语句进行查询:
SELECT
SF_GET_PAGE_SIZE() AS PAGE_SIZE,
SF_GET_EXTENT_SIZE() AS EXTENT_SIZE,
CASE_SENSITIVE() AS CASE_SENSITIVE,
(SELECT PARA_VALUE FROM V$DM_INI WHERE PARA_NAME = 'BLANK_PAD_MODE') AS BLANK_PAD_MODE,
CASE SF_GET_UNICODE_FLAG()
WHEN 0 THEN 'GB18030'
WHEN 1 THEN 'UTF-8'
ELSE 'UNKNOWN'
END AS CHARSET,
(SELECT PARA_VALUE FROM SYS."V$OPTION" WHERE PARA_NAME = 'LENGTH_IN_CHAR') AS LENGTH_IN_CHAR,
(SELECT PARA_VALUE FROM V$DM_INI WHERE PARA_NAME = 'COMPATIBLE_MODE') AS COMPATIBLE_MODE
FROM DUAL;
在完成了基础的信息收集与环境准备之后,我们需要进行源库与目的库的链接。
Oracle迁移到达梦,在DTS中选择相应的迁移方式
一般是通过指定驱动路径来连接oracle端
获得oracle驱动的方法如下:
1.通过Oracle官方网站下载相应版本:
2.通过Oracle的安装目录获得,位置在
“{ORACLE_HOME}/jdbc/lib/ojdbc6.jar”
目的端达梦同样可以通过指定驱动来连接,dts客户端版本最好和目的端达梦数据库版本接近:
2.3建立连接常见问题
1)Sid错误(instance_name)
原因:SID配置错误;填写的 SID 值在 listener 中未注册,或实例当前未启动,或实际实例名与填写不符。
解决方法:查看Oracle端instance_name,利用如下语句查看:
select value from v$parameter where name='instance_name';
将查到的值填写到迁移工具的连接配置中的 “SID” 字段
2)Service_name错误
原因:配置的service_name错误;配置的 Service Name 与 listener 中注册的服务名不匹配。
解决方法:查看源端Oracle库中的service_name配置,如下语句:
select value from v$parameter where name='service_names';
在迁移工具配置中,将 “服务名” 字段填写该值,并确保连接串中使用 SERVICE_NAME 而非 SID
完成源与目的库的链接之后,即可开始数据迁移,其中介绍几种常见的报错与解决方案,为多种异构数据库的迁移提供解决思路。
约束迁移主要涉及三类:外键、唯一约束、检查约束
核心注意一点,外键跨模式问题
如果外键引用的表在另一个模式下,需要勾选“保留引用表原有模式信息”,否则迁移后外键找不到引用的表会报错,还要确认目标库中,被引用的表存在且有访问权限。
原因:一条记录的长度超过页大小的一半,这是为什么我们设置目的库初始化参数建议设置为32的原因。
解决方案:
1)修改初始化参数页大小为32,如果表中存在大量的varchar类型,并且长度很长,不太使用。并且这个参数只能在初始化时修改,初始化之后没法修改,适用于新建库时预规划以及测试环境新建库。
2)将varchar(8000)这些字段类型修改为text
将超长的varchar字段改成text类型,达梦中text最大支持2GB,不受页大小限制,例如:
-- 示例:修改字段类型
ALTER TABLE HY_QGGWY.TABLEINFO_HISTORY
MODIFY 字段名 TEXT;
3)开启超长记录
通过达梦数据库参数,开启超长记录功能,让超过页大小一半的字段自动存储到行外
-- 开启超长记录(会话级或系统级)
ALTER SYSTEM SET 'ENABLE_LONG_RECORD' = 1;
-- 或针对特定表启用
ALTER TABLE HY_QGGWY.TABLEINFO_HISTORY ENABLE LONG RECORD;
操作简单,适用表结构复杂,字段多,难逐个修改的情况,优先选择!
原因:数据中含有中文,目的端达梦为UTF-8,源端为GBK,因两个字符集中文所占字节数不同,导致目的端存储数据报错。
解决方案:
1)初始化目的库选择GB18030
即初始化参数CHARSET=0
2)初始化时选择varchar类型以字符为单位
初始化时,将LENGTH_IN_CHAR=1,这样varchar中的字段将以字符个数为单位,而不是字节。
3)迁移时指定字符映射关系x2倍,即迁移时自动将源端的字符型长度x2,再创建目标表。
原因:
1.表中设置了唯一性约束或者主键约束,但是表中有重复记录
2.如果源库是oracle,oracle默认区分结尾空格,达梦端如果初始化没有指定BLANK_PAD_MODE=1则默认不区分,如果这个字段上有唯一性约束,会报错。
解决方案:
1.如果是重复数据,那就和应用确认重复数据的处理方式,可以在目的库删除干净数据之后在迁移,也可以指定删除已有数据
2.如果是空格问题,需要考虑重新初始化实例,指定初始化参数BLANK_PAD_MODE=1后再重新迁移。
问题描述:迁移时报错,JAVA HEAP SPACE
解决方案:
DTS所在机器内存不足导致,可以适当调整迁移数据时候的并发数量,源和目的的一次读取、写入的数据条数。
3.6局部唯一索引必须包含全部分区列
问题描述:迁移到达梦作为分区表的时候报错“局部唯一索引必须包含全部分区列”
原因:假设在Oracle有一张分区表(比如按月份分12个区),上面有一个主键,迁移到达梦时,DTS把这张表同样创为分区表,然后报错“局部唯一索引必须包含全部分区列”。
Oracle的宽松机制允许主键不包含分区列,但在达梦更为严格,分区表的主键(或唯一索引)必须包含所有分区列。
解决方案:
在迁移时,将分区列映射成主键,使用复合主键的方式
在源库执行以下语句,查出分区列:
SELECT COLUMN_NAME
FROM ALL_PART_KEY_COLUMNS
WHERE OWNER = '你的模式名'
AND NAME = '你的表名';
如果create_at是分区列,给它加上主键,如下图
保留原有的主键列,继续执行迁移即可。
本博客记录了在使用DTS工具进行数据迁移时,如何快速查询源与目的库的信息,并详细介绍了几个目的库的实例初始化参数,这几个参数都对数据迁移有较大的影响,需要与源库保持适配,并且从连接阶段到迁移阶段,介绍了几个常见的报错问题以及解决方案,可以发散到其他异构数据库为同样的报错问题解决提供思路。
文章
阅读量
获赞
