一篇文章帮你详细了解Greenplum迁移工具—GPCopy

以下资料是根据Pivotal Greenplum官网翻译、Grenplum中文社区博客以及个人测试所得,如有部分描述错误,欢迎下方评论指出,共同进步。

目录

一:gpcopy介绍

二:gpcopy相较于gptransfer

三:gpcopy版本发展史

四:gpcopy命令(基于gpcopy1.5.0)

五:gpcopy官方提示注意点

六:gpcopy使用测试注意点

七:gpcopy参考地址

一、gpcopy介绍

gpcopy是一个数据迁移实用程序,可以在不同集群之间进行传输数据,可以将一个集群中的Greenplum数据库的元数据和数据复制到另一个集群的Greenplum数据库中。gpcopy可以迁移数据库的全部内容,包括数据库架构、表数据、索引、视图、角色、用户自定义函数、资源队列、资源组。

二、gpcopy相较于gptransfer

(1)复制数据更快:注意这里说的是数据,而不是元数据。gpcopy更快速原因可分为三点:segment间直接传输、Snappy压缩传输、数据校验。

         ①segment间直接传输:当一个表的数据超过指定数据行数(–on-segment-threshold默认为10000行)时,gpcopy会利用COPY ON SEGMENT特性使得gpcopy可以做到两个cluster的多节点间并发传输。除此之外,gpcopy的数据传输本身就是利用copy命令,而gptransfer则是通过外部表的SELECT和INSERT进行逐条操作,copy使用批量操作自然而然要比insert更快。

         ②Snappy压缩传输:gpcopy默认使用Google的Snappy格式对数据进行压缩和传输,而gptransfer使用zlib格式进行压缩和传输,百度snappy和zlib压缩性能对比,Snappy性能明显要高很多。

         ③数据校验:gpcopy和gptransfer都有两种校验方式,第一种校验方式相同:比较源表数据和目标表数据之间的行数,第二种校验方式也都是基于md5校验,但是gptransfer是先对源表和目标表进行排序,再对排序后的行计算MD5哈希值并逐行比较,反观gpcopy,先将每一行的所有列转换为文本,然后计算每行的md5值,最后对md5值进行XOR(异或)比较。

(2)数据迁移更稳定:命名管道以文件的形式存在于文件系统中,任何进程只要有权限,打开该文件即可通信。导致命名管道文件难以管理,也容易出问题。gpcopy没有命名管道文件。而gptransfer使用可写和可读外部表、Greenplum的gpfdist并行数据装载工具以及命名管道来从源数据库传输数据到目标数据库,所以命名管道必不可少。

参考地址:https://cloud.tencent.com/developer/news/355959

三、gpcopy版本发展史

根据官网解释、网上查阅资料了解以及手动实践,我发现,gpcopy改动变迁比较大的版本分别为1.0.0、1.1.0、1.5.0。

gpcopy1.0.0:始于greenplum-db-5.9.0,仅支持相同segment数的gpdb之间的数据迁移。

gpcopy1.1.0:始于greenplum-db-5.12.0,支持不同segment数的Greenplum集群间传输,分为两种情况,如下图。

         ①gpcopy从小集群到大集群传输架构图

②gpcopy从大集群到小集群传输架构图

gpcopy1.5.0:从4.3.33.0、5.21.0开始,gpcopy不再捆绑在greenplum的安装包中,成为Pivotal gpcopy的第一个独立发行版,gpcopy1.5.0相比较于之前版本做出了如下更改:
         ①在复制表数据时可以更改目标schema和table名称,前提是目标表必须存在,且必须具有与源表完全相同的表结构。
         ②默认支持传输表所有权和特权信息,以前只有在使用-full选项时才复制所有权和特权信息。
关于gpcopy实用程序最低运行的Greenplum环境:见《六:gpcopy使用测试注意点》第五节。

四、gpcopy命令(基于gpcopy1.5.0)

概要

选择要复制数据的选项

–full:此选项执行Greenplum数据库源系统到目标系统的迁移。迁移复制所有用户定义的数据库的所有数据库对象,包括表,索引,视图,角色,函数,用户定义类型(UDT),资源队列和资源组。默认数据库postgres,template0和template1不会被复制。不能使用–dbname,–include-table,–include-table-file或–include-table-json选项指定此选项。

–dbname database:要复制的源数据库名称。要将多个数据库复制到目标系统,请指定以逗号分隔的数据库列表,名称之间不得有空格。所有用户定义的表和表数据都将复制到目标系统。如果源数据库不存在,则gpcopy返回错误并退出。如果目标数据库不存在,则会创建一个数据库。不能与–full,–include-table,–include-table-file或–include-table-json选项同时存在。

–dest-dbname database:将数据库复制到其他目标数据库,需要指定目标数据库的名称。对于多个数据库,请指定一个逗号分隔的数据库列表,名称之间没有空格。数据库名称的数量必须与–dbname选项中指定的名称数量匹配。该实用程序按照列出的顺序将源数据库复制到目标数据库。如果源数据库不存在,则gpcopy返回错误并退出。如果目标数据库不存在,则会创建一个数据库。仅对–dbname选项有效。

–include-table db.schema.table:从源数据库系统复制一个或多个表。您必须提供标准的表名(database.schema.table)。您不能指定视图或系统目录表。要复制多个表,请包含以逗号分隔的表名列表,或使用正则表达式来描述一组表。您可以选择使用–dest-table更改将–include-table中的表数据复制到的数据库,架构或表名。您可以在完全限定的表名的数据库,模式和表部分中使用Go语言正则表达式来定义一组输入表。正则表达式模式必须用斜杠(/ RE_pattern /)括起来。例如,–include-table mytest.public.demo /.*/指定公共模式下mytest数据库中以demo开头的所有表。

–dest-table db.schema.table:更改数据库,架构或表名,在其中复制–include-table定义的表中的数据。如果更改目标模式或表名,则目标表必须存在并且具有与源表完全相同的表结构。当目标表与源表不同时,gpcopy不会生成创建新的目标模式或表所必需的DDL。

–include-table-file table-file:定义要复制的表和数据的文本文件的位置和名称。要使用多个文件,则需要多次指定–include-table-file。在文本文件中,每行指定一个完全限定的表(database.schema.table)。您不能指定视图或系统目录表。您可以使用Go语言正则表达式语法选择多个表。

–include-table-json json-table-file:定义要复制的表和数据的JSON格式文件的位置和名称。与–include-table-file一起使用的文本文件相反,JSON文件可以包含目标表名称,该目标表名称用于更改将表数据复制到的数据库,模式或表。注意:–include-table-json选项仅受Greenplum Database 5.20或更高版本附带的gpcopy支持,或与从Pivotal Network单独下载提供的任何gpcopy版本一起支持。您提供的JSON文件必须定义一个或多个具有键-值对的对象用于描述源表source、可选查询sql、目标表dest。多个表对象放在一个JSON数组中。例如:


     {
         "source": "database.schema.table",
         "sql": "query"
         "dest": "database.schema.table"
     },
     {
         ...     }
]

您不能将视图或系统目录表指定为源表。您提供的任何查询都必须引用也只能引用一个源表,并且输出语句的列要求与源表的列相同。如果查询包含ORDER BY子句,则目标Greenplum群集必须与源群集具有相同的大小(段数相同)。某些字符必须在字符串中转义,以便在JSON中解析,特别是如下字符:

如果无法将文件解析为JSON,则gpcopy退出并显示错误。您也可以使用Go语言正则表达式语法选择多个表。可以在dest:键中引用source:键中定义的捕获组,以更改将数据复制到的目标数据库。例如:

[
     {
         "source": "testdb/(\\d+)/.myschema/(\\d+)/.mytable/(\\d+)/",
         "dest": "productiondb/$1/.myschema/$1/.mytable/$1/"
     }
]

Notice:–include-table-json如果使用正则表达式复制多个表,那么就不能使用sql;sql如果使用了order by,那么目标集群和源集群的大小(段实例数量)要求相同。

–metadata-only:仅创建命令指定的架构,数据不传输。如果使用–full选项指定,gpcopy将复制完整的数据库模式,包括源数据库的所有表,索引,视图,用户定义的类型(UDT)和用户定义的函数(UDF),没有数据传输。如果使用–dbname选项指定数据库,或者使用–include-table –include-table-file或–include-table-json选项指定表,则gpcopy仅创建表和索引,没有数据传输。此选项不能与–truncate选项一起使用。

–exclude-table db.schema.table:要从源数据库系统中排除的表。必须指定标准表名(database.schema.table)。要排除多个表,请指定以逗号分隔的表名列表。可以使用Go语言正则表达式语法指定一组表。排除时,仅排除指定的表,不排除从属对象。您不能指定视图或系统目录表。必须使用以下选项之一指定此选项:–full,–dbname,–include-table,–include-table-file或–include-table-json。如果选项–exclude-table导致没有要复制的表,则不会在目标系统中创建数据库或架构。

–exclude-table-file table-file:要从源数据库系统中排除的表的文件,table-file表示标准限定表名列表的文件的位置和名称。在文本文件中,为每行指定一个标准限定的表(database.schema.table)。要指定多个文件,则需要多次指定–exclude-table-file ,也可以使用Go语言正则表达式语法指定一组表。如果源表不存在,则gpcopy将显示警告。仅排除指定的表。您不能指定视图或系统目录表。必须使用以下选项之一指定此选项:–full,–dbname,–include-table,–include-table-file或–include-table-json。如果选项–exclude-table无法复制任何表,则不会在目标系统中创建数据库或模式。

数据库连接选项

–dest-host dest_host:目标Greenplum数据库主实例主机名或IP地址。该选项必须指定。

–dest-port dest_port:目的Greenplum数据库主实例端口号。如果未指定,则默认值为5432。

–dest-user dest_user:用于连接到目标Greenplum数据库主实例用户ID。如果未指定,则默认值为gpadmin。(注意设置dest_user在pg_hba.conf的登录验证方式应为trust)

–source-host source_host:源Greenplum数据库主段主机名或IP地址。如果未指定,则默认主机是运行gpcopy(127.0.0.1)的系统。

–source-port source_port:源Greenplum数据库主端口号。如果未指定,则默认值为5432。

–source-user source_user:用于连接到源Greenplum数据库系统的用户ID。如果未指定,则默认值为gpadmin。(注意设置source_user在pg_hba.conf的登录验证方式应为trust)

–jobs int:gpcopy并行运行的进程数。范围是1到64。–jobs产生2 * n + 1个数据库连接。默认值为4,创建9个连接。如果增加此选项,请确保为Greenplum数据库系统配置了足够的最大并发连接值,以容纳gpcopy连接和其他并发连接,例如用户连接。

–on-segment-threshold int:指定决定gpcopy何时使用Greenplum数据库源和目标主库而不是源和目标段实例复制表的行数。默认值是10000行。如果表包含10000行或更少,则使用Greenplum数据库主数据库复制该表。值为-1时禁止使用主服务器复制表,使用段实例复制所有表。对于较小的表,使用Greenplum数据库主表复制表比使用段实例更有效。

–parallelize-leaf-partitions:如果指定,该实用程序将并行复制分区表的叶分区表。默认设置是根据根分区表将分区表复制为单个表。如果还指定了–validate选项,该实用程序将在复制过程中验证每个叶分区表,然后验证整个分区表。如果JSON文件包含查询分区表的sql:键,则不能使用–include-table-json指定此选项。

–data-port-range lower_port-upper_port:在Greenplum数据库目标主机上用于数据传输的一系列端口号。这适用于目标段主机,或者,如果数据是使用主段传输的,则仅适用于主段主机。gpcopy使用范围(含)范围内指定的第一个可用端口。lower_port必须大于或等于1024(以避免保留系统端口),并且upper_port必须大于一个值。范围指定的端口数必须大于或等于使用–jobs创建的并行进程数(如果已指定)。如果未指定–data-port-range,则gpcopy使用任何可用的端口。

用于配置如何复制数据的选项

注意:以下选项必须指定一个也只能指定一个用于管理目标数据库中的数据。例如:–skip-existing, –truncate, –drop, or –append。

–skip-existing:如果此表已存在于目标数据库中,请指定此选项以跳过从源数据库复制表的操作。

–truncate:指定此选项以截断目标数据库中已存在的表。

–drop:指定此选项以删除目标数据库中已存在的表。复制表数据之前,gpcopy会删除表并再次创建它。

–append:将数据附加到目标数据库中的表(如果已存在)。

–analyze:在非系统表上运行ANALYZE命令。默认为不运行ANALYZE命令。复制表数据后,将对每个表执行该操作。

–no-compression:如果指定,数据将不压缩地传输。默认情况下,将数据复制到其他主机时,gpcopy会在从源数据库到目标数据库的传输过程中压缩数据。将数据复制到同一主机时,该实用程序不会压缩数据。

–no-distribution-check:指定此选项以禁用表数据分布检查。默认情况下,gpcopy执行数据分布检查,以确保正确地将数据分布到段实例。如果分发检查失败,则表副本失败。当复制由外部表的叶表定义的分区表时,或者使用与根分区表不同的分布策略定义叶表时,该实用程序不支持表数据分布检查。

–truncate-source-after:指定此选项可在gpcopy复制表并验证目标数据库中的表数据之后截断源数据库中的表。如果指定此选项,则还必须指定–validate选项。

        –yes:可选的。复制并验证表数据后,自动确认以截断源表数据。没有出现截断源 表的提示。默认设置是在复制和验证数据后提示您确认截断源表数据。

–validate type:复制表数据后,对目标数据库中的表数据执行数据验证。这些是受支持的验证类型。

        count-比较源和目标表数据之间的行数。

        md5xor-计算所有行的MD5值,然后对MD5值执行XOR。

如果指定–append选项,并且目标表包含数据,则对该表的验证将失败。如果对表的验证失败,则gpcopy会回滚目标表。

附加选项

–dry-run:指定此选项后,gpcopy会生成使用指定选项执行的迁移操作的列表。数据不迁移。该信息显示在命令行中,并写入日志文件。

–quiet:如果指定,请在命令提示符处取消显示状态消息。消息仅发送到日志文件。仍显示更高级别的消息,例如警告和错误消息。不能使用–debug选项指定此选项。

–debug:如果指定,调试消息将显示在命令提示符中。不能使用——quiet选项指定此选项。

–version:查看gpcopy版本,如果输入gpcopy_helper –version也可以查看gpcopy_helper版本。

–help:帮助文档,显示gpcopy大致功能,提示所有选项的大概功能。

五、gpcopy官方提示注意点

(1)如果gpcopy命令指定了无效的选项,或者指定了不存在的源表或数据库,则该实用程序将返回错误并退出。并且没有数据被复制。
(2)gpcopy在复制数据时是不会在源表上添加事务锁的,此时是可以修改源表数据的。
(3)gpcopy无法复制宽度大于1GB(PostgreSQL限制)的行。
(4)如果使用–dbname,–include-table,–include-table-file或–include-table-json选项复制一组数据库表,而目标数据库不存在,则该实用程序将创建数据库,然后再复制表。如果目标数据库存在,则该实用程序根据需要在数据库中创建表。如果目标表存在但是表结构不一致,该实用程序将返回错误然后回滚当前数据表的复制操作并继续开始下一个数据表迁移操作。
(5)除非指定–full选项,否则gpcopy实用程序不会复制依赖的数据库对象。
例如,如果一个表在一个用户定义的函数的列上有一个默认值,那么在使用–dbname、–include-table、–include-table-file或–include-table-json选项时,该函数必须存在于目标系统数据库中。
(6)复制表时,为表定义的序列被视为表数据并被复制。如果使用序列列创建表或将序列指定为默认值,则将复制序列。如果指定–truncate选项,则会重置序列。
(7)gpcopy仅在使用–full或–drop选项后重新创建表索引。
(8)gpcopy不会复制配置文件,例如postgresql.conf和pg_hba.conf。您必须单独设置目标系统配置。
(9)gpcopy实用程序不会复制外部对象,例如Greenplum数据库扩展名,第三方jar文件和共享对象文件。您必须单独安装外部对象。
(10)gpcopy当前不支持对其连接进行SSL加密。
(11)gpcopy实用程序将消息记录在master主机上〜/ gpAdminLogs目录中的日志文件gpcopy_date.log中。如果您在同一天运行多个gpcopy命令,该实用程序会将消息追加到当天的日志文件中。

六、gpcopy使用测试注意点

(1)gpcopy支持也只支持从Greenplum低版本往高版本进行数据迁移:因为Greenplum不同版本(4、5、6)之间分别基于PostgreSQL8.2.x、8.3.x、9.x为内核开发的,它们的pg_dump版本不一致,测试发现gpcopy在复制数据时使用了pg_dump工具,所以在这种情况下只能复制元数据。

(2)gpcopy实用程序分为元数据迁移和表数据迁移,当指定–metadata-only选项时,gpcopy就可以实现很多特殊环境的迁移工作,如:

        ①gpcopy1.0.0执行迁移工具时,集群间可以具有不同的segment数。

        ②高版本gp往低版本gp迁移工作:gp5.x为源集群往gp4.x目标集群迁移。

(3)gpcopy与gpcopy_helper在源集群和目标集群的作用,测试情况有如下几种:

        ①仅迁移元数据时,源集群只需要master主机有gpcopy文件,目标集群只需要master主机上有gpcopy_helper文件。

        ②迁移的表数据行数都低于10000行时(–on-segment-threshold默认为10000行),源集群需要master主机有gpcopy文件和gpcopy_helper文件,目标集群只需要master主机上有gpcopy_helper文件。

分析猜测为gpcopy用于源集群迁移元数据、gpcopy_helper用于源和目标集群迁移元数据和表数据。总之,在实际生产环境中不要考虑这些,都装上即可。Notice:我的测试环境是:source集群(1个master实例,4个segment实例)、dest集群(1个master实例,4个segment实例)。

(4)源集群的主机和目标集群的主机之间需要互相ping通,假设有test1、test2两个cluster,test1能够ping通test2,而test2不能ping通test1,大致场景:test1为局域网,test2为公网。gpcopy的source-host为test1时,可以向test2迁移数据进行正常操作,而当test2为source-host、test1为dest-host时,gpcopy能够将所有表的元数据迁移,但是在迁移表数据时会报错并回滚整个表的复制操作,如果指定–metadata-only能正常操作。

对于前四点,基本都会围绕master节点和元数据这两个关键词,对于master节点数据库有以下解释:

master数据库也是一个被改造过的PostgreSQL数据库,它包含了整个分布式数据库中的所有元数据,如表结构定义、索引、数据分布信息等等。但其并不存储实际的数据,实际的数据是存储在segment数据库的。

(5)gpcopy诞生于Greenplum5.9.0,不代表只能从5.9.0开始使用,也不是说5.x的版本都能够使用。经过测试,gpcopy实际能够运行环境分别为4.3.20.0及以上、5.4.1及以上、6.x。除此之外,gptransfer在Greenplum6.x中已被移除。

七、gpcopy参考地址

gpcopy1.5.0独立发行版官网:

https://gpdb.docs.pivotal.io/gpcopy/1-5/gpcopy.html

gpcopy实用工具官网参考:

https://gpdb.docs.pivotal.io/5200/utility_guide/admin_utilities/gpcopy.html

数据迁移工具-gpcopy官网概述:

https://gpdb.docs.pivotal.io/5200/admin_guide/managing/gpcopy-migrate.html

Greenplum中文社区讲解gpcopy1.1.0博客:

https://greenplum.cn/2019/01/10/greenplum-gpcopy-1-1-0/

从copy到gpcopy的诞生史:

https://liming01.github.io/post/copy2gpcopy/

Greenplum5.20.0下载地址:

https://network.pivotal.io/products/pivotal-gpdb#/releases/396386

关于作者

王发瑞,Greenplum爱好者,目前在武汉数智物联从事GP数据仓库管理工作。


发表评论

电子邮件地址不会被公开。 必填项已用*标注