mxshift

本文档介绍了数据迁移工具 mxshift。

1 描述

mxshift 工具目前支持以下功能:

  • 全量迁移:以数据库为单位,实现从 Greenplum 5 / Greenplum 6/ MatrixDB 集群并行迁移数据表数据定义语言(DDL)及数据到新的 MatrixDB 集群。目前只有全量迁移模式支持迁移数据表 DDL。
  • 反向迁移:从 MatrixDB 到 Greenplum 5 / Greenplum 6 反向迁移。
  • 增量迁移:通过 WHERE 条件实现数据的增量迁移。
  • 支持的数据分布策略:哈希分布、随机分布、复制表(REPLICATED)、Master-only。

2 参数信息

此部分主要介绍 mxshift 工具相关参数信息。

2.1 配置文件

使用 mxshift 工具需要先准备一个 TOML 文件。以下是配置文件中的详细参数介绍:

参数名 描述 必选
[database.source]类别
--db-host 源集群 Master 节点主机名(Host)或 IP 地址。源数据库集群指需要迁出数据的数据库集群
--db-port 源数据库 Master 的端口号
--db-database 源数据库名
--db-user 源数据库用户名
--db-password 源数据库用户密码
--install-dir 数据库安装路径(v4.8.3 开始支持此参数,v4.8.2 及之前需使用 gphome 参数配置)
--hostname-to-ip 指定主机名对应的 IP 地址。在源库和目标库主机名相同时,使用该配置可保障路由的准确性(v4.8.3 开始支持此参数)
[database.target]类别
--db-host 目标集群 Master 节点主机名(Host)或 IP 地址。目标集群指数据迁入的数据库集群
--db-port 目标数据库 Master 的端口号
--db-database 目标数据库名
--db-user 目标数据库用户名
--db-password 目标数据库用户密码
[scope]类别
--mode 运行模式。允许下列几个值:normaldryrunfetchmotion
normal:默认值,指正常的数据迁移流程;
dryrun:验证两边数据库的连通性,使用简单的数据库定义语言(DDL)进行验证操作,但不进行数据的读取和写入;
fetch:在 dryrun 的基础上,读取源端的数据并发送到目标端数据节点(Segment),但直接丢弃,不进行处理,此选项用于验证源端读取效率和源端到目标端网络传输效率;
motion:在 fetch 的基础上,在目标端数据库解析数据并交换到真正的目标 Segment,此选项用于进一步测试目标端数据库的数据交换速率
--compress-method 压缩方式:gzip / zstd / lz4 / 0,默认值为 0 ,即不压缩。
目前开启任何压缩算法,都需要目标端的每个 Segment 的 mxadmin 用户可以免密 ssh 登陆到源端的每个 Segment,建议配置后用 dryrun 进行测试
--gphome 源端数据库的 GPHOME 绝对路径(v4.8.3 开始此选项被去掉)
--table-list 源数据表的模式(Schema)和名称列表,如果是分区表需填写分区表,如果需要迁移整个数据库,该参数配置为空即可,mxshift 会从大到小开始迁移所有大小不为 0 的表
--exclude-table-list 需排除的表的 Schema 和名称列表
--schema-list 源数据库的 Schema,优先级是如果 table-list 有配置具体的表,则只传输 table-list 中的表,如果没有,则检查 schema-list 中是否配置了 Schema,如果配置了,则传输该 Schema 下的所有表,如果没有,则传输 [database.source] db-database 下的所有表
--exclude-schema-list 排除源数据库的 Schema,不对该 Schema 下的表进行数据迁移,如果 schema-listexclude-schema-list 中配置了同名的 Schema,那么该 Schema 会被排除掉
[log]类别
--log-level 默认值为 info,会打印正常的进度信息以及错误和警告信息。如果改为 debug,则会输出更多调试信息,仅用于开发和故障定位
--no-color 默认为 falsetrue 则关闭颜色标签
[controller]类别
--both-way 默认为 false,会先迁移最大的表,以达到最短时间内迁移完全体数据。如果设置 both-waytrue,则会从最大的表和最小的表两端同时迁移
--concurrency 支持并行迁移的表数量,默认 5,不超过 10
[transfer]类别
--verify 校验数据迁移前后的行数是否匹配,默认为 false
--with-index 是否迁移索引,默认为 false,选择不进行自动迁移,此时 mxshift 会将迁移索引的 SQL 语句保存在当前 mxshift 执行路径下的一个文件中,便于之后手动创建索引。注意:如果你使用的是 MARS2 存储引擎建表,是必须创建索引表才生效的。因此 MARS2 表迁移 DDL 的同时会自动把索引也迁移过去,不受此选项的影响
[ddl]类别(此类别 4.8.2 开始支持)
--enabled 是否迁移数据表 DDL,默认为 false。mxshift 在启动后,迁移数据表的数据之前,会优先按数据库为单位迁移其 DDL。
DDL 迁移支持的数据库版本:
Greenplum6 -> YMatrix4 / YMatrix5;
YMatrix4 -> YMatrix4 / YMatrix5;
YMatrix5 -> YMatrix5
--file-path 用于导入/导出 DDL SQL 的文件路径。当文件不存在时会自动创建,若文件中包含其他内容会将文件清空后再行写入。导出的文件可查看或修改,但切记不要修改或者删除任何以“-- DO NOT EDIT.” 开头的注释内容,否则会影响导入效果,甚至导入出错
--mode DDL 的处理模式。有 execoutput 以及 input 三个选项。exec 为默认值,意为直接在目标数据库执行;output 意为输出到文件, DDL 导出完毕后将直接退出,不会进行数据迁移;input 意为从文件读入。使用此模式必须将 --file-path 指向 mxshift 所导出的文件,否则 mxshift 会无法识别。SPEC:如果 output 模式下目标数据库无法连接,则可在 [database.target] 类别下增加 --db-version 配置(详见下文示例模版);如果 input 模式下源库无法连接,则可将 [ddl] 类别下的 --only-ddl 设置为 true,并在 [database.source] 类别下增加 --db-version 配置(详见下文示例模版)
--only-ddl 是否仅迁移 DDL。默认为 false。当配置为 false 时,DDL 迁移完成后会自动迁移相关表的数据;当配置为 true 时,DDL 迁移完成后即退出程序,不会迁移表数据
--skip-resource-queue-and-group 配置是否迁移资源队列(组)。当 skip-resource-queue-and-group=true,则在 DDL 迁移过程中会跳过资源组和资源队列
--skip-table-space 配置是否迁移表空间。当 skip-table-space=true,则在 DDL 迁移过程中会跳过表空间

如果你想要通过 WHERE 条件实现增量数据迁移,那么可能会使用到以下参数:

类别 子类别 子参数 子子类别 子子参数 描述 必选
[transfer]类别 [transfer.table-data-where-sql]类别 --enabled 如果为 `true`,则利用 WHERE 条件过滤源数据库数据, 仅迁移满足 WHERE 条件的数据,实现增量迁移。本功能默认关闭,启用需手动指认 `true`
--global 此参数指 SQL 的 `WHERE` 表达式,mxshift 会对本次迁移的所有表附加此条件表达式,如果表中不包含 `WHERE` 关键字,则提示 `SKIPPED` 自动跳过该表
[[transfer.table-data-where-sql.override]]类别 --where 表示 WHERE 子表达式,优先级高于 global 中的 WHERE 表达式,仅对某个特定表进行过滤的表级应用。
[transfer.table-data-where-sql.override.table]类别 --schema 需迁移的模式名
--name 需迁移的表名

以上参数用法示例见下文配置文件模版。

2.2 命令行参数

mxshift 命令行参数如下:

参数名 描述
--config 打印配置文件默认内容
-a 或 --all 无需确认,直接执行迁移。默认跳过已完成的表和空表
-c 或 --config-path mxshift 工具全局配置文件路径
-v 或 --version mxshift 工具版本
-l 或 --show-progress 打印最近一次迁移的进度。若目前未在迁移,则展示上一次的迁移结果;若目前正在迁移,则展示当前迁移进度。其中,“STATUS”取值及其含义为:Not start:不在迁移范围;Skip:跳过(已迁移过或者为空表);Processing/Interrupted:正在迁移或者迁移过程中被打断;Complete:完成迁移;Failed:迁移失败
-R 或 --redo 若表已迁移过,不跳过,重新迁移(该选项会清除目标库中表的所有数据,并重新迁移)

3 示例

完整的模版文件命名为 config.toml。此模版也可通过执行 mxshift --config 获得,你可以执行 vim config.toml 命令开始编辑文件,随后直接将全部内容复制到文件中,再修改响应配置项。或使用下文我们给出的针对不同使用场景的示例模版。选你所需即可。

[database]
    [database.source]
        ## Name of database
        db-database= "testdb"
        ## Hostname of database master
        db-host="sdw3"
        ## password of database
        db-password="xxxx"
        ## Port of database master
        db-port=54322
        ## user name of database
        db-user="mxadmin"
        ## Version of database(Please use the result of 'SELECT version();' as value). Required only when
        ##       1. Source database is un-reachable, and 'ddl.only-ddl' is enabled and 'ddl.mode' is 'input'
        ##       2. Target database is un-reachable, and 'ddl.mode' is 'output' */
         # db-version="PostgreSQL 12 (MatrixDB 4.5.0-enterprise) (Greenplum Database 7.0.0+dev.17410.gedbdb5ef84 build dev) on arm-apple-darwin21.5.0, compiled by Apple clang version 13.0.0 (clang-1300.0.27.3), 64-bit compiled on Jul  5 2022 15:45:24"
        ## The installation directory of matrixdb(this option is supported starting from version 4.8.3,4.8.2 and earlier versions need to be specified by gphome)
        install-dir="/usr/local/greenplum-db-6.7.1"
         [[database.source.hostname-to-ip]]
             ## The content within <> should be replaced with actual information and <> should be removed(this option is supported starting from version 4.8.3)
             node-hostname="<mdw>" 
             node-ip="<127.0.0.1>"
        [[database.source.hostname-to-ip]]
             node-hostname="<sdw1>"
             node-ip="<127.0.0.2>"
        [[database.source.hostname-to-ip]]
             node-hostname="<sdw2>"
             node-ip="<127.0.0.3>"

    [database.target]
        ## Name of database
        db-database="destdb"
        ## Hostname of database master
        db-host="172.16.100.32"
        ## password of database
        db-password="yyyy"
        ## Port of database master
        db-port=5432
        ## user name of database
        db-user="mxadmin"
        ## Version of database(Please use the result of 'SELECT version();' as value). Required only when
        ##       1. Source database is un-reachable, and 'ddl.only-ddl' is enabled and 'ddl.mode' is 'input'
        ##       2. Target database is un-reachable, and 'ddl.mode' is 'output' */
         # db-version="PostgreSQL 12 (MatrixDB 4.5.0-enterprise) (Greenplum Database 7.0.0+dev.17410.gedbdb5ef84 build dev) on arm-apple-darwin21.5.0, compiled by Apple clang version 13.0.0 (clang-1300.0.27.3), 64-bit compiled on Jul  5 2022 15:45:24"

[scope]
compress_method="lz4"
## (this option is abandoned from version 4.8.3)
# gphome="/usr/local/greenplum-db-6.7.1"
mode="normal"
        [[scope.table-list]]
                schema="test_schema_1"
                name="table_001"
        [[scope.table-list]]
                schema="test_schema_2"
                name="table_002"     
        [[scope.exclude-table-list]]
                schema="test_schema_3"
                name="table_003"       
schema-list=["test_schema_1", "test_schema_2"]
exclude-schema-list=["test_schema_5", "test_schema_8"]

[log]
log-level="info"
## Print log without color.
# no-color=false

[controller]
both-way=true
concurrency=5

[transfer]
verify=true
# with-index=true
[transfer.table-data-where-sql]
enabled=false
global="txdate >= '2022-10-01' AND batchnum >= 100000000"
[[transfer.table-data-where-sql.override]]
        where="abc > 10"
        [transfer.table-data-where-sql.override.table]
        schema="test_schema_1"
        name="table_001"
[[transfer.table-data-where-sql.override]]
        where="tag != 'aabbcc' AND ts > '2022-01-01'"
        [transfer.table-data-where-sql.override.table]
        schema="test_schema_2"
        name="another_table"

[ddl]
enabled=true
# file-path="/tmp/mxshift.sql"
# mode="output"
only-ddl=false
## During the DDL transfer, whether to skip the transfer of resource queue or group, by default, it is true.
skip-resource-queue-and-group=true
## During the DDL transfer, whether to skip the transfer of tablespace, by default, it is true.
skip-table-space=true
        [[ddl.replace]]
        ## Only applicable for the case of migration from Greenplum to YMatrix
                category="role"
                [[ddl.replace.pairs]]
                        old="gpadmin"
                        new="mxadmin"      

准备好 TOML 文件后,执行如下命令以启动 mxshift 进行迁移。

$ mxshift -c config_path.toml

3.1 全量迁移

[database]
        [database.source]
        ## Name of database
        db-database= "testdb"
        ## Hostname of database master
        db-host="sdw3"
        ## password of database
        db-password="xxxx"
        ## Port of database master
        db-port=54322
        ## user name of database
        db-user="gpadmin"
        ## Version of database(Please use the result of 'SELECT version();' as value). Required only when
        ##       1. Source database is un-reachable, and 'ddl.only-ddl' is enabled and 'ddl.mode' is 'input'
        ##       2. Target database is un-reachable, and 'ddl.mode' is 'output' */
         # db-version="PostgreSQL 12 (MatrixDB 4.5.0-enterprise) (Greenplum Database 7.0.0+dev.17410.gedbdb5ef84 build dev) on arm-apple-darwin21.5.0, compiled by Apple clang version 13.0.0 (clang-1300.0.27.3), 64-bit compiled on Jul  5 2022 15:45:24"
        ## The installation directory of matrixdb(this option is supported starting from version 4.8.3,4.8.2 and earlier versions need to be specified by gphome)
        install-dir="/usr/local/greenplum-db-6.7.1"
        [[database.source.hostname-to-ip]]
             ## The content within <> should be replaced with actual information and <> should be removed(this option is supported starting from version 4.8.3)
            node-hostname="<mdw>" 
             node-ip="<127.0.0.1>"
        [[database.source.hostname-to-ip]]
             node-hostname="<sdw1>"
             node-ip="<127.0.0.2>"
        [[database.source.hostname-to-ip]]
             node-hostname="<sdw2>"
             node-ip="<127.0.0.3>"

        [database.target]
        ## Name of database
        db-database="destdb"
        ## Hostname of database master
        db-host="172.16.100.32"
        ## password of database
        db-password="yyyy"
        ## Port of database master
        db-port=5432
        ## user name of database
        db-user="mxadmin"
        ## Version of database(Please use the result of 'SELECT version();' as value). Required only when
        ##       1. Source database is un-reachable, and 'ddl.only-ddl' is enabled and 'ddl.mode' is 'input'
        ##       2. Target database is un-reachable, and 'ddl.mode' is 'output' */
         # db-version="PostgreSQL 12 (MatrixDB 4.5.0-enterprise) (Greenplum Database 7.0.0+dev.17410.gedbdb5ef84 build dev) on arm-apple-darwin21.5.0, compiled by Apple clang version 13.0.0 (clang-1300.0.27.3), 64-bit compiled on Jul  5 2022 15:45:24"

[scope]
## The compress method for transferring data, methods restricted to 0/gzip/lz4/zstd        
compress-method="lz4"
## (this option is abandoned  from version 4.8.3)
# gphome="/usr/local/greenplum-db-6.7.1"
## mode for transferring data from source to target database, and value restricted to normal/dryrun/fetch/motion.
##dryrun for only executing ddl, not transferring data
##fetch for fetching data from source and abandon
##motion for fetching data from source, redistributing and finally abandon
mode="normal"
## Sql for select segment information from source database        
# select-source-segment-sql="SELECT dbid, content, port, hostname FROM gp_segment_configuration WHERE status = 'u' AND role = 'p' ORDER BY CONTENT;"
## Sql for select segment information from target database
# select-target-segment-sql="SELECT dbid, content, port, hostname FROM gp_segment_configuration WHERE status = 'u' AND role = 'p' ORDER BY CONTENT;"
        [[scope.table-list]]
                schema="test_schema_1"
                name="table_001"
        [[scope.table-list]]
                schema="test_schema_2"
                name="table_002"   
        [[scope.exclude-table-list]]
                schema="test_schema_3"
                name="table_003"  
schema-list=["test_schema_1", "test_schema_2"]
exclude-schema-list=["test_schema_5", "test_schema_8"]

[log]
## The log level, value restricted to: debug/verbose/info.
log-level="info"
## Print log without color.
# no-color=false

[controller]
## By default, transfer work will start from the largest table. If set 'bothway' it will start from both the largest and the smallest table
both-way=true
## The number of table transferred at the same time
concurrency=5

[transfer]
## Verity the number of record of every table
verify=true
with-index=true

[ddl]
enabled=true
# file-path="/tmp/mxshift.sql"
# mode="output"
only-ddl=false
## During the DDL transfer, whether to skip the transfer of resource queue or group, by default, it is true.
# skip-resource-queue-and-group=true
## During the DDL transfer, whether to skip the transfer of tablespace, by default, it is true.
# skip-table-space=true
        [[ddl.replace]]
        ## Only applicable for the case of migration from Greenplum to YMatrix
                category="role"
                [[ddl.replace.pairs]]
                        old="gpadmin"
                        new="mxadmin"

准备好 TOML 文件后,执行如下命令以启动 mxshift 进行全量迁移。

$ mxshift -c config_path_full.toml

3.2 增量迁移

通过 WHERE 条件实现增量数据迁移:

[database]
        [database.source]
        ## Name of database
        db-database= "testdb"
        ## Hostname of database master
        db-host="sdw3"
        ## password of database
        db-password="xxxx"
        ## Port of database master
        db-port=54322
        ## user name of database
        db-user="gpadmin"

        [database.target]
        ## Name of database
        db-database="destdb"
        ## Hostname of database master
        db-host="172.16.100.32"
        ## password of database
        db-password="yyyy"
        ## Port of database master
        db-port=5432
        ## user name of database
        db-user="mxadmin"

[scope]
## The compress method for transferring data, methods restricted to 0/gzip/lz4/zstd        
compress-method="lz4"
## The installation directory of matrixdb
gphome="/usr/local/greenplum-db-6.7.1"
## mode for transferring data from source to target database, and value restricted to normal/dryrun/fetch/motion.
##dryrun for only executing ddl, not transferring data
##fetch for fetching data from source and abandon
##motion for fetching data from source, redistributing and finally abandon
mode="normal"
## Sql for select segment information from source database        
# select-source-segment-sql="SELECT dbid, content, port, hostname FROM gp_segment_configuration WHERE status = 'u' AND role = 'p' ORDER BY CONTENT;"
## Sql for select segment information from target database
# select-target-segment-sql="SELECT dbid, content, port, hostname FROM gp_segment_configuration WHERE status = 'u' AND role = 'p' ORDER BY CONTENT;"
        [[scope.table-list]]
                schema=......
                name=......
        [[scope.table-list]]
        ......   
        [[scope.exclude-table-list]]
        ......      
schema-list=["test_schema_1", "test_schema_2"]
exclude-schema-list=["test_schema_5", "test_schema_8"]

[log]
## The log level, value restricted to: debug/verbose/info.
log-level="info"
## Print log without color.
# no-color=false

[controller]
## By default, transfer work will start from the largest table. If set 'bothway' it will start from both the largest and the smallest table
both-way=true
## The number of table transferred at the same time
concurrency=5

[transfer]
## Verity the number of record of every table
verify=true
[transfer.table-data-where-sql]
enabled=true
global="txdate >= '2022-10-01' AND batchnum >= 100000000"
[[transfer.table-data-where-sql.override]]
        where="abc > 10"
        [transfer.table-data-where-sql.override.table]
        schema="test_schema_1"
        name="table_001"
[[transfer.table-data-where-sql.override]]
        where="tag != 'aabbcc' AND ts > '2022-01-01'"
        [transfer.table-data-where-sql.override.table]
        schema="test_schema_2"
        name="another_table"

准备好 TOML 文件后,执行如下命令以启动 mxshift 进行增量迁移。

$ mxshift -c config_path_incremental.toml

3.3 迁移复制表(Replicated Table)

如果是迁移某个数据库,或者某个 Schema 下的所有复制表,不需要在 config_path.toml 里面做额外的配置,mxshfit 会自动判断哪些表是复制表,执行相应的迁移策略,防止重复迁移数据的问题发生。你仅需要在 scope.table-list 中配置好 schemaname 即可。

   [[scope.table-list]]
                schema=“public1”
                name=“table_replicated1”
   [[scope.table-list]]
                schema=“public2”
                name=“table_replicated2”

准备好 TOML 文件后,执行如下命令以启动 mxshift 进行复制表迁移。

$ mxshift -c config_path_replicated.toml

注意!
数据迁移思路及完整步骤介绍请见 数据迁移