将 PostgreSQL 数据库作为 AWS Database Migration Service的目标 - AWS 数据库迁移服务

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

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

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

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

注意

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

在 PostgreSQL 中,将使用触发器实施外键 (引用完整性约束)。在满载阶段,每次 AWS 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 数据库作为目标的更多详细信息, AWS DMS请参阅以下各节:

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

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

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

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

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

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

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

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

您的 PostgreSQL 目标端点需要最低的用户权限才能运行迁移,请参阅以下示 AWS 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) AWS DMS

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

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

此属性具有 AWS 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 数据库端点 AWS DMS 支持大多数 PostgreSQL 数据库数据类型。下表显示了 AWS DMS 使用时支持的 PostgreSQL 数据库目标数据类型以及数据类型的默认映射 AWS DMS 。

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

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

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

可以使用 AWS 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。

使用 AWS DMS 控制台、API 或 CLI 命令创建 AWS 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 表。

  • AWS 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" }