

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用 PostgreSQL 資料庫做為 的目標 AWS Database Migration Service
<a name="CHAP_Target.PostgreSQL"></a>

您可以使用 從另一個 PostgreSQL 資料庫或其中一個其他支援的資料庫 AWS DMS，將資料遷移至 PostgreSQL 資料庫。

如需 AWS DMS 支援 做為目標之 PostgreSQL 版本的資訊，請參閱 [的目標 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)。 **
您只能從 Amazon VPC 存取 Aurora Serverless 資料庫叢集，且此類叢集無法使用[公有 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 之中，不會產生額外費用。如需詳細資訊，請參閱[使用 Babelfish for Aurora PostgreSQL 作為 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)
+ [使用 Amazon 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 中的資料欄包含 NULL 字元 （十六進位值 U\$10000)， 會將 NULL 字元 AWS DMS 轉換為空格 （十六進位值 U\$10020)。這是因 PostgreSQL 限制所致。
+ AWS DMS 不支援複寫至具有以 coalesce 函數建立之唯一索引的資料表。
+ 如果您的資料表使用序列，請在停止來源資料庫的複寫之後，更新目標資料庫中每個序列`NEXTVAL`的 值。 會從來源資料庫 AWS DMS 複製資料，但不會在持續複寫期間將序列遷移至目標。

## 使用 Amazon 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 會將來源資料表遷移為未分佈的標準資料表。遷移後，您可以遵循官方轉換指南，將這些標準資料表轉換為無限資料表。

## 使用 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 做為目標使用的端點設定。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/dms/latest/userguide/CHAP_Target.PostgreSQL.html)

## PostgreSQL 的目標資料類型
<a name="CHAP_Target.PostgreSQL.DataTypes"></a>

的 PostgreSQL 資料庫端點 AWS DMS 支援大多數 PostgreSQL 資料庫資料類型。下表顯示使用 時支援的 PostgreSQL 資料庫目標資料類型， AWS DMS 以及來自 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。 如果擴展是從 7 到 9，則使用 VARCHAR (37)。  | 
|  INT1  |  SMALLINT  | 
|  INT2  |  SMALLINT  | 
|  INT4  |  INTEGER  | 
|  INT8  |  BIGINT  | 
|  NUMERIC   |  DECIMAL (P,S)  | 
|  REAL4  |  FLOAT4  | 
|  REAL8  |  FLOAT8  | 
|  STRING  |  如果長度是從 1 到 21,845，則使用 VARCHAR (長度為位元組)。 如果長度是從 21,846 到 2,147,483,647，則使用 VARCHAR (65535)。  | 
|  UINT1  |  SMALLINT  | 
|  UINT2  |  INTEGER  | 
|  UINT4  |  BIGINT  | 
|  UINT8  |  BIGINT  | 
|  WSTRING  |  如果長度是從 1 到 21,845，則使用 VARCHAR (長度為位元組)。 如果長度是從 21,846 到 2,147,483,647，則使用 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 伺服器來源資料表遷移到 Babelfish for Amazon Aurora PostgreSQL 目標。透過 Babelfish，Aurora PostgreSQL 便可理解 T-SQL、Microsoft SQL 服務器的專有 SQL 方言，並支援相同的通訊協議。因此，針對 SQL Server 撰寫的應用程式現在只需較少的程式碼變更即可使用 Aurora。Babelfish 功能內建於 Amazon Aurora 之中，不會產生額外費用。您可以從 Amazon RDS 主控台啟用 Amazon Aurora 叢集上的 Babelfish。

當您使用 AWS DMS 主控台、API 或 CLI 命令建立 AWS DMS 目標端點時，請將目標引擎指定為 **Amazon Aurora PostgreSQL**，並將資料庫命名為 **babelfish\$1db**。在**端點設定**區段中，新增設定以將 `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 資料庫名稱為 mydb，請使用轉換規則將結構描述重新命名為 mydb\$1dbo。

**注意**  
使用 Babelfish for Aurora PostgreSQL 16 或更新版本時，預設遷移模式為「mutidatabase」。執行 DMS 遷移任務時，請務必檢閱遷移模式參數，並視需要更新轉換規則。

如果您使用單一資料庫模式，則不需要轉換規則來重新命名結構描述名稱。結構描述名稱與 Babelfish 中的目標 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": []
   }
]
}
```

### 將 PostgreSQL 目標端點與 Babelfish 資料表搭配使用的限制
<a name="CHAP_Target.PostgreSQL.Babelfish.limitations"></a>

將 PostgreSQL 目標端點與 Babelfish 資料表搭配使用時，將適用下列限制：
+ 對於**目標資料表準備**模式，請僅使用**不執行任何操作**或**截斷**模式。請勿使用**刪除目標中的資料表**模式。在該模式下，DMS 會將資料表建立為 T-SQL 可能無法辨識的 PostgreSQL 資料表。
+ AWS DMS 不支援 sql\$1variant 資料類型。
+ 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 伺服器進行中複寫到 Babelfish，則需要將 `SERIAL` 資料類型指派給任何使用 `IDENTITY` 欄的資料表。從 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"
       }
  ```