数据的迁徙
在数据的世界里,每一次迁移都是一次深刻的变革。DB2至南大通用GBase 8s的旅程不仅是技术的跨越,更是企业信息架构的一次全面升级。数据,作为企业的核心资产,其迁移过程的稳健与效率,直接关系到企业运营的连续性和数据资产的安全性。本文将带您深入了解这一过程,探索数据迁移的艺术与科学。
一、迁移过程的蓝图
如图,数据的迁移过程由两部分组成。第一部分是迁移数据库的结构,主要包括数据库对象的迁移;第二部分是将数据迁移到目标数据库中。
其中,第一部分我们在上篇已经详细讲解。真正的数据迁移是在第二部分完成的。对于数据的迁移,通常情况下是要暂停应用程序,这样可以保证迁移前后的数据一致性和完整性。
二、文件格式的桥梁
把数据从DB2导出时,要将导出文件格式调整为匹配GBase 8s的导入格式,这样可以最大程度上减小数据在转换过程中的工作量。这里以GBase 8s的load工具格式为例,来说明 一下导入时对文件格式的要求。
南大通用GBase 8s的load工具是一个常用的文本导入工具,它的字段间默认分隔符是“|”管道符。由于“|”在文本中是很少出现的字符,所以也推荐在导出时使用“|”来作为分隔符。每个字段后都应由“|”来作为结束标识,换行符作为行与行之间的分隔符。每个表的数据单独存储在一个文件中。
示例:
create table customer_log
( id char(14),
update_date datetime year to second,
tablename varchar(20),
update_count float,
updated float );
表customer_log的导出/导入格式如下:
20101013114153|2010-10-13 11:41:53|2|53.0|53.0|
20101013114153|2010-10-13 11:41:53|3|0.0|0.0|
20101015094917|2010-10-15 09:49:17|2|15.0|15.0|
20101015094917|2010-10-15 09:49:17|3|0.0|0.0|
20101015094918|2010-10-15 09:49:18|4|1.0|1.0|
20101015102622|2010-10-15 10:26:22|2|2.0|2.0|
20101015102622|2010-10-15 10:26:22|4|0.0|0.0|
20101015111103|2010-10-15 11:11:03|1|1.0|1.0|
三、数据导出的策略
1. 设置远程连接工具字符集,根据现场实际字符集设置,这里是使用Xshell设置成UTF8
2. DB2的数据可以通过export实用程序的功能,导出符合GBase 8s要求的文本格式。
以下是export导出数据时的一个示例
Export 数据导出
语法:export to filename of filetype modified by filetype-mod messages message-file select-statement
filetype:支持del|wsf|ixf等格式,del为ASCII字符隔离格式,gbase8s支持ASCII格式,所以用del格式
filetype-mod:文件类型模式(下面列举的只针对del格式,其中codepage可用于ixf格式)
nochardel: 列没有包裹字符,默认为("")
coldelx:指定列分隔符,缺省是逗号,可以改为|分隔符 modified by coldel|
codepage=x : 设置代码页,1208为UTF-8编码格式, 1392(GB18030),1383 (gb2312),1386(GBK)
decplusblank:指定对正数是否用+符号,缺省带+,可以指定不加正数符号
striplzeros:指定移走数据前导的0,如:+00001.8–>+1.8
timestampformat="x" : 设置日期数据格式,YYYY-MM-DD HH:MM:SS.UUUUU
示例:
db2 "export to test.del of del modified by nochardel coldel| codepage=1208 decplusblank striplzeros timestampformat=\"YYYY-MM-DD HH:MM:SS.UUUUU\" select * from test"
结果:
[db2inst2@localhost ~]$ cat test.del
3|李四| 85.60|20230916|2023-09-14 09:42:25.00032
1|张三| 90.80|20230915|2023-09-14 08:42:25.00032
2|peter| 90.80|20231015|2023-09-14 08:42:25.00032
4|张鹏| 91.80|20231016|2023-09-15 08:42:25.00032
1|张三| 90.80|20230915|2023-09-14 08:42:25.00032
2|peter| 90.80|20231015|2023-09-14 08:42:25.00032
4|张鹏| 91.80|20231016|2023-09-15 08:42:25.00032
3. 生成批量导出语句:
db2 "select 'export to ' || rtrim(tabname)||'.del of del modified by nochardel coldel| codepage=1208 decplusblank striplzeros timestampformat=\"YYYY-MM-DD HH:MM:SS.UUUUU\" select * from '||rtrim(tabname) ||';' from syscat.tables where tabschema in ( 'db2inst1','DB2INST2' )" >>exportdata.sql
备注:tabschema 要改为现场实际的schema值
4. 执行批量导出:db2 -tvf exportdata.sql
四、数据导入的技巧
1、注意事项
建立数据库时,以无日志模式建立,这样数据在导入时无需记录逻辑日志,导入效率会大幅提高。当数据导入完毕后,使用ontape命令将数据库改为需要的日志模式。
例如将某数据库日志模式改为UNBUFF:
ontape –U database_name –s –L 0 –t /dev/null
在数据量大的迁移中,可以将建立索引、约束等脚本单独提取出来,在所有数据成功导入后,再打开PDQ建立。
2、load工具
1)先检查字符集:
[gbasedbt@localhost ~]$ env|grep LOCALE
CLIENT_LOCALE=zh_CN.utf8
DB_LOCALE=zh_CN.utf8
2)设置环境变量:GL_DATE,GL_DATETIME,确保跟导出文件的日期,时间格式一样。
[gbasedbt@localhost ~]$ export GL_DATE='%iY%m%d'
[gbasedbt@localhost ~]$ export GL_DATETIME='%iY-%m-%d %H:%M%S.%F5'
3)使用load工具进行导入:
load是GBase 8s最基础和最常用的文本数据导入工具,支持多表并发导入,操作简单。
示例:
load from TAB_NAME.del insert into TAB_NAME;
执行结果:
4)生成批量导入脚本
db2 " select 'load from '|| rtrim(tabname)||'.del insert into ' ||rtrim(tabname) ||';' from syscat.tables where tabschema in ( 'db2inst1','DB2INST2' )" >>loaddata.sql
5)执行生成导入脚本,并交脚本拷贝到Gbase8s服务器,用dbaccess DB_NAME loaddata.sql 命令进行导入
3、迁移大对象
1)导出大对象
命令: db2 "export to emp_photo.del of del lobs to /home/db2inst2/lobs lobfile emp_photo modified by nochardel coldel| codepage=1208 decplusblank striplzeros timestampformat=\"YYYY-MM-DD HH:MM:SS.UUUUU\" select * from emp_photo"
备注:黄色根据实际表名进行修改;
先查一下这个表结构:
4、外部表导入
使用GBase 8s外部表(external table)进行导入:
对于数据量大的表,传统的load导入方式会在迁移过程中占用大量的时间窗口,成为迁移效率的瓶颈。针对这个问题,对大表的导入,可以采用GBase 8s外部表的方式进行,创建External table:
语法
CREATE EXTERNAL TABLE table-name
(
column-name { datatype [DEFAULT default_opts] | <UDTs> } [
<external-column-defn> ] [,...]
)
USING (DATAFILES("{DISK | PIPE} : file-path" [,...] )
[, <table-option> [...] ])
<external-column-defn>:EXTERNAL CHAR( size ) [ NULL 'null-string' [ NOT NULL ] ]
<table-options>:
FORMAT format-type
DEFAULT | DELUXE | EXPRESS
ESCAPE 'escape-character'
DELIMITER 'field-delimiter'
RECORDEND 'record-delimiter'
MAXERRORS num-errors
REJECTFILE 'filename'
NUMROWS num-rows
示例:
create external table orders_ext
( order_num serial, order_date date, customer_num integer,ship_instruct char(40),
backlog char(1), po_num char(10),ship_date date, ship_weight decimal(8,2),
ship_charge money(6,2), paid_date date )
using
(
datafiles ("DISK:/opt/gbase/test/external_table/orders1.unl",
"DISK:/opt/gbase/test/external_table/orders2.unl" ),
format "delimited",
DELIMITER "|",
rejectfile "/opt/gbase/test/external_table/orders_rejfile.err",
maxerrors 100
);
也可根据已有表结构建立相同结构的外部表:
create external table orders_ext SAMEAS orders
using
(
datafiles ("DISK:/opt/gbse/test/external_table/orders1.unl",
"DISK:/opt/gbase/test/external_table/orders2.unl" ),
format "delimited",
DELIMITER "|",
rejectfile "/opt/gbase/test/external_table/orders_rejfile.err",
maxerrors 100
);
导入数据:
insert into orders select * from orders_ext;
外部表使用技巧:PDQ & 分片表 & Light append
打开PDQ功能,并行处理。
目的表是分片表能进行并行的insert和select。
当导入表为RAW TABLE时,利用Light append进行快速数据导入。
五、数据校验的重要性
对数据行数进行校验
DB2数据库中各表的行数统计:
db2 => select count(*) from table_name;
批量脚本:
db2 " select 'select count(*) from '|| rtrim(tabname) ||';' from syscat.tables where tabschema in ( 'db2inst1','DB2INST2' ) order by tabname " >> table_count.sql
执行脚本:db2 -tvf table_count.sql >count.out
GBase 8s数据库中各表的行数统计:
方法1:update statistics;
select tabname,nrows from systables where tabid>99 and tabtpye='T' order by 2 desc;
方法2:可以使用db2生成的语句进行统计:
命令:dbaccess DB_NAME table_count.sql;
六、迁移大对象的迁移智慧
案例:我们以DB2 自带数据库SAMPLE 下的表emp_photo为例,以下是表结构信息
1、单行导出大对象
命令:db2 "export to 000190.del of del lobs to /home/db2inst2/lobs lobfile 000190 select * from emp_photo where EMPNO=000190 "
2、生成批量导出语句
命令:db2 "select 'export to '||EMPNO||'.del of del lobs to /home/db2inst2/lobs lobfile '||EMPNO ||' select * from emp_photo where EMPNO='||EMPNO|| ';' from emp_photo where PHOTO_FORMAT='gif'" >gif.sql
3、执行批量导出:
命令:db2 -tvf gif.sql
到现在导出步骤已完成。
4、生成批量导入的语句:
1)db2 "select 'INSERT INTO emp_photo VALUES('||EMPNO||',@gif@,FILETOBLOB(@/home/gbasedbt/lobs/'||EMPNO||'.001.lob@,@server@));' from emp_photo where photo_format='gif' " >infile_gif.sql
2)db2 "select 'INSERT INTO emp_photo VALUES('||EMPNO||',@bitmap@,FILETOBLOB(@/home/gbasedbt/lobs/'||EMPNO||'.001.lob@,@server@));' from emp_photo where photo_format='bitmap' " >infile_bitmap.sql
3)sed -i "s#@#'#g" infile_gif.sql --把@符文替换成单引号’
4)sed -i "s#@#'#g" infile_bitmap.sql --把@符文替换成单引号’
5、把导入文件和导入脚本传到gbase8s服务器上的/home/gbasedbt/lobs 目录上;
6、开始执行批量导入:dbaccess mydb infile_gif.sql , dbaccess mydb infile_bitmap.sql
至此导入完成,需要去验证导入的大对象时候可用。由于条件有限,我这里只能验证导入是否成功,暂无法验证导入数据是否可用。
数据迁移是一场关于精确、效率和安全的较量。从DB2到南大通用GBase 8s,每一步都充满了挑战,但也孕育着机遇。企业通过这一过程,不仅能够提升数据管理的能力,还能够在数字化转型的道路上迈出坚实的步伐。
随着技术的不断演进,数据迁移将成为企业成长的必经之路。我们期待,通过本文的分享,能够帮助更多的企业在数据迁移的旅途中,找到正确的方向,实现数据价值的最大化。下一篇我们来说说从DB2至南大通用GBase 8s的应用迁移。