使用 Gptransfer 命令迁移一个 Greenplum 数据库集群中的数据到另一台集群(metradata, data)
gptransfer 可以迁移数据库中的全部数据或者部分选择的表到另外一台 Greenplum 中。 源数据库和目的数据库可以在同一个集群中,也可以在不同的集群中。 gptransfer 所有的段数据库是并行的移动数据的,使用 gpfdist 可以获得更高的数据移动效率。
gptransfer 处理这数据的启动和执行。 参与的集群必须存在。同时确保集群间的访问时可以用过 SSH 访问实现的。网络互通。
gptranfer 参数包括处理一个数据库和多个数据库参数, 处理一张表和多张表参数。 全部的数据集迁移包括 schema, table date, indexes, views, roles, user-defined fuctions , resource queues. 参数配置文件 postgres.conf, ph_hba.conf, 必须使用超级用户在源与目的数据库之间执行操作。使用外部命令 gppkg 安装 gptransfer. 就像安装 MADLIB 一样。
gptransfer 是如何工作的
gptransfer 是通过使用对外部表的读写操作试下你的,底层使用的工具是greenplum提供的 gpfdist 实现并行加载数据, 管道用来从源数据到目的数据端传输数据。 从源数据中选择需要向目的数据段可写外部表的数据,执行插入操作。在目的段数据库中选择表和数据库,从外部表将数据导入到本地。这可读可写的外部表是用过命名管道去访问源数据库的, 每一个命名管道都有一个 gpfdist 进程存在,实现从源数据到目的数据库。
gptransfer 通过批处理的方式编排数据, 每移动一张表, 他都要经历如下的任务:
- 在源数据库中创建可写的外部表
- 在目的数据库中创建可读的外部表
- 在源数据集群中的每一个段数据库上,创建一个命名管道和 gptranfer 进程。
- 在源数据库段执行 SELECT INTO 语句,将源数据库中的数据加载到可写的外部表中
- 在目的数据库中执行 SELECT INTO 语句, 从可读的外部表中加载数据到数据库中的表中
- 选择有效的 MD5 参数,用来确定导入的数据在源数据库与目的数据库之间没有任何问题
- 清空外部表, 命名管道, gpfdist 进程
前提准备
- gptranfer 只适合Greenplum数据库集群, HAWQ 并不支持
- Greenplum 的版本必须是在 4.2 或 以上
- 源与目的的数据库集群必须要有 gptransfer
- 目的数据库集群中的段数据库数量必须大于等于源数据库中段的数量。如果满足这个条件,数据迁移会非常的慢
- 集群间的节点必须是可以连通的
- 可以使用 ssh 连接各个及诶到哪。 我们可以使用 gpssh_exkeys 命令来交换秘钥,在集群之间
快模式和慢模式
同时运行多个 gptransfer , 可以更快的完成数据迁移。原理就是启动更多的 gpfdist 进程,这种模式叫做快模式
当目的数据库集群中的段数据库数量大于源数据库集群段数据库很多时,可以这个干。
当目的数据库集群中的段数库数量小于源数据库集群段数据库时, 启动的 gptransfer 数量就会很少, 同时代表着 gpfdist 进程数量的减少。这就意味着将会花费着更多的时间。就是慢模式
批量处理的大小和子批量处理的大小
gpftransfer 的参数用来控制执行并行的读,这里有两个执行参数, --batch-size, --sub-batch-size; 其中 --batch-size 参数用来确定在一个批处理中处理多少表。 默认值是2, 这就意味着在任何进程中一次处理两张表。最小的批处理的值是1, 最大的值是10.
--sub-batch-size 用来确定在转移数据时,子进程的最大并行数量。默认值是25, 最大值是50.批处理的值和子进程的值的乘积就是数据迁移的并行值。如果都按着默认的值设置, 那么 gpftranser 就是50个任务并行。 每一个线程都是 Python 和 内存,所以,如果值设置的很大就会导致内存溢出的问题。所以这个值,我们要根据自己的实际环境来处理。
节点的准备工作
Greenplum 集群中的各个节点间实现无密通信, 实现 ssh 通信。gpftranser 要求源与目的数据库集群间都要装有该工具。
首先,确保网络环境正常。然后确定有一个 host file 用来存储全部需要使用到无密码传输的节点名,最后使用 gpssh-exkeys 交换秘钥。
这个映射文件 host file 里面包含了源集群中的全部节点名,它用来实现集群间的节点通信。 在Gptransfer 中使用的参数是
--source-map-file=host_map_file 参数。 这个参数是使用 gptransfer 在集群间copy数据使用的
host_name,host1_ip_addr
host_name,host2_ip_addr
该文件使用IP地址而不是主机名来避免集群之间名称解析的问题。
缺点
gptransfer 仅仅可以移动用户数据库。对于数据库 poostgresql, template0, template1 数据库不能被移动。超级用户手动移动配置文件和使用 gppkg 安装外部应用,在目的数据中。
目的数据库集群最好有比源数据库集群更多的段数据库,不然移动数据会非常慢。
对于移动小表或者空表时, gptransfer 也会很慢, 这是为什么呢?主要是因为,时间都花费在建议读写外部表,进程间的连接等上面。
全模式 和 表模式
当使用参数 --full 时, gptransfer 会拷贝全部的 tables, views, indexes, roles, user-defined function, resource queneue 从源数据库到目的数据库。将要从源数据库移动的数据库必须不存在在目的数据库集群中。如果 gptransfer 报出如下错误时
去独立的拷贝某一个表,需要强调使用的参数是 -t, 如果只想拷贝一个表的一部分数据使用的是 -f 参数。 当拷贝表时, 目的数据库必须存在。拷贝表使用如下格式 database.schema.table; 这个表的 索引 ,表结构, 表中的数据都会被拷贝。
如果目的数据库已经存在该表, 在尝试迁移源数据库的表将会遇到如下错误
想要跳过这个错误使用如下参数
--skip-existing, --truncate 或者 --drop
接下来的表格用来显示全拷贝模式与表拷贝模式
object Full Mode Table Mode
Data Yes Yes
Indexes Yes Yes
Roles Yes No
Functions Yes No
Resource Queues Yes No
postgres.conf No No
pg_hba.conf No No
gppkg No No
使用如下参数在全拷贝模式下,只会拷贝表结构,不会拷贝数据
gptransfer --full --schema-only -d
在接下来使用表模式的时候,需要注意可能要用到表模式的参数 --truncate OR --drop 参数
锁
使用参数 -x 可以给表加锁。直到验证和数据拷贝完成,才会释放排他锁。
验证
默认情况下, gptransfer 并不会去验证迁移完成的数据。 我们可以使用参数 --validate=type 选项来设置验证。
type 的类型可以是
count - 用来比较源数据与目的数据的记录数量是否一致
md5 - 对源数据的表和目的数据的表排序, 然后一行一行比较。检查不同
在使用 gptransfer 迁移数据的时候,要确保加上参数 -x 来确保所有的对源表有排他锁。因为在迁移数据时,表中的记录发生该表将会验证失败。
迁移失败
迁移失败并不会一起 gptransfer 任务中止。 当一个迁移任务失败的时候。 gptransfer 就会将错误信息加载到失败的gptransfer文件中。 在 gptransfer 会话中, 它会提供到底哪里出错了, 如下例子
[WARNING] : - Some tables failed to transfer. A list of these tables
正如上面提示的警告信息, 我们可以使用 -f 参数去重新的请求文件格式
最佳实践
对于大数据量的表的迁移使用 gptransfer 是非常好的选择, 对于空表和小数据量的表而言, 迁移的准备工作和后期的清理公共,会显示的数据迁移的非常的慢。那么最好的做法就是使用 gptransfer 去迁移大数据量的表,对于小数据量的表使用其他的方法。
-
在开始迁移数据时, 在目的数据库集群备份源数据的schema. 不要去使用 gptransfer 中的参数 --full -schema-only , 可以使用如下命令来完成上述工作
1.1 使用 *gpsd* (Greenplum Statistics Dump) 支持工具。所以要在目的数据库集群上运行完 *ANALYZE* 命令后, 在使用 *gpsd* 命令 1.2 使用 PostgreSQL 的 pg_dump OR pg_dumpall 工具, 使用参数是 *-shcma-only* 1.3 使用 DDL 脚本手动重新创建也可以
- 将要迁移的大表分割为大类和小类, 使用自己制定的标准。举个例子, 我们可以将大表划分为多个小表, 每一个表含有的记录熟练是 1千万条记录或者是每个表有1GB大小
- 对于迁移小表数据, 建议使用 COPY 命令。
这样可以循环使用之前写的脚本文件。 -
使用 gptransfer 用来批量迁移数据文件
4.1 最好使用 *fast* 模式。 即目的数据库有更多的段数据库 4.2 在迁移数据之前,先把索引给删除了 4.3 使用 *-t OR -f* 参数,迁移数据, 不要使用全模式迁移数据。 4.4 在生产环境中,先测试一下数据迁移,在实际去执行。可以试验如下参数 *--batch-size* 和 *--sub-batch-size* 参数 4.5 如果在目的段数据库中已经存了模式信息, 记得使用 *--skip-existing* 参数 4.6 使用完全限定的表名。注意 (.) (') (") 引起的问题 4.7 如果决定使用了校验参数 *--validation* 参数, 注意要加上排他锁在源数据库的表上 *-x* 参数
-
在所有的表都迁移完成后, 执行如下的操作
5.1 检查和更改错误的 *gptransfer* 任务 5.2 重新为表创建索引 5.3 明确 *roles* , *functions* , *resource queues* 等, 在目的数据库中。 5.4 复制 *postgresql.conf* 和 *pg_hba.conf* 参数文件从源数据库到目的数据库 5.5 使用 *gppkg* 重新安装扩展文件
参考文献
">https://gpdb.docs.pivotal.io/500/best_practices/gptransfer.html>