将 PostgreSQL 数据库作为 Amazon Database Migration Service 的目标 - Amazon 数据库迁移服务
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

将 PostgreSQL 数据库作为 Amazon Database Migration Service 的目标

您可以使用将数据从另一个 PostgreSQ Amazon DMS L 数据库或其他支持的数据库迁移到 PostgreSQL 数据库。

有关支持作为目标的 PostgreSQL 版本的信息 Amazon DMS ,请参阅。的目标 Amazon DMS

PostgreSQL 源版本

Amazon DMS 要使用的版本

9.x、10.x、11.x、12.x

使用任何可用的 Amazon DMS 版本。

13.x

使用 3.4.3 及更高 Amazon DMS 版本。

14.x

使用 3.4.7 及更高 Amazon DMS 版本。

15.x

使用 3.5.1 及更高 Amazon DMS 版本。

注意

Amazon DMS 在满载阶段将数据从源迁移到目标时 table-by-table 采用了一种方法。无法在完全加载阶段保证表顺序。在完全加载阶段以及应用各个表的缓存事务时,表将不同步。因此,活动引用完整性约束可能会导致任务在完全加载阶段失败。

在 PostgreSQL 中,将使用触发器实施外键 (引用完整性约束)。在满载阶段,每次 Amazon DMS 加载一个表。强烈建议您在完全加载期间使用以下方法之一禁用外键约束:

  • 从实例中临时禁用所有触发器并完成完全加载。

  • 在 PostgreSQL 中使用 session_replication_role参数。

在任何给定时间,触发器可能处于以下状态之一:originreplicaalwaysdisabled。在将 session_replication_role 参数设置为 replica 时,只有处于 replica 状态的触发器是活动触发器,并且它们在被调用时触发。否则,触发器保持非活动状态。

PostgreSQL 具有故障保护机制以防止截断表,即使设置了 session_replication_role。您可以将该机制作为禁用触发器的替代方法,以帮助完成完全加载运行。为此,请将目标表准备模式设置为 DO_NOTHING。否则,在具有外键约束时,DROP 和 TRUNCATE 操作将失败。

在 Amazon RDS 中,可以使用参数组控制该参数的设置。对于在 Amazon EC2 上运行的 PostgreSQL 实例,可以直接设置该参数。

有关使用 PostgreSQL 数据库作为目标的更多详细信息, Amazon DMS请参阅以下各节:

使用 PostgreSQL 作为目标的限制 Amazon Database Migration Service

将 PostgreSQL 数据库作为 Amazon DMS 的目标时,存在以下限制:

  • 对于异构迁移,JSON 数据类型将在内部转换为原生 CLOB 数据类型。

  • 在 Oracle 到 PostgreSQL 的迁移中,如果 Oracle 中的一列包含空字符(十六进制值 U+0000) Amazon DMS ,则将空字符转换为空格(十六进制值 U+0020)。这是出于 PostgreSQL 限制的原因。

  • Amazon DMS 不支持复制到使用合并函数创建的具有唯一索引的表。

  • 如果您的表使用序列,则在停止从源数据库NEXTVAL进行复制后,请更新目标数据库中每个序列的值。 Amazon DMS 复制源数据库中的数据,但在正在进行的复制过程中不会将序列迁移到目标数据库。

使用 PostgreSQL 数据库作为目标时的安全要求 Amazon Database Migration Service

出于安全目的,用于数据迁移的用户账户,必须是您作为目标的任意 PostgreSQL 数据库中的注册用户。

您的 PostgreSQL 目标端点需要最低的用户权限才能运行迁移,请参阅以下示 Amazon DMS 例。

CREATE USER newuser WITH PASSWORD 'your-password'; ALTER SCHEMA schema_name OWNER TO newuser;

或者,

GRANT USAGE ON SCHEMA schema_name TO myuser; GRANT CONNECT ON DATABASE postgres to myuser; GRANT CREATE ON DATABASE postgres TO myuser; GRANT CREATE ON SCHEMA schema_name TO myuser; GRANT UPDATE, INSERT, SELECT, DELETE, TRUNCATE ON ALL TABLES IN SCHEMA schema_name TO myuser; GRANT TRUNCATE ON schema_name."BasicFeed" TO myuser;

使用 PostgreSQL 作为目标时的端点设置和额外连接属性 (ECA) Amazon DMS

您可以使用端点设置和额外连接属性 (ECA) 来配置您的 PostgreSQL 目标数据库。

您可以在使用 Amazon DMS 控制台创建目标端点时指定设置,或者使用中的create-endpoint命令和 --postgre-sql-settings '{"EndpointSetting": "value", ...}' JSON 语法。Amazon CLI

您可以使用终端节点的ExtraConnectionAttributes参数指定 ECA。

下表显示了您可以使用 PostgreSQL 作为目标的端点设置。

名称 描述

MaxFileSize

指定用于将数据传输到 PostgreSQL 的任何 .csv 文件的最大大小(以 KB 为单位)。

默认值:32768 KB(32 MB)

有效值:1–1048576 KB(最大 1.1 GB)

例如:--postgre-sql-settings '{"MaxFileSize": 512}'

ExecuteTimeout

设置 PostgreSQL 实例的客户端语句超时 (以秒为单位)。默认值为 60 秒。

例如:--postgre-sql-settings '{"ExecuteTimeout": 100}'

AfterConnectScript: SET session_replication_role = replica

此属性仅用于更改数据捕获 (CDC),它具有 Amazon DMS 绕过外键和用户触发器,可缩短批量加载数据所需的时间。

MapUnboundedNumericAsString

此参数将具有无界 NUMERIC 数据类型的列视为 STRING,以便在不损失数值精度的前提下成功迁移。此参数仅用于从 PostgreSQL 源复制到 PostgreSQL 目标或与 PostgreSQL 兼容的数据库。

默认值:false

有效值:false/true

例如:--postgre-sql-settings '{"MapUnboundedNumericAsString": "true"}

使用此参数可能会导致某些复制性能下降,因为需要从数字转换为字符串,然后再转换回数字。DMS 版本 3.4.4 及更高版本支持使用此参数

注意

只能同时在 PostgreSQL 源端点和目标端点中使用 MapUnboundedNumericAsString

在 CDC 期间,在源 PostgreSQL 端点上使用 MapUnboundedNumericAsString 会将精度限制在 28 以内。在目标端点上使用 MapUnboundedNumericAsString 时,使用精度 28、小数位数 6 迁移数据。

请勿将 MapUnboundedNumericAsString 与非 PostgreSQL 目标一起使用。

loadUsingCSV

使用此额外连接属性 (ECA) 通过\ COPY 命令传输用于满载操作的数据。

默认值:true

有效值:true/false

ECA 示例:loadUsingCSV=true;

注意:由于直接执行 INSERT,将此 ECA 设置为 false 可能会导致某些复制性能下降。

DatabaseMode

使用此属性可以更改复制过程在处理需要一些额外配置的 Postgresql 兼容端点(例如 Babelfish 端点)时的默认行为。

默认值:DEFAULT

有效值:DEFAULTBABELFISH

例如:DatabaseMode=default;

BabelfishDatabaseName

使用此属性指定要迁移到的目标 Babelfish T-SQL 数据库的名称。如果 DatabaseMode 设置为 Babelfish,则此项为必填。这不是保留的 babelfish_db 数据库。

例如:BabelfishDatabaseName=TargetDb;

PostgreSQL 的目标数据类型

的 PostgreSQL 数据库端点 Amazon DMS 支持大多数 PostgreSQL 数据库数据类型。下表显示了 Amazon DMS 使用时支持的 PostgreSQL 数据库目标数据类型以及数据类型的默认映射 Amazon DMS 。

有关 Amazon DMS 数据类型的更多信息,请参见Amazon Database Migration Service 的数据类型

Amazon DMS 数据类型

PostgreSQL 数据类型

BOOLEAN

BOOLEAN

BLOB

BYTEA

BYTES

BYTEA

DATE

DATE

TIME

TIME

DATETIME

如果小数位数介于 0 和 6 之间,请使用 TIMESTAMP。

如果小数位数介于 7 和 9 之间,请使用 VARCHAR (37)。

INT1

SMALLINT

INT2

SMALLINT

INT4

INTEGER

INT8

BIGINT

NUMERIC

DECIMAL (P,S)

REAL4

FLOAT4

REAL8

FLOAT8

string

如果长度介于 1 和 21845 之间,请使用 VARCHAR(以字节为单位的长度)。

如果长度介于 21846 和 2147483647 之间,请使用 VARCHAR (65535)。

UINT1

SMALLINT

UINT2

INTEGER

UINT4

BIGINT

UINT8

BIGINT

WSTRING

如果长度介于 1 和 21845 之间,请使用 VARCHAR(以字节为单位的长度)。

如果长度介于 21846 和 2147483647 之间,请使用 VARCHAR (65535)。

NCLOB

TEXT

CLOB

TEXT

注意

从 PostgreSQL 源进行复制时 Amazon DMS ,除了具有用户定义数据类型的列之外,会为所有列创建具有相同数据类型的目标表。在此类情况下,在目标中创建数据类型作为“可变字符”。

使用 Babelfish for Aurora PostgreSQL 作为目标 Amazon Database Migration Service

可以使用 Amazon Database Migration Service 将 SQL Server 源表迁移到适用于 Amazon Aurora PostgreSQL 的 Babelfish 目标。有了 Babelfish,Aurora PostgreSQL 可以理解 Microsoft SQL Server 的专有 SQL 语言 T-SQL,并支持相同的通信协议。因此,为 SQL Server 编写的应用程序现在只需更改更少的代码,即可与 Aurora 配合使用。Babelfish 功能内置在 Amazon Aurora 中,无需支付额外费用。可以通过 Amazon RDS 控制台在 Amazon Aurora 集群上激活 Babelfish。

使用 Amazon DMS 控制台、API 或 CLI 命令创建 Amazon DMS 目标终端节点时,将目标引擎指定为 Amazon Aurora PostgreSQL,并将数据库命名为 babelfish_db。端点设置部分,添加相关设置以将 DatabaseMode 设置为 Babelfish,并将 BabelfishDatabaseName 设置为 Babelfish T-SQL 数据库的名称。

向迁移任务添加转换规则

在为 Babelfish 目标定义迁移任务时,需要包含转换规则,以确保 DMS 使用目标数据库中预先创建的 T-SQL Babelfish 表。

首先,在迁移任务中添加一个转换规则,使所有表名都变为小写。Babelfish 将您使用 T-SQL 创建的表的名称以小写形式存储在 PostgreSQL pg_class 目录中。但是,当您的 SQL Server 表具有大小写混合的名称时,DMS 会使用 PostgreSQL 原生数据类型而不是与 T-SQL 兼容的数据类型来创建表。因此,请务必添加一个转换规则,使所有表名都变为小写。请注意,不应将列名称转换为小写。

接下来,如果您在定义集群时使用了多数据库迁移模式,请添加重命名原始 SQL Server 架构的转换规则。务必重命名 SQL Server 架构名称,使之包含 T-SQL 数据库的名称。例如,如果原始 SQL Server 架构名称为 dbo,而您的 T-SQL 数据库名称为 mydb,则使用转换规则将架构重命名为 mydb_dbo

如果您使用单数据库模式,则不需要转换规则即可重命名架构名称。架构名称与 Babelf one-to-one ish 中的目标 T-SQL 数据库存在映射。

以下转换规则示例将所有表名设置为小写,并将原始 SQL Server 架构名称从 dbo 重命名为 mydb_dbo

{ "rules": [ { "rule-type": "transformation", "rule-id": "566251737", "rule-name": "566251737", "rule-target": "schema", "object-locator": { "schema-name": "dbo" }, "rule-action": "rename", "value": "mydb_dbo", "old-value": null }, { "rule-type": "transformation", "rule-id": "566139410", "rule-name": "566139410", "rule-target": "table", "object-locator": { "schema-name": "%", "table-name": "%" }, "rule-action": "convert-lowercase", "value": null, "old-value": null }, { "rule-type": "selection", "rule-id": "566111704", "rule-name": "566111704", "object-locator": { "schema-name": "dbo", "table-name": "%" }, "rule-action": "include", "filters": [] } ] }

使用包含 Babelfish 表的 PostgreSQL 目标端点的限制

使用包含 Babelfish 表的 PostgreSQL 目标端点时,存在以下限制:

  • 对于目标表准备模式,仅使用不执行任何操作截断模式。不要使用删除目标中的表模式。在该模式下,DMS 会将这些表创建为 T-SQL 可能无法识别的 PostgreSQL 表。

  • Amazon DMS 不支持 sql_variant 数据类型。

  • Babelfish 不支持 HEIRARCHYIDGEOMETRYGEOGRAPHY 数据类型。要迁移这些数据类型,您可以添加转换规则以将数据类型转换为 wstring(250)

  • Babelfish 仅支持使用 BYTEA 数据类型迁移 BINARYVARBINARYIMAGE 数据类型。对于早期版本的 Aurora PostgreSQL,可以使用 DMS 将这些表迁移到 Babelfish 目标端点。您不必为 BYTEA 数据类型指定长度,如以下示例所示。

    [Picture] [VARBINARY](max) NULL

    将前面的 T-SQL 数据类型更改为 T-SQL 支持的 BYTEA 数据类型。

    [Picture] BYTEA NULL
  • 对于早期版本的 Aurora PostgreSQL Babelfish,如果您使用 PostgreSQL 目标端点创建用于从 SQL Server 持续复制到 Babelfish 的迁移任务,则需要为任何使用 IDENTITY 列的表分配 SERIAL 数据类型。从 Aurora PostgreSQL(版本 15.3/14.8 及更高版本)和 Babelfish(版本 3.2.0 及更高版本)开始,支持标识列,并且不再需要分配 SERIAL 数据类型。有关更多信息,请参阅《SQL Server 到 Aurora PostgreSQL 迁移行动手册》的“序列和标识”部分中的 SERIAL 使用情况。然后,当您在 Babelfish 中创建表时,需修改如下的列定义。

    [IDCol] [INT] IDENTITY(1,1) NOT NULL PRIMARY KEY

    将前面的内容改为以下内容。

    [IDCol] SERIAL PRIMARY KEY

    兼容 Babelfish 的 Aurora PostgreSQL 使用默认配置创建序列并向该列添加 NOT NULL 约束。新创建的序列的行为类似于常规序列(以 1 为增量),并且没有复合 SERIAL 选项。

  • 使用包含 IDENTITY 列或 SERIAL 数据类型的表迁移数据后,根据列的最大值重置基于 PostgreSQL 的序列对象。对表执行完全加载后,使用以下 T-SQL 查询生成语句以便设置关联序列对象的种子。

    DECLARE @schema_prefix NVARCHAR(200) = '' IF current_setting('babelfishpg_tsql.migration_mode') = 'multi-db' SET @schema_prefix = db_name() + '_' SELECT 'SELECT setval(pg_get_serial_sequence(''' + @schema_prefix + schema_name(tables.schema_id) + '.' + tables.name + ''', ''' + columns.name + ''') ,(select max(' + columns.name + ') from ' + schema_name(tables.schema_id) + '.' + tables.name + '));' FROM sys.tables tables JOIN sys.columns columns ON tables.object_id = columns.object_id WHERE columns.is_identity = 1 UNION ALL SELECT 'SELECT setval(pg_get_serial_sequence(''' + @schema_prefix + table_schema + '.' + table_name + ''', ''' + column_name + '''),(select max(' + column_name + ') from ' + table_schema + '.' + table_name + '));' FROM information_schema.columns WHERE column_default LIKE 'nextval(%';

    该查询会生成一系列 SELECT 语句,您可以执行这些语句来更新 IDENTITY 和 SERIAL 的最大值。

  • 对于 3.2 之前的 Babelfish 版本,完整 LOB 模式可能会导致表错误。如果发生这种情况,请为加载失败的表创建一个单独任务。然后,使用受限 LOB 模式最大 LOB 大小(KB) 指定相应的值。另一种选择是设置 SQL Server 端点连接属性设置 ForceFullLob=True

  • 对于 3.2 之前的 Babelfish 版本,如果对不使用基于整数的主键的 Babelfish 表执行数据验证,则会生成一条消息,指出找不到合适的唯一键。从 Aurora PostgreSQL(版本 15.3/14.8 及更高版本)和 Babelfish(版本 3.2.0 及更高版本)开始,支持对非整数主键进行数据验证。

  • 由于秒的小数位数存在精度差异,DMS 会报告使用 DATETIME 数据类型的 Babelfish 表的数据验证失败。为避免出现这类失败,可以为 DATETIME 数据类型添加以下验证规则类型。

    { "rule-type": "validation", "rule-id": "3", "rule-name": "3", "rule-target": "column", "object-locator": { "schema-name": "dbo", "table-name": "%", "column-name": "%", "data-type": "datetime" }, "rule-action": "override-validation-function", "source-function": "case when ${column-name} is NULL then NULL else 0 end", "target-function": "case when ${column-name} is NULL then NULL else 0 end" }