【揭祕GP】一文幫你詳解 Greenplum 遷移工具——GPCopy

導讀:以下資料是根據 Pivotal Greenplum 官網翻譯、Grenplum 中文社區博客以及個人測試所得,如有部分描述錯誤,歡迎下方評論指出,共同進步。

目錄

  • 一:gpcopy 介紹
  • 二:gpcopy 相較於 gptransfer
  • 三:gpcopy 版本發展史
  • 四:gpcopy 命令(基於 gpcopy 1.5.0)
  • 五:gpcopy 官方提示注意點
  • 六:gpcopy 使用測試注意點
  • 七:gpcopy 參考地址

一、gpcopy 介紹

gpcopy 是一個數據遷移實用程序,可以在不同集群之間進行傳輸數據,可以將一個集群中的 greenplum 數據庫的元數據和數據複製到另一個集群的 greenplum 數據庫中。gpcopy 可以遷移數據庫的全部內容,包括數據庫架構、表數據、索引、視圖、角色、用戶自定義函數、資源隊列、資源組。

二、gpcopy 相較於 gptransfer

(1)複製數據更快:注意這裡說的是數據,而不是元數據。gpcopy 更快速原因可分為三點: segment 間直接傳輸、Snappy 壓縮傳輸、數據校驗。

  1. segment 間直接傳輸:當一個表的數據超過指定數據行數(–on-segment-threshold 默認為10000行)時,gpcopy 會利用 COPY ON SEGMENT 特性使得 gpcopy 可以做到兩個 cluster 的多節點間併發傳輸。除此之外,gpcopy 的數據傳輸本身就是利用 copy 命令,而 gptransfer 則是通過外部表的 SELECT 和 INSERT 進行逐條操作,copy 使用批量操作自然而然要比 insert 更快。
  2. Snappy 壓縮傳輸:gpcopy 默認使用 Google 的 Snappy 格式對數據進行壓縮和傳輸,而 gptransfer 使用 zlib 格式進行壓縮和傳輸,搜索 snappy 和 zlib 壓縮性能對比,Snappy 性能明顯要高很多。
  3. 數據校驗: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。

gpcopy 1.0.0:始於 greenplum-db-5.9.0,僅支持相同 segment 數的 gpdb 之間的數據遷移。

gpcopy 1.1.0:始於 greenplum-db-5.12.0,支持不同 segment 數的 greenplum 集群間傳輸,分為兩種情況,如下兩圖:

【揭秘GP】一文幫你詳解 Greenplum 遷移工具——GPCopy

gpcopy 從小集群到大集群傳輸架構圖

【揭秘GP】一文幫你詳解 Greenplum 遷移工具——GPCopy

gpcopy 從大集群到小集群傳輸架構圖

gpcopy 1.5.0:從 4.3.33.0、5.21.0 開始,gpcopy 不再捆綁在 greenplum 的安裝包中,成為 Pivotal gpcopy 的第一個獨立發行版。gpcopy 1.5.0 相比較於之前版本做出瞭如下更改:

  1. 在複製表數據時可以更改目標 schema 和 table 名稱,前提是目標表必須存在,且必須具有與源表完全相同的表結構。
  2. 默認支持傳輸表所有權和特權信息,以前只有在使用-full選項時才複製所有權和特權信息。關於 gpcopy 實用程序最低運行的 greenplum 環境:見《六:gpcopy 使用測試注意點》第五節。

四、gpcopy 命令(基於gpcopy 1.5.0)

概要:

【揭秘GP】一文幫你詳解 Greenplum 遷移工具——GPCopy

選擇要複製數據的選項:

–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數組中。例如:

<code>
{
"source": "database.schema.table",
"sql": "query"
"dest": "database.schema.table"
},
{
... }
]/<code>

您不能將視圖或系統目錄表指定為源表。您提供的任何查詢都必須引用也只能引用一個源表,並且輸出語句的列要求與源表的列相同。如果查詢包含ORDER BY子句,則目標Greenplum群集必須與源群集具有相同的大小(段數相同)。某些字符必須在字符串中轉義,以便在JSON中解析,特別是如下字符:

【揭秘GP】一文幫你詳解 Greenplum 遷移工具——GPCopy

如果無法將文件解析為 JSON,則 gpcopy 退出並顯示錯誤。您也可以使用Go語言正則表達式語法選擇多個表。可以在dest:鍵中引用source:鍵中定義的捕獲組,以更改將數據複製到的目標數據庫。例如:

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

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)之間分別基於 PostgreSQL 8.2.x、8.3.x、9.x 為內核開發的,它們的 pg_dump 版本不一致,測試發現 gpcopy 在複製數據時使用了 pg_dump 工具,所以在這種情況下只能複製元數據。

(2)gpcopy 實用程序分為元數據遷移和表數據遷移,當指定–metadata-only選項時,gpcopy 就可以實現很多特殊環境的遷移工作,如:

  • gpcopy 1.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 誕生於 Greenplum 5.9.0,不代表只能從 5.9.0 開始使用,也不是說 5.x 的版本都能夠使用。經過測試,gpcopy 實際能夠運行環境分別為 4.3.20.0 及以上、5.4.1 及以上、6.x。除此之外,gptransfer 在Greenplum 6.x 中已被移除。

七、gpcopy 參考地址

  1. gpcopy1.5.0 獨立發行版官網:https://gpdb.docs.pivotal.io/gpcopy/1-5/gpcopy.html
  2. gpcopy 實用工具官網參考:https://gpdb.docs.pivotal.io/5200/utility_guide/admin_utilities/gpcopy.html
  3. 數據遷移工具-gpcopy官網概述:https://gpdb.docs.pivotal.io/5200/admin_guide/managing/gpcopy-migrate.html
  4. Greenplum中文社區講解 gpcopy 1.1.0 博客:https://greenplum.cn/2019/01/10/greenplum-gpcopy-1-1-0/
  5. 從 copy 到 gpcopy 的誕生史:https://liming01.github.io/post/copy2gpcopy/
  6. Greenplum 5.20.0下載地址:https://network.pivotal.io/products/pivotal-gpdb#/releases/396386




王發瑞,Greenplum 愛好者,目前在武漢數智物聯從事GP數據倉庫管理工作。


分享到:


相關文章: