一、迁移过程示意
数据的迁移过程由两部分组成:
第一部分是迁移数据库的结构,主要包括数据库对象的迁移;
第二部分是将数据迁移到目标数据库中。
真正的数据迁移是在第二部分完成的。对于数据的迁移,通常情况下是要暂停应用程序,这样可以保证迁移前后的数据一致性和完整性。使用常规方法,如果数据量很大的话,则需要较长的应用停机时间窗口。
在对时间窗口要求比较小的应用做迁移时,可以使用第三方工具(如 CDC)来进行增量数据的迁移,这样可以最大限度的减少停机时间,甚至可以实现 MySQL 到 GBase 8s 无缝迁移。
数据库结构和初始数据可以使用 GMTK(GBaseMigrationToolkit)工具来完成,工具可以按预设置的规划进行数据迁移,但仍需人工确认迁移后的数据库结构合理性。
二、文件格式
把数据从 MySQL 导出时,要将格式尽量调整为匹配 GBase 8s 的导入格式,这样可以最大程度上减小数据在转换过程中的工作量。这里以 GBase 8s 的 load 工具格式为例,来说明 一下导入时对文件格式的要求。
GBase 8s 的 load 工具是一个常用的文本导入工具,它的字段间默认分隔符是“|”管道符。由于“|”在文本中是很少出现的字符,所以也推荐在导出时使用“|”来作为分隔符。每个字段后都应由“|”来作为结束标识,换行符作为行与行之间的分隔符。每个表的数据单独存储在一个文件中。
demo
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|
复制代码
三、数据导出
从 MySQL 提取数据库架构后,下一步需要考虑从 MySQL 中的每个表提取数据。为此,可以使用 SELECT 语句和 mysqldump 或 OUTFILE 选项。无论采用哪种数据提取方法,要在 MySQL 和 GBase 8s 之间实现平滑数据移动,必须要考虑以下事项:
1)、MySQL 中的卸载数据是文本格式。
2)、为 MySQL 中的每个表创建一个独立卸载文件(outfile)
3)、卸载文件中的每一行表示 MySQL 中的一行。
4)、MySQL 中的每一列/字段通过一个字符|分隔。
5)、MySQL 中的每一行通过“/n”字符或其他有效的行结束符终止。
demo
SELECT * INTO OUTFILE '/tmp/tab1.unl'
FIELDS TERMINATED BY '|'
LINES TERMINATED BY '|\n'
FROM tab1;
复制代码
可以编写脚本来并发执行以上操作来提升数据从 MySQL 导出的效率。
导出的数据以 GBase 8s 导入要求的格式存储在/tmp/tab1.unl 中。
四、数据导入
(1)建立数据库时,以无日志模式建立,这样数据在导入时无需记录逻辑日志,导入效率会大幅提高。当数据导入完毕后,使用 ontape 命令将数据库改为需要的日志模式。
例如将某数据库日志模式改为 UNBUFF:
ontape -u DATABASE -s -L 0 -t /dev/null
复制代码
在数据量大的迁移中,可以将建立索引、约束等脚本单独提取出来,在所有数据成功导入后,再打开 PDQ 建立。
(2)使用 load 工具进行导入:
load 是 GBase 8s 最基础和最常用的文本数据导入工具,支持多表并发导入,操作简单。
demo
Load from /datam/tab1.unl insert into tab1;
复制代码
五、外部表导入
使用 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
复制代码
demo
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 进行快速数据导入。
六、对数据行数进行校验
MySQL 数据库中各表的行数统计:
use information_schema;
select table_name,table_rows from tables
where TABLE_SCHEMA = 'DATABASENAME' order by table_rows desc;
复制代码
GBase 8s 数据库中各表的行数统计:
update statistics;
select tabname,nrows from systables where tabid>99 and tabtpye='T' order by 2 desc;
复制代码
评论