

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

# 使用 PostgreSQL 数据库作为目标 AWS Database Migration Service
<a name="CHAP_Target.PostgreSQL"></a>

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

有关支持作为目标的 PostgreSQL 版本的信息 AWS DMS ，请参阅。[的目标 AWS DMS](CHAP_Introduction.Targets.md)

**注意**  
Amazon Aurora Serverless 可作为与 PostgreSQL 兼容的 Amazon Aurora 的目标。有关 Amazon Aurora Serverless 的更多信息，请参阅《Amazon Aurora 用户指南》**中的[使用 Amazon Aurora Serverless v2](https://docs.aws.amazon.com//AmazonRDS/latest/AuroraUserGuide/aurora-serverless-v2.html)。
Aurora Serverless 数据库集群只能从 Amazon VPC 访问，不能使用[公有 IP 地址](https://docs.aws.amazon.com//AmazonRDS/latest/AuroraUserGuide/aurora-serverless-v2.requirements.html)。因此，如果您要在不同于 Aurora PostgreSQL Serverless 的其他区域创建复制实例，则必须配置 [VPC 对等连接](https://docs.aws.amazon.com//dms/latest/userguide/CHAP_ReplicationInstance.VPC.html#CHAP_ReplicationInstance.VPC.Configurations.ScenarioVPCPeer)。否则，请检查 Aurora PostgreSQL Serverless [区域](https://docs.aws.amazon.com//AmazonRDS/latest/AuroraUserGuide/Concepts.AuroraFeaturesRegionsDBEngines.grids.html#Concepts.Aurora_Fea_Regions_DB-eng.Feature.Serverless)的可用性，并决定将其中一个区域用于 Aurora PostgreSQL Serverless 和您的复制实例。
Babelfish 功能内置在 Amazon Aurora 中，无需支付额外费用。有关更多信息，请参阅[将适用于 Aurora PostgreSQL 的 Babelfish 作为 AWS Database Migration Service的目标](#CHAP_Target.PostgreSQL.Babelfish)。

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

在 PostgreSQL 中，将使用触发器实施外键 (引用完整性约束)。在满载阶段，每次 AWS DMS 加载一个表。强烈建议您在完全加载期间使用以下方法之一禁用外键约束：
+ 从实例中临时禁用所有触发器并完成完全加载。
+ 在 PostgreSQL 中使用 `session_replication_role`参数。

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

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

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



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

**Topics**
+ [使用 PostgreSQL 作为目标的限制 AWS Database Migration Service](#CHAP_Target.PostgreSQL.Limitations)
+ [使用亚马逊 Aurora PostgreSQL Limitless 作为目标的限制 AWS Database Migration Service](#CHAP_Target.PostgreSQL.Aurora.Limitations)
+ [使用 PostgreSQL 数据库作为目标时的安全要求 AWS Database Migration Service](#CHAP_Target.PostgreSQL.Security)
+ [使用 PostgreSQL 作为ECAs目标时的端点设置和额外连接属性 () AWS DMS](#CHAP_Target.PostgreSQL.ConnectionAttrib)
+ [PostgreSQL 的目标数据类型](#CHAP_Target.PostgreSQL.DataTypes)
+ [使用 Babelfish for Aurora PostgreSQL 作为目标 AWS Database Migration Service](#CHAP_Target.PostgreSQL.Babelfish)

## 使用 PostgreSQL 作为目标的限制 AWS Database Migration Service
<a name="CHAP_Target.PostgreSQL.Limitations"></a>

将 PostgreSQL 数据库作为 AWS DMS的目标时，存在以下限制：
+ 对于异构迁移，JSON 数据类型将在内部转换为原生 CLOB 数据类型。
+ 在 Oracle 到 PostgreSQL 的迁移中，如果 Oracle 中的一列包含空字符（十六进制值 U\+0000） AWS DMS ，则将空字符转换为空格（十六进制值 U\+0020）。这是出于 PostgreSQL 限制的原因。
+ AWS DMS 不支持复制到使用合并函数创建的具有唯一索引的表。
+ 如果您的表使用序列，则在停止从源数据库`NEXTVAL`进行复制后，请更新目标数据库中每个序列的值。 AWS DMS 复制源数据库中的数据，但在正在进行的复制过程中不会将序列迁移到目标数据库。

## 使用亚马逊 Aurora PostgreSQL Limitless 作为目标的限制 AWS Database Migration Service
<a name="CHAP_Target.PostgreSQL.Aurora.Limitations"></a>

使用 Amazon Aurora PostgreSQL Limitless 作为目标时，以下限制适用： AWS DMS
+ AWS DMS 数据验证不支持 Amazon Aurora PostgreSQL Limitless。
+ AWS DMS 将源表迁移为标准表，这些表不是分布式的。迁移后，您可以按照官方转换指南将这些标准表转换为 Limitless 表。

## 使用 PostgreSQL 数据库作为目标时的安全要求 AWS Database Migration Service
<a name="CHAP_Target.PostgreSQL.Security"></a>

出于安全目的，用于数据迁移的用户账户，必须是您作为目标的任意 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 作为ECAs目标时的端点设置和额外连接属性 () AWS DMS
<a name="CHAP_Target.PostgreSQL.ConnectionAttrib"></a>

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

您可以在使用 AWS DMS 控制台创建目标端点时指定设置，或者使用中的`create-endpoint`命令和 `--postgre-sql-settings '{"{{EndpointSetting}}": {{"value"}}, {{...}}}'` JSON 语法。[AWS CLI](https://docs.aws.amazon.com/cli/latest/reference/dms/index.html)

您可以使用终端节点的`ExtraConnectionAttributes`参数进行指定 ECAs 。

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


| Name | 说明 | 
| --- | --- | 
| `ConnectionTimeout` | 使用此额外连接属性（ECA）设置 PostgreSQL 实例的端点连接超时时间（以秒为单位）。默认值为 10 秒。ECA 示例：`ConnectionTimeout=30`。 | 
| `MaxFileSize` | 指定用于将数据传输到 PostgreSQL 的任何 .csv 文件的最大大小（以 KB 为单位）。<br />默认值：32768 KB（32 MB）<br />有效值：1–1048576 KB（最大 1.1 GB）<br />示例：`--postgre-sql-settings '{"MaxFileSize": 512}'` | 
| `ExecuteTimeout` | 设置 PostgreSQL 实例的客户端语句超时 (以秒为单位)。默认值为 60 秒。<br />示例：`--postgre-sql-settings '{"ExecuteTimeout": 100}'` | 
| `AfterConnectScript= SET session_replication_role = replica` | 此属性具有 AWS DMS 绕过外键和用户触发器，可缩短批量加载数据所需的时间。 | 
| `MapUnboundedNumericAsString` | 此参数将具有无界 NUMERIC 数据类型的列视为 STRING，以便在不损失数值精度的前提下成功迁移。此参数仅用于从 PostgreSQL 源复制到 PostgreSQL 目标或与 PostgreSQL 兼容的数据库。<br />默认值：false<br />有效值：false/true<br />示例：`--postgre-sql-settings '{"MapUnboundedNumericAsString": "true"}`<br />使用此参数可能会导致某些复制性能下降，因为需要从数字转换为字符串，然后再转换回数字。DMS 版本 3.4.4 及更高版本支持使用此参数 只能同时在 PostgreSQL 源端点和目标端点中使用 `MapUnboundedNumericAsString`。 <br />在 CDC 期间，在源 PostgreSQL 端点上使用 `MapUnboundedNumericAsString` 会将精度限制在 28 以内。在目标端点上使用 `MapUnboundedNumericAsString` 时，使用精度 28、小数位数 6 迁移数据。 <br />请勿将 `MapUnboundedNumericAsString` 与非 PostgreSQL 目标一起使用。  | 
| `loadUsingCSV` | 使用此额外连接属性（ECA）可通过使用 \\COPY 命令传输数据以进行完全加载操作。<br />默认值：`true`<br />有效值：true/false<br />ECA 示例：`loadUsingCSV=true;`<br />**注意：**将此 ECA 设置为 false 可能会因为直接执行 INSERTs 而导致某些复制性能下降。 | 
| `DatabaseMode` | 使用此属性可以更改复制过程在处理需要一些额外配置的 Postgresql 兼容端点（例如 Babelfish 端点）时的默认行为。<br />默认值：`DEFAULT`<br />有效值：`DEFAULT`、`BABELFISH`<br />示例：`DatabaseMode=default;` | 
| `BabelfishDatabaseName` | 使用此属性指定要迁移到的目标 Babelfish T-SQL 数据库的名称。如果 `DatabaseMode` 设置为 `Babelfish`，则此项为必填。这不是保留的 `babelfish_db` 数据库。<br />示例：`BabelfishDatabaseName=TargetDb;` | 

## PostgreSQL 的目标数据类型
<a name="CHAP_Target.PostgreSQL.DataTypes"></a>

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

有关 AWS DMS 数据类型的更多信息，请参见[AWS Database Migration Service 的数据类型](CHAP_Reference.DataTypes.md)。


|  AWS DMS 数据类型  |  PostgreSQL 数据类型  | 
| --- | --- | 
| BOOLEAN | BOOLEAN | 
| BLOB | BYTEA | 
| BYTES | BYTEA | 
| DATE | DATE | 
| TIME | TIME | 
| DATETIME | 如果小数位数介于 0 和 6 之间，请使用 TIMESTAMP。<br />如果小数位数介于 7 和 9 之间，请使用 VARCHAR (37)。 | 
| INT1 | SMALLINT | 
| INT2 | SMALLINT | 
| INT4 | INTEGER | 
| INT8 | BIGINT | 
| NUMERIC  | DECIMAL (P,S) | 
| REAL4 | FLOAT4 | 
| REAL8 | FLOAT8 | 
| string | 如果长度介于 1 和 21845 之间，请使用 VARCHAR（以字节为单位的长度）。<br />如果长度介于 21846 和 2147483647 之间，请使用 VARCHAR (65535)。 | 
| UINT1 | SMALLINT | 
| UINT2 | INTEGER | 
| UINT4 | BIGINT | 
| UINT8 | BIGINT | 
| WSTRING | 如果长度介于 1 和 21845 之间，请使用 VARCHAR（以字节为单位的长度）。<br />如果长度介于 21846 和 2147483647 之间，请使用 VARCHAR (65535)。 | 
| NCLOB | TEXT | 
| CLOB | TEXT | 

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

## 使用 Babelfish for Aurora PostgreSQL 作为目标 AWS Database Migration Service
<a name="CHAP_Target.PostgreSQL.Babelfish"></a>

可以使用 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 数据库的名称。

### 向迁移任务添加转换规则
<a name="CHAP_Target.PostgreSQL.Babelfish.transform"></a>

在为 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 数据库名称为 dbo，则使用转换规则将架构重命名为 mydb\_dbo。

**注意**  
使用适用于 Aurora PostgreSQL 的 Babelfish 16 或更高版本时，默认迁移模式为“多数据库”。运行 DMS 迁移任务时，请务必查看迁移模式参数并在需要时更新转换规则。

如果您使用单数据库模式，则不需要转换规则即可重命名架构名称。架构名称与 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 目标端点的限制
<a name="CHAP_Target.PostgreSQL.Babelfish.limitations"></a>

使用包含 Babelfish 表的 PostgreSQL 目标端点时，存在以下限制：
+ 对于**目标表准备**模式，仅使用**不执行任何操作**或**截断**模式。不要使用**删除目标中的表**模式。在该模式下，DMS 会将这些表创建为 T-SQL 可能无法识别的 PostgreSQL 表。
+ AWS DMS 不支持 sql\_variant 数据类型。
+ Postgres 端点下的 Babelfish 不支持 `HEIRARCHYID`、`GEOMETRY`（3.5.4 之前版本）和 `GEOGRAPHY`（3.5.4 之前版本）数据类型。要迁移这些数据类型，您可以添加转换规则以将数据类型转换为 wstring(250)。
+ Babelfish 仅支持使用 `BYTEA` 数据类型迁移 `BINARY`、`VARBINARY` 和 `IMAGE` 数据类型。对于早期版本的 Aurora PostgreSQL，可以使用 DMS 将这些表迁移到 [Babelfish 目标端点](CHAP_Target.Babelfish.md)。您不必为 `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 使用情况](https://docs.aws.amazon.com/dms/latest/sql-server-to-aurora-postgresql-migration-playbook/chap-sql-server-aurora-pg.tsql.sequences..html)。然后，当您在 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"
       }
  ```