特性说明¶
版本查看¶
调用datamigrate –V命令可以获得datamigrate的版本以及依赖的ACI和STOI库、ECI库的版本号:
# ./datamigrate -V
datamigrate 2.0.30 (64bit) (build 241931) for Linux
STOI 2.0.30 (64bit)(build 241931 001) for Linux
ACI 2.0.37 (64bit)(build 241931 020) for Linux
ECI 2.0.10 (64bit)(build 321730 020) for Linux
文本文件加载相关特性¶
文本文件加载时注意以下事项:
- 标准的文本文件可能有行头,因此在加载前,需要确认文件的情况,否则会出错,去掉行头参数为:sfrowhead ( -h )
- 文本文件允许最后一行是空行,可以没有最后一个空行;
- 文本文件加载经常容易出错的一个原因就是转义符问题。部分使用者用非标准的csv文件格式进行导入,会出现错误,原因基本就是数据中包含类列或者行分隔符,而数据没有转义导致;
- 如果文本文件中的列数据顺序与表中的列顺序不同,可使用dmycols ( -J )来调整目的端列顺序,这个顺序与文本文件中的列顺序保持一致;
- 需要注意文本文件的文件编码格式,可通过设置convmode ( -M )和scharset ( -s )、dcharset ( -d )参数来设置字符集。
转移字符的使用¶
对于一般的数据,由数据部分、行分隔符和列分隔符组成。如果数据中含有行列分隔符,则工具解析时会出现错误。例如,列分隔符为"|",第一列数据是AA,第二列数据是B|B,第三列数据是CC,则数据在文本中保存为AA|B|B|CC,由于第二列数据中包含了分隔符"|",造成工具解析时认为本行数据含有四列,与表定义不符报错。
为有效解决实际数据中包含行分隔符或者列分隔符的情况,导入工具引入了参数-c。特别需要注意的是,导出的时候需要指定-c参数,否则数据很难再导入。
指定-c "\"",则导出数据为AA|"B|b"|CC,同样指定-c "\""进行导入,工具则认为转义字符”中间的|是数据,而非列分隔符,解决了数据中包含行列分隔符的问题。这个选项在导入导出csv格式文本时一定要使用。
Buffer复用特性¶
提交行数,默认为0 (表示该功能关闭,即达到BUFF加载行数或BUFF大小后提交)。该参数只在MPP5.0及后续版本中使用。参数意义如下:
原代码中采用隐式事务。每一个buffer数据导入的时候都向后台提交一次commit,后台收到commit以后开始处理数据。如果数据行数没有达到要压缩需要的行数时,会产生碎包。
为了减少碎包,通过设置参数rowcount ( -FN )开启buffer重用,用户定义向后台导入的行数,只有达到该行数时或者数据读取完成时,才向后台发送commit。
当有buffer数据提交后,从连接池中选择1个session,每个session记录自己获取的数据行数,当前session中写入的数据达到用户定义的提交行数时,向后台发送commit。
Buffer备份特性¶
Datamigrate对于一批数据在目的端加载失败,不管是因为数据本身的问题还是数据库的问题,datamigrate都会进行一次重试,而如果开启了rowcount ( -FN )参数时,由于buffer可能被重用了,重试时没有数据了,无法重试。因此datamigrate会将buffer数据在王目的端写入时,将这个buffer中的数据写入到一个临时文件,这个临时文件一般在datamigrate程序所在目录下dm_temp_file文件中,备份文件的后缀为.bin,加载过程中会为每个线程创建一个bin文件。数据加载完成后,会删除dm_temp_file文件及目录下的bin文件。
开启buffer复用功能默认也会开启备份功能,备份功能属于buffer复用功能的附属功能。
注意:如果同时指向多个datamigrate,多个datamigrate会公用dm_temp_file目录,通过bin文件无法知道bin文件属于哪一个datamigrate进程的。
dm_temp_file不管是正确加载还是错误加载数据,datamigrate结束运行时,都会删除dm_temp_file文件夹,datamigrate人为KILL、OOM或者crash的情况会有残留。
错误数据转存¶
当我们希望将失败数据保留时,可以指定-D参数,指定了一个错误数据转存的目录。此时如果有一批数据失败,且经过一次重试后依然无法成功的。在开启buffer复用时,datamigrate将这批数据对应的bin文件直接重命名到指定的转存目录中;没有开启buffer复用时将内存中的buffer写入到转成目录中。转成文件命名规则为:表名_0_时间戳_线程id_会话地址_数据行数_数据列数.bin。比如:一个转存文件名举例:student_0_1634006681_28919_0xffff541a6570_103027_34.bin
加载重试机制¶
Datamigrate对于一批加载失败的数据都会进行一次重试,重试依然失败,使用者如果想记录未加载成功的数据,则需要指定-D参数进行错误数据转存,否则这批数据会被丢弃,可能造成数据丢失。
源端数据库并行模式¶
如果源端是OSCAR、KSTORE或XCLUSTER时,可以设置sdbparall ( -p )来指定不同的并行模式,并行的意义提高从数据库中读取数据的效率。下面简单介绍并行的原理
- Partition: 按分区并行,需要源表已经进行了行分区处理(范围分区、列表分区等),否则指定后无效果。支持源库类型stype为OSCAR、KSTORE或XCLUSTER。只能与sdbtab ( -t )参数配合使用,这种模式下,datamigrate会执行查询数据库中的系统表,获得当前表的所有子分区名,然后多个多个线程并行去查询各个分区中的数据,实现并行。
- Package: 按包并行,支持源库类型stype为XCLUSTER,只有这两款产品才有数据包的概念,这种模式下datamigrate中会自动查询表中的数据包,并将这些包分配到多个线程中去并行处理。
- Node: 按node并行,datamigrate会查询集群中的节点,直接到各个节点中去查询数据并处理,支持源库类型stype为KSTORE或XCLUSTER。
- Limit: 按limit分页并行,将查询按照limit进行分页,分页的大小受sdblimit参数控制。支持源库类型stype为OSCAR,只能与-t参数搭配使用。
序列优化特性¶
日常我们可能期望目的端的数据某个字段的数据是自动增长,如果依赖数据库的序列,会较大影响数据的加载性能,因此datamigrate做了序列的优化设计:
给定序列名称后,从序列中拿到序列的当前值,且设置序列的下一个值为步长。比如序列的起始值为1,序列的步长为10000,我们获得序列的起始值1后,会利用1~9999的值,将这些值按行放到数据buffer中,直接入库。如果1~9999用完,我们会去获取序列的下一个值,因为可能并发获取序列的值,当前线程获取的序列的下一个值可能并不是10000,而可能是30000,则此时datamigrate会利用30000~3999的值,以此类推。
这样做的好处不依赖数据库去生成每一个序列,而是在程序生成序列的每一个值,提高了数据库的加载效率。
模拟数据生成¶
Datamigrate工具可以用来模拟想要的数据,模拟的数据可以直接入库,也可以写入csv文件。
gcoltype ( -x )参数指定生成模式数据各个列的类型和规则。列按逗号分割,格式为:"[类型]|[最小值或者文件路径]|[最大值]|[NULL率]|[头部]|[尾部]",默认为 NULL。
[类型]:参考gcoltype ( -x )参数中的详细介绍,这里忽略;
[最小值或者文件路径]:如果是数值,是值的最小值,如果是字符串类型,则是数据的最小长度;
[最大值]:如果是数值,是值的最大值,如果是字符串类型,则是数据的最大长度;注意,最大长度不能超过要导入数据库中的列长度限制。且必须大于头部和尾部字符串长度的和。
[NULL率]:0~100的数值,代表有多大概率生成空值,默认为0,不会生成空值;
[头部]:对于字符串类型,设置生成字符串的开头;
[尾部]:对于字符串类型,设置生成字符串的结尾;
设置列类型如下:
gcoltype="CONST_INT|0,RAND_STR|5|10|10|www.|.com,RAND_TIMESTAMP|130000000|1300001000
生成了3个列的数据,
第一列是int类型,最小值为0,无最大值;
第二列为字符串类型,字符串长度最少5个,最大10个,字符串以www.开头,以.com结束,模拟生成网址数据;
第三列为一个时间戳类型,设置的是一个数值,datamigrate会根据格林威治时间 加上这个值来生成具体的时间。
gdatacount ( -v )指定生成数据的行数,默认为 0。
编码转换¶
数据迁移一般把数据导出端称为源端,数据导入端称为目的端,datamigrate执行所在的平台称为客户端。在数据迁移过程中,字符集编码方式不同时容易产生乱码,有时需要对字符集编码方式进行转换。
源端与目的端字符集编码方式不同,根据字符集编码转换的阶段,可分为:前端转换、后端转换和自动转换。
1)前端转换(FOREEND)是在数据导出之后对数据进行转换,即dmig转换。需要指出源端及目的端的字符集编码方式。使用参数:-M "FOREEND" -s 源端编码方式 -d 目的端编码方式。示例如下:
a)源端(UTF8)导出数据到TEXTDIR(GBK):
datamigrate -y OSCAR -u sysdba/szoscar55@localhost:2003/OSRDB -t SYSDBA.STUDENT -Y TEXTDIR -F "/opt/test" -C "," -R "\n" -M "FOREEND" -s "UTF8" -d "GBK"
最终导出的文本文件尾GBK编码的CSV文件。
b)TEXTDIR(UTF8)导入数据到目的端(GBK):
datamigrate -y TEXTDIR -c "," -r "\n" -j ".csv" -f "/opt/test" -Y OSCAR -U sysdba/szoscar55@localhost:2003/OSRDB -T SYSDBA. STUDENT -M "FOREEND" -s "UTF8" -d "GBK"
此时文本文件是UTF8编码的文件,导入到GBK编码的数据库中。
2)后端转换(BACKEND)是在数据导入之前对数据进行转换,即stoi转换。需要指出源端及目的端的字符集编码方式。使用参数:-M "BACKEND" -s 源端编码方式 -d 目的端编码方式。示例如下:
a)源端(UTF8)导出数据到TEXTDIR(GBK):
datamigrate -y OSCAR -u sysdba/szoscar55@localhost:2003/OSRDB -t SYSDBA.STUDENT -Y TEXTDIR -F "/opt/test" -C "," -R "\n" -M "BACKEND" -s "UTF8" -d "GBK"
b)TEXTDIR(UTF8)导入数据到目的端(GBK):
datamigrate -y TEXTDIR -c "," -r "\n" -j ".csv" -f "/opt/test" -Y OSCAR -U sysdba/szoscar55@localhost:2003/OSRDB -T SYSDBA.STUDENT -M "BACKEND" -s "UTF8" -d "GBK"
3)自动转换(AUTO)是当目的端是数据库时在驱动层将数据转换成目的端编码方式。使用参数:-M "AUTO" -s 源端编码方式(当源端为数据库时,可以不用指定源端的编码方式)。示例如下:
a)源端为数据库(GBK),目的端为数据库(UTF8):
datamigrate -y OSCAR -u sysdba/szoscar55@localhost:2003/OSRDB -t STUDENT -Y OSCAR -U sysdba/szoscar55@localhost:2004/OSRDB2 -T STUDENT -M "AUTO"
b)源端为TEXTDIR(UTF8),目的端为数据库(GBK):
datamigrate -y TEXTDIR -c "," -r "\n" -j ".csv" -f "/opt/test" -Y OSCAR -U sysdba/szoscar55@localhost:2003/OSRDB -T SYSDBA.STUDENT -M "AUTO" -s "UTF8"
源端与客户端字符集编码方式不同:
当源端是数据库时,在驱动层将数据转换成客户端的编码方式。该方式下导出数据编码方式为客户端的编码方式。使用参数:-m "TRUE"。示例如下:
datamigrate -y OSCAR -u sysdba/szoscar55@localhost:2003/OSRDB -t SYSDBA.STUDENT -Y TEXTFILE -F "/opt/test.csv" -C "," -R "\n" -m "TRUE"
注解
从源端到目的端迁移数据的时候,务必要清楚以下3个编码方式:源端数据编码方式、客户端编码方式、目的端编码方式。
数据为文件(或文件路径)时,可以通过记事本、UE等文本编辑器查看数据编码方式。
注解
文本数据文件的编码目前只支持ASCII、GBK、GB18030、GB2312、UTF8这些单字节编码,不支持UTF16、UTF32、UNICODE。
获取数据库及客户端的编码方式方法如下:
| 数据类型 | 数据库编码方式 | 客户端编码方式 |
|---|---|---|
| Oracle | NLS_CHARACTERSET | NLS_LANG |
| MySQL | character_set_database | Linux: LANG; windows:正在生效的ANSI代码页 |
| Oscar | GETDATABASEENCODING() | Linux: LANG; windows:正在生效的ANSI代码页也会受NLS_OSCAR_LANG环境变量影响 |
| Kstore/MPP5 | ||
| xcluster |
内存占用的说明¶
由于datamigrate采用多线程和数据buffer池方式,且为了提高效率,会适当提高线程数量以及buffer个数和buffer大小,这些参数的调整会直接影响datamigrate进程的内存占用,因此在调整这些参时,需要评估环境的内存资源和CPU资源是否能满足需求。其中几个参数会较大影响内存,这里着重强调下:
-b参数,这个参数是从文本文件中读取数据的缓存大小,且与-k参数相关,因为每个线程有单独对应的数据缓存;
-B参数,这个参数代表buffer池中buffer的个数,而commitsize ( -Z )参数代表每个buffer的内存大小,因此buffer个数* buffer大小,这些内存也是不小的。
同时各个数据库接口层面和datamigrate还有其他一些内存开销,需要开发者根据实际硬件进行调整合适的参数。所有的值并不是越大越好。
TEXT类型支持约束¶
数据导入时
当前对于text类型,datamigrate的限制为300003,如果插入数据超过这个长度则会报错。
老版本报错信息为:[ERROR] - Thread migrate file1 c:\testsyn1.txt00000000000000 failed, Error Info -- "Index out of bounds exeception " ...
新版本报错信息为:[ERROR] - The data in column 5 is too large, the size limit is 292 KB , assign "-ML" value to solve the problem...
当使用了ML参数更改了限制时,导入信息数据长度超过1128576,源端获取信息时仍然会报错。
报错信息为:[ERROR] - File filepath data error: header and the data is empty, Considering that the data is too long, , assign "-MR" value to solve the problem ...
数据导出时
对于datamigrate获取数据库信息的类型为text时,超过300000字节时则会报错,超过限定数据大小时报错信息为:提取的列值被截断
由于数据库的text类型支持最大16M数据,datamigrate调用aci接口获取数据,如果aci获取数据时默认就分配16M的空间,但实际数据大部分都远远小于16M,这样会导致分配空间浪费,因此在aci接口有一个dbtext_max_len参数控制查询TEXT类型数据时默认分配的内存大小,这个值默认为150000,在连接字符串中修改dbtext_max_len的值,以便能查询更大数据,避免截断。
连接字符串设置dbtext_max_len参数举例如下:datamigrate -y OSCAR -u sysdba/szoscar55@localhost:2003/OSRDB?dbtext_max_len=4000000 -t test -Y TEXTFILE -F "/opt/test01.csv" -C "," -R "\n" -E "\""
注解
dbtext_max_len 为字符个数,实际分配空间会根据aci所在客户端的字符集进行翻倍,如果是GBK,则内存分配大小为dbtext_max_len*2,如果是UTF8,这时实际内存分配大小为dbtext_max_len*4.
Lob对象支持约束¶
Datamigrate的主要定位是文本数据的快速加载,因此对LOB的处理非常弱,目前限制datamigrate只能迁移100MB以下的LOB数据,如果需要迁移大于100MB的lob数据,可使用神通数据库的图像化迁移工具datamigrate_java。
HDFS集群本地配置¶
当在Windows本地使用datamigrate工具进行对源端为HDFS操作时,需要在本地hosts(C:\Windows\System32\drivers\etc)文件进行配置Hadoop集群ip信息,否则在进行连接时会无法识别域名信息。
例:
192.168.1.1 node1
192.168.1.2 node2
192.168.1.3 node3