Greenplum集群迁移--gptransfer的使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hmxz2nn/article/details/87881433

在使用greenplum时,当想将旧的集群中的数据迁移到新的集群中,有多种方法。如使用gp_dump命令进行数据的备份、拷贝与恢复,但相比较来说,还是使用gptransfer工具更简单方便,且更高效。

总述

gptransfer迁移工具把Greenplum数据库元数据从一个Greenplum数据库传输到另一个Greenplum数据库,允许用户迁移整个数据库的内容或者选中的表到另一个数据库。源数据库和目标数据库可以在相同或者不同的集群中。gptransfer在所有Segment间并行地移动数据,它使用gpfdist数据装载工具以获得最高的传输率。

gptransfer会处理数据传输的设置和执行。参与其中的集群必须已经存在,在两个集群的所有主机之间都有网络访问和证书认证的ssh访问。

gptransfer接口包括传输一个或者更多完整数据库以及一个或者更多数据库表的选项。一次完整数据库传输包括数据库模式、表数据、索引、视图、角色、用户定义的函数以及资源队列。包括postgres.conf和pg_hba.conf在内的配置文件必须由管理员手工传输。用gppkg安装在数据库中的扩展(例如MADlib和编程语言扩展)必须由管理员安装在目标数据库中。

gptransfer会做什么

gptransfer会使用可写和可读外部表、Greenplum的gpfdist并行数据装载工具以及命名管道来从源数据库传输数据到目标数据库。源集群上的Segment从源数据库表中选择并且插入到一个可写外部表中。目标集群中的Segment从一个可读外部表选择并且插入到目标数据库表。可写和可读外部表由源集群的Segment主机上的命名管道支撑,并且每个命名管道都有一个gpfdist进程负责把该管道的输出供应给目标Segment上的可读外部表。

gptransfer通过以批次处理要被传输的数据库对象来编排其处理过程。对于每个要被传输的表,它会执行下列任务:
1.在源数据库中创建一个可写外部表
2.在目标数据库中创建一个可读外部表
3.在源集群中的Segment主机上创建命名管道和gpfdist进程
4.在源数据库中执行一个SELECT INTO语句以插入源数据到可写外部表中
5.在目标数据库中执行一个SELECT INTO语句把数据从可读外部表插入到目标表中
6.可以选择通过在源和目标中比较行计数或者行的MD5哈希来验证数据
7.清除外部表、命名管道和gpfdist进程

先决条件

1.gptransfer功能只能用于Greenplum数据库,包括Dell EMC DCA appliance。不支持用Pivotal HAWQ作为源或者目的。
2.源和目的Greenplum集群必须为4.2及以上版本。
3.至少一个Greenplum实例必须在其发布中包括有gptransfer工具。该工具被包括在4.2.8.1或更高版本以及4.3.2.0或更高版本的 Greenplum数据库中。如果源或目标都不包括gptransfer,用户必须升级其中一个集群以使用gptransfer。
4.可以从源数据库或者目标数据库的集群中运行gptransfer工具。
5.目标集群中的Segment数量必须大于等于源集群中主机的数量。目标中的Segment数量可以小于源中的Segment数量,但是数据将会以较低的速率被传输。
6.两个集群中的Segment主机必须有网络连接彼此。
7.两个集群中的每一台主机必须能够用证书认证的SSH连接到其他每一台主机。用户可以使用gpssh_exkeys工具在两个集群的主机之间交换公钥。

在实际操作中,往往只需注意第7条即可。

限制

gptransfer只从用户数据库传输数据,postgres、template0以及template1数据库无法被传输。管理员必须手工传输配置文件并且用gppkg把扩展安装到目标数据库中。

目标集群必须具有至少和源集群Segment主机一样多的Segment。传输数据到一个较小的集群不如传输数据到较大的集群快。

传输小表或者空表无疑会比较慢。不管有没有实际的数据要传输,总是会有设置外部表以及Segment间并行数据装载的通信处理等固定开销。因此,对于小表可以使用copy命令在两个集群中进行拷贝迁移。

快模式和慢模式

gptransfer使用gpfdist并行文件服务工具建立数据传输,后者会均匀地把数据提供给目标Segment。运行更多的gpfdist进程可以提高并行性和数据传输率。
当目标集群的Segment数量与源集群相同或者更多时,gptransfer会为每一个源Segment建立一个命名管道和一个gpfdist进程。这是用于最优数据传输率的配置,并且被称为快模式。

当目标集群中的Segment比源集群中少时,命名管道的输入端配置会有所不同。gptransfer会自动处理这种替代设置。配置中的不同意味着传输数据到比源集群Segment少的目标集群比传输到具有和源集群同等或者更多Segment的目标集群更慢。它被称为慢模式。因为有较少的gpfdist进程将数据提供给目标集群,不过每台Segment主机的那个gpfdist的传输仍然很快。

批尺寸和子批尺寸

一次gptransfer执行的并行度由两个命令行选项决定:–batch-size和–sub-batch-size。–batch-size选项指定一批中传输的表数量。默认的批尺寸为2,这意味着任何时候都有两个表正在被传输。最小批尺寸为1,而最大值是10。–sub-batch-size参数指定用于传输一个表的并行子进程的最大数目。默认值是25,并且最大值是50。批尺寸和子批尺寸的积就是并行量。例如如果被设置为默认值,gptransfer可以执行50个并发任务。每个线程是一个Python进程并且会消耗内存,因此把这些值设置得太高可能会导致Python Out of Memory错误。因此,在用户的环境下应该调整批尺寸。

实际操作

为gptransfer准备主机

当用户安装一个Greenplum数据库集群时,会设置所有的Master和Segment主机让Greenplum数据库管理用户(gpadmin)能从集群中每一台主机用ssh连接到集群中其他任一台主机而无需提供口令。gptransfer工具要求在源集群和目标集群中每一台主机之间都具备这样的能力。首先,确保集群彼此有网络连接。然后,准备一个hosts文件,其中包含两个集群中所有的主机,并且使用gpssh-exkeys工具交换密钥。常见的操作是,将源集群和目标集群的IP得知放在一个文件中,然后执行gpssh-exkeys -f命令。

主机映射文件是一个文本文件,其中列出了源集群中的Segment主机(注意只包含segment主机)。它被用来启用Greenplum集群中主机之间的通信。该文件用–source-map-file=host_map_file命令选项在gptransfer命令行上指定。当使用gptransfer在两个单独的Greenplum集群之间拷贝数据时,它是一个必要选项。

该文件包含一个下列格式的列表:

host1_name,host1_ip_addr
host2_name,host2_ipaddr
...

该文件使用IP地址而不是主机名以避免集群之间的名称解析问题。

示例

迁移一个数据库:

gptransfer -d test_db --source-map-file=host_source -a --dest-host=101.8.187.11  --batch-size=2 --truncate 

该命令从源集群迁移一个数据库test_db到目标集群,目标集群的master节点IP为101.8.187.11,–truncate命令表示当执行迁移时,若发现目标集群已经数据库中已经有要迁移的表时,先进行truncate操作。

几个比较重要的参数

具体参数解释可以参考gptransfer的帮助文件。

-d  	后接要迁移的数据库
--source-map-file 		必须的参数,参考上文

--source-port greenplum默认的源端口和目标端口都是5432,如果使用的是其他端口,注意要修改

迁移时,有一个full模式,在使用–full选项运行时,gptransfer把源数据库中的所有表、视图、索引、角色、用户定义的函数和资源队列都拷贝到目标数据库中。要被传输的数据不能在目标集群上已经存在。如果gptransfer在目标上找到该数据库,它将失败并且报出下面这样的消息:

[ERROR]:- gptransfer: error: --full option specified but tables exist on destination system

注意–full模式不能和-t、-f、-truncate等命令一起使用。

要单独拷贝表,可以使用-t命令行选项(一个表用一个选项)指定表或者使用-f命令行选项指定一个包含要传输表列表的文件。表以完全限定的格式database.schema.table指定。表定义、索引和表数据会被拷贝。数据库必须在目标集群上已经存在。

如果用户尝试传输一个在目标数据库中已经存在的表,gptransfer默认会失败:

[INFO]:-Validating transfer table set...
[CRITICAL]:- gptransfer failed. (Reason='Table database.schema.table exists in database database .') exiting...

可以用–skip-existing、–truncate或者–drop选项覆盖这一行为。

下面的表格展示了在完整模式和表模式中会被拷贝的对象。

对象 完整模式 表模式
数据
索引
角色
函数
资源队列
postgres.conf
pg_hba.conf
gppkg
-x		选项启用表锁定。会在源表上放置一个排他锁直到拷贝以及验证(如果请求)完成。

gptransfer默认不验证已传输的数据。用户可以使用--validate=type选项请求验证。验证类型可以是下列之一:
count – 比较源数据库和目标数据库中表的行计数。
md5 – 在源和目标上都排序表,然后执行已排序行的逐行MD5哈希比较。
如果数据库在传输期间是可访问的,确保增加-x选项锁住表。否则,表可能在传输期间被更改,这会导致验证失败。

失败的传输

一个表上的失败不会结束gptransfer任务。当一个传输失败时,gptransfer会显示一个错误消息并且把表名加到一个失败传输文件中。在gptransfer会话结束时,gptransfer会写出一个消息告诉用户有失败出现,并且提供失败传输文件的名称。例如:

[WARNING]:-Some tables failed to transfer. A list of these tables
[WARNING]:-has been written to the file failed_transfer_tables_20140808_101813.txt
[WARNING]:-This file can be used with the -f option to continue

失败传输文件的格式由-f选项决定,因此用户可以用它来开始一个新的gptransfer会话以重试失败的传输。

最佳实践

1)对大型表使用gptransfer而用其他方法(如copy)拷贝较小的表。

2)在用户开始传输数据之前,从源集群复制模式到目标集群。不要使用带–full –schema-only选项的gptransfer。这里有一些选项可以拷贝schema:
1.使用gpsd(Greenplum统计信息转储)支持工具。这种方法会包括统计信息,因此要确保在目标集群上创建模式之后运行ANALYZE。
2.使用PostgreSQL的pg_dump或者pg_dumpall工具,并且加上–schema-only选项。
3.DDL脚本或者其他在目标数据库中重建模式的方法。

3)最好是传输到相同尺寸的集群或者较大的集群,这样gptransfer会运行在快模式中。

4)如果存在索引,在开始传输过程之前删除它们。

5)使用gptransfer的表选项(-t)或者文件选项(-f)以批次执行迁移。不要使用完整模式运行gptransfer,模式和较小的表已经被传输过了。

6)在进行生产迁移之前,执行gptransfer处理的测试运行。这确保表可以被成功地传输。用户可以用–batch-size和–sub-batch-size选项进行实验以获得最大的并行性。为gptransfer的迭代运行确定正确的表批次。

7)包括–skip-existing选项,因为模式已经在目标集群上存在。

8)仅使用完全限定的表名。注意表名中的句点(.)、空白、引号(’)以及双引号(")可能会导致问题。

9)如果用户决定使用–validation选项在传输后验证数据,确保也使用-x选项在源表上放置一个排他锁。

10)在所有的表都被传输后,执行下列任务:
1.检查并且改正失败的传输。
2.重新创建在传输前被删除的索引。
3.确保角色、函数和资源队列在目标数据库中被创建。当用户使用gptransfer -t选项时,这些对象不会被传输。
4.从源集群拷贝postgres.conf和pg_hba.conf配置文件到目标集群。
5.在目标数据库中用gppkg安装需要的扩展。

参考:
1.https://gp-docs-cn.github.io/docs/best_practices/gptransfer.html#top
2.https://blog.csdn.net/wxc20062006/article/details/77650244

猜你喜欢

转载自blog.csdn.net/hmxz2nn/article/details/87881433