

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

# Amazon RDS for PostgreSQL
<a name="CHAP_PostgreSQL"></a>

Amazon RDS 支援執行幾個 PostgreSQL 版本的資料庫執行個體。如需可用版本的清單，請參閱 [可用的 PostgreSQL 資料庫版本](PostgreSQL.Concepts.General.DBVersions.md)。

您可以建立資料庫執行個體和資料庫快照的時間點還原及備份。執行 PostgreSQL 的資料庫執行個體支援多可用區域部署、僅供讀取複本、佈建 IOPS，且可以在 Virtual Private Cloud (VPC) 內建立。您也可以使用 Secure Sockets Layer (SSL) 來連線至執行 PostgreSQL 的資料庫執行個體。

建立資料庫執行個體之前，請務必完成 [設定您的 Amazon RDS 環境](CHAP_SettingUp.md) 中的步驟。

您可以從用戶端電腦使用任何標準 SQL 用戶端應用程式對執行個體執行命令。此類應用程式包括 pgAdmin (適用於 PostgreSQL 的常見開放原始碼管理和開發工具) 或 psql (隨 PostgreSQL 一併安裝的命令列公用程式)。為了提供受管理的服務體驗，Amazon RDS 並不會提供資料庫執行個體的主機存取權。此外，其也會將存取權限制在某些需要進階權限的系統程序和資料表。Amazon RDS 可支援使用任何標準 SQL 用戶端應用程式存取資料庫執行個體上的資料庫。Amazon RDS 不允許使用者利用 Telnet 或安全殼層 (SSH) 直接託管資料庫執行個體的存取權。

Amazon RDS for PostgreSQL 符合多項業界標準。舉例來說，您可以使用 Amazon RDS for PostgreSQL 資料庫來建置符合 HIPAA 規範的應用程式並存放醫療保健相關資訊。這包括依據與 AWS 簽署的完整商業夥伴協議 (BAA) 儲存受保護醫療資訊 (PHI)。Amazon RDS for PostgreSQL 亦符合美國聯邦風險與授權管理計劃 (FedRAMP) 的安全性要求。Amazon RDS for PostgreSQL 已獲得 FedRAMP 聯合授權委員會 (JAB) 核發的 FedRAMP 高基準臨時操作授權書 (P-ATO)，可在 AWS GovCloud (US) 區域內執行。如需支援的合規標準的詳細資訊，請參閱 [AWS雲端合規](https://aws.amazon.com/compliance/)。

若要將 PostgreSQL 資料匯入資料庫執行個體，請遵循[將資料匯入 Amazon RDS 上的 PostgreSQL](PostgreSQL.Procedural.Importing.md)一節的資訊。

**重要**  
如果 RDS for PostgreSQL 資料庫執行個體發生問題，您的 AWS Support 客服可能需要資料庫運作狀態的詳細資訊。目標是確保 AWS Support 盡快取得所需資訊。  
您可以使用 PG Collector 來協助在合併的 HTML 檔案中收集寶貴的資料庫資訊。如需 PG Collector、如何執行以及如何下載 HTML 報告的詳細資訊，請參閱 [PG Collector](https://github.com/awslabs/pg-collector)。  
成功完成後，除非另有說明，否則指令碼會以可讀的 HTML 格式傳回輸出。該指令碼旨在從 HTML 中排除任何可能危及您業務的資料或安全性詳細資訊。其也不會對您的資料庫或其環境進行任何修改。但是，如果您在 HTML 中發現任何不希望分享的資訊，請在上傳 HTML 之前移除有問題資訊。當您能夠放心分享 HTML 中的資訊時，請使用支援案例的案例詳細資訊中的附件區段來上傳 HTML。

**Topics**
+ [Amazon RDS for PostgreSQL 的常用管理任務](CHAP_PostgreSQL.CommonTasks.md)
+ [使用資料庫預覽環境](working-with-the-database-preview-environment.md)
+ [可用的 PostgreSQL 資料庫版本](PostgreSQL.Concepts.General.DBVersions.md)
+ [了解 RDS for PostgreSQL 增量發行程序](PostgreSQL.Concepts.General.ReleaseProcess.md)
+ [支援的 PostgreSQL 擴充功能版本](PostgreSQL.Concepts.General.FeatureSupport.Extensions.md)
+ [使用 Amazon RDS for PostgreSQL 支援的 PostgreSQL 功能](PostgreSQL.Concepts.General.FeatureSupport.md)
+ [連線至執行 PostgreSQL 資料庫引擎的資料庫執行個體](USER_ConnectToPostgreSQLInstance.md)
+ [使用 SSL/TLS 保護連接至 RDS for PostgreSQL 的連線](PostgreSQL.Concepts.General.Security.md)
+ [搭配 Amazon RDS for PostgreSQL 使用 Kerberos 身分驗證](postgresql-kerberos.md)
+ [針對傳出網路存取使用自訂 DNS 伺服器。](Appendix.PostgreSQL.CommonDBATasks.CustomDNS.md)
+ [RDS for PostgreSQL 資料庫引擎的升級](USER_UpgradeDBInstance.PostgreSQL.md)
+ [升級 PostgreSQL 資料庫快照引擎版本](USER_UpgradeDBSnapshot.PostgreSQL.md)
+ [使用 Amazon RDS for PostgreSQL 的僅供讀取複本](USER_PostgreSQL.Replication.ReadReplicas.md)
+ [使用 Amazon RDS Optimized Reads 改善 RDS for PostgreSQL 的查詢效能](USER_PostgreSQL.optimizedreads.md)
+ [將資料匯入 Amazon RDS 上的 PostgreSQL](PostgreSQL.Procedural.Importing.md)
+ [將資料從 RDS for PostgreSQL 資料庫執行個體匯出至 Amazon S3](postgresql-s3-export.md)
+ [從 RDS for PostgreSQL 資料庫執行個體叫用 AWS Lambda 函數](PostgreSQL-Lambda.md)
+ [Amazon RDS for PostgreSQL 的常用 DBA 任務](Appendix.PostgreSQL.CommonDBATasks.md)
+ [調校 RDS for PostgreSQL 的等待事件](PostgreSQL.Tuning.md)
+ [使用 Amazon DevOps Guru 主動洞察，調校 RDS for PostgreSQL](PostgreSQL.Tuning_proactive_insights.md)
+ [搭配 Amazon RDS for PostgreSQL 使用 PostgreSQL 擴充功能](Appendix.PostgreSQL.CommonDBATasks.Extensions.md)
+ [使用 Amazon RDS for PostgreSQL 支援的外部資料包裝函式](Appendix.PostgreSQL.CommonDBATasks.Extensions.foreign-data-wrappers.md)
+ [使用適用於 PostgreSQL 的受信任語言延伸模組](PostgreSQL_trusted_language_extension.md)

# Amazon RDS for PostgreSQL 的常用管理任務
<a name="CHAP_PostgreSQL.CommonTasks"></a>

下列是您可在執行 Amazon RDS for PostgreSQL 資料庫執行個體時使用的一般管理任務，並隨附各工作相關說明文件的連結。


| 任務區域 | 相關文件 | 
| --- | --- | 
|  **Amazon RDS 首次使用設定** 在建立資料庫執行個體前，請務必完成一些先決條件。例如，根據預設，建立資料庫執行個體時也包含可防止存取的防火牆。您需要以正確的 IP 地址和網路組態建立安全群組，才能存取資料庫執行個體。  |  [設定您的 Amazon RDS 環境](CHAP_SettingUp.md)  | 
|  **Understanding Amazon RDS DB instances (認識 &RDS; 資料庫執行個體)** 如果您要針對生產用途建立資料庫執行個體，您應該了解執行個體類別、儲存體類型和佈建的 IOPS 在 Amazon RDS 中的運作方式。  |  [ 資料庫執行個體類別](Concepts.DBInstanceClass.md) [Amazon RDS 儲存類型](CHAP_Storage.md#Concepts.Storage) [佈建 IOPS SSD 儲存體](CHAP_Storage.md#USER_PIOPS)  | 
|  **查找可用的 PostgreSQL 版本** Amazon RDS 支援數個 PostgreSQL 版本。  |  [可用的 PostgreSQL 資料庫版本](PostgreSQL.Concepts.General.DBVersions.md)  | 
|  **設定高可用性和容錯移轉支援** 生產資料庫執行個體應該使用多個可用區部署。「異地同步備份部署」可提高資料庫執行個體的可用性、資料耐用性和容錯能力。  |  [設定及管理 Amazon RDS 的多可用區域部署](Concepts.MultiAZ.md)  | 
|  **認識 Amazon Virtual Private Cloud (VPC) 網路** 如果 AWS 您的帳戶具有預設 VPC，則會自動在預設 VPC 內建立資料庫執行個體。在某些情況下，您的帳戶可能沒有預設 VPC，而且您可能會想要在 VPC 中的資料庫執行個體。在這些情況下，建立資料庫執行個體前，建立 VPC 和子網路群組。   |  [在 VPC 中使用資料庫執行個體](USER_VPC.WorkingWithRDSInstanceinaVPC.md)  | 
|  **將資料匯入 Amazon RDS PostgreSQL** 您可使用多種不同的工具，將資料匯入 Amazon RDS 上的 PostgreSQL 資料庫執行個體。  |  [將資料匯入 Amazon RDS 上的 PostgreSQL](PostgreSQL.Procedural.Importing.md)  | 
|  **設定唯讀僅供讀取複本 (主要和待命)** RDS for PostgreSQL 在與主要執行個體相同的 AWS 區域和不同的 AWS 區域中都支援僅供讀取複本。  |  [使用資料庫執行個體僅供讀取複本](USER_ReadRepl.md) [使用 Amazon RDS for PostgreSQL 的僅供讀取複本](USER_PostgreSQL.Replication.ReadReplicas.md) [在不同的 中建立僅供讀取複本 AWS 區域](USER_ReadRepl.XRgn.md)  | 
|  **了解安全群組** 根據預設，建立資料庫執行個體時會同時建立防火牆，可防止執行個體遭受不適當的存取。若要透過該防火牆提供存取權，請編輯與託管資料庫執行個體 VPC 相關聯的 VPC 安全群組的傳入規則。  |  [使用安全群組控制存取](Overview.RDSSecurityGroups.md)  | 
|  **設定參數群組和功能** 若要變更資料庫執行個體的預設參數，請建立自訂資料庫參數群組並將設定變更為如此。如果在建立資料庫執行個體之前執行此作業，您可以在建立執行個體時選擇自訂資料庫參數群組。  |  [Amazon RDS 的參數群組](USER_WorkingWithParamGroups.md)  | 
|  **連線至 PostgreSQL 資料庫執行個體** 建立安全群組並與資料庫執行個體建立關聯後，您可以使用任何標準 SQL 用戶端應用程式 (例如 `psql` 或 `pgAdmin`) 來連線至資料庫執行個體。  |  [連線至執行 PostgreSQL 資料庫引擎的資料庫執行個體](USER_ConnectToPostgreSQLInstance.md) [將 SSL 與 PostgreSQL 資料庫執行個體搭配使用](PostgreSQL.Concepts.General.SSL.md)  | 
|  **備份與還原資料庫執行個體** 您可以設定資料庫執行個體以進行自動備份，或取得手動快照，然後從備份或快照還原執行個體。  |  [備份、還原和匯出資料](CHAP_CommonTasks.BackupRestore.md)  | 
|  **監控資料庫執行個體的活動和效能** 您能夠利用 CloudWatch Amazon RDS 指標、事件和增強型監控，進而監控 PostgreSQL 資料庫執行個體。  |  [在 Amazon RDS 主控台中檢視指標](USER_Monitoring.md) [檢視 Amazon RDS 事件](USER_ListEvents.md)  | 
|  **升級 PostgreSQL 資料庫版本** 您可以對 PostgreSQL 資料庫執行個體進行主要和次要版本升級。  |  [RDS for PostgreSQL 資料庫引擎的升級](USER_UpgradeDBInstance.PostgreSQL.md) [選擇 RDS for PostgreSQL 升級的主要版本](USER_UpgradeDBInstance.PostgreSQL.MajorVersion.md)  | 
|  **使用日誌檔案** 您可以存取 PostgreSQL 資料庫執行個體的日誌檔案。  |  [ RDS for PostgreSQL 資料庫日誌檔案](USER_LogAccess.Concepts.PostgreSQL.md)  | 
|  **了解 PostgreSQL 資料庫執行個體的最佳實務** 尋找在 Amazon RDS 上使用 PostgreSQL 的一些最佳實務。  |  [使用 PostgreSQL 的最佳實務](CHAP_BestPractices.md#CHAP_BestPractices.PostgreSQL)  | 

以下是本指南中其他章節的列表，這些章節可幫助您了解並使用 RDS for PostgreSQL 的重要功能：
+  [了解 PostgreSQL 角色和許可](Appendix.PostgreSQL.CommonDBATasks.Roles.md) 
+  [控制使用者對 PostgreSQL 資料庫的存取控制使用者對 PostgreSQL 的存取](Appendix.PostgreSQL.CommonDBATasks.Access.md) 
+  [在 RDS for PostgreSQL 資料庫執行個體上搭配使用參數](Appendix.PostgreSQL.CommonDBATasks.Parameters.md) 
+  [了解 RDS for PostgreSQL 支援的記錄機制](Appendix.PostgreSQL.CommonDBATasks.md#Appendix.PostgreSQL.CommonDBATasks.Auditing) 
+  [在 Amazon RDS for PostgreSQL 上使用 PostgreSQL 自動清空](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.md) 
+  [針對傳出網路存取使用自訂 DNS 伺服器。](Appendix.PostgreSQL.CommonDBATasks.CustomDNS.md) 

# 使用資料庫預覽環境
<a name="working-with-the-database-preview-environment"></a>

 PostgreSQL 社群會持續發佈新的 PostgreSQL 版本和新的延伸模組。包括 Beta 版本。這讓 PostgreSQL 使用者有機會提早嘗試新的 PostgreSQL 版本。若要進一步了解 PostgreSQL 社群 Beta 發行程序，請參閱 PostgreSQL 文件中的 [Beta 資訊](https://www.postgresql.org/developer/beta/)。同樣地，Amazon RDS 會使某些 PostgreSQL Beta 版本當作預覽版本提供。這可讓您使用預覽版本建立資料庫執行個體，並在資料庫預覽環境中測試其功能。

資料庫預覽環境中的 RDS for PostgreSQL 資料庫執行個體是類似於其他 RDS for PostgreSQL 執行個體的功能。不過，您無法使用預覽版本進行生產。

請謹記下列重要限制：
+ 所有資料庫執行個體在建立後 60 天就會刪除，也會一併刪除任何備份和快照。
+ 您只能在以 Amazon VPC 服務為基礎的 Virtual Private Cloud (VPC) 中建立資料庫執行個體。
+ 您只能使用一般用途 SSD 和佈建 IOPS SSD 儲存裝置。
+ 您無法從 AWS Support with 資料庫執行個體取得協助。相反地，您可以將問題發佈至 AWS受管問答社群 [AWS re：Post](https://repost.aws/tags/TAsibBK6ZeQYihN9as4S_psg/amazon-relational-database-service)。
+ 您無法將資料庫執行個體的快照複製到生產環境。

預覽版支援下列選項：
+ 您只能使用 M6i、R6i、M6g、M5、T3、R6g 和 R5 執行個體類型建立資料庫執行個體。如需 RDS 執行個體類別的詳細資訊，請參閱[ 資料庫執行個體類別](Concepts.DBInstanceClass.md)。
+ 您可以同時使用單一可用區域和多可用區域部署。
+ 您可以使用標準 PostgreSQL 傾印和載入函數，從資料庫預覽環境匯出資料庫，或匯入資料庫至資料庫預覽環境。

**Topics**
+ [資料庫預覽環境中不支援的功能](#preview-environment-exclusions)
+ [資料庫預覽環境中的 PostgreSQL 第 17 版](#PostgreSQL.Concepts.General.version17)
+ [在資料庫預覽環境中建立新的資料庫執行個體](create-db-instance-in-preview-environment.md)

## 資料庫預覽環境中不支援的功能
<a name="preview-environment-exclusions"></a>

資料庫預覽環境中無法使用下列功能：
+ 跨區域快照複製
+ 跨區域僅供讀取複本

## 資料庫預覽環境中的 PostgreSQL 第 17 版
<a name="PostgreSQL.Concepts.General.version17"></a>

**注意**  
這是 Amazon RDS PostgreSQL 第 17 版的預覽文件。內容可能變動。

PostgreSQL 17.0 版現已可在 Amazon RDS 資料庫預覽環境中使用。PostgreSQL 第 17 版包含 PostgreSQL 文件中所述的下列數項改進：[PostgreSQL 17 已發佈](https://www.postgresql.org/docs/17/release-17.html)。

如需資料庫預覽環境的資訊，請參閱 [使用資料庫預覽環境](#working-with-the-database-preview-environment)。若要從主控台存取預覽環境，請選取 [https://console.aws.amazon.com/rds-preview/](https://console.aws.amazon.com/rds-preview/)。

# 在資料庫預覽環境中建立新的資料庫執行個體
<a name="create-db-instance-in-preview-environment"></a>

使用下列程序在預覽環境中建立資料庫執行個體。

**在資料庫預覽環境中建立資料庫執行個體**

1. 登入 AWS 管理主控台 ，並在 [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/)：// 開啟 Amazon RDS 主控台。

1. 從導覽窗格中選擇 **Dashboards (儀表板)**。

1. 在儀表板頁面中，找出儀表板頁面上的 **Database Preview Environment** (資料庫預覽環境) 區段，如下圖所示。  
![\[預覽環境區段，其中具有 RDS 主控台 (儀表板) 中顯示的連結\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/images/preview-environment-dashboard.png)

   您可以直接導覽至[資料庫預覽環境](https://us-east-2.console.aws.amazon.com/rds-preview/home?region=us-east-2#)。在繼續之前，您必須確認並接受限制。  
![\[預覽環境限制對話方塊\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/images/preview-environment-console.png)

1. 若要建立 RDS for PostgreSQL 資料庫執行個體，請遵循與建立任何 Amazon RDS 資料庫執行個體相同的程序。如需詳細資訊，請參閱 [建立資料庫執行個體](USER_CreateDBInstance.md#USER_CreateDBInstance.Creating) 中的 [主控台](USER_CreateDBInstance.md#USER_CreateDBInstance.CON) 程序。

若要使用 RDS API 或 AWS CLI在資料庫預覽環境中建立執行個體，請使用下列端點。

```
rds-preview.us-east-2.amazonaws.com
```

# 可用的 PostgreSQL 資料庫版本
<a name="PostgreSQL.Concepts.General.DBVersions"></a>

Amazon RDS 支援執行幾個 PostgreSQL 版本的資料庫執行個體。建立新的資料庫執行個體時，您可以指定使用目前可用的任一 PostgreSQL 版本。您可以指定主要版本 (例如 PostgreSQL 14)，以及所指定主要版本的任何可用次要版本。若未指定版本，Amazon RDS 會預設使用可用的版本，通常是最新版本。若已指定主要版本，但未指定次要版本，Amazon RDS 會預設使用您指定主要版本的最新次要版本。

若要查看可用版本的清單，以及新建立資料庫執行個體的預設值，請使用 [https://docs.aws.amazon.com/cli/latest/reference/rds/describe-db-engine-versions.html](https://docs.aws.amazon.com/cli/latest/reference/rds/describe-db-engine-versions.html) AWS CLI 命令。例如，若要顯示預設 PostgreSQL 引擎版本，請使用下列命令：

```
aws rds describe-db-engine-versions --default-only --engine postgres
```

如需有關 Amazon RDS 支援的 PostgreSQL 版本的詳細內容，請參閱 [https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/Welcome.html](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/Welcome.html)。您也可以執行 [describe-db-major-engine-versions](https://docs.aws.amazon.com/cli/latest/reference/rds/describe-db-major-engine-versions.html) AWS CLI 命令或使用 [DescribeDBMajorEngineVersions](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_DescribeDBMajorEngineVersions.html) RDS API 操作，以檢視主要引擎版本支援日期的相關資訊。

如果您未在標準支援日期結束前準備好手動升級至新的主要引擎版本，Amazon RDS 會在標準支援日期結束後，自動在 Amazon RDS 延長支援中註冊您的資料庫。其後，您可以繼續執行 RDS for PostgreSQL 第 11 版和更高版本。如需詳細資訊，請參閱 [使用 Amazon RDS 的 Amazon RDS 延伸支援](extended-support.md) 和 [Amazon RDS 定價](https://aws.amazon.com/rds/pricing/)。

## 的已棄用版本 Amazon RDS for PostgreSQL
<a name="PostgreSQL.Concepts.General.DeprecatedVersions"></a>

請留意下列已棄用的版本：
+ RDS for PostgreSQL 10 已於 2023 年 2 月棄用。
+ RDS for PostgreSQL 9.6 已於 2022 年 3 月棄用。
+ RDS for PostgreSQL 9.5 已於 2021 年 3 月棄用。

若要進一步了解 RDS for PostgreSQL 的棄用政策，請參閱 [Amazon RDS 常見問答集](https://aws.amazon.com/rds/faqs/)。如需 PostgreSQL 版本的詳細資訊，請參閱 PostgreSQL 說明文件中的[版本控制政策](https://www.postgresql.org/support/versioning/)。

# 了解 RDS for PostgreSQL 增量發行程序
<a name="PostgreSQL.Concepts.General.ReleaseProcess"></a>

RDS for PostgreSQL 會透過增量發行提供安全修正、效能改善和新功能，同時保持次要版本相容性。這些版本標示為 R1、R2、R3，依此類推。

**發行版本命名慣例**
+ R1 是次要版本的初始版本。其中有時會包含新功能、延伸模組，或現有的延伸模組的升級。
+ 後續發行版本 (R2、R3 和更新版本) 包含：
  + 安全性更新
  + 效能改進
  + 錯誤修正
  + 延伸模組更新

## RDS for PostgreSQL 增量發行程序的優點
<a name="PostgreSQL.Concepts.General.ReleaseProcess.Adv"></a>

增量發行程序提供下列優點：
+ 快速採用新的 PostgreSQL 社群版本，同時透過後續版本個別管理 RDS 的特定增強功能。這樣可以簡化發行程序，並確保可以更快速交付重要更新。
+ 存取錯誤修正、新功能、安全性更新和延伸模組更新，同時維持與 PostgreSQL 次要版本的相容性。

## 管理版本更新
<a name="PostgreSQL.Concepts.General.ReleaseProcess.Manage"></a>

Amazon RDS 會透過 AWS 管理主控台中的待處理維護動作通知您有新的增量發行。您可以使用下列其中一種方法來更新資料庫：
+ 在排程維護時段啟用自動更新。
+ 透過待處理維護動作手動套用更新。
+ 使用藍/綠部署搭配實體複寫，盡可能縮短停機時間。如需詳細資訊，請參閱[藍/綠部署支援 RDS for PostgreSQL 的次要版本升級](https://aws.amazon.com/about-aws/whats-new/2024/11/rds-blue-green-deployments-upgrade-rds-postgresql/)。

在更新資料庫之前，請考量下列要點：
+ 更新後必須將資料庫重新開機，除非您使用藍/綠部署搭配實體複寫。
+ 某些增量發行是強制性的，尤其是包含安全修正的發行。

如需更新 Amazon RDS 資料庫執行個體的詳細資訊，請參閱 [PostgreSQL 可信任延伸](PostgreSQL.Concepts.General.FeatureSupport.Extensions.md#PostgreSQL.Concepts.General.Extensions.Trusted) 和 [apply-pending-maintenance-action](https://docs.aws.amazon.com/cli/latest/reference/rds/apply-pending-maintenance-action.html)。

# 支援的 PostgreSQL 擴充功能版本
<a name="PostgreSQL.Concepts.General.FeatureSupport.Extensions"></a>

RDS for PostgreSQL 支援許多 PostgreSQL 擴充功能。PostgreSQL 社群有時會將這些稱為模組。擴充功能可以擴充 PostgreSQL 引擎所提供的功能。您可以在該 PostgreSQL 版本的預設資料庫參數群組中找到 Amazon RDS 支援的延伸清單。您也可以使用 `psql` 來顯示 `rds.extensions` 參數，即可看到目前的延伸清單，如下列範例所示。

```
SHOW rds.extensions; 
```

**注意**  
在 `rds.extensions` 中使用 `psql` 參數時，次要版本中新增的參數可能不會正確顯示。

從 RDS for PostgreSQL 13 開始，某些擴充功能可由資料庫使用者安裝，而不是 `rds_superuser`。這些稱為*受信任的擴充功能*。如需詳細資訊，請參閱 [PostgreSQL 可信任延伸](#PostgreSQL.Concepts.General.Extensions.Trusted)。

特定 RDS for PostgreSQL 版本支援 `rds.allowed_extensions` 參數。此參數可讓 `rds_superuser` 限制 RDS for PostgreSQL 資料庫執行個體中安裝的擴充功能。如需詳細資訊，請參閱[限制安裝 PostgreSQL 擴充功能](#PostgreSQL.Concepts.General.FeatureSupport.Extensions.Restriction)。

如需有關 Amazon RDS 支援的 PostgreSQL 擴充功能的詳細清單，請參閱 *Amazon RDS for PostgreSQL 版本備註*中的 [Amazon RDS 上支援的 PostgreSQL 擴充功能](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html)。

## 限制安裝 PostgreSQL 擴充功能
<a name="PostgreSQL.Concepts.General.FeatureSupport.Extensions.Restriction"></a>

您可以限制 PostgreSQL 資料庫執行個體上能安裝哪些擴充功能。依預設，並未設定此參數，因此若使用者具有許可權限，則可新增任何受支援的擴充功能。若要執行這項操作，請將 `rds.allowed_extensions` 參數設定為逗號分隔的副檔名字串。將擴充功能清單新增至此參數，可明確識別 RDS for PostgreSQL 資料庫執行個體可使用的擴充功能。然後，只有這些擴充功能才能安裝在 PostgreSQL 資料庫執行個體中。

`rds.allowed_extensions` 參數的預設字串是 '\$1'，這表示可以安裝引擎版本可用的任何擴充功能。變更 `rds.allowed_extensions` 參數不需要重新啟動資料庫，因為它是動態參數。

PostgreSQL 資料庫執行個體引擎必須是下列其中一個版本，才能使用 `rds.allowed_extensions` 參數：
+ 所有 PostgreSQL 16 版本
+ PostgreSQL 15 和所有更高的版本
+ PostgreSQL 14 和所有更高的版本
+ PostgreSQL 13.3 和更高的次要版本
+ PostgreSQL 12.7 和更高的次要版本

 若要查看允許安裝哪些擴充功能，請使用下列 psql 命令。

```
postgres=> SHOW rds.allowed_extensions;
 rds.allowed_extensions
------------------------
 *
```

如果在將其排除於 `rds.allowed_extensions` 參數清單外之前已經安裝擴充功能，則擴充功能仍然可以正常使用，而且 `ALTER EXTENSION` 和 `DROP EXTENSION` 等命令將繼續運作。但是，在限制擴充功能之後，限制擴充功能的 `CREATE EXTENSION` 命令將會失敗。

`CREATE EXTENSION CASCADE` 擴充功能相依性的安裝也會受到限制。必須在 `rds.allowed_extensions` 中指定擴充功能及其相依性。如果擴充功能相依性安裝失敗，整個 `CREATE EXTENSION CASCADE` 陳述式將會失敗。

如果 `rds.allowed_extensions` 參數中未包含擴充功能，您會在嘗試安裝擴充功能時看到下列錯誤。

```
ERROR: permission denied to create extension "extension-name" 
HINT: This extension is not specified in "rds.allowed_extensions".
```

## PostgreSQL 可信任延伸
<a name="PostgreSQL.Concepts.General.Extensions.Trusted"></a>

若要安裝大多數 PostgreSQL 延伸，需要 `rds_superuser` 權限。PostgreSQL 13 推出了可信任擴充功能，這減少了向普通使用者授予 `rds_superuser` 權限的需求。使用此功能，使用者可以安裝許多延伸 (如果他們具有目前資料庫的 `CREATE` 權限而不是 `rds_superuser` 角色)。如需詳細資訊，請參閱 PostgreSQL 文件中的 SQL [CREATE EXTENSION](https://www.postgresql.org/docs/current/sql-createextension.html) 命令。

下面列出了具有目前資料庫 `CREATE` 權限但不需要 `rds_superuser` 角色的使用者可以安裝的延伸：
+ bool\$1plperl
+ [btree\$1gin](http://www.postgresql.org/docs/current/btree-gin.html)
+ [btree\$1gist](http://www.postgresql.org/docs/current/btree-gist.html)
+ [citext ](http://www.postgresql.org/docs/current/citext.html)
+ [cube ](http://www.postgresql.org/docs/current/cube.html)
+ [ dict\$1int ](http://www.postgresql.org/docs/current/dict-int.html)
+ [fuzzystrmatch](http://www.postgresql.org/docs/current/fuzzystrmatch.html)
+  [hstore](http://www.postgresql.org/docs/current/hstore.html)
+ [ intarray](http://www.postgresql.org/docs/current/intarray.html)
+ [isn ](http://www.postgresql.org/docs/current/isn.html)
+ jsonb\$1plperl
+ [ltree ](http://www.postgresql.org/docs/current/ltree.html)
+ [pg\$1trgm](http://www.postgresql.org/docs/current/pgtrgm.html)
+ [pgcrypto](http://www.postgresql.org/docs/current/pgcrypto.html)
+ [ plperl](https://www.postgresql.org/docs/current/plperl.html)
+ [ plpgsql](https://www.postgresql.org/docs/current/plpgsql.html)
+ [ pltcl](https://www.postgresql.org/docs/current/pltcl-overview.html)
+ [tablefunc](http://www.postgresql.org/docs/current/tablefunc.html) 
+ [ tsm\$1system\$1rows](https://www.postgresql.org/docs/current/tsm-system-rows.html)
+ [ tsm\$1system\$1time](https://www.postgresql.org/docs/current/tsm-system-time.html)
+ [unaccent ](http://www.postgresql.org/docs/current/unaccent.html)
+ [uuid-ossp](http://www.postgresql.org/docs/current/uuid-ossp.html)

如需有關 Amazon RDS 支援的 PostgreSQL 擴充功能的詳細清單，請參閱 *Amazon RDS for PostgreSQL 版本備註*中的 [Amazon RDS 上支援的 PostgreSQL 擴充功能](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html)。

# 使用 Amazon RDS for PostgreSQL 支援的 PostgreSQL 功能
<a name="PostgreSQL.Concepts.General.FeatureSupport"></a>

Amazon RDS for PostgreSQL 支援許多最常用的 PostgreSQL 功能。例如，PostgreSQL 的自動資料清理功能可對資料庫執行例行維護。根據預設，會使用自動真空功能。雖然您可以關閉此功能，但我們強烈建議保持開啟。了解此功能以及您可以做些什麼來確保它能夠正常工作是任何 DBA 的基本任務。如需有關自動資料清理的詳細資訊，請參閱 [在 Amazon RDS for PostgreSQL 上使用 PostgreSQL 自動清空](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.md)。若要進一步了解其他常見 DBA 任務，請參閱 [Amazon RDS for PostgreSQL 的常用 DBA 任務](Appendix.PostgreSQL.CommonDBATasks.md)。

RDS for PostgreSQL 也支援為資料庫執行個體新增重要功能的擴充功能。例如，您可以使用 PostGIS 擴充功能來處理空間資料，或者使用 pg\$1cron 擴充功能在執行個體內進行維護排程。如需 PostgreSQL 擴充功能的詳細資訊，請參閱 [搭配 Amazon RDS for PostgreSQL 使用 PostgreSQL 擴充功能](Appendix.PostgreSQL.CommonDBATasks.Extensions.md)。

外部資料包裝函式是一種特定類型的擴充功能，旨在讓您的 RDS for PostgreSQL 資料庫執行個體與其他商業資料庫或資料類型搭配使用。如需 RDS PostgreSQL 支援的外部資料包裝函式的詳細資訊，請參閱 [使用 Amazon RDS for PostgreSQL 支援的外部資料包裝函式](Appendix.PostgreSQL.CommonDBATasks.Extensions.foreign-data-wrappers.md)。

在下文中，您可以了解 RDS for PostgreSQL 支援其他功能的資訊。

**Topics**
+ [使用 RDS for PostgreSQL 的自訂資料類型和列舉](PostgreSQL.Concepts.General.FeatureSupport.AlterEnum.md)
+ [RDS for PostgreSQL 適用的事件觸發程序](PostgreSQL.Concepts.General.FeatureSupport.EventTriggers.md)
+ [RDS for PostgreSQL 的巨型分頁](PostgreSQL.Concepts.General.FeatureSupport.HugePages.md)
+ [為 Amazon RDS for PostgreSQL 執行邏輯複寫](PostgreSQL.Concepts.General.FeatureSupport.LogicalReplication.md)
+ [設定邏輯複寫連線的 IAM 身分驗證](PostgreSQL.Concepts.General.FeatureSupport.IAMLogicalReplication.md)
+ [stats\$1temp\$1directory 的 RAM 磁碟](PostgreSQL.Concepts.General.FeatureSupport.RamDisk.md)
+ [RDS for PostgreSQL 的資料表空間](PostgreSQL.Concepts.General.FeatureSupport.Tablespaces.md)
+ [適用於 EBCDIC 和其他大型機遷移的 RDS for PostgreSQL 定序](PostgreSQL.Collations.mainframe.migration.md)
+ [管理 RDS for PostgreSQL 的邏輯槽同步](Appendix.PostgreSQL.CommonDBATasks.pglogical.slot.synchronization.md)

# 使用 RDS for PostgreSQL 的自訂資料類型和列舉
<a name="PostgreSQL.Concepts.General.FeatureSupport.AlterEnum"></a>

PostgreSQL 支援建立自訂資料類型和使用列舉。如需如何建立並使用列舉及其他資料類型的詳細資訊，請參閱 PostgreSQL 文件中的[列舉類型](https://www.postgresql.org/docs/14/datatype-enum.html)。

以下範例示範將類型建立為列舉，然後將值插入到資料表。

```
CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple');
CREATE TYPE
CREATE TABLE t1 (colors rainbow);
CREATE TABLE
INSERT INTO t1 VALUES ('red'), ( 'orange');
INSERT 0 2
SELECT * from t1;
colors
--------
red
orange
(2 rows)
postgres=> ALTER TYPE rainbow RENAME VALUE 'red' TO 'crimson';
ALTER TYPE
postgres=> SELECT * from t1;
colors
---------
crimson
orange
(2 rows)
```

# RDS for PostgreSQL 適用的事件觸發程序
<a name="PostgreSQL.Concepts.General.FeatureSupport.EventTriggers"></a>

所有目前的 PostgreSQL 版本都支援事件觸發程序，所有 RDS for PostgreSQL 版本也支援事件觸發程序。您可以使用主要使用者帳戶 (預設 `postgres`) 來建立、修改、重新命名和刪除事件觸發程序。事件觸發是在資料庫執行個體層級上運作，可套用至執行個體上的所有資料庫。

例如，下列程式碼建立的事件觸發程序會在每個資料定義語言 (DDL) 命令結束時列印目前使用者。

```
CREATE OR REPLACE FUNCTION raise_notice_func()
    RETURNS event_trigger
    LANGUAGE plpgsql AS
$$
BEGIN
    RAISE NOTICE 'In trigger function: %', current_user;
END;
$$;

CREATE EVENT TRIGGER event_trigger_1 
    ON ddl_command_end
EXECUTE PROCEDURE raise_notice_func();
```

如需 PostgreSQL 事件觸發的詳細資訊，請參閱 PostgreSQL 文件中的[事件觸發](https://www.postgresql.org/docs/current/static/event-triggers.html)。

在 Amazon RDS 上使用 PostgreSQL 事件觸發時有幾項限制。這些索引標籤包括以下項目：
+ 您無法在僅供讀取複本上建立事件觸發程序。不過，您可以在僅供讀取複本來源建立事件觸發。然後，事件觸發會複製到僅供讀取複本。從來源推送變更時，僅供讀取複本上的事件觸發不會在僅供讀取複本上發動。不過，如果提升僅供讀取複本，則資料庫操作發生時，現有的事件觸發會啟動。
+ 若要對使用事件觸發程序的 PostgreSQL 資料庫執行個體執行主要版本升級，就必須在升級執行個體之前刪除事件觸發程序。

# RDS for PostgreSQL 的巨型分頁
<a name="PostgreSQL.Concepts.General.FeatureSupport.HugePages"></a>

*巨型分頁*是一項記憶體管理功能，可減少資料庫執行個體處理大型連續記憶體區塊 (如共用緩衝區使用的記憶體區塊) 時的額外負荷。所有目前可用的 RDS for PostgreSQL 版本都支援此 PostgreSQL 功能。您可以呼叫 `mmap` 或 `SYSV` 共用記憶體，以分配巨型分頁給您的應用程式。RDS for PostgreSQL 同時支援 4 KB 和 2 MB 分頁大小。

您可以開啟或關閉巨型分頁功能，方法是變更 `huge_pages` 參數的值。除了微型、小型和中型資料庫執行個體類之外，所有資料庫執行個體類都預設開啟該功能。

RDS for PostgreSQL 會根據可用的共用記憶體使用巨型分頁。如果資料庫執行個體因為共用記憶體限制而無法使用巨型分頁，Amazon RDS 會阻止資料庫執行個體啟動。在此情況下，Amazon RDS 會將資料庫執行個體的狀態設為不相容的參數狀態。如果發生這種情況，您可以將 `huge_pages` 參數設為「`off`」，以允許 Amazon RDS 啟動資料庫執行個體。

`shared_buffers` 參數是為了使用巨型分頁而設定所需之共用記憶體集區的關鍵。`shared_buffers` 參數的預設值會使用資料庫參數巨集。此巨集會設定可用於資料庫執行個體記憶體的總計 8 KB 分頁的百分比。當您使用巨型分頁時，這些頁面會與巨型分頁放在一起。如果共用記憶體參數設為需要 90% 以上的資料庫執行個體記憶體，Amazon RDS 會將資料庫執行個體設為不相容的參數狀態。

若要進一步了解 PostgreSQL 記憶體管理，請參閱 PostgreSQL 說明文件中的[資源耗用](https://www.postgresql.org/docs/current/static/runtime-config-resource.html)。

# 為 Amazon RDS for PostgreSQL 執行邏輯複寫
<a name="PostgreSQL.Concepts.General.FeatureSupport.LogicalReplication"></a>

從 10.4 版開始，RDS for PostgreSQL 支援 PostgreSQL 10 中引進的發佈與訂閱 SQL 語法。如需進一步了解，請參閱 PostgreSQL 文件中的[邏輯複寫](https://www.postgresql.org/docs/current/logical-replication.html)。

**注意**  
除了在 PostgreSQL 10 中引進的原生 PostgreSQL 邏輯複寫功能之外，RDS for PostgreSQL 也支援 `pglogical` 延伸模組。如需詳細資訊，請參閱[使用 pglogical 跨執行個體同步資料](Appendix.PostgreSQL.CommonDBATasks.pglogical.md)。

在下文中，您可以了解如何設定 RDS for PostgreSQL 資料庫執行個體邏輯複寫的資訊。

**Topics**
+ [了解邏輯複寫和邏輯解碼](#PostgreSQL.Concepts.General.FeatureSupport.LogicalDecoding)
+ [使用邏輯複寫槽](#PostgreSQL.Concepts.General.FeatureSupport.LogicalReplicationSlots)
+ [使用邏輯複寫來複寫資料表層級資料](#PostgreSQL.Concepts.LogicalReplication.Tables)

## 了解邏輯複寫和邏輯解碼
<a name="PostgreSQL.Concepts.General.FeatureSupport.LogicalDecoding"></a>

RDS for PostgreSQL 支援使用 PostgreSQL 的邏輯複寫槽來串流預寫日誌 (WAL) 變更。它也支援使用邏輯解碼。您可以在執行個體上設定邏輯複寫槽，然後透過這些槽將資料庫變更串流至用戶端，例如 `pg_recvlogical`。邏輯複寫插槽在資料庫層級建立，且支援對單一資料庫的多個複寫連線。

PostgreSQL 邏輯複寫最常見的用戶端是 AWS Database Migration Service 或 Amazon EC2 執行個體上的自訂受管主機。邏輯複寫插槽沒有關於串流接收者的資訊。此外，不要求目標必須是複本資料庫。如果您設定邏輯複寫槽，但未讀取這個槽，則資料會寫入並快速填滿資料庫執行個體的儲存體。

Amazon RDS 的 PostgreSQL 邏輯複寫與邏輯解碼是以參數、複寫連線類型和安全角色來開啟。任何用戶端只要能夠在 PostgreSQL 資料庫執行個體上的資料庫建立複寫連線，都可以當作邏輯解碼的用戶端。

**開啟 RDS for PostgreSQL 資料庫執行個體的邏輯解碼**

1. 確保您正在使用的使用者帳戶具有以下角色：
   + 可讓您開啟邏輯複寫的 `rds_superuser` 角色 
   + 授權來管理邏輯槽和利用邏輯槽來串流資料的 `rds_replication` 角色

1. 將 `rds.logical_replication` 靜態參數設為 1。套用此參數時，也會設定 `wal_level`、`max_wal_senders`、`max_replication_slots` 和 `max_connections` 參數。這些參數變更會產生更多 WAL，因此請僅在使用邏輯槽時才設定 `rds.logical_replication` 參數。

1. 為了讓靜態 `rds.logical_replication` 參數生效，請重新啟動資料庫執行個體。

1. 建立邏輯複寫槽將在下一章節中說明。此程序要求您指定解碼外掛程式。目前，RDS for PostgreSQL 支援隨附於 PostgreSQL 的 test\$1decoding 和 wal2json 輸出外掛程式。

如需有關 PostgreSQL 邏輯解碼的詳細資訊，請參閱 [PostgreSQL 文件](https://www.postgresql.org/docs/current/static/logicaldecoding-explanation.html)。

## 使用邏輯複寫槽
<a name="PostgreSQL.Concepts.General.FeatureSupport.LogicalReplicationSlots"></a>

您可以利用 SQL 命令來使用邏輯槽。例如，下列命令使用預設 PostgreSQL 輸出外掛程式 `test_slot`，建立一個名為 `test_decoding` 的邏輯槽。

```
SELECT * FROM pg_create_logical_replication_slot('test_slot', 'test_decoding');
slot_name    | xlog_position
-----------------+---------------
regression_slot | 0/16B1970
(1 row)
```

若要列出邏輯槽，請使用下列命令。

```
SELECT * FROM pg_replication_slots;
```

若要捨棄邏輯槽，請使用下列命令。

```
SELECT pg_drop_replication_slot('test_slot');
pg_drop_replication_slot
-----------------------
(1 row)
```

如需有關使用邏輯複寫槽的其他範例，請參閱 PostgreSQL 文件中的[邏輯解碼範例](https://www.postgresql.org/docs/9.5/static/logicaldecoding-example.html)。

建立邏輯複寫槽之後，即可開始串流。下列範例顯示如何透過串流複寫協定來控制邏輯解碼。此範例會使用包含在 PostgreSQL 發行版中的 pg\$1recvlogical 程式。這會需要將用戶端身分驗證設為允許複寫連線。

```
pg_recvlogical -d postgres --slot test_slot -U postgres
    --host -instance-name.111122223333.aws-region.rds.amazonaws.com 
    -f -  --start
```

若要查看檢視 `pg_replication_origin_status` 的內容，請查詢 `pg_show_replication_origin_status` 函式。

```
SELECT * FROM pg_show_replication_origin_status();
local_id | external_id | remote_lsn | local_lsn
----------+-------------+------------+-----------
(0 rows)
```

## 使用邏輯複寫來複寫資料表層級資料
<a name="PostgreSQL.Concepts.LogicalReplication.Tables"></a>

您可以使用邏輯複寫，將資料從來源資料表複寫至 RDS for PostgreSQL 中的目標資料表。邏輯複寫會先從來源資料表執行現有資料的初始載入，然後繼續複寫進行中的變更。

1. 

**建立來源資料表**

   連線至 RDS for PostgreSQL 資料庫執行個體中的來源資料庫：

   ```
   source=> CREATE TABLE testtab (slno int primary key);
   CREATE TABLE
   ```

1. 

**將資料插入來源資料表中**

   ```
   source=> INSERT INTO testtab VALUES (generate_series(1,1000));
   INSERT 0 1000
   ```

1. 

**建立來源資料表的發行集**
   + 建立來源資料表的發行集：

     ```
     source=> CREATE PUBLICATION testpub FOR TABLE testtab;
     CREATE PUBLICATION
     ```
   + 使用 SELECT 查詢來驗證已建立之發行集的詳細資訊：

     ```
     source=> SELECT * FROM pg_publication;
       oid   | pubname | pubowner | puballtables | pubinsert | pubupdate | pubdelete | pubtruncate | pubviaroot
     --------+---------+----------+--------------+-----------+-----------+-----------+-------------+------------
      115069 | testpub |    16395 | f            | t         | t         | t         | t           | f
     (1 row)
     ```
   + 確認來源資料表已新增至發行集：

     ```
     source=> SELECT * FROM pg_publication_tables; 
     pubname | schemaname | tablename
     ---------+------------+-----------
      testpub | public     | testtab
     (1 rows)
     ```
   + 若要複寫資料庫中的所有資料表，請使用：

     ```
     CREATE PUBLICATION testpub FOR ALL TABLES;
     ```
   + 如果已為個別資料表建立發行集，且您需要新增資料表，您可以執行以下查詢，將任何新資料表新增至現有的發行集：

     ```
     ALTER PUBLICATION <publication_name> add table <new_table_name>;
     ```

1. 

**連線至目標資料庫並建立目標資料表**
   + 連線至目標資料庫執行個體中的目標資料庫。使用與來源資料表相同的名稱建立目標資料表：

     ```
     target=> CREATE TABLE testtab (slno int primary key);
     CREATE TABLE
     ```
   + 對目標資料表執行 SELECT 查詢，以確定目標資料表中沒有資料：

     ```
         
     target=> SELECT count(*) FROM testtab;
      count
     -------
          0
     (1 row)
     ```

1. 

**在目標資料庫中建立和驗證訂閱**
   + 在目標資料庫中建立訂閱：

     ```
     target=> CREATE SUBSCRIPTION testsub 
     CONNECTION 'host=<source RDS/host endpoint> port=5432 dbname=<source_db_name> user=<user> password=<password>' 
     PUBLICATION testpub;
     NOTICE:  Created replication slot "testsub" on publisher
     CREATE SUBSCRIPTION
     ```
   + 使用 SELECT 查詢來驗證訂閱已啟用：

     ```
     target=> SELECT oid, subname, subenabled, subslotname, subpublications FROM pg_subscription;
       oid  | subname | subenabled | subslotname | subpublications
     -------+---------+------------+-------------+-----------------
      16434 | testsub | t          | testsub     | {testpub}
     (1 row)
     ```
   + 訂閱建立後，會將來源資料表中的所有資料載入至目標資料表。對目標資料表執行 SELECT 查詢，以確認初始資料載入：

     ```
     target=> SELECT count(*) FROM testtab;
      count
     -------
       1000
     (1 row)
     ```

1. 

**驗證來源資料庫中的複寫插槽**

   在目標資料庫中建立訂閱，將會在來源資料庫中建立複寫插槽。對來源資料庫執行下列 SELECT 查詢，以驗證複寫插槽詳細資訊：

   ```
   source=> SELECT * FROM pg_replication_slots;
    
   slot_name |  plugin  | slot_type | datoid | database | temporary | active | active_pid | xmin | catalog_xmin | restart_lsn | confirmed_flush_lsn | wal_status | safe_wal_size
   ----------+----------+-----------+--------+----------+-----------+--------+------------+------+--------------+-------------+---------------------+------------+---------------
   testsub   | pgoutput | logical   | 115048 | source   | f         | t      |        846 |      |         6945 | 58/B4000568 | 58/B40005A0         | reserved   |
   (1 row)
   ```

1. 

**測試複寫**
   + 將資料列插入來源資料表中，藉以測試來源資料表中的資料變更是否複寫至目標資料表：

     ```
     source=> INSERT INTO testtab VALUES(generate_series(1001,2000));
     INSERT 0 1000
     
     source=> SELECT count(*) FROM testtab; 
      count
     -------
       2000
     (1 row)
     ```
   + 驗證目標資料表中的資料列數，以確認正在複寫新的插入項目：

     ```
     target=> SELECT count(*) FROM testtab;
      count
     -------
       2000
     (1 row)
     ```

1. 

**在新增資料表後重新整理訂閱**
   + 當您將新資料表新增至現有發行集時，必須重新整理訂閱，變更才會生效：

     ```
     ALTER SUBSCRIPTION <subscription_name> REFRESH PUBLICATION;
     ```
   + 此命令會從發佈者擷取缺少的資料表資訊，並開始複寫自訂閱建立或上次重新整理以來新增至訂閱發行集的資料表。

# 設定邏輯複寫連線的 IAM 身分驗證
<a name="PostgreSQL.Concepts.General.FeatureSupport.IAMLogicalReplication"></a>

從 RDS for PostgreSQL 第 11 版及更新版本開始，您可以使用 AWS Identity and Access Management (IAM) 身分驗證進行複寫連線。此功能可讓您使用 IAM 角色而非密碼來管理資料庫存取，以增強安全性。它適用於叢集和執行個體精細程度，並遵循與標準 IAM 身分驗證相同的安全模型。

複寫連線的 IAM 身分驗證是一項選擇加入功能。若要啟用它，請在資料庫叢集或資料庫`rds.iam_auth_for_replication`參數群組中將 參數設定為 1。由於這是動態參數，因此您的資料庫叢集或執行個體不需要重新啟動，可讓您利用 IAM 身分驗證與現有的工作負載，而無須停機。啟用此功能之前，您必須符合下列先決條件。

**Topics**
+ [先決條件](#PostgreSQL.Concepts.General.FeatureSupport.IAMLogicalReplication.Prerequisites)
+ [啟用複寫連線的 IAM 身分驗證](#PostgreSQL.Concepts.General.FeatureSupport.IAMLogicalReplication.Enabling)
+ [停用複寫連線的 IAM 身分驗證](#PostgreSQL.Concepts.General.FeatureSupport.IAMLogicalReplication.Disabling)
+ [限制及考量](#PostgreSQL.Concepts.General.FeatureSupport.IAMLogicalReplication.Limitations)

## 先決條件
<a name="PostgreSQL.Concepts.General.FeatureSupport.IAMLogicalReplication.Prerequisites"></a>

若要針對複寫連線使用 IAM 身分驗證，您需要符合下列所有要求：
+ 您的 RDS for PostgreSQL 資料庫執行個體必須是 11 版或更新版本。
+ 在您的發佈者 RDS for PostgreSQL 資料庫執行個體上：
  + 啟用 IAM 資料庫身分驗證。如需詳細資訊，請參閱[啟用和停用 IAM 資料庫身分驗證](UsingWithRDS.IAMDBAuth.Enabling.md)。
  + 將 `rds.logical_replication` 參數設定為 1 以啟用邏輯複寫。

在邏輯複寫中，發佈者是將資料傳送至訂閱者資料庫的來源 RDS for PostgreSQL 資料庫。如需詳細資訊，請參閱[為 Amazon RDS for PostgreSQL 執行邏輯複寫](PostgreSQL.Concepts.General.FeatureSupport.LogicalReplication.md)。

**注意**  
必須在發佈者 RDS for PostgreSQL 資料庫執行個體上啟用 IAM 身分驗證和邏輯複寫。如果其中一個未啟用，則您無法針對複寫連線使用 IAM 身分驗證。

## 啟用複寫連線的 IAM 身分驗證
<a name="PostgreSQL.Concepts.General.FeatureSupport.IAMLogicalReplication.Enabling"></a>

完成下列步驟，以啟用複寫連線的 IAM 身分驗證。

**啟用複寫連線的 IAM 身分驗證**

1. 確認您的 RDS for PostgreSQL 資料庫叢集或執行個體符合具有複寫連線的 IAM 身分驗證的所有先決條件。如需詳細資訊，請參閱[先決條件](#PostgreSQL.Concepts.General.FeatureSupport.IAMLogicalReplication.Prerequisites)。

1. 根據您的 RDS for PostgreSQL 設定來設定 `rds.iam_auth_for_replication` 參數：
   + 對於 RDS for PostgreSQL 資料庫執行個體：修改資料庫參數群組。
   + 對於多可用區域叢集：修改資料庫叢集參數群組。

   `rds.iam_auth_for_replication` 設定為 1。這是一個動態參數，無需重新開機即可立即生效。
**注意**  
多可用區域叢集僅使用資料庫叢集參數群組。無法在多可用區域叢集中修改個別執行個體參數群組。

1. 連線至您的資料庫，並將必要的角色授予您的複寫使用者：

   下列 SQL 命令會授予必要角色，以啟用複寫連線的 IAM 身分驗證：

   ```
   -- Grant IAM authentication role
   GRANT rds_iam TO replication_user_name;
   
   -- Grant replication privileges
   ALTER USER replication_user_name WITH REPLICATION;
   ```

   完成這些步驟後，指定的使用者必須使用 IAM 身分驗證進行複寫連線。
**重要**  
當您啟用此功能時，具有 `rds_iam`和 `rds_replication`角色的使用者必須使用 IAM 身分驗證進行複寫連線。無論角色是直接指派給使用者或透過其他角色繼承，這都會套用。

## 停用複寫連線的 IAM 身分驗證
<a name="PostgreSQL.Concepts.General.FeatureSupport.IAMLogicalReplication.Disabling"></a>

您可以使用下列任一方法停用複寫連線的 IAM 身分驗證：
+ 將資料庫執行個體的資料庫參數群組或多可用區域叢集的資料庫叢集參數群組中的 `rds.iam_auth_for_replication` 參數設定為 0。
+ 或者，您可以在 RDS for PostgreSQL 資料庫叢集或執行個體上停用下列其中一項功能：
  + 將 `rds.logical_replication` 參數設定為 0 以停用邏輯複寫
  + 停用 IAM 身分驗證

當您停用此功能時，複寫連線可以使用資料庫密碼進行身分驗證。

**注意**  
即使啟用 功能，沒有 `rds_iam`角色的使用者複寫連線也可以使用密碼身分驗證。

## 限制及考量
<a name="PostgreSQL.Concepts.General.FeatureSupport.IAMLogicalReplication.Limitations"></a>

針對邏輯複寫連線使用 IAM 身分驗證時，請考慮下列限制和考量事項：
+ 此功能僅適用於 RDS for PostgreSQL 第 11 版及更新版本。
+ 發佈者必須支援複寫連線的 IAM 身分驗證。
+ IAM 身分驗證字符預設會在 15 分鐘後過期。您可能需要在字符過期之前重新整理長時間執行的複寫連線。

# stats\$1temp\$1directory 的 RAM 磁碟
<a name="PostgreSQL.Concepts.General.FeatureSupport.RamDisk"></a>

您可以使用 RDS for PostgreSQL 參數 `rds.pg_stat_ramdisk_size` 指定組態給 RAM 磁碟的系統記憶體，以存放 PostgreSQL `stats_temp_directory`。RAM 磁碟參數僅適用於 RDS for PostgreSQL 第 14 版和較低版本。

在某些工作負載下，設定此參數可以提高效能和降低輸入/輸出需求。如需 `stats_temp_directory` 的詳細資訊，請參閱 [PostgreSQL 文件](https://www.postgresql.org/docs/current/static/runtime-config-statistics.html#GUC-STATS-TEMP-DIRECTORY)。

如要設定 `stats_temp_directory` 的 RAM 磁碟，請於資料庫執行個體所使用的參數群組中，將 `rds.pg_stat_ramdisk_size` 參數設為整數常值。此參數表示 MB，因此您必須使用整數值。表達式、公式和函數對 `rds.pg_stat_ramdisk_size` 參數無效。請務必重新啟動資料庫執行個體，變更才會生效。如需有關設定參數的詳細資訊，請參閱 [Amazon RDS 的參數群組](USER_WorkingWithParamGroups.md)。

例如，下列 AWS CLI 命令會將 RAM 磁碟參數設定為 256 MB。

```
aws rds modify-db-parameter-group \
    --db-parameter-group-name pg-95-ramdisk-testing \
    --parameters "ParameterName=rds.pg_stat_ramdisk_size, ParameterValue=256, ApplyMethod=pending-reboot"
```

重新啟動之後，執行以下命令來查看 `stats_temp_directory` 的狀態。

```
postgres=> SHOW stats_temp_directory;
```

 此命令應該會傳回下列結果。

```
stats_temp_directory
---------------------------
/rdsdbramdisk/pg_stat_tmp
(1 row)
```

# RDS for PostgreSQL 的資料表空間
<a name="PostgreSQL.Concepts.General.FeatureSupport.Tablespaces"></a>

RDS for PostgreSQL 支援資料表空間以實現相容性。因為所有儲存區都位於單一邏輯磁碟區上，所以您無法使用資料表空間進行輸入/輸出分割或隔離。我們的基準和經驗指出，單一邏輯磁碟區是多數使用案例的最佳設定。

若要建立資料表空間並搭配 RDS for PostgreSQL 資料庫執行個體一起使用，需要 `rds_superuser` 角色。RDS for PostgreSQL 資料庫執行個體的主使用者帳戶 (預設名稱 `postgres`) 是此角色的成員。如需詳細資訊，請參閱[了解 PostgreSQL 角色和許可](Appendix.PostgreSQL.CommonDBATasks.Roles.md)。

如果您在建立資料表空間時指定檔案名稱，路徑前綴為 `/rdsdbdata/db/base/tablespace`。以下範例會將資料表空間檔案置於 `/rdsdbdata/db/base/tablespace/data` 中。此範例假設 `dbadmin` 使用者 (角色) 存在，且已獲派處理資料表空間所需的 `rds_superuser` 角色。

```
postgres=> CREATE TABLESPACE act_data
  OWNER dbadmin
  LOCATION '/data';
CREATE TABLESPACE
```

若要進一步了解 PostgreSQL 資料表空間，請參閱 PostgreSQL 說明文件中的[資料表空間](https://www.postgresql.org/docs/current/manage-ag-tablespaces.html)。

# 適用於 EBCDIC 和其他大型機遷移的 RDS for PostgreSQL 定序
<a name="PostgreSQL.Collations.mainframe.migration"></a>

RDS for PostgreSQL 10 版及更高版本包括基於 Unicode 10.0 的 ICU 版本 60.2，其中包含來自 Unicode 通用語言環境資料儲存庫 (CLDR 32) 的定序。這些軟體國際化程式庫可確保字元編碼以一致的方式呈現，不論作業系統或平台為何。如需 Unicode CLDR-32 的詳細資訊，請參閱 Unicode CLDR 網站上的 [CLDR 32 版本備註](https://cldr.unicode.org/index/downloads/cldr-32)。您可以在 [ICU Technical Committee (ICU-TC)](https://icu.unicode.org/home) 網站了解有關 Unicode (ICU) 的國際化元件的更多資訊。如需有關 ICU-60 的資訊，請參閱[下載 ICU 60](https://icu.unicode.org/download/60)。

從 14.3 版開始，RDS for PostgreSQL 也包含有助於從 EBCDC 系統進行資料整合和轉換的定序。擴展的二進制編碼十進制交換碼或 *EBCDIC* 編碼通常由大型機作業系統使用。這些 Amazon RDS 提供的定序定義很小，只能夠直接對應至 EBCDIC 字碼頁的 Unicode 字元。這些字元按 EBCDIC 代碼點順序進行排序，以便在轉換後進行資料驗證。這些定序不包含部正常的格式，也不包含未直接對應至來源 EBCDIC 字碼頁的 Unicode 字元。

EBCDIC 字碼頁與 Unicode 字碼點之間的字元對應是以 IBM 發佈的表格為基礎。完整的設定可從 IBM 的[壓縮檔案](http://download.boulder.ibm.com/ibmdl/pub/software/dw/java/cdctables.zip)下載。RDS for PostgreSQL 會將這些對應與 ICU 提供的工具搭配使用，以建立本節中表格中列出的定序。定序名稱包括 ICU 要求的語言和國家/地區。但是，EBCDIC 字碼頁不會指定語言，有些 EBCDIC 字碼頁涵蓋多個國家/地區。這表示資料表中定序名稱的語言和國家/地區部分是任意的，而且不需要與目前的地區設定相符。換句話說，字碼頁編號是此表格中定序名稱最重要的部分。您可以在任何 RDS for PostgreSQL 資料庫中使用下列表格中列出的任何定序。
+ [Unicode to EBCDIC collations table](#ebcdic-table) - 部分大型主機資料移轉工具在內部使用 LATIN1 或 LATIN9 來編碼及處理資料。這類工具使用往返結構描述來保留資料完整性並支援反向轉換。此資料表中的定序可以由使用 LATIN1 編碼來處理資料的工具使用，這不需要特殊處理。
+ [Unicode to LATIN9 collations table](#latin9-table) - 您可以在任何 RDS for PostgreSQL 資料庫中使用這些定序。

 

在下表中，您會發現 RDS 版 PostgreSQL 中可用的定序，這些定序會將 EBCDIC 字碼頁對應至 Unicode 字碼點。我們建議您使用此表格中的定序來進行應用程式開發，這些應用程式開發需要根據 IBM 字碼頁的順序進行排序。<a name="ebcdic-table"></a>


| PostgreSQL 定序名稱 | 字碼頁對應和排序順序的說明 | 
| --- | --- | 
| da-DK-cp277-x-icu | Unicode 字元直接對應至 IBM EBCDIC 字碼頁 277 (每個轉換表) 按照 IMB CP 277 字碼點順序排序 | 
| de-DE-cp273-x-icu | Unicode 字元直接對應至 IBM EBCDIC 字碼頁 273 (每個轉換表) 按照 IMB CP 273 字碼點順序排序 | 
| en-GB-cp285-x-icu | Unicode 字元直接對應至 IBM EBCDIC 字碼頁 285 (每個轉換表) 按照 IMB CP 285 字碼點順序排序 | 
| en-US-cp037-x-icu | Unicode 字元直接對應至 IBM EBCDIC 字碼頁 037 (每個轉換表) 按照 IMB CP 37 字碼點順序排序 | 
| es-ES-cp284-x-icu | Unicode 字元直接對應至 IBM EBCDIC 字碼頁 284 (每個轉換表) 按照 IMB CP 284 字碼點順序排序 | 
| fi-FI-cp278-x-icu | Unicode 字元直接對應至 IBM EBCDIC 字碼頁 278 (每個轉換表) 按照 IMB CP 278 字碼點順序排序 | 
| fr-FR-cp297-x-icu | Unicode 字元直接對應至 IBM EBCDIC 字碼頁 297 (每個轉換表) 按照 IMB CP 297 字碼點順序排序 | 
| it-IT-cp280-x-icu | Unicode 字元直接對應至 IBM EBCDIC 字碼頁 280 (每個轉換表) 按照 IMB CP 280 字碼點順序排序 | 
| nl-BE-cp500-x-icu | Unicode 字元直接對應至 IBM EBCDIC 字碼頁 500 (每個轉換表) 按照 IMB CP 500 字碼點順序排序 | 

Amazon RDS 提供一組額外的定序，可根據來源資料的 EBCDIC 字碼頁，使用 IBM 發佈的表格，依原始程式碼點的順序，對應至 LATIN9 字元的 Unicode 程式碼點進行排序。<a name="latin9-table"></a>


| PostgreSQL 定序名稱 | 字碼頁對應排序順序的說明 | 
| --- | --- | 
| da-DK-cp1142m-x-icu | Unicode 字元對應至 LATIN9 字元，原始轉換自 IBM EBCDIC 字碼頁 1142 (每個轉換表) 按照 IMB CP 1142 字碼點順序排序 | 
| de-DE-cp1141m-x-icu | Unicode 字元對應至 LATIN9 字元，原始轉換自 IBM EBCDIC 字碼頁 1141 (每個轉換表) 按照 IMB CP 1141 字碼點順序排序 | 
| en-GB-cp1146m-x-icu | Unicode 字元對應至 LATIN9 字元，原始轉換自 IBM EBCDIC 字碼頁 1146 (每個轉換表) 按照 IMB CP 1146 字碼點順序排序 | 
| en-US-cp1140m-x-icu | Unicode 字元對應至 LATIN9 字元，原始轉換自 IBM EBCDIC 字碼頁 1140 (每個轉換表) 按照 IMB CP 1140 字碼點順序排序 | 
| es-ES-cp1145m-x-icu | Unicode 字元對應至 LATIN9 字元，原始轉換自 IBM EBCDIC 字碼頁 1145 (每個轉換表) 按照 IMB CP 1145 字碼點順序排序 | 
| fi-FI-cp1143m-x-icu | Unicode 字元對應至 LATIN9 字元，原始轉換自 IBM EBCDIC 字碼頁 1143 (每個轉換表) 按照 IMB CP 1143 字碼點順序排序 | 
| fr-FR-cp1147m-x-icu | Unicode 字元對應至 LATIN9 字元，原始轉換自 IBM EBCDIC 字碼頁 1147 (每個轉換表) 按照 IMB CP 1147 字碼點順序排序 | 
| it-IT-cp1144m-x-icu | Unicode 字元對應至 LATIN9 字元，原始轉換自 IBM EBCDIC 字碼頁 1144 (每個轉換表) 按照 IMB CP 1144 字碼點順序排序 | 
| nl-BE-cp1148m-x-icu | Unicode 字元對應至 LATIN9 字元，原始轉換自 IBM EBCDIC 字碼頁 1148 (每個轉換表) 按照 IMB CP 1148 字碼點順序排序 | 

在下列各項中，您可以找到使用 RDS for PostgreSQL 定序的範例。

```
db1=> SELECT pg_import_system_collations('pg_catalog');
 pg_import_system_collations
-----------------------------
                          36
db1=> SELECT '¤' < 'a' col1;
 col1
------
 t  
db1=> SELECT '¤' < 'a' COLLATE "da-DK-cp277-x-icu" col1;
 col1
------
 f
```

我們建議您使用 [Unicode to EBCDIC collations table](#ebcdic-table) 中的定序並在 [Unicode to LATIN9 collations table](#latin9-table) 中用於需要根據 IBM 字碼頁排序進行排序的應用程式開發。下列定序 （尾碼為字母「b」) 也可見於 `pg_collation`，但適用於大型主機資料整合和遷移工具 AWS ，其對應具有特定程式碼點位移的程式碼頁面，且需要特殊的定序處理。換言之，不建議使用下列定序。
+ da-DK-277b-x-icu
+ da-DK-1142b-x-icu
+ de-DE-cp273b-x-icu
+ de-DE-cp1141b-x-icu
+ en-GB-cp1146b-x-icu
+ en-GB-cp285b-x-icu
+ en-US-cp037b-x-icu
+ en-US-cp1140b-x-icu
+ es-ES-cp1145b-x-icu
+ es-ES-cp284b-x-icu
+ fi-FI-cp1143b-x-icu
+ fr-FR-cp1147b-x-icu
+ fr-FR-cp297b-x-icu
+ it-IT-cp1144b-x-icu
+ it-IT-cp280b-x-icu
+ nl-BE-cp1148b-x-icu
+ nl-BE-cp500b-x-icu

若要進一步了解如何將應用程式從大型主機環境遷移至 AWS，請參閱[什麼是 AWS 大型主機現代化？](https://docs.aws.amazon.com/m2/latest/userguide/what-is-m2.html)。

若要進一步了解管理 PostgreSQL 中的定序，請參閱 PostgreSQL 文件中的[定序支援](https://www.postgresql.org/docs/current/collation.html)。

# 管理 RDS for PostgreSQL 的邏輯槽同步
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.slot.synchronization"></a>

從社群 PostgreSQL 17 開始，已透過參數 `sync_replication_slots` 或相關函數 `pg_sync_replication_slots()` 引入自動將邏輯複寫槽從主要伺服器同步至待命伺服器的新功能，其會在執行時手動同步槽。

從 RDS for PostgreSQL 17 開始提供這些功能。典型的設定將具有主要執行個體及其[僅供讀取複本](USER_PostgreSQL.Replication.ReadReplicas.md)，以及主要執行個體的邏輯複寫訂閱者。

確保已建立訂閱，並將容錯移轉選項設定為 true：

```
CREATE SUBSCRIPTION subname CONNECTION 'host=...' PUBLICATION pubname WITH (failover = true);
```

這會在已啟用容錯移轉的發佈者上建立邏輯槽。

```
postgres=> SELECT slot_name, slot_type, failover FROM pg_catalog.pg_replication_slots;
 slot_name | slot_type | failover 
-----------+-----------+----------
 subname   | logical   | t
(1 row)
```

透過啟用槽同步，主要執行個體上的所有容錯移轉邏輯複寫槽都會在實體待命上自動建立，並定期同步。確定已透過[參數群組](USER_WorkingWithParamGroups.Associating.md)設定下列值：
+ `rds.logical_replication` 必須是 `1` 以啟用邏輯複寫
+ `hot_standby_feedback` 必須 `1` 以處於待命狀態
+ 待命上的 `rds.logical_slot_sync_dbname` 必須設定為有效的資料庫名稱

  參數的預設值為 `postgres`。如果邏輯發佈執行個體具有 `postgres` 資料庫，則不需要變更預設參數。
+ 主要執行個體上的 `synchronized_standby_slots` 必須設定為待命的實體複寫槽，以處於同步狀態
+ `sync_replication_slots` 必須是 `1` 以啟用自動同步

透過已啟用容錯移轉的訂閱槽和上述參數值，當待命提升時，訂閱者可以變更對此新提升執行個體的訂閱，並無縫地繼續邏輯複寫。

# 連線至執行 PostgreSQL 資料庫引擎的資料庫執行個體
<a name="USER_ConnectToPostgreSQLInstance"></a>

在 Amazon RDS 佈建資料庫執行個體之後，您就可以使用任何標準 SQL 用戶端應用程式來連線至執行個體。連線到資料庫執行個體之前，資料庫執行個體必須可用且可存取。您是否可以從 VPC 外部連線到執行個體，取決於您建立 Amazon RDS 資料庫執行個體的方式：
+ 如果您將資料庫執行個體建立為*公有*，VPC 外部的裝置和 Amazon EC2 執行個體都可以連線到您的資料庫。
+ 如果您將資料庫執行個體建立為*私有*，只有 Amazon EC2 執行個體和 Amazon VPC 內的裝置可以連線到您的資料庫。

若要檢查您的資料庫執行個體是公有還是私有，請使用 檢視執行個體的 AWS 管理主控台 **連線與安全**索引標籤。在 **Security** (安全性) 底下會顯示 "Publicly accessible" (可公開存取)值，其中為 No (否) 表示私有，Yes (是) 表示公有。

若要進一步了解不同的 Amazon RDS 和 Amazon VPC 組態，以及這些組態如何影響可存取性，請參閱 [在 VPC 中存取資料庫執行個體的案例](USER_VPC.Scenarios.md)。

**Contents**
+ [安裝 psql 用戶端](#install-psql)
+ [尋找 RDS for PostgreSQL 資料庫執行個體的連線資訊](#postgresql-endpoint)
+ [使用 pgAdmin 連線至 RDS for PostgreSQL 資料庫執行個體](USER_ConnectToPostgreSQLInstance.pgAdmin.md)
+ [使用 psql 連線至 RDS for PostgreSQL 資料庫執行個體](USER_ConnectToPostgreSQLInstance.psql.md)
+ [使用 Amazon Web Services (AWS) JDBC 驅動程式連線至 RDS for PostgreSQL](PostgreSQL.Connecting.JDBCDriver.md)
+ [使用 Amazon Web Services (AWS) Python 驅動程式連線至 RDS for PostgreSQL](PostgreSQL.Connecting.PythonDriver.md)
+ [針對您的 RDS for PostgreSQL 執行個體連線進行疑難排解](USER_ConnectToPostgreSQLInstance.Troubleshooting.md)
  + [錯誤 – 嚴重：資料庫*名稱*不存在](USER_ConnectToPostgreSQLInstance.Troubleshooting.md#USER_ConnectToPostgreSQLInstance.Troubleshooting-DBname)
  + [錯誤 – 無法連線至伺服器：連線逾時](USER_ConnectToPostgreSQLInstance.Troubleshooting.md#USER_ConnectToPostgreSQLInstance.Troubleshooting-timeout)
  + [安全性群組存取規則發生錯誤](USER_ConnectToPostgreSQLInstance.Troubleshooting.md#USER_ConnectToPostgreSQLInstance.Troubleshooting-AccessRules)

## 安裝 psql 用戶端
<a name="install-psql"></a>

若要從 EC2 執行個體連線到資料庫執行個體，您可以在 EC2 執行個體上安裝 PostgreSQL 用戶端。若要在 Amazon Linux 2023 上安裝最新版本的 psql 用戶端，請執行下列命令：

```
sudo dnf install postgresql<version number>
```

若要在 Amazon Linux 2 上安裝最新版本的 psql 用戶端，請執行下列命令：

```
sudo yum install -y postgresql
```

若要在 Ubuntu 上安裝最新版本的 psql 用戶端，請執行下列命令：

```
sudo apt install -y postgresql-client
```

## 尋找 RDS for PostgreSQL 資料庫執行個體的連線資訊
<a name="postgresql-endpoint"></a>

如果資料庫執行個體可用且可存取，您可以透過提供下列資訊給 SQL 用戶端應用程式來連線：
+ 資料庫執行個體端點，做為執行個體的主機名稱 (DNS 名稱)。
+ 資料庫執行個體接聽所在的連接埠。PostgreSQL 的預設連接埠為 5432。
+ 資料庫執行個體的使用者名稱和密碼。PostgreSQL 的預設「主要使用者名稱」是 `postgres`。
+ 資料庫的名稱和密碼 (資料庫名稱)。

 您可以使用 AWS 管理主控台、 AWS CLI [describe-db-instances](https://docs.aws.amazon.com/cli/latest/reference/rds/describe-db-instances.html) 命令或 Amazon RDS API [DescribeDBInstances](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_DescribeDBInstances.html) 操作來取得這些詳細資訊。

**使用 尋找端點、連接埠號碼和資料庫名稱 AWS 管理主控台**

1. 登入 AWS 管理主控台 ，並在 [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/)：// 開啟 Amazon RDS 主控台。

1. 開啟 RDS 主控台，然後選擇 **Databases** (資料庫)，以顯示資料庫執行個體清單。

1. 選擇 PostgreSQL 資料庫執行個體名稱以顯示其詳細資訊。

1. 在 **Connectivity & security (連線能力和安全性)** 索引標籤上，複製該端點。另外，請記下連接埠號碼。您需要同時有端點和連接埠號碼，才能連線至資料庫執行個體。  
![\[從 RDS 主控台取得端點\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/images/PostgreSQL-endpoint.png)

1. 在 **Configuration (組態)** 索引標籤上，記下資料庫名稱。如果您在建立 RDS for PostgreSQL 執行個體時建立資料庫，您會看到名稱列在資料庫名稱底下。如果您沒有建立資料庫，資料庫名稱會顯示破折號 (‐)。  
![\[從 RDS 主控台取得資料庫名稱\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/images/PostgreSQL-db-name.png)

以下是連線至 PostgreSQL 資料庫執行個體的兩個方式。第一個範例使用 pgAdmin，這是常見的 PostgreSQL 開放式原始碼管理和開發工具。第二個範例使用 psql，這是屬於 PostgreSQL 安裝一部分的命令列公用程式。

# 使用 pgAdmin 連線至 RDS for PostgreSQL 資料庫執行個體
<a name="USER_ConnectToPostgreSQLInstance.pgAdmin"></a>

您可以使用開放原始碼工具 pgAdmin 來連線至 RDS for PostgreSQL 資料庫執行個體。您可以從 [http://www.pgadmin.org/](http://www.pgadmin.org/) 下載及安裝 pgAdmin，不需要在您的用戶端電腦上有 PostgreSQL 的本機執行個體。

**若要使用 pgAdmin 連線至 RDS for PostgreSQL 資料庫執行個體**

1. 在您的用戶端電腦上啟動 pgAdmin 應用程式。

1. 在 **Dashboard (儀表板)** 標籤上，選擇 **Add New Server (新增伺服器)**。

1. 在 **Create - Server (建立 - 伺服器)** 對話方塊中，於 **General (一般)** 標籤上輸入名稱，以識別 pgAdmin 中的伺服器。

1. 在 **Connection (連線)** 標籤上，輸入來自資料庫執行個體的下列資訊：
   + 針對 **Host (主機)**，輸入端點，例如 `mypostgresql.c6c8dntfzzhgv0.us-east-2.rds.amazonaws.com`。
   + 針對 **Port (連接埠)**，輸入指派的連接埠。
   + 針對 **Username (使用者名稱)**，輸入您在建立資料庫執行個體時輸入的使用者名稱 (如果從預設值 `postgres` 變更「主要使用者名稱」)。
   + 針對 **Password (密碼)**，輸入建立資料庫執行個體時所輸入的密碼。  
![\[輸入您在建立資料庫執行個體時輸入的密碼\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/images/Postgres-Connect01.png)

1. 選擇**儲存**。

   如果有連線問題，請參閱 [針對您的 RDS for PostgreSQL 執行個體連線進行疑難排解](USER_ConnectToPostgreSQLInstance.Troubleshooting.md)。

1. 若要在 pgAdmin 瀏覽器中存取資料庫，請展開 **Servers** (伺服器)、資料庫執行個體，和 **Databases** (資料庫)。選擇資料庫執行個體的資料庫名稱。  
![\[在 pgAdmin 瀏覽器中選擇資料庫執行個體的資料庫名稱\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/images/Postgres-Connect02.png)

1. 若要開啟您可以在其中輸入 SQL 命令的面板，請選擇 **Tools (工具)** 然後選擇 **Query Tool (查詢工具)**。

# 使用 psql 連線至 RDS for PostgreSQL 資料庫執行個體
<a name="USER_ConnectToPostgreSQLInstance.psql"></a>

您可以使用 psql 命令列公用程式的本機執行個體來連線至 RDS for PostgreSQL 資料庫執行個體。您需要在用戶端電腦上安裝 PostgreSQL 或 psql 用戶端。

您可以從 [PostgreSQL](https://www.postgresql.org/download/) 網站下載 PostgreSQL 用戶端。請遵循適用於您作業系統版本的指示，以安裝 psql。

若要使用 psql 連線至 RDS for PostgreSQL 資料庫執行個體，您必須提供主機 (DNS) 資訊、存取憑證和資料庫的名稱。

請使用下列其中一個格式來連線至 RDS for PostgreSQL 資料庫執行個體。連線時，系統會提示您輸入密碼。如需批次工作或指令碼，請使用 `--no-password` 選項。此選項是為整個工作階段設定。

**注意**  
當伺服器需要密碼驗證，且無法從其他來源取得密碼時，使用 `--no-password` 的連線嘗試會失敗。如需詳細資訊，請參閱 [psql 文件](https://www.postgresql.org/docs/13/app-psql.html)。

如果這是您第一次連線至此資料庫執行個體，或者尚未針對此 RDS for PostgreSQL 執行個體建立資料庫，則可以使用「主要使用者名稱」和密碼連線至 **postgres** 資料庫。

針對 Unix，使用下列格式。

```
psql \
   --host=<DB instance endpoint> \
   --port=<port> \
   --username=<master username> \
   --password \
   --dbname=<database name>
```

針對 Windows，使用下列格式。

```
psql ^
   --host=<DB instance endpoint> ^
   --port=<port> ^
   --username=<master username> ^
   --password ^
   --dbname=<database name>
```

例如，下列命令會在名為 `mypgdb` 的 PostgreSQL 資料庫執行個體上使用虛擬登入資料連線至名為 `mypostgresql` 的資料庫。

```
psql --host=mypostgresql.c6c8mwvfdgv0.us-west-2.rds.amazonaws.com --port=5432 --username=awsuser --password --dbname=mypgdb 
```

# 使用 Amazon Web Services (AWS) JDBC 驅動程式連線至 RDS for PostgreSQL
<a name="PostgreSQL.Connecting.JDBCDriver"></a>

Amazon Web Services (AWS) JDBC 驅動程式設計為進階 JDBC 包裝函式。此包裝函式是現有 JDBC 驅動程式的補充和延伸功能。驅動程式與社群 pgJDBC 驅動程式相容。

若要安裝 AWS JDBC 驅動程式，請附加 AWS JDBC 驅動程式 .jar 檔案 （位於應用程式 `CLASSPATH`)，並保留對個別社群驅動程式的參考。更新個別的連線 URL 字首，如下所示：
+ `jdbc:postgresql://` 至 `jdbc:aws-wrapper:postgresql://`

如需 AWS JDBC 驅動程式的詳細資訊和完整的使用說明，請參閱 [Amazon Web Services (AWS) JDBC 驅動程式 GitHub 儲存庫](https://github.com/awslabs/aws-advanced-jdbc-wrapper)。

# 使用 Amazon Web Services (AWS) Python 驅動程式連線至 RDS for PostgreSQL
<a name="PostgreSQL.Connecting.PythonDriver"></a>

Amazon Web Services (AWS) Python 驅動程式設計為進階 Python 包裝函式。此包裝函式是開放原始碼 Psycopg 驅動程式的補充和延伸功能。 AWS Python 驅動程式支援 Python 3.8 版和更高版本。您可以使用 `pip` 命令以及`psycopg`開放原始碼`aws-advanced-python-wrapper`套件來安裝套件。

如需 AWS Python 驅動程式的詳細資訊和完整的使用說明，請參閱 [Amazon Web Services (AWS) Python Driver GitHub 儲存庫](https://github.com/awslabs/aws-advanced-python-wrapper)。

# 針對您的 RDS for PostgreSQL 執行個體連線進行疑難排解
<a name="USER_ConnectToPostgreSQLInstance.Troubleshooting"></a>

**Topics**
+ [錯誤 – 嚴重：資料庫*名稱*不存在](#USER_ConnectToPostgreSQLInstance.Troubleshooting-DBname)
+ [錯誤 – 無法連線至伺服器：連線逾時](#USER_ConnectToPostgreSQLInstance.Troubleshooting-timeout)
+ [安全性群組存取規則發生錯誤](#USER_ConnectToPostgreSQLInstance.Troubleshooting-AccessRules)

## 錯誤 – 嚴重：資料庫*名稱*不存在
<a name="USER_ConnectToPostgreSQLInstance.Troubleshooting-DBname"></a>

如果您在連線時收到類似 `FATAL: database name does not exist` 的鐠誤，請在 `--dbname` 選項中嘗試使用預設資料庫名稱 **postgres**。

## 錯誤 – 無法連線至伺服器：連線逾時
<a name="USER_ConnectToPostgreSQLInstance.Troubleshooting-timeout"></a>

如果您無法連線至資料庫執行個體，常見的錯誤是 `Could not connect to server: Connection timed out.`，如果遇到此錯誤，請檢查以下事項：
+ 檢查使用的主機名稱是否是資料庫執行個體端點，且使用的連接埠號碼是否正確。
+ 確定該資料庫執行個體的公開存取性是設為 **Yes (是)** 以允許外部連線。若要修改 **Public access (公開存取)** 設定，請參閱 [修改 Amazon RDS 資料庫執行個體](Overview.DBInstance.Modifying.md)。
+ 確定連線到資料庫的使用者對它具有 CONNECT 存取權。您可以使用下列查詢來提供資料庫的連線存取權。

  ```
  GRANT CONNECT ON DATABASE database name TO username;
  ```
+ 檢查指派給資料庫執行個體的安全群組是否具有以下規則：允許透過您的連線可能行經之防火牆的存取。例如，資料庫執行個體是使用預設連接埠 5432 來建立，而公司的防火牆規則會封鎖從外部公司裝置到該連接埠的連線。

  若要修復此情況，請將資料庫執行個體修改為使用不同的連接埠。同時，確定套用至資料庫執行個體的安全群組，可允許對該新連接埠的連線。若要修改 **Database port (資料庫連接埠)** 設定，請參閱 [修改 Amazon RDS 資料庫執行個體](Overview.DBInstance.Modifying.md)。
+ 檢查您嘗試使用的連接埠是否已由 PostgreSQL 的本機執行個體或在您電腦上執行的其他服務佔用。例如，如果您在相同的連接埠 (預設為 5432) 上執行本機 PostgreSQL 資料庫，則可能無法成功連線至 RDS for PostgreSQL 資料庫執行個體。請確定該連接埠是可用的，或在情況允許時嘗試使用不同的連接埠號碼連線。
+ 另請參閱 [安全性群組存取規則發生錯誤](#USER_ConnectToPostgreSQLInstance.Troubleshooting-AccessRules)。

## 安全性群組存取規則發生錯誤
<a name="USER_ConnectToPostgreSQLInstance.Troubleshooting-AccessRules"></a>

顯然地，最常見的連線問題在於對資料庫執行個體指派之安全群組的存取規則。如果建立資料庫執行個體時使用的是預設的安全群組，安全群組很可能沒有可允許您存取該執行個體的存取規則。

為了讓連線運作，您在建立時指派給資料庫執行個體的安全群組，必須允許對該資料庫執行個體的存取。例如，如果資料庫執行個體是在 VPC 中建立，則它必須具有可授權連線的 VPC 安全群組。檢查建立資料庫執行個體所用的安全群組，是否未授權從執行應用程式所在的裝置或 Amazon EC2 執行個體的連線。

您可以新增或編輯安全群組中的傳入規則。針對 **Source (來源)**，選擇 **My IP (我的 IP)** 允許透過您的瀏覽器中偵測到的 IP 位址存取資料庫執行個體。如需更多詳細資訊，請參閱 [建立安全群組以存取在您的 VPC 中您的資料庫執行個體](CHAP_SettingUp.md#CHAP_SettingUp.SecurityGroup)。

或者，如果資料庫執行個體是在 VPC 之外建立，則它必須具有可授權那些連線的安全群組。

如需 Amazon RDS 安全群組的詳細資訊，請參閱 [使用安全群組控制存取](Overview.RDSSecurityGroups.md)。

# 使用 SSL/TLS 保護連接至 RDS for PostgreSQL 的連線
<a name="PostgreSQL.Concepts.General.Security"></a>

RDS for PostgreSQL 支援 PostgreSQL 資料庫執行個體的 Secure Sockets Layer (SSL) 加密。您可以使用 SSL 將應用程式與 PostgreSQL 資料庫執行個體之間的 PostgreSQL 連線加密。您也可以強制 PostgreSQL 資料庫執行個體的所有連線皆使用 SSL。RDS PostgreSQL 也支援 Transport Layer Security (TLS)，也即 SSL 的後繼通訊協定。

若要進一步了解 Amazon RDS 和資料保護 (包括使用 SSL/TLS 加密連線)，請參閱 [Amazon RDS 中的資料保護](DataDurability.md)。

**Topics**
+ [將 SSL 與 PostgreSQL 資料庫執行個體搭配使用](PostgreSQL.Concepts.General.SSL.md)
+ [更新應用程式使用新的 SSL/TLS 憑證來連線至 PostgreSQL 資料庫執行個體](ssl-certificate-rotation-postgresql.md)

# 將 SSL 與 PostgreSQL 資料庫執行個體搭配使用
<a name="PostgreSQL.Concepts.General.SSL"></a>

對於 PostgreSQL 資料庫執行個體，Amazon RDS 支援 Secure Sockets Layer (SSL) 加密。您可以使用 SSL 將應用程式與 PostgreSQL 資料庫執行個體之間的 PostgreSQL 連線加密。依預設，RDS for PostgreSQL 使用並期望所有用戶端皆使用 SSL/TLS 進行連線，但您也可加以要求。RDS for PostgreSQL 支援 Transport Layer Security (TLS) 1.1、1.2 和 1.3 版。

如需 SSL 支援和 PostgreSQL 資料庫的一般資訊，請參閱 PostgreSQL 文件中的 [SSL 支援](https://www.postgresql.org/docs/11/libpq-ssl.html)。如需透過 JDBC 使用 SSL 連線的資訊，請參閱 PostgreSQL 文件中的[設定用戶端](https://jdbc.postgresql.org/documentation/head/ssl-client.html)。

SSL 支援適用於所有 PostgreSQL 的 AWS 區域。建立執行個體時，Amazon RDS 會為 PostgreSQL 資料庫執行個體建立 SSL 憑證。如果您啟用 SSL 憑證驗證，則 SSL 憑證會包含資料庫執行個體端點做為 SSL 憑證的一般名稱 (CN)，以防止詐騙攻擊。

**Topics**
+ [透過 SSL 連接至 PostgreSQL 資料庫執行個體](#PostgreSQL.Concepts.General.SSL.Connecting)
+ [需要以 SSL 連線至 PostgreSQL 資料庫執行個體](#PostgreSQL.Concepts.General.SSL.Requiring)
+ [判斷 SSL 連線狀態](#PostgreSQL.Concepts.General.SSL.Status)
+ [RDS for PostgreSQL 中的 SSL 密碼套件](#PostgreSQL.Concepts.General.SSL.Ciphers)

## 透過 SSL 連接至 PostgreSQL 資料庫執行個體
<a name="PostgreSQL.Concepts.General.SSL.Connecting"></a>

**透過 SSL 連接至 PostgreSQL 資料庫執行個體**

1. 下載憑證。

   如需有關下載憑證的詳細資訊，請參閱[使用 SSL/TLS 加密與資料庫執行個體或叢集的連線](UsingWithRDS.SSL.md)。

1. 透過 SSL 連接至 PostgreSQL 資料庫執行個體。

   當您使用 SSL 來連線時，用戶端可以選擇是否驗證憑證鏈。如果您的連線參數指定 `sslmode=verify-ca` 或 `sslmode=verify-full`，則用戶端在信任存放區必須有 RDS CA 憑證，或在連線 URL 中必須參考這些憑證。此需求是為了驗證用於簽署資料庫憑證的憑證鏈。

   當用戶端 (例如 psql 或 JDBC) 設有 SSL 支援時，依預設，用戶端會先嘗試以 SSL 連線至資料庫。如果用戶端無法以 SSL 連線，則回復為不以 SSL 來連線。以 libpq 為基礎的用戶端 (例如 psql) 和 JDBC 使用的預設 `sslmode` 模式不同。以 libpq 為基礎的用戶端和 JDBC 用戶端預設為 `prefer`。

   使用 `sslrootcert` 參數來參考憑證，例如 `sslrootcert=rds-ssl-ca-cert.pem`。

下列是使用 `psql` 連線至使用具認證驗證 SSL 之 PostgreSQL 資料庫執行個體的範例。

```
$ psql "host=db-name.555555555555.ap-southeast-1.rds.amazonaws.com 
    port=5432 dbname=testDB user=testuser sslrootcert=rds-ca-rsa2048-g1.pem sslmode=verify-full"
```

## 需要以 SSL 連線至 PostgreSQL 資料庫執行個體
<a name="PostgreSQL.Concepts.General.SSL.Requiring"></a>

您可以使用 `rds.force_ssl` 參數來要求對 PostgreSQL 資料庫執行個體的連線使用 SSL。RDS for PostgreSQL 第 15 版和更新版本的 `rds.force_ssl` 參數預設值為 1 (開啟)。至於其他所有 RDS for PostgreSQL 主要版本 14 和較舊版本，此參數的預設值皆為 0 (關閉)。您可以將 `rds.force_ssl` 參數設為 1 (開啟)，以要求使用 SSL/TLS 連線至資料庫叢集。您可以將 `rds.force_ssl` 參數設為 1 (開啟)，以要求對資料庫執行個體的連線使用 SSL。

如要變更此參數值，您需要建立自訂資料庫參數群組。然後，您可變更您自訂資料庫參數群組中的 `rds.force_ssl` 值為 `1`，以開啟此功能。若於建立 RDS for PostgreSQL 資料庫執行個體之前準備了自訂資料庫參數群組，則可於建立程序期間加以選擇 (而非預設參數群組)。若您於 RDS for PostgreSQL 資料庫執行個體已執行之後進行此作業，則需要重新啟動執行個體，如此您的執行個體便可使用自訂參數群組。如需詳細資訊，請參閱[Amazon RDS 的參數群組](USER_WorkingWithParamGroups.md)。

當 `rds.force_ssl` 功能在資料庫執行個體上處於活動狀態時，未使用 SSL 的連線嘗試將遭到拒絕，並顯示下列訊息：

```
$ psql -h db-name.555555555555.ap-southeast-1.rds.amazonaws.com port=5432 dbname=testDB user=testuser
psql: error: FATAL: no pg_hba.conf entry for host "w.x.y.z", user "testuser", database "testDB", SSL off
```

## 判斷 SSL 連線狀態
<a name="PostgreSQL.Concepts.General.SSL.Status"></a>

當您連接至資料庫執行個體時，登入橫幅中會顯示連線的加密狀態：

```
Password for user master: 
psql (10.3) 
SSL connection (cipher: DHE-RSA-AES256-SHA, bits: 256) 
Type "help" for help.
postgres=>
```

您也可以載入 `sslinfo` 延伸，然後呼叫 `ssl_is_used()` 函數，以判斷是否正在使用 SSL。如果連線正在使用 SSL，此函數會傳回 `t`，否則傳回 `f`。

```
postgres=> CREATE EXTENSION sslinfo;
CREATE EXTENSION
postgres=> SELECT ssl_is_used();
ssl_is_used
---------
t
(1 row)
```

如需更多詳細資訊，您可使用下列查詢，從 `pg_settings` 取得資訊：

```
SELECT name as "Parameter name", setting as value, short_desc FROM pg_settings WHERE name LIKE '%ssl%';
             Parameter name             |                  value                  |                      short_desc
----------------------------------------+-----------------------------------------+-------------------------------------------------------
 ssl                                    | on                                      | Enables SSL connections.
 ssl_ca_file                            | /rdsdbdata/rds-metadata/ca-cert.pem     | Location of the SSL certificate authority file.
 ssl_cert_file                          | /rdsdbdata/rds-metadata/server-cert.pem | Location of the SSL server certificate file.
 ssl_ciphers                            | HIGH:!aNULL:!3DES                       | Sets the list of allowed SSL ciphers.
 ssl_crl_file                           |                                         | Location of the SSL certificate revocation list file.
 ssl_dh_params_file                     |                                         | Location of the SSL DH parameters file.
 ssl_ecdh_curve                         | prime256v1                              | Sets the curve to use for ECDH.
 ssl_key_file                           | /rdsdbdata/rds-metadata/server-key.pem  | Location of the SSL server private key file.
 ssl_library                            | OpenSSL                                 | Name of the SSL library.
 ssl_max_protocol_version               |                                         | Sets the maximum SSL/TLS protocol version to use.
 ssl_min_protocol_version               | TLSv1.2                                 | Sets the minimum SSL/TLS protocol version to use.
 ssl_passphrase_command                 |                                         | Command to obtain passphrases for SSL.
 ssl_passphrase_command_supports_reload | off                                     | Also use ssl_passphrase_command during server reload.
 ssl_prefer_server_ciphers              | on                                      | Give priority to server ciphersuite order.
(14 rows)
```

您還可使用下列查詢，依程序、用戶端和應用程式收集有關 RDS for PostgreSQL 資料庫執行個體之 SSL 使用情況的所有資訊：

```
SELECT datname as "Database name", usename as "User name", ssl, client_addr, application_name, backend_type
   FROM pg_stat_ssl
   JOIN pg_stat_activity
   ON pg_stat_ssl.pid = pg_stat_activity.pid
   ORDER BY ssl;
 Database name | User name | ssl |  client_addr   |    application_name    |         backend_type
---------------+-----------+-----+----------------+------------------------+------------------------------
               |           | f   |                |                        | autovacuum launcher
               | rdsadmin  | f   |                |                        | logical replication launcher
               |           | f   |                |                        | background writer
               |           | f   |                |                        | checkpointer
               |           | f   |                |                        | walwriter
 rdsadmin      | rdsadmin  | t   | 127.0.0.1      |                        | client backend
 rdsadmin      | rdsadmin  | t   | 127.0.0.1      | PostgreSQL JDBC Driver | client backend
 postgres      | postgres  | t   | 204.246.162.36 | psql                   | client backend
(8 rows)
```

如要識別用於 SSL 連線的密碼，可依如下方式查詢：

```
postgres=> SELECT ssl_cipher();
ssl_cipher
--------------------
DHE-RSA-AES256-SHA
(1 row)
```

若要進一步了解 `sslmode`，請參閱 *PostgreSQL 文件*中的[資料庫連線控制函數](https://www.postgresql.org/docs/11/libpq-connect.html#LIBPQ-CONNECT-SSLMODE)。

## RDS for PostgreSQL 中的 SSL 密碼套件
<a name="PostgreSQL.Concepts.General.SSL.Ciphers"></a>

PostgreSQL 組態參數 [ssl\$1cipher](https://www.postgresql.org/docs/current/runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SSL) 會指定在使用 TLS 1.2 和較低版本時，資料庫的 SSL 連線所允許的密碼套件類別。

 在 RDS for PostgreSQL 16 和更新版本中，您可以修改 `ssl_ciphers` 參數，以使用列入允許清單的密碼套件中的特定值。這是動態參數，不需要將資料庫執行個體重新開機。若要檢視列入允許清單的密碼套件，請使用 Amazon RDS 主控台或下列 CLI AWS 命令：

```
aws rds describe-db-parameters --db-parameter-group-name <your-parameter-group> --region <region> --endpoint-url <endpoint-url> --output json | jq '.Parameters[] | select(.ParameterName == "ssl_ciphers")'
```

下表列出支援自訂組態的版本允許的密碼套件和預設密碼套件。


| PostgreSQL 引擎版本 | 預設 ssl\$1cipher 套件值 | 列入允許清單的自訂 ssl\$1cipher 套件值 | 
| --- | --- | --- | 
| 18 | HIGH:\$1aNULL:\$13DES |  `TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384` `TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256` `TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256` `TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384` `TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256`  | 
| 17 | HIGH:\$1aNULL:\$13DES |  `TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384` `TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256` `TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256` `TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384` `TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256`  | 
| 16 | HIGH:\$1aNULL:\$13DES |  `TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384` `TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256` `TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256` `TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384` `TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256`  | 
| 15 | HIGH:\$1aNULL:\$13DES | 不支援自訂 ssl\$1ciphers | 
| 14 | HIGH:\$1aNULL:\$13DES | 不支援自訂 ssl\$1ciphers | 
| 13 | HIGH:\$1aNULL:\$13DES | 不支援自訂 ssl\$1ciphers | 
| 12 | HIGH:\$1aNULL:\$13DES | 不支援自訂 ssl\$1ciphers | 
| 11.4 及更高次要版本 | HIGH:MEDIUM:\$13DES:\$1aNULL:\$1RC4 | 不支援自訂 ssl\$1ciphers | 
| 11.1、11.2 | HIGH:MEDIUM:\$13DES:\$1aNULL | 不支援自訂 ssl\$1ciphers | 
| 10.9 及更高次要版本 | HIGH:MEDIUM:\$13DES:\$1aNULL:\$1RC4 | 不支援自訂 ssl\$1ciphers | 
| 10.7 及較低次要版本 | HIGH:MEDIUM:\$13DES:\$1aNULL | 不支援自訂 ssl\$1ciphers | 

若要將所有執行個體連線設定為使用 `TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384` 加密套件，請修改參數群組，如下列範例所示：

```
aws rds modify-db-parameter-group --db-parameter-group-name <your-parameter-group> --parameters "ParameterName='ssl_ciphers',ParameterValue='TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384',ApplyMethod=immediate"
```

此範例使用 ECDSA 密碼，因此您的執行個體必須使用具有橢圓曲線密碼編譯 (ECC) 的憑證授權機構來建立連線。若要了解 Amazon RDS 提供了哪些憑證授權機構，請參閱[憑證授權機構](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/singWithRDS.SSL.html#UsingWithRDS.SSL.RegionCertificateAuthorities)。

您可以透過[判斷 SSL 連線狀態](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/PostgreSQL.Concepts.General.SSL.html#PostgreSQL.Concepts.General.SSL.Status)中所述的方法，來驗證使用中的密碼。

密碼可能隨著內容而有不同的名稱：
+ 您可以在參數群組中設定的允許密碼，會以其 IANA 名稱來指稱。
+ `sslinfo` 和 `psql` 登入橫幅是指使用其 OpenSSL 名稱的密碼。

根據預設，RDS for PostgreSQL 16 和更新版本中的 `ssl_max_protocol_version` 值為 TLS v1.3。您必須將此參數的值設定為 TLS v1.2，因為 TLS v1.3 不使用 `ssl_ciphers` 參數中指定的密碼組態。該值設定為 TLS v1.2 時，連線只會使用您在 `ssl_ciphers` 中定義的密碼。

```
aws rds modify-db-parameter-group --db-parameter-group-name <your-parameter-group> --parameters "ParameterName='ssl_max_protocol_version',ParameterValue='TLSv1.2',ApplyMethod=immediate"
```

若要確保資料庫連線會使用 SSL，請在參數群組中將 `rds.force_ssl parameter` 設定為 1。如需參數和參數群組的詳細資訊，請參閱 [Amazon RDS 的參數群組](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_WorkingWithParamGroups.html)。

# 更新應用程式使用新的 SSL/TLS 憑證來連線至 PostgreSQL 資料庫執行個體
<a name="ssl-certificate-rotation-postgresql"></a>

用於 Secure Socket Layer 或 Transport Layer Security (SSL/TLS) 的憑證通常具有設定生命週期。當服務供應商更新其憑證授權機構 (CA) 憑證時，用戶端必須更新其應用程式以使用新憑證。您可以在下文找到相關資訊，了解如何判斷用戶端應用程式是否使用 SSL/TLS 連線至 Amazon RDS for PostgreSQL 資料庫執行個體。您還可以找到如何檢查這些應用程式在連線時是否驗證伺服器憑證的相關資訊。

**注意**  
設定為在 SSL/TLS 連線之前驗證伺服器憑證的用戶端應用程式，必須在用戶端的信任存放區中具有有效的 CA 憑證。在需要時更新用戶端信任存放區以取得新憑證。

更新用戶端應用程式信任存放區中的 CA 憑證之後，您就可以在資料庫執行個體輪換憑證。強烈建議先在非生產環境中測試這些步驟，再於生產環境中實作。

如需憑證輪換的詳細資訊，請參閱[輪換您的 SSL/TLS 憑證](UsingWithRDS.SSL-certificate-rotation.md)。如需下載憑證的詳細資訊，請參閱[使用 SSL/TLS 加密與資料庫執行個體或叢集的連線](UsingWithRDS.SSL.md)。如需對 PostgreSQL 資料庫執行個體使用 SSL/TLS 的資訊，請參閱[將 SSL 與 PostgreSQL 資料庫執行個體搭配使用](PostgreSQL.Concepts.General.SSL.md)。

**Topics**
+ [判斷任何應用程式是否使用 SSL 連線至 PostgreSQL 資料庫執行個體](#ssl-certificate-rotation-postgresql.determining-server)
+ [判斷用戶端是否需要驗證憑證才能連線](#ssl-certificate-rotation-postgresql.determining-client)
+ [更新應用程式信任存放區](#ssl-certificate-rotation-postgresql.updating-trust-store)
+ [針對不同類型的應用程式使用 SSL/TLS 連線](#ssl-certificate-rotation-postgresql.applications)

## 判斷任何應用程式是否使用 SSL 連線至 PostgreSQL 資料庫執行個體
<a name="ssl-certificate-rotation-postgresql.determining-server"></a>

在資料庫執行個體組態中檢查 `rds.force_ssl` 參數的值。對於使用 PostgreSQL 版本 15 之前版本的資料庫執行個體，`rds.force_ssl` 參數預設會設定為 `0` (關閉)。對於使用 PostgreSQL 版本 15 及更新主要版本的資料庫執行個體，`rds.force_ssl` 預設會設定為 `1` (開啟)。如果 `rds.force_ssl` 參數設為 `1` (開啟)，則用戶端需要使用 SSL/TLS 進行連線。如需參數群組的詳細資訊，請參閱[Amazon RDS 的參數群組](USER_WorkingWithParamGroups.md)。

如果您使用 RDS PostgreSQL 9.5 版或更新的主要版本，而 `rds.force_ssl` 未設為 `1` (開啟)，請查詢 `pg_stat_ssl` 檢視，以檢查使用 SSL 的連線。例如，下列查詢只傳回 SSL 連線和關於使用 SSL 的用戶端的資訊。

```
SELECT datname, usename, ssl, client_addr 
  FROM pg_stat_ssl INNER JOIN pg_stat_activity ON pg_stat_ssl.pid = pg_stat_activity.pid
  WHERE ssl is true and usename<>'rdsadmin';
```

只有使用 SSL/TLS 連線的列才會顯示連線的相關資訊。下列為範例輸出。

```
 datname  | usename | ssl | client_addr 
----------+---------+-----+-------------
 benchdb  | pgadmin | t   | 53.95.6.13
 postgres | pgadmin | t   | 53.95.6.13
(2 rows)
```

此查詢只顯示查詢當時的連線。沒有結果不代表沒有應用程式使用 SSL 連線。其他 SSL 連線可能在不同時間建立。

## 判斷用戶端是否需要驗證憑證才能連線
<a name="ssl-certificate-rotation-postgresql.determining-client"></a>

當用戶端 (例如 psql 或 JDBC) 設有 SSL 支援時，依預設，用戶端會先嘗試以 SSL 連線至資料庫。如果用戶端無法以 SSL 連線，則回復為不以 SSL 來連線。用於 libpq 型用戶端 (例如 psql) 與 JDBC 的預設 `sslmode` 模式設定為 `prefer`。只有當提供 `sslrootcert` 並搭配 `sslmode` 設為 `verify-ca` 或 `verify-full` 時，才會驗證伺服器上的憑證。如果憑證無效，則擲出錯誤。

使用 `PGSSLROOTCERT` 搭配 `PGSSLMODE` 環境變數來驗證憑證，而且 `PGSSLMODE` 設為 `verify-ca` 或 `verify-full`。

```
PGSSLMODE=verify-full PGSSLROOTCERT=/fullpath/ssl-cert.pem psql -h pgdbidentifier.cxxxxxxxx.us-east-2.rds.amazonaws.com -U masteruser -d postgres
```

使用 `sslrootcert` 引數搭配連線字串格式中的 `sslmode` 來驗證憑證，且 `sslmode` 設定為 `verify-ca` 或 `verify-full` 來驗證憑證。

```
psql "host=pgdbidentifier.cxxxxxxxx.us-east-2.rds.amazonaws.com sslmode=verify-full sslrootcert=/full/path/ssl-cert.pem user=masteruser dbname=postgres"
```

例如，在上述案例中，如果您使用無效根憑證，則在用戶端會看到類似以下的錯誤。

```
psql: SSL error: certificate verify failed
```

## 更新應用程式信任存放區
<a name="ssl-certificate-rotation-postgresql.updating-trust-store"></a>

如需為 PostgreSQL 應用程式更新信任存放區的資訊，請參閱 PostgreSQL 文件中的[使用 SSL 保護 TCP/IP 連線的安全](https://www.postgresql.org/docs/current/ssl-tcp.html)。

如需下載根憑證的資訊，請參閱 [使用 SSL/TLS 加密與資料庫執行個體或叢集的連線](UsingWithRDS.SSL.md)。

如需匯入憑證的範例指令碼，請參閱 [將憑證匯入信任存放區的範例指令碼](UsingWithRDS.SSL-certificate-rotation.md#UsingWithRDS.SSL-certificate-rotation-sample-script)。

**注意**  
更新信任存放區時，除了新增憑證，您還可以保留舊憑證。

## 針對不同類型的應用程式使用 SSL/TLS 連線
<a name="ssl-certificate-rotation-postgresql.applications"></a>

以下提供針對不同類型的應用程式使用 SSL/TLS 連線的資訊：
+ **psql**

  以連線字串或環境變數指定選項，從命令列叫用此用戶端。若為 SSL/TLS 連線，相關選項為 `sslmode` (環境變數 `PGSSLMODE`)、`sslrootcert` (環境變數 `PGSSLROOTCERT`)。

  如需完整的選項清單，請參閱 PostgreSQL 文件中的[參數關鍵字](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-PARAMKEYWORDS)。如需完整的環境變數清單，請參閱 PostgreSQL 文件中的[環境變數](https://www.postgresql.org/docs/current/libpq-envars.html)。
+ **pgAdmin**

  這個以瀏覽器為基礎的用戶端是更方便連線至 PostgreSQL 資料庫的介面。

  如需設定連線的資訊，請參閱 [pgAdmin 文件](https://www.pgadmin.org/docs/pgadmin4/latest/server_dialog.html)。
+ **JDBC**

  JDBC 可讓 Java 應用程式連線至資料庫。

  如需使用 JDBC 連線至 PostgreSQL 資料庫的一般資訊，請參閱 PostgreSQL JDBC 驅動程式文件中的[連線至資料庫](https://jdbc.postgresql.org/documentation/use/#connecting-to-the-database)。如需使用 SSL/TLS 來連線的資訊，請參閱 PostgreSQL JDBC 驅動程式文件中的[設定用戶端](https://jdbc.postgresql.org/documentation/ssl/#configuring-the-client)。
+ **Python**

  常用來連線至 PostgreSQL 資料庫的 Python 程式庫是 `psycopg2`。

  如需使用 `psycopg2` 的資訊，請參閱 [psycopg2 文件](https://pypi.org/project/psycopg2/)。如需如何連線至 PostgreSQL 資料庫的簡短教學課程，請參閱 [Psycopg2 教學](https://wiki.postgresql.org/wiki/Psycopg2_Tutorial)。您可以在 [psycopg2 模組內容](http://initd.org/psycopg/docs/module.html#module-psycopg2)中找到 connect 命令接受的選項的相關資訊。

**重要**  
在確定了資料庫連線使用 SSL/TLS 並已更新應用程式信任存放區之後，您可以將資料庫更新為使用 rds-ca-rsa2048-g1 憑證。如需說明，請參閱[透過修改資料庫執行個體或叢集來更新憑證授權機構憑證](UsingWithRDS.SSL-certificate-rotation.md#UsingWithRDS.SSL-certificate-rotation-updating)中的步驟 3。

# 搭配 Amazon RDS for PostgreSQL 使用 Kerberos 身分驗證
<a name="postgresql-kerberos"></a>

在使用者連線至執行 PostgreSQL 的資料庫執行個體時，您可以使用 Kerberos 驗證用戶身分。若要這樣做，請將資料庫執行個體設定為 AWS Directory Service for Microsoft Active Directory 用於 Kerberos 身分驗證。 AWS Directory Service for Microsoft Active Directory 也稱為 AWS Managed Microsoft AD。這是 提供的功能 Directory Service。若要進一步了解，請參閱《 *AWS Directory Service 管理指南*》中的[什麼是 Directory Service？](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/what_is.html)。

若要開始，請建立 AWS Managed Microsoft AD 目錄來存放使用者登入資料。然後，將 Active Directory 網域和其他資訊提供給 PostgreSQL 資料庫執行個體。當使用者向 PostgreSQL 資料庫執行個體進行驗證時，身分驗證請求會轉送到 AWS Managed Microsoft AD 目錄。

將您的所有登入資料保留在相同目錄可以節省您的時間和精力。這樣您就有一個集中的位置來存放及管理多個資料庫執行個體的登入資料。使用目錄也可以改善您的整體安全性描述檔。

除此之外，您也可以從自己的內部部署 Microsoft Active Directory 存取登入資料。若要執行這項操作，請建立信任網域關聯，讓 AWS Managed Microsoft AD 目錄信任您的內部部署 Microsoft Active Directory。如此一來，使用者就可以透過在存取您內部部署網路的工作負載時的相同 Windows 單一登入 (SSO) 體驗，來存取 PostgreSQL 執行個體。

資料庫可以使用密碼身分驗證或密碼身分驗證搭配 Kerberos 或 AWS Identity and Access Management (IAM) 身分驗證。如需 IAM 身分驗證的詳細資訊，請參閱 [適用於 MariaDB、MySQL 和 PostgreSQL 的 IAM 資料庫身分驗證](UsingWithRDS.IAMDBAuth.md)。

**注意**  
RDS for PostgreSQL 不支援 Active Directory 群組的 Kerberos 身分驗證。

**Topics**
+ [區域和版本可用性](#postgresql-kerberos.RegionVersionAvailability)
+ [對 PostgreSQL 資料庫執行個體進行 Kerberos 身分驗證的概觀](#postgresql-kerberos-overview)
+ [為 PostgreSQL 資料庫執行個體設定 Kerberos 身分驗證](postgresql-kerberos-setting-up.md)
+ [在 Active Directory 網域中管理 RDS for PostgreSQL 資料庫執行個體](postgresql-kerberos-managing.md)
+ [使用 Kerberos 身分驗證連線至 PostgreSQL](postgresql-kerberos-connecting.md)

## 區域和版本可用性
<a name="postgresql-kerberos.RegionVersionAvailability"></a>

功能可用性和支援會因每個資料庫引擎的特定版本以及 AWS 區域而有所不同。如需有關 RDS for PostgreSQL 搭配 Kerberos 驗證的版本和區域可用性的詳細資訊，請參閱 [支援 Amazon RDS 中 Kerberos 身分驗證的區域和資料庫引擎](Concepts.RDS_Fea_Regions_DB-eng.Feature.KerberosAuthentication.md)。

## 對 PostgreSQL 資料庫執行個體進行 Kerberos 身分驗證的概觀
<a name="postgresql-kerberos-overview"></a>

若要為 PostgreSQL 資料庫執行個體設定 Kerberos 身分驗證，請遵循下列步驟，稍後會提供更詳細的說明：

1. 使用 AWS Managed Microsoft AD 建立 AWS Managed Microsoft AD 目錄。您可以使用 AWS 管理主控台、 AWS CLI或 Directory Service API 來建立目錄。請務必開啟目錄安全性群組上的相關輸出連接埠，以便目錄可以與  執行個體  通訊。

1. 建立提供 Amazon RDS 存取權的角色，以呼叫您的 AWS Managed Microsoft AD 目錄。若要這樣做，請建立使用 受管 IAM 政策 的 AWS Identity and Access Management (IAM) 角色`AmazonRDSDirectoryServiceAccess`。

   若要讓 IAM 角色允許存取，必須在您 AWS 帳戶的正確 AWS 區域中啟用 AWS Security Token Service (AWS STS) 端點。 AWS STS 端點預設會在所有 中處於作用中狀態 AWS 區域，而且您可以使用它們，而不需要任何進一步的動作。如需詳細資訊，請參閱《*IAM 使用者指南*》中的[AWS STS 在 AWS 區域中啟用和停用](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html#sts-regions-activate-deactivate) 。

1. 使用 Microsoft Active Directory 工具在 AWS Managed Microsoft AD 目錄中建立和設定使用者。如需有關在 Active Directory 中建立使用者的詳細資訊，請參閱[《 管理指南》中的管理 AWS Managed Microsoft AD 中的使用者和群組](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_manage_users_groups.html)。 *Directory Service *

1. 如果您打算在不同 AWS 帳戶或 Virtual Private Cloud (VPC) 中尋找目錄和資料庫執行個體，請設定 VPC 互連。如需詳細資訊，請參閱《Amazon VPC Peering Guide》**中的[什麼是 VPC 互連？](https://docs.aws.amazon.com/vpc/latest/peering/Welcome.html)。

1. 使用下列其中一種方法，從主控台、CLI 或 RDS API 建立或修改 PostgreSQL 資料庫執行個體：
   + [建立 Amazon RDS 資料庫執行個體](USER_CreateDBInstance.md) 
   + [修改 Amazon RDS 資料庫執行個體](Overview.DBInstance.Modifying.md) 
   + [還原至資料庫執行個體](USER_RestoreFromSnapshot.md)
   + [將 Amazon RDS 的資料庫執行個體還原至指定時間](USER_PIT.md)

   您可以在與目錄相同的 Amazon Virtual Private Cloud (VPC) 或不同的 AWS 帳戶或 VPC 中找到執行個體。當您建立或修改 PostgreSQL 資料庫執行個體時，請執行下列動作：
   + 請提供您建立目錄時產生的網域識別符 (`d-*` 識別符)。
   + 請提供所建立的 IAM 角色名稱。
   + 確保資料庫執行個體安全群組可以從目錄的安全群組接收傳入流量。

1. 使用 RDS 主要使用者登入資料來連接至 PostgreSQL 資料庫執行個體。然後，在 PostgreSQL 中建立要在外部識別的使用者。外部識別的使用者可以使用 Kerberos 身分驗證來登入 PostgreSQL 資料庫執行個體。

# 為 PostgreSQL 資料庫執行個體設定 Kerberos 身分驗證
<a name="postgresql-kerberos-setting-up"></a>

您可以使用 AWS Directory Service for Microsoft Active Directory (AWS Managed Microsoft AD) 來設定 PostgreSQL 資料庫執行個體的 Kerberos 身分驗證。若要設定 Kerberos 身分驗證，請遵循下列步驟。

**Topics**
+ [步驟 1：使用 建立目錄 AWS Managed Microsoft AD](#postgresql-kerberos-setting-up.create-directory)
+ [步驟 2：（選用） 在內部部署 Active Directory 與 之間建立信任關係 Directory Service](#postgresql-kerberos-setting-up.create-trust)
+ [步驟 3：為 Amazon RDS 建立 IAM 角色以存取 Directory Service](#postgresql-kerberos-setting-up.CreateIAMRole)
+ [步驟 4：建立和設定使用者](#postgresql-kerberos-setting-up.create-users)
+ [步驟 5：啟用目錄和資料庫執行個體之間的跨 VPC 流量](#postgresql-kerberos-setting-up.vpc-peering)
+ [步驟 6：建立或修改 PostgreSQL 資料庫執行個體](#postgresql-kerberos-setting-up.create-modify)
+ [步驟 7：針對您的 Kerberos 主體建立 PostgreSQL 使用者](#postgresql-kerberos-setting-up.create-logins)
+ [步驟 8：設定 PostgreSQL 用戶端](#postgresql-kerberos-setting-up.configure-client)

## 步驟 1：使用 建立目錄 AWS Managed Microsoft AD
<a name="postgresql-kerberos-setting-up.create-directory"></a>

Directory Service 在 AWS 雲端中建立全受管 Active Directory。當您建立 AWS Managed Microsoft AD 目錄時， 會為您 Directory Service 建立兩個網域控制站和 DNS 伺服器。目錄伺服器是在 VPC 的不同子網路中建立。此備援有助於確保即使發生故障，您仍然可以存取目錄。

 當您建立 AWS Managed Microsoft AD 目錄時， AWS Directory Service 會代表您執行下列任務：
+ 在 VPC 內設定 Active Directory。
+ 建立含有使用者名稱 `Admin` 與指定密碼的目錄管理員帳戶。您可以使用此帳戶來管理目錄。
**重要**  
請務必儲存此密碼。 Directory Service 不會儲存此密碼，而且無法擷取或重設。
+ 建立目錄控制器的安全群組。安全群組必須允許與 PostgreSQL 資料庫執行個體進行通訊。

啟動時 AWS Directory Service for Microsoft Active Directory， 會 AWS 建立組織單位 (OU)，其中包含目錄的所有物件。此 OU 有您在建立目錄時所輸入的 NetBIOS 名稱，位於根網域中。網域根由 擁有和管理 AWS。

 使用 AWS Managed Microsoft AD 目錄建立`Admin`的帳戶具有 OU 最常見管理活動的許可：
+ 建立、更新或刪除使用者
+ 將資源 (例如檔案或列印伺服器) 新增至您的網域，然後對您 OU 中的使用者指派這些資源的許可 
+ 建立額外的 OU 和容器 
+ 委派授權 
+ 從 Active Directory 資源回收筒還原已刪除的物件 
+ 在 Active Directory Web 服務上執行適用於 Windows PowerShell 的 Active Directory 和網域名稱服務 (DNS) 模組 

`Admin` 帳戶也有權執行下列全網域活動：
+ 管理 DNS 組態 (新增、移除或更新記錄、區域和轉寄站) 
+ 檢視 DNS 事件日誌 
+ 檢視安全事件日誌 

**使用 建立目錄 AWS Managed Microsoft AD**

1.  在 [Directory Service 主控台](https://console.aws.amazon.com/directoryservicev2/)中，選擇 **Directories (目錄)**，然後選擇 **Set up directory (設定目錄)**。

1. 選擇 **AWS Managed Microsoft AD**. AWS Managed Microsoft AD 是目前支援與 Amazon RDS 搭配使用的唯一選項。

1. 選擇**下一步**。

1. 在 **Enter directory information (輸入目錄資訊)** 頁面上，提供下列資訊：  
**版本**  
 選擇滿足您需求的版本。  
**目錄 DNS 名稱**  
 目錄的完全合格名稱，例如 **corp.example.com**。  
**目錄 NetBIOS 名稱**  
 目錄的簡短名稱，例如：`CORP`。  
**目錄描述**  
 選擇填寫其他目錄說明。  
**管理員密碼**  
 目錄管理員的密碼。目錄建立程序會建立含有使用者名稱 `Admin` 與這組密碼的管理者帳戶。  
 目錄管理員密碼不得包含 "admin" 字組。密碼區分大小寫，長度須為 8 至 64 個字元。至少須有一位字元屬於以下四種類型中的三類：  
   +  小寫字母 (a–z) 
   +  大寫字母 (A–Z) 
   +  數字 (0–9) 
   +  非英數字元 (\$1\$1@\$1\$1%^&\$1\$1-\$1=`\$1\$1()\$1\$1[]:;"'<>,.?/)   
**Confirm password (確認密碼)**  
 重新輸入管理員密碼。  
請確定您儲存此密碼。 Directory Service 不會儲存此密碼，而且無法擷取或重設。

1. 選擇**下一步**。

1. 在 **Choose VPC and subnets (選擇 VPC 和子網路)** 頁面上，提供下列資訊：  
**VPC**  
選擇目錄的 VPC。您可在此相同 VPC 或不同 VPC 中建立 PostgreSQL 資料庫執行個體。  
**子網路**  
 選擇目錄伺服器的子網路。這兩個子網路必須位於不同的可用區域。

1. 選擇 **Next (下一步)**。

1.  檢閱目錄資訊。如果需要變更，請選擇 **Previous (上一步)**，然後進行變更。若資訊無誤，請選擇 **Create directory (建立目錄)**。  
![\[目錄詳細資訊頁面\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/images/WinAuth2.png)

 建立目錄需要幾分鐘的時間。成功建立時，**Status (狀態)** 值會變更為 **Active (作用中)**。

 若要查看目錄的資訊，請選擇目錄清單中的目錄 ID。請記下 **Directory ID (目錄 ID)** 值，建立或修改 PostgreSQL 資料庫執行個體時需要此值。

![\[詳細資訊頁面的影像\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/images/WinAuth3.png)


## 步驟 2：（選用） 在內部部署 Active Directory 與 之間建立信任關係 Directory Service
<a name="postgresql-kerberos-setting-up.create-trust"></a>

如果您不打算使用自己的內部部署 Microsoft Active Directory，請跳至[步驟 3：為 Amazon RDS 建立 IAM 角色以存取 Directory Service](#postgresql-kerberos-setting-up.CreateIAMRole).

若要使用現場部署 Active Directory 取得 Kerberos 身分驗證，您需要使用現場部署 Microsoft Active Directory 與 AWS Managed Microsoft AD 目錄 （在 中建立） 之間的樹系信任來建立信任網域關係[步驟 1：使用 建立目錄 AWS Managed Microsoft AD](#postgresql-kerberos-setting-up.create-directory)。信任可以是單向，其中 AWS Managed Microsoft AD 目錄信任內部部署 Microsoft Active Directory。信任也可以是雙向，其中兩個 Active Directory 互相信任。如需使用 設定信任的詳細資訊 Directory Service，請參閱《 *AWS Directory Service 管理指南*》中的[何時建立信任關係](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_setup_trust.html)。

**注意**  
如果您使用內部部署 Microsoft Active Directory，Windows 用戶端會使用端點 Directory Service 中 的網域名稱進行連線，而不是使用 rds.amazonaws.com。如需詳細資訊，請參閱 [使用 Kerberos 身分驗證連線至 PostgreSQL](postgresql-kerberos-connecting.md)。

請確定您的內部部署 Microsoft Active Directory 網域名稱包含對應至新建立之信任關係的 DNS 尾碼路由。以下螢幕擷取畫面顯示了一個範例。

![\[DNS 路由對應至建立的信任\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/images/kerberos-auth-trust.png)


## 步驟 3：為 Amazon RDS 建立 IAM 角色以存取 Directory Service
<a name="postgresql-kerberos-setting-up.CreateIAMRole"></a>

若要讓 Amazon RDS Directory Service 為您呼叫 ， AWS 您的帳戶需要使用 受管 IAM 政策 的 IAM 角色`AmazonRDSDirectoryServiceAccess`。此角色允許 Amazon RDS 呼叫 Directory Service。

當您使用 建立資料庫執行個體， AWS 管理主控台 且主控台使用者帳戶具有 `iam:CreateRole`許可時，主控台會自動建立所需的 IAM 角色。在此情況下，角色名稱為 `rds-directoryservice-kerberos-access-role`。否則，您必須手動建立 IAM 角色。當您建立此 IAM 角色時，請選擇 `Directory Service`，然後將 AWS 受管政策連接到`AmazonRDSDirectoryServiceAccess`該角色。

如需為服務建立 IAM 角色的詳細資訊，請參閱《*IAM 使用者指南*》中的[建立角色以將許可委派給 AWS 服務](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html)。

**注意**  
用於 Windows Authentication for RDS for Microsoft SQL Server 的 IAM 角色不可用於 Amazon RDS for PostgreSQL。

作為使用 `AmazonRDSDirectoryServiceAccess` 受管政策的替代方案，您可以建立具有必要許可的政策。在此情況下，IAM 角色必須有以下 IAM 信任政策。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "directoryservice.rds.amazonaws.com",
          "rds.amazonaws.com"
        ]
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

------

此角色也須具有下列 IAM 角色政策：

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Action": [
        "ds:DescribeDirectories",
        "ds:AuthorizeApplication",
        "ds:UnauthorizeApplication",
        "ds:GetAuthorizedApplicationDetails"
      ],
    "Effect": "Allow",
    "Resource": "*"
    }
  ]
}
```

------

對於選擇加入 AWS 區域，請在 IAM 角色信任政策中使用區域特定的服務主體。當您為這些區域中的服務建立信任政策時，請在服務主體中指定區域代碼。

下列範例顯示的信任政策，其中包含區域專屬服務主體：

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "directoryservice.rds.REGION-CODE.amazonaws.com",
          "rds.REGION-CODE.amazonaws.com"
        ]
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

------

將 REGION-CODE 取代為特定區域的代碼。例如，針對亞太區域 (墨爾本) 使用下列服務主體：

```
"Service": [
  "directoryservice.rds.ap-southeast-4.amazonaws.com",
  "rds.ap-southeast-4.amazonaws.com"
]
```

## 步驟 4：建立和設定使用者
<a name="postgresql-kerberos-setting-up.create-users"></a>

 您可以透過使用 Active Directory 使用者和運算集區來建立使用者。這是 Active Directory Domain Services 和 Active Directory 輕量型目錄服務工具之一。如需詳細資訊，請參閱 Microsoft 文件中的[將使用者和電腦新增至 Active Directory 網域](https://learn.microsoft.com/en-us/troubleshoot/windows-server/identity/create-an-active-directory-server#add-users-and-computers-to-the-active-directory-domain)。在此情況下，使用者是個人或其他實體，例如其電腦屬於網域，而其身分在目錄中維護。

若要在 Directory Service 目錄中建立使用者，您必須連線到屬於 Directory Service 目錄成員的 Windows 型 Amazon EC2 執行個體。同時，您必須以具有建立使用者之許可的使用者身分來登入。如需詳細資訊，請參閱《AWS Directory Service 管理指南》**中的[建立使用者](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_manage_users_groups_create_user.html)。

## 步驟 5：啟用目錄和資料庫執行個體之間的跨 VPC 流量
<a name="postgresql-kerberos-setting-up.vpc-peering"></a>

如果您打算在相同 VPC 中尋找目錄和資料庫執行個體，請略過本步驟，並移至[步驟 6：建立或修改 PostgreSQL 資料庫執行個體](#postgresql-kerberos-setting-up.create-modify)。

如果您打算在不同 VPC 中尋找目錄和資料庫執行個體，請使用 VPC 互連或 [AWS Transit Gateway](https://docs.aws.amazon.com/vpc/latest/tgw/what-is-transit-gateway.html) 來設定跨 VPC 流量。

下列程序會使用 VPC 互連來啟用 VPC 之間的流量。請遵循《Amazon Virtual Private Cloud 互連指南》**中[什麼是 VPC 互連？](https://docs.aws.amazon.com/vpc/latest/peering/Welcome.html)的指示。

**使用 VPC 互連以啟用跨 VPC 流量**

1. 設定適當的 VPC 路由規則，以確保網路流量可以雙向對流。

1. 確保資料庫執行個體安全群組可以從目錄的安全群組接收傳入流量。

1. 確保沒有網路存取控制清單 (ACL) 規則來封鎖流量。

如果不同的 AWS 帳戶擁有該目錄，您必須共用該目錄。

**在 AWS 帳戶之間共用目錄**

1. 遵循《 AWS *Directory Service 管理指南*》中的[教學課程：共用 AWS Managed Microsoft AD 目錄以實現無縫 EC2 網域加入](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_tutorial_directory_sharing.html)，開始與將在其中建立資料庫執行個體的帳戶共用目錄。

1. 使用資料庫執行個體的帳戶登入 Directory Service 主控台，並確保網域具有 `SHARED` 狀態，然後再繼續。

1. 使用資料庫執行個體的帳戶登入 Directory Service 主控台時，請注意**目錄 ID** 值。您可以使用此目錄 ID，將資料庫執行個體加入網域。

## 步驟 6：建立或修改 PostgreSQL 資料庫執行個體
<a name="postgresql-kerberos-setting-up.create-modify"></a>

建立或修改要搭配目錄使用的 PostgreSQL 資料庫執行個體。您可以使用主控台、CLI 或 RDS API，將資料庫執行個體與目錄建立關聯。您可採用下列其中一種方式來這麼做：
+  使用主控台、[create-db-instance](https://docs.aws.amazon.com/cli/latest/reference/rds/create-db-instance.html) CLI 命令，或 [CreateDBInstance](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_CreateDBInstance.html) RDS API 操作，建立新的 PostgreSQL 資料庫執行個體。如需說明，請參閱「[建立 Amazon RDS 資料庫執行個體](USER_CreateDBInstance.md)」。
+  使用主控台、[modify-db-instance](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-instance.html) CLI 命令，或 [ModifyDBInstance](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_ModifyDBInstance.html) RDS API 操作，修改現有的 PostgreSQL 資料庫執行個體。如需說明，請參閱「[修改 Amazon RDS 資料庫執行個體](Overview.DBInstance.Modifying.md)」。
+  使用主控台、[restore-db-instance-from-db-snapshot](https://docs.aws.amazon.com/cli/latest/reference/rds/restore-db-instance-from-db-snapshot.html) CLI 命令，或 [RestoreDBInstanceFromDBSnapshot](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_RestoreDBInstanceFromDBSnapshot.html) RDS API 操作，從資料庫快照還原 PostgreSQL 資料庫執行個體。如需說明，請參閱「[還原至資料庫執行個體](USER_RestoreFromSnapshot.md)」。
+  使用主控台、[restore-db-instance-to-point-in-time](https://docs.aws.amazon.com/cli/latest/reference/rds/restore-db-instance-to-point-in-time.html) CLI 命令，或 [RestoreDBInstanceToPointInTime](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_RestoreDBInstanceToPointInTime.html) RDS API 操作，將 PostgreSQL 資料庫執行個體還原至某個時間點。如需說明，請參閱「[將 Amazon RDS 的資料庫執行個體還原至指定時間](USER_PIT.md)」。

僅有 VPC 中的 PostgreSQL 資料庫執行個體支援 Kerberos 身分驗證。資料庫執行個體可在與目錄相同的 VPC 中，或在不同 VPC 中。資料庫執行個體必須使用允許在目錄 VPC 內傳入和傳出的安全群組，如此資料庫執行個體才能與目錄通訊。

### 主控台
<a name="postgresql-kerberos-setting-up.create-modify.Console"></a>

使用主控台建立、修改或還原資料庫執行個體時，請在 **Database authentication** (資料庫身分驗證) 區段中選擇 **Password and Kerberos authentication** (密碼和 Kerberos 身分驗證)。然後選擇 **Browse Directory** (瀏覽目錄)。選取目錄或選擇 **Create a new directory** (建立新目錄) 以使用 Directory Service。

![\[選擇 Kerberos 進行身分驗證並識別要使用的目錄。\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/images/rpg-authentication-use-kerberos.png)


### AWS CLI
<a name="postgresql-kerberos-setting-up.create-modify.CLI"></a>

當您使用 時 AWS CLI，資料庫執行個體需要下列參數，才能使用您建立的目錄：
+ 針對 `--domain` 參數，使用您建立目錄時產生的網域識別碼 ("d-\$1" 識別碼)。
+ 針對 `--domain-iam-role-name` 參數，使用您建立的規則，其會使用受管 IAM 政策 `AmazonRDSDirectoryServiceAccess`。

例如，下列 CLI 命令會修改資料庫執行個體來使用目錄。

```
aws rds modify-db-instance --db-instance-identifier mydbinstance --domain d-Directory-ID --domain-iam-role-name role-name 
```

**重要**  
如果您修改資料庫執行個體，以啟用 Kerberos 身分驗證，請在進行變更後重新啟動資料庫執行個體。

## 步驟 7：針對您的 Kerberos 主體建立 PostgreSQL 使用者
<a name="postgresql-kerberos-setting-up.create-logins"></a>

此時，您的 RDS for PostgreSQL 資料庫執行個體已加入 AWS Managed Microsoft AD 網域中。您在 [步驟 4：建立和設定使用者](#postgresql-kerberos-setting-up.create-users) 的目錄中建立的使用者必須設定為 PostgreSQL 資料庫使用者，並授予登入資料庫的權限。您可以透過以具有 `rds_superuser` 權限的資料庫使用者身分登入來執行此操作。例如，如果您在建立 RDS for PostgreSQL 資料庫執行個體時接受預設值，請使用 `postgres`，如下列步驟中所示。

**針對 Kerberos 主體建立 PostgreSQL 資料庫使用者**

1. 使用 `psql` 搭配 `psql` 以連線至 RDS for PostgreSQL 資料庫執行個體端點。下列範例使用 `rds_superuser` 角色的預設 `postgres` 帳戶。

   ```
   psql --host=cluster-instance-1.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password
   ```

1. 針對您想要其有權存取資料庫之每個 Kerberos 主體建立資料庫使用者名稱 (Active Directory 使用者名稱)。針對該使用者名稱使用 Active Directory 執行個體中定義的標準使用者名稱 (身分) (亦即小寫 `alias` (Active Directory 中的使用者名稱))，以及 Active Directory 網域的大寫名稱。Active Directory 使用者名稱是經過外部驗證的使用者，因此請使用引號括住名稱，如下所示。

   ```
   postgres=> CREATE USER "username@CORP.EXAMPLE.COM" WITH LOGIN;
   CREATE ROLE
   ```

1. 將 `rds_ad` 角色授予資料庫使用者。

   ```
   postgres=> GRANT rds_ad TO "username@CORP.EXAMPLE.COM";
   GRANT ROLE
   ```

在您完成了針對 Active Directory 使用者身分建立所有 PostgreSQL 使用者之後，使用者就可以使用其 Kerberos 憑證存取 RDS for PostgreSQL 資料庫執行個體。

使用 Kerberos 進行驗證的資料庫使用者，都必須從屬於 Active Directory 網域成員的用戶端機器執行這項操作。

已獲授予 `rds_ad` 角色的資料庫使用者也無法具有 `rds_iam` 角色。這也適用於巢狀成員資格。如需詳細資訊，請參閱[適用於 MariaDB、MySQL 和 PostgreSQL 的 IAM 資料庫身分驗證](UsingWithRDS.IAMDBAuth.md)。

## 步驟 8：設定 PostgreSQL 用戶端
<a name="postgresql-kerberos-setting-up.configure-client"></a>

若要設定 PostgreSQL 用戶端，請執行下列步驟：
+ 建立可指向網域的 krb5.conf 檔案 (或同等檔案)。
+ 確認流量可以在用戶端主機與 之間流動 Directory Service。請使用 Netcat 等網路公用程式檢查以下各項：
  + 確認透過 DNS 傳送至連接埠 53 的流量。
  + 確認透過 TCP/UDP 傳送至連接埠 53 和 Kerberos 的流量，其中包括用於 Directory Service的連接埠 88 和 464。
+ 確定流量可透過資料庫連接埠在用戶端主機和資料庫執行個體之間往來。例如，您可以使用 psql 來連接和存取資料庫。

以下是 的 krb5 AWS Managed Microsoft AD.conf 內容範例。

```
[libdefaults]
 default_realm = EXAMPLE.COM
[realms]
 EXAMPLE.COM = {
  kdc = example.com
  admin_server = example.com
 }
[domain_realm]
 .example.com = EXAMPLE.COM
 example.com = EXAMPLE.COM
```

下列是內部部署 Microsoft Active Directory 的範例 krb5.conf 內容。

```
[libdefaults]
 default_realm = EXAMPLE.COM
[realms]
 EXAMPLE.COM = {
  kdc = example.com
  admin_server = example.com
 }
 ONPREM.COM = {
  kdc = onprem.com
  admin_server = onprem.com
 }
[domain_realm]
 .example.com = EXAMPLE.COM
 example.com = EXAMPLE.COM
 .onprem.com = ONPREM.COM
 onprem.com = ONPREM.COM  
 .rds.amazonaws.com = EXAMPLE.COM
 .amazonaws.com.rproxy.goskope.com.cn = EXAMPLE.COM
 .amazon.com = EXAMPLE.COM
```

# 在 Active Directory 網域中管理 RDS for PostgreSQL 資料庫執行個體
<a name="postgresql-kerberos-managing"></a>

您可以使用主控台、CLI 或 RDS API，來管理資料庫執行個體，以及其與 Microsoft Active Directory 的關係。例如，您可以使 Active Directory 產生關聯，以啟用 Kerberos 身分驗證。您也可以移除 Active Directory 的關聯，以停用 Kerberos 身分驗證。您可以將要由某個 Microsoft Active Directory 外部識別的資料庫執行個體移至另一個 Microsoft Active Directory。

例如，使用 CLI，您可以執行下列動作：
+ 若要對失敗的成員資格重新嘗試啟用 Kerberos 身分驗證，請使用 [modify-db-instance](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-instance.html) CLI 命令。並針對 `--domain` 選項指定目前成員資格的目錄 ID。
+ 若要在資料庫執行個體上停用 Kerberos 身分驗證，請使用 [modify-db-instance](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-instance.html) CLI 命令。並針對 `none` 選項指定 `--domain`。
+ 若要將資料庫執行個體從某個網域移至另一個網域，請使用 [modify-db-instance](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-instance.html) CLI 命令。並針對 `--domain` 選項指定新網域的網域識別符。

## 了解網域成員資格
<a name="postgresql-kerberos-managing.understanding"></a>

在您建立或修改資料庫執行個體之後，網域的成員。您可以在主控台中或執行 [describe-db-instances](https://docs.aws.amazon.com/cli/latest/reference/rds/describe-db-instances.html) CLI 命令，來檢視網域成員資格狀態。資料庫執行個體的狀態可以是下列其中一個：
+ `kerberos-enabled` – 資料庫執行個體已啟用 Kerberos 身分驗證。
+ `enabling-kerberos` – AWS 正在在此資料庫執行個體上啟用 Kerberos 身分驗證。
+ `pending-enable-kerberos` – 在此資料庫執行個體上擱置 Kerberos 身分驗證的啟用。
+ `pending-maintenance-enable-kerberos` – AWS 將在下一個排定的維護時段嘗試在資料庫執行個體上啟用 Kerberos 身分驗證。
+ `pending-disable-kerberos` – 在此資料庫執行個體上擱置 Kerberos 身分驗證的停用。
+ `pending-maintenance-disable-kerberos` – AWS 將嘗試在下一個排定的維護時段停用資料庫執行個體上的 Kerberos 身分驗證。
+ `enable-kerberos-failed` – AWS 無法在資料庫執行個體上啟用 Kerberos 身分驗證的組態問題。請更正問題，然後重新發出命令來修改資料庫執行個體。
+ `disabling-kerberos` – AWS 正在停用此資料庫執行個體上的 Kerberos 身分驗證。

由於網路連線問題或 IAM 角色不正確，請求啟用 Kerberos 身分驗證可能失敗。在某些情況下，當您建立或修改資料庫執行個體時，嘗試啟用 Kerberos 身分驗證可能會失敗。若是如此，請確定您使用正確的 IAM 角色，然後修改要加入網域的資料庫執行個體。

**注意**  
只有搭配使用 Kerberos 身分驗證與 RDS for PostgreSQL 時，流量才會傳送至網域的 DNS 伺服器。所有其他 DNS 請求都會被視為執行 PostgreSQL 之資料庫執行個體上的傳出網路存取。如需傳出網路存取搭配 RDS for PostgreSQL 的詳細資訊，請參閱[針對傳出網路存取使用自訂 DNS 伺服器。](Appendix.PostgreSQL.CommonDBATasks.CustomDNS.md)。

# 使用 Kerberos 身分驗證連線至 PostgreSQL
<a name="postgresql-kerberos-connecting"></a>

您可以使用 pgAdmin 界面或 psql 等命令列界面搭配 Kerberos 身分驗證連接至 PostgreSQL。如需連線的詳細資訊，請參閱 [連線至執行 PostgreSQL 資料庫引擎的資料庫執行個體](USER_ConnectToPostgreSQLInstance.md) 。如需取得端點、連接埠號碼和其他連線所需詳細資訊的資訊，請參閱 [連接至 PostgreSQL 資料庫執行個體](CHAP_GettingStarted.CreatingConnecting.PostgreSQL.md#CHAP_GettingStarted.Connecting.PostgreSQL)。

**注意**  
PostgreSQL 中的 GSSAPI 身分驗證和加密是由 Kerberos 程式庫 `libkrb5.so` 實作。`postgres_fdw` 和 `dblink` 等功能也依賴此相同的程式庫，來使用 Kerberos 身分驗證或加密進行傳出連線。

## pgAdmin
<a name="collapsible-section-pgAdmin"></a>

若要使用 Kerberos 身分驗證搭配 pgAdmin 連接至 PostgreSQL，請遵循下列步驟：

1. 在您的用戶端電腦上啟動 pgAdmin 應用程式。

1. 在 **Dashboard (儀表板)** 標籤上，選擇 **Add New Server (新增伺服器)**。

1. 在 **Create - Server (建立 - 伺服器)** 對話方塊中，於 **General (一般)** 標籤上輸入名稱，以識別 pgAdmin 中的伺服器。

1. 在 **Connection** (連線) 標籤上，輸入來自 RDS for PostgreSQL 資料庫的下列資訊：
   + 對於 **Host** (託管)，輸入 的端點。RDS for PostgreSQL 資料庫執行個體。端點看起來類似下列：

     ```
     RDS-DB-instance.111122223333.aws-region.rds.amazonaws.com
     ```

     若要從 Windows 用戶端連線至內部部署 Microsoft Active Directory，您可以使用 AWS 受管 Active Directory 的網域名稱，而不是在主機端點`rds.amazonaws.com`中。例如，假設 AWS Managed Active Directory 的網域名稱為 `corp.example.com`。然後對於 **Host** (託管)，端點的指定方式如下：

     ```
     RDS-DB-instance.111122223333.aws-region.corp.example.com
     ```
   + 針對 **Port (連接埠)**，輸入指派的連接埠。
   + 針對 **Maintenance database (維護資料庫)**，輸入用戶端將連接的初始資料庫名稱。
   + 針對 **Username (使用者名稱)**，輸入您在 [步驟 7：針對您的 Kerberos 主體建立 PostgreSQL 使用者](postgresql-kerberos-setting-up.md#postgresql-kerberos-setting-up.create-logins) 中為 Kerberos 身分驗證輸入的使用者名稱。

1. 選擇**儲存**。

## Psql
<a name="collapsible-section-psql"></a>

若要使用 Kerberos 身分驗證搭配 psql 連接至 PostgreSQL，請遵循下列步驟：

1. 在命令提示中，執行下列命令。

   ```
   kinit username                
   ```

   請將 *`username`* 換成使用者名稱。在提示字元中，輸入 Microsoft Active Directory 中為使用者存放的密碼。

1. 如果 PostgreSQL 資料庫執行個體是使用可公開存取的 VPC，請將資料庫執行個體端點的 IP 地址放入 EC2 用戶端上的 `/etc/hosts` 檔案。例如，使用下列命令取得 IP 地址，然後將該地址放入 `/etc/hosts` 檔案。

   ```
   % dig +short PostgreSQL-endpoint.AWS-Region.rds.amazonaws.com  
   ;; Truncated, retrying in TCP mode.
   ec2-34-210-197-118.AWS-Region.compute.amazonaws.com.
   34.210.197.118 
   
   % echo " 34.210.197.118  PostgreSQL-endpoint.AWS-Region.rds.amazonaws.com" >> /etc/hosts
   ```

   如果使用來自 Windows 用戶端的內部部署 Microsoft Active Directory，則需要使用特殊化的端點進行連線。使用 AWS Managed Active Directory 的網域名稱，而不是在主機端點`rds.amazonaws.com`中使用 Amazon 網域。

   例如，假設 AWS Managed Active Directory 的網域名稱為 `corp.example.com`。則為端點使用 `PostgreSQL-endpoint.AWS-Region.corp.example.com` 格式並將其放入 `/etc/hosts` 檔案中。

   ```
   % echo " 34.210.197.118  PostgreSQL-endpoint.AWS-Region.corp.example.com" >> /etc/hosts
   ```

1. 使用下列 psql 命令來登入與 Active Directory 整合的 PostgreSQL 資料庫執行個體。

   ```
   psql -U username@CORP.EXAMPLE.COM -p 5432 -h PostgreSQL-endpoint.AWS-Region.rds.amazonaws.com postgres
   ```

   若要使用內部部署 Active Directory 從 Windows 用戶端登入 PostgreSQL 資料庫叢集，請使用下列 psql 命令搭配上一個步驟的網域名稱 (`corp.example.com`)：

   ```
   psql -U username@CORP.EXAMPLE.COM -p 5432 -h PostgreSQL-endpoint.AWS-Region.corp.example.com postgres
   ```

# 針對傳出網路存取使用自訂 DNS 伺服器。
<a name="Appendix.PostgreSQL.CommonDBATasks.CustomDNS"></a>

RDS for PostgreSQL 支援資料庫執行個體上的傳出網路存取，且允許來自客戶擁有的自訂 DNS 伺服器的網域名稱服務 (DNS) 解析。您僅可以透過您的自訂 DNS 伺服器，解析來自您 RDS for PostgreSQL 資料庫執行個體的完整網域名稱。

**Topics**
+ [開啟自訂 DNS 解析](#Appendix.PostgreSQL.CommonDBATasks.CustomDNS.Enable)
+ [關閉自訂 DNS 解析](#Appendix.PostgreSQL.CommonDBATasks.CustomDNS.Disable)
+ [設定自訂 DNS 伺服器](#Appendix.Oracle.CommonDBATasks.CustomDNS.Setup)

## 開啟自訂 DNS 解析
<a name="Appendix.PostgreSQL.CommonDBATasks.CustomDNS.Enable"></a>

若要在您的客戶 VPC 中開啟 DNS 解析，請先將自訂資料庫參數群組與您的 RDS for PostgreSQL 執行個體建立關聯。然後將參數設定為 1 來開啟 `rds.custom_dns_resolution`，接下來將資料庫執行個體重新啟動，讓變更生效。

## 關閉自訂 DNS 解析
<a name="Appendix.PostgreSQL.CommonDBATasks.CustomDNS.Disable"></a>

若要在客戶 VPC 中關閉 DNS 解析，請首先關閉自訂資料庫參數群組的 `rds.custom_dns_resolution` 參數，方法是將資料庫參數群組設定為 0。然後重新啟動資料庫執行個體，讓變更生效。

## 設定自訂 DNS 伺服器
<a name="Appendix.Oracle.CommonDBATasks.CustomDNS.Setup"></a>

設定您的自訂 DNS 名稱伺服器之後，需要最多 30 分鐘的時間，才能將變更傳播到您的資料庫執行個體。變更傳播到您的資料庫執行個體之後，所有傳出網路流量都需要透過連接埠 53 對您的 DNS 伺服器進行 DNS 查閱查詢。

**注意**  
如果您未設定自訂 DNS 伺服器，且設定 `rds.custom_dns_resolution` 為 1，則會使用 Amazon Route 53 私有區域來解析主機。如需詳細資訊，請參閱[使用私有託管區域](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/hosted-zones-private.html)。

**為 RDS for PostgreSQL 資料庫執行個體設定自訂 DNS 伺服器**

1. 從連接至您 VPC 的 動態主機組態協定 (DHCP) 選項集，將 `domain-name-servers` 選項設定為您 DNS 名稱伺服器的 IP 地址。如需詳細資訊，請參閱 [DHCP 選項集](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_DHCP_Options.html)。
**注意**  
`domain-name-servers` 選項會接受最多四個值，但您的 Amazon RDS 資料庫執行個體只會使用第一個值。

1. 請確保您的 DNS 伺服器可以解析所有查閱查詢，包括公有 DNS 名稱、Amazon EC2 私有 DNS 名稱，以及客戶特定的 DNS 名稱。如果傳出網路流量包含您的 DNS 伺服器無法處理的任何 DNS 查閱，您的 DNS 伺服器就必須設定適當的上游 DNS 提供者。

1. 設定您的 DNS 伺服器以產生 512 個位元組或更少的使用者資料包通訊協定 (UDP) 回應。

1. 設定您的 DNS 伺服器以產生 1,024 個位元組或更少的傳輸控制通訊協定 (TCP) 回應。

1. 設定您的 DNS 伺服器以允許來自您的 Amazon RDS 資料庫執行個體透過連接埠 53 的傳入流量。如果您的 DNS 伺服器位於 Amazon VPC 中，VPC 必須具有一個安全群組，其中包含允許連接埠 53 上的 UDP 和 TCP 流量的傳入規則。如果您的 DNS 伺服器不在 Amazon VPC 中，則必須具有適當的防火牆設定，才能允許連接埠 53 上的 UDP 和 TCP 傳入流量。

   如需更多詳細資訊，請參閱 [VPC 安全群組](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html)和[新增與移除規則](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html#AddRemoveRules)。

1. 設定您 Amazon RDS 資料庫執行個體的 VPC，以允許透過連接埠 53 的傳出流量。您的 VPC 必須具有一個安全群組，其中包含允許連接埠 53 上的 UDP 和 TCP 流量的傳出規則。

   如需詳細資訊，請參閱《Amazon VPC 使用者指南》**中的[VPC 的安全群組](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html)和[新增與移除規則](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html#AddRemoveRules)。

1. 必須正確設定 Amazon RDS 資料庫執行個體和 DNS 伺服器之間的路由路徑，才能允許 DNS 流量。

   此外，如果 Amazon RDS 資料庫執行個體和 DNS 伺服器不在相同的 VPC 中，請務必在兩者之間設定對等連線。如需詳細資訊，請參閱《Amazon VPC 對等互連指南》**中的[什麼是 VPC 對等互連？](https://docs.aws.amazon.com/vpc/latest/peering/Welcome.html) 

# RDS for PostgreSQL 資料庫引擎的升級
<a name="USER_UpgradeDBInstance.PostgreSQL"></a>

您可以為 PostgreSQL 資料庫管理兩種類型的升級：
+ 作業系統更新 - Amazon RDS 偶爾可能需要更新資料庫的基礎作業系統，才能套用安全修正或作業系統變更。您可以使用 RDS 主控台、 AWS Command Line Interface (AWS CLI) 或 RDS API 來決定 Amazon RDS 何時套用作業系統更新。如需作業系統更新的詳細資訊，請參閱[將更新套用至資料庫執行個體](USER_UpgradeDBInstance.Maintenance.md#USER_UpgradeDBInstance.OSUpgrades)。
+  資料庫引擎升級 - 當 Amazon RDS 支援新版本的資料庫引擎時，您可以將資料庫升級為新版本。

此環境中的*資料庫*是 RDS for PostgreSQL 資料庫執行個體或多可用區域資料庫叢集。

PostgreSQL 資料庫有兩種引擎升級︰主要版本升級和次要版本升級。

**主要版本升級**  
*主要版本升級* 可能包含與現有應用程式回溯不相容的資料庫變更。因此，您必須手動執行資料庫的主要版本升級。您可以透過修改資料庫執行個體或多可用區域資料庫叢集來啟動主要版本升級。在您執行主要的版本升級之前，建議您依照 [選擇 RDS for PostgreSQL 升級的主要版本](USER_UpgradeDBInstance.PostgreSQL.MajorVersion.md) 中所述的步驟操作。  
Amazon RDS 會以下列方式處理多可用區域主要版本升級：  
+ **多可用區域資料庫執行個體部署** - Amazon RDS 會同時升級主要和任何待命執行個體。升級完成後，您的資料庫可能會有幾分鐘無法使用。
+ **多可用區域資料庫叢集部署** - Amazon RDS 會同時升級讀取器和寫入器執行個體。升級完成後，您的資料庫可能會有幾分鐘無法使用。
如果您升級具有區域內僅供讀取複本的資料庫執行個體，Amazon RDS 會將複本與主要資料庫執行個體一起升級。  
Amazon RDS 不會升級多可用區域資料庫叢集讀取複本。如果您執行多可用區域資料庫叢集的主要版本升級，則其僅供讀取複本的複寫狀態會變更為**已終止**。升級完成後，您必須手動刪除並重新建立僅供讀取複本。  
您可以使用藍/綠部署，將主要版本升級所需的停機時間降至最低。如需詳細資訊，請參閱 [使用 Amazon RDS 藍/綠部署進行資料庫更新](blue-green-deployments.md)。

**次要版本升級**  
反之，*次要版本升級* 只包含與現有應用程式回溯相容的變更。您可以藉由修改資料庫來手動啟動次要版本升級。或者，您也可以在建立或修改資料庫時啟用**自動次要版本升級**選項。這麼做代表 Amazon RDS 會在測試並核准新版本後自動升級您的資料庫。  
Amazon RDS 會以下列方式處理多可用區域次要版本升級：  
+ **多可用區域資料庫執行個體部署** - Amazon RDS 會同時升級主要和任何待命執行個體。升級完成後，您的資料庫可能會有幾分鐘無法使用。
+ **多可用區域資料庫叢集部署** – Amazon RDS 會逐一升級讀取器資料庫執行個體。然後，其中一個讀取器資料庫執行個體會切換為新的寫入器資料庫執行個體。Amazon RDS 接著會升級舊的寫入器執行個體 (現在是讀取器執行個體)。多可用區域資料庫叢集通常可將次要版本升級的停機時間縮短到約 35 秒。與 RDS Proxy 搭配使用時，可以進一步將停機時間縮短到一秒或更短。如需詳細資訊，請參閱[Amazon RDS Proxy ](rds-proxy.md)。或者，您可以使用開放原始碼資料庫代理，例如 [ProxySQL](https://aws.amazon.com/blogs/database/achieve-one-second-or-less-of-downtime-with-proxysql-when-upgrading-amazon-rds-multi-az-deployments-with-two-readable-standbys/)、[PgBouncer](https://aws.amazon.com/blogs/database/fast-switchovers-with-pgbouncer-on-amazon-rds-multi-az-deployments-with-two-readable-standbys-for-postgresql/) 或 [AWS 進階 JDBC 包裝函式驅動程式](https://aws.amazon.com/blogs/database/achieve-one-second-or-less-downtime-with-the-advanced-jdbc-wrapper-driver-when-upgrading-amazon-rds-multi-az-db-clusters/)。
如果您的資料庫含有僅供讀取複本，則在升級來源執行個體或叢集之前，您必須先升級所有僅供讀取複本。  
如需詳細資訊，請參閱[RDS for PostgreSQL 的自動次要版本升級](USER_UpgradeDBInstance.PostgreSQL.Minor.md)。如需有關手動執行次要版本升級的詳細資訊，請參閱[手動升級引擎版本](USER_UpgradeDBInstance.Upgrading.md#USER_UpgradeDBInstance.Upgrading.Manual)。

如需資料庫引擎版本和取代資料庫引擎版本之政策的詳細資訊，請參閱 Amazon RDS 常見問答集中的[資料庫引擎版本](https://aws.amazon.com/rds/faqs/#Database_Engine_Versions)。

**Topics**
+ [PostgreSQL 升級考量](#USER_UpgradeDBInstance.PostgreSQL.Considerations)
+ [尋找有效的升級目標](#USER_UpgradeDBInstance.PostgreSQL.FindingTargets)
+ [PostgreSQL 版本編號](USER_UpgradeDBInstance.PostgreSQL.VersionID.md)
+ [RDS for PostgreSQL 中的 RDS 版本號碼](USER_UpgradeDBInstance.PostgreSQL.rds.version.md)
+ [選擇 RDS for PostgreSQL 升級的主要版本](USER_UpgradeDBInstance.PostgreSQL.MajorVersion.md)
+ [如何執行 RDS for PostgreSQL 的主要版本升級](USER_UpgradeDBInstance.PostgreSQL.MajorVersion.Process.md)
+ [RDS for PostgreSQL 的自動次要版本升級](USER_UpgradeDBInstance.PostgreSQL.Minor.md)
+ [升級 RDS for PostgreSQL 資料庫中的 PostgreSQL 延伸模組](USER_UpgradeDBInstance.PostgreSQL.ExtensionUpgrades.md)
+ [使用事件監控 RDS for PostgreSQL 引擎升級](USER_UpgradeDBInstance.PostgreSQL.Monitoring.md)

## PostgreSQL 升級考量
<a name="USER_UpgradeDBInstance.PostgreSQL.Considerations"></a>

為了安全地升級您的資料庫，Amazon RDS 會使用 [PostgreSQL 文件](https://www.postgresql.org/docs/current/pgupgrade.html)中所述的 `pg_upgrade` 公用程式

如果您的備份保留期大於 0，則 Amazon RDS 會在升級程序期間建立兩個資料庫快照。第一個資料庫快照是屬於完成任何升級變更之前的資料庫。如果資料庫升級失敗，您可以還原此快照，以建立執行舊版本的資料庫。升級完成後會建立第二個資料庫快照。這些資料庫快照會在備份保留期間過期後自動刪除。

**注意**  
您必須將資料庫的備份保留期設定為大於 0 的數字，Amazon RDS 才會在升級過程中拍攝資料庫快照。若要變更資料庫執行個體的備份保留期，請參閱 [修改 Amazon RDS 資料庫執行個體](Overview.DBInstance.Modifying.md)。您無法為多可用區域資料庫叢集設定自訂備份保留期。

當您執行資料庫執行個體的主要版本升級時，任何區域內僅供讀取複本也都會自動升級。升級工作流程開始後，僅供讀取複本會等待主要資料庫執行個體上的 `pg_upgrade` 順利完成。然後，主要資料庫執行個體升級會等待僅供讀取複本升級完成。在升級完成之前，可能會遭遇停機。當您執行多可用區域資料庫叢集的主要版本升級時，其僅供讀取複本的複寫狀態會變更為**已終止**。

升級完成後，您就無法還原為舊版的資料庫引擎。若您想要恢復前一版本，請從升級前拍攝的資料庫快照進行還原，以建立新的資料庫。

## 尋找有效的升級目標
<a name="USER_UpgradeDBInstance.PostgreSQL.FindingTargets"></a>

當您使用 AWS 管理主控台 來升級資料庫時，會顯示資料庫的有效升級目標。您也可以使用下列 AWS CLI 命令來識別資料庫的有效升級目標：

針對 Linux、macOS 或 Unix：

```
aws rds describe-db-engine-versions \
  --engine postgres \
  --engine-version version-number \
  --query "DBEngineVersions[*].ValidUpgradeTarget[*].{EngineVersion:EngineVersion}" --output text
```

在 Windows 中：

```
aws rds describe-db-engine-versions ^
  --engine postgres ^
  --engine-version version-number ^
  --query "DBEngineVersions[*].ValidUpgradeTarget[*].{EngineVersion:EngineVersion}" --output text
```

例如，若要識別 PostgreSQL 16.1 版資料庫的有效升級目標，請執行下列 AWS CLI 命令：

針對 Linux、macOS 或 Unix：

```
aws rds describe-db-engine-versions \
  --engine postgres \
  --engine-version 16.1 \
  --query "DBEngineVersions[*].ValidUpgradeTarget[*].{EngineVersion:EngineVersion}" --output text
```

在 Windows 中：

```
aws rds describe-db-engine-versions ^
  --engine postgres ^
  --engine-version 16.1 ^
  --query "DBEngineVersions[*].ValidUpgradeTarget[*].{EngineVersion:EngineVersion}" --output text
```

# PostgreSQL 版本編號
<a name="USER_UpgradeDBInstance.PostgreSQL.VersionID"></a>

PostgreSQL 資料庫引擎的版本編號順序如下：
+ 針對 PostgreSQL 第 10 版和更高版本，引擎版本號碼的格式為 *major.minor*。主要版本號是版本號碼的整數部分。次要版本號碼是版本號碼的小數部分。

  主要版本升級會增加版本號碼的整數部分，例如從 10.*minor* 升級為 11.*minor*。
+ 低於第 10 版的 PostgreSQL 會採用 *major.major.minor* 格式的引擎版本號碼。主要引擎版本號碼是整數和版本號碼的第一個小數部分。例如，9.6 是主要版本。次要版本號碼是版本號碼的第三部分。例如，對於第 9.6.12 版而言，12 是次要版本號碼。

  主要版本升級會增加版本號碼的主要部分。例如，從 *9.6*.12 升級至 11.14 是主要版本升級，其中 *9.6* 和 *11* 是主要版本編號。

如需 RDS 延長支援版本編號的詳細資訊，請參閱 [Amazon RDS 延伸支援版本命名](extended-support-versions.md#extended-support-naming)。

# RDS for PostgreSQL 中的 RDS 版本號碼
<a name="USER_UpgradeDBInstance.PostgreSQL.rds.version"></a>

RDS 版本編號會使用 `major.minor.patch` 命名方案。RDS 修補程式版本中包含發行後新增到次要版本的重要錯誤修正。如需 RDS 延長支援版本編號的詳細資訊，請參閱 [Amazon RDS 延伸支援版本命名](extended-support-versions.md#extended-support-naming)。

若要識別資料庫的 Amazon RDS 版本編號，您必須先使用下列命令建立 `rds_tools` 延伸模組：

```
CREATE EXTENSION rds_tools;
```

從 PostgreSQL 15.2-R2 版開始，您可以使用以下 SQL 查詢，找出 RDS for PostgreSQL 資料庫的 RDS 版本編號：

```
postgres=> SELECT rds_tools.rds_version();
```

例如，查詢 RDS for PostgreSQL 15.2 資料庫會傳回以下內容：

```
rds_version
----------------
 15.2.R2
(1 row)
```

# 選擇 RDS for PostgreSQL 升級的主要版本
<a name="USER_UpgradeDBInstance.PostgreSQL.MajorVersion"></a>

主要版本升級可能包含無法與舊版資料庫回溯相容的變更。新功能可能導致現有的應用程式停止正確運作。因此，Amazon RDS 不會自動套用主要版本升級。若要執行主要版本升級，請手動修改資料庫。所有升級都務必要經過完整測試，以確認您的應用程式正常運作，再將升級套用至您的生產資料庫。進行 PostgreSQL 主要版本升級時，建議您遵循 [如何執行 RDS for PostgreSQL 的主要版本升級](USER_UpgradeDBInstance.PostgreSQL.MajorVersion.Process.md) 中描述的步驟。

當您將 PostgreSQL 單一可用區域資料庫執行個體或多可用區域資料庫執行個體部署升級到下一個主要版本時，任何與資料庫相關聯的僅供讀取複本也會升級到相同的下一個主要版本。在某些情況下，您可以在升級時跳到更高的主要版本。如果您的升級略過主要版本，僅供讀取複本也會升級至該目標主要版本。跳過其他主要版本直接升級至第 11 版存在某些限制。您可以按照 [如何執行 RDS for PostgreSQL 的主要版本升級](USER_UpgradeDBInstance.PostgreSQL.MajorVersion.Process.md) 所述的步驟中找到詳細資訊。

PostgreSQL 引擎升級時並不會升級大多數的 PostgreSQL 擴充功能。這些擴充功能必須單獨升級。如需詳細資訊，請參閱[升級 RDS for PostgreSQL 資料庫中的 PostgreSQL 延伸模組](USER_UpgradeDBInstance.PostgreSQL.ExtensionUpgrades.md)。

您可以執行下列 AWS CLI 查詢，找出 RDS for PostgreSQL 資料庫可用的主要版本：

```
aws rds describe-db-engine-versions --engine postgres  --engine-version your-version --query "DBEngineVersions[*].ValidUpgradeTarget[*].{EngineVersion:EngineVersion}" --output text
```

下表總結了所有可用版本的查詢結果。版本號碼上的星號 (\$1) 表示該版本已不受支援。如果您目前的版本已不受支援，建議您升級到最新的次要版本升級目標，或升級到該版本的其他可用升級目標之一。


| 目前來源版本 | 升級目標 | 
| --- | --- | 
| 17.6 | 無 | 
| 17.5 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176) | 
| 17.4 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175) | 
| 17.3\$1、17.2 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175)、[17.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version174) | 
| 17.1\$1 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175)、[17.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version174)、[17.2](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version172) | 
| 16.10 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176) | 
| 16.9 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610) | 
| 16.8 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175)、[17.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version174) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169) | 
| 16.7\$1 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175)、[17.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version174) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169)、[16.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version168) | 
| 16.7 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175)、[17.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version174) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169)、[16.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version168) | 
| 16.6 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175)、[17.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version174)、[17.2](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version172) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169)、[16.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version168) | 
| 16.5\$1、16.4 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175)、[17.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version174)、[17.2](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version172) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169)、[16.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version168)、[16.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version166) | 
| 16.3 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175)、[17.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version174)、[17.2](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version172) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169)、[16.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version168)、[16.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version166)、[16.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version164) | 
| 16.2\$1、16.1\$1 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175)、[17.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version174)、[17.2](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version172) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169)、[16.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version168)、[16.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version166)、[16.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version164)、[16.3](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version163) | 
| 15.14 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610) | 
| 15.13 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169) [15.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1514) | 
| 15.12、15.11\$1 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175)、[17.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version174) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169)、[16.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version168) [15.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1514)、[15.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1513) | 
| 15.10 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175)、[17.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version174)、[17.2](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version172) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169)、[16.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version168)、[16.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version166) [15.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1514)、[15.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1513)、[15.12](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1512) | 
| 15.9\$1 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175)、[17.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version174)、[17.2](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version172) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169)、[16.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version168)、[16.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version166) [15.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1514)、[15.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1513)、[15.12](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1512)、[15.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1510) | 
| 15.8 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175)、[17.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version174)、[17.2](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version172) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169)、[16.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version168)、[16.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version166)、[16.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version164) [15.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1514)、[15.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1513)、[15.12](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1512)、[15.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1510) | 
| 15.7 | [16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169)、[16.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version168)、[16.7](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version167)、[16.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version166)、[16.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version165)、[16.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version164)、[16.3](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version163) [15.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1513)、[15.12](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1512)、[15.11](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1511)、[15.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1510)、[15.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version159)、[15.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version158) | 
| 15.6\$1、15.5\$1、15.4\$1、15.3\$1、15.2\$1 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175)、[17.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version174)、[17.2](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version172) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169)、[16.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version168)、[16.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version166)、[16.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version164)、[16.3](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version163) [15.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1514)、[15.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1513)、[15.12](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1512)、[15.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1510)、[15.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version158)、[15.7](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version157) | 
| 14.19 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610) [15.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1514) | 
| 14.18 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169) [15.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1514)、[15.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1513) [14.19](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1419) | 
| 14.17、14.16\$1 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175)、[17.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version174) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169)、[16.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version168) [15.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1514)、[15.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1513)、[15.12](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1512) [14.19](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1419)、[14.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1418) | 
| 14.15 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175)、[17.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version174)、[17.2](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version172) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169)、[16.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version168)、[16.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version166) [15.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1514)、[15.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1513)、[15.12](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1512)、[15.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1510) [14.19](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1419)、[14.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1418)、[14.17](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1417) | 
| 14.14\$1 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175)、[17.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version174)、[17.2](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version172) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169)、[16.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version168)、[16.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version166) [15.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1514)、[15.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1513)、[15.12](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1512)、[15.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1510) [14.19](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1419)、[14.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1418)、[14.17](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1417)、[14.15](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1415) | 
| 14.13 | [16.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version164) [15.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1513)、[15.12](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1512)、[15.11](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1511)、[15.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1510)、[15.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version159)、[15.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version158) [14.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1418)、[14.17](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1417)、[14.16](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1416)、[14.15](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1415)、[14.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1414) | 
| 14.12 | [16.3](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version163) [15.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1513)、[15.12](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1512)、[15.11](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1511)、[15.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1510)、[15.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version159)、[15.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version158)、[15.7](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version157) [14.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1418)、[14.17](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1417)、[14.16](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1416)、[14.15](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1415)、[14.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1414)、[14.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1413) | 
| 14.11\$1、14.10\$1、14.9\$1、14.8\$1、14.7\$1、14.6\$1、14.5\$1、14.4\$1、14.3\$1、14.2\$1、14.1\$1 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175)、[17.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version174)、[17.2](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version172) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169)、[16.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version168)、[16.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version166)、[16.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version164)、[16.3](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version163) [15.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1514)、[15.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1513)、[15.12](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1512)、[15.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1510)、[15.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version158)、[15.7](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version157) [14.19](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1419)、[14.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1418)、[14.17](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1417)、[14.15](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1415)、[14.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1413)、[14.12](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1412) | 
| 13.22 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610) [15.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1514) [14.19](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1419) | 
| 13.21 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169) [15.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1514)、[15.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1513) [14.19](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1419)、[14.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1418) [13.22](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1322) | 
| 13.20、13.19\$1 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175)、[17.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version174) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169)、[16.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version168) [15.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1514)、[15.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1513)、[15.12](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1512) [14.19](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1419)、[14.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1418)、[14.17](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1417) [13.22](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1322)、[13.21](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1321) | 
| 13.18、13.17\$1 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175)、[17.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version174)、[17.2](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version172) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169)、[16.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version168)、[16.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version166) [15.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1514)、[15.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1513)、[15.12](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1512)、[15.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1510) [14.19](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1419)、[14.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1418)、[14.17](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1417)、[14.15](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1415) [13.22](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1322)、[13.21](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1321)、[13.20](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1320) | 
| 13.16 | [16.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version164) [15.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version158) [14.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1418)、[14.17](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1417)、[14.15](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1415)、[14.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1414)、[14.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1413) [13.21](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1321)、[13.20](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1320)、[13.19](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1319)、[13.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1318)、[13.17](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1317) | 
| 13.15 | [16.3](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version163) [15.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version158)、[15.7](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version157) [14.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1418)、[14.17](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1417)、[14.15](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1415)、[14.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1414)、[14.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1413)、[14.12](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1412) [13.21](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1321)、[13.20](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1320)、[13.19](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1319)、[13.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1318)、[13.17](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1317)、[13.16](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1316) | 
| 13.14\$1、13.13\$1、13.12\$1、13.11\$1、13.10\$1、13.9\$1、13.8\$1、13.7\$1、13.6\$1、13.5\$1、13.4\$1、13.3\$1、13.2\$1、13.1\$1 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175)、[17.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version174)、[17.2](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version172) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169)、[16.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version168)、[16.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version166)、[16.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version164)、[16.3](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version163) [15.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1514)、[15.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1513)、[15.12](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1512)、[15.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1510)、[15.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version158)、[15.7](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version157) [14.19](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1419)、[14.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1418)、[14.17](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1417)、[14.15](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1415)、[14.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1413)、[14.12](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1412) [13.22](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1322)、[13.21](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1321)、[13.20](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1320)、[13.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1318)、[13.16](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1316)、[13.15](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1315) | 
| 12.22-rds.20250508 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169) [15.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1514)、[15.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1513) [14.19](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1419)、[14.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1418) [13.22](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1322)、[13.21](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1321) | 
| 12.22-rds.20250220 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175)、[17.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version174) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169)、[16.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version168) [15.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1514)、[15.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1513)、[15.12](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1512) [14.19](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1419)、[14.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1418)、[14.17](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1417) [13.22](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1322)、[13.21](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1321)、[13.20](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1320) [12.22-rds.20250508](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1222rds20250508) | 
| 12.22、12.21\$1 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175)、[17.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version174)、[17.2](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version172) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169)、[16.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version168)、[16.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version166) [15.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1514)、[15.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1513)、[15.12](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1512)、[15.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1510) [14.19](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1419)、[14.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1418)、[14.17](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1417)、[14.15](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1415) [13.22](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1322)、[13.21](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1321)、[13.20](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1320)、[13.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1318) [12.22-rds.20250220](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1222rds20250220)、[12.22-rds.20250508](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1222rds20250508) | 
| 12.20\$1 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175)、[17.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version174)、[17.2](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version172) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169)、[16.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version168)、[16.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version166)、[16.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version164) [15.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1514)、[15.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1513)、[15.12](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1512)、[15.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1510)、[15.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version158) [14.19](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1419)、[14.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1418)、[14.17](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1417)、[14.15](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1415)、[14.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1413) [13.22](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1322)、[13.21](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1321)、[13.20](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1320)、[13.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1318)、[13.16](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1316) [12.22](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1222)、[12.22-rds.20250220](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1222rds20250220)、[12.22-rds.20250508](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1222rds20250508) | 
| 12.19\$1、12.18\$1、12.17\$1、12.16\$1、12.15\$1、12.14\$1、12.13\$1、12.12\$1、12.11\$1、12.10\$1、12.9\$1、12.8\$1、12.7\$1、12.6\$1、12.5\$1、12.4\$1、12.3\$1、12.2\$1 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175)、[17.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version174)、[17.2](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version172) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169)、[16.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version168)、[16.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version166)、[16.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version164)、[16.3](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version163) [15.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1514)、[15.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1513)、[15.12](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1512)、[15.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1510)、[15.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version158)、[15.7](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version157) [14.19](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1419)、[14.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1418)、[14.17](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1417)、[14.15](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1415)、[14.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1413)、[14.12](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1412) [13.22](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1322)、[13.21](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1321)、[13.20](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1320)、[13.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1318)、[13.16](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1316)、[13.15](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1315) [12.22](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1222)、[12.22-rds.20250220](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1222rds20250220)、[12.22-rds.20250508](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1222rds20250508) | 
| 11.22-rds.20250508 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169) [15.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1514)、[15.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1513) [14.19](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1419)、[14.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1418) [13.22](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1322)、[13.21](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1321) [12.22-rds.20250508](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1222rds20250508) | 
| 11.22-rds.20250220 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175)、[17.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version174) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169)、[16.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version168) [15.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1514)、[15.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1513)、[15.12](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1512) [14.19](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1419)、[14.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1418)、[14.17](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1417) [13.22](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1322)、[13.21](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1321)、[13.20](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1320) [12.22-rds.20250220](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1222rds20250220)、[12.22-rds.20250508](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1222rds20250508) [11.22-rds.20250508](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1122rds20250508) | 
| 11.22-rds.20240509 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175)、[17.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version174)、[17.2](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version172) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169)、[16.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version168)、[16.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version166)、[16.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version164)、[16.3](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version163) [15.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1514)、[15.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1513)、[15.12](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1512)、[15.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1510)、[15.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version158)、[15.7](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version157) [14.19](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1419)、[14.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1418)、[14.17](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1417)、[14.15](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1415)、[14.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1413)、[14.12](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1412) [13.22](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1322)、[13.21](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1321)、[13.20](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1320)、[13.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1318)、[13.16](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1316)、[13.15](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1315) [12.22](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1222)、[12.22-rds.20250220](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1222rds20250220)、[12.22-rds.20250508](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1222rds20250508) [11.22-rds.20240808](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1122rds20240808)、[11.22-rds.20241121](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1122rds20241121)、[11.22-rds.20250220](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1122rds20250220)、[11.22-rds.20250508](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1122rds20250508) | 
| 11.22、11.21\$1、11.20\$1、11.19\$1、11.18\$1、11.17\$1、11.16\$1、11.15\$1、11.14\$1、11.13\$1、11.12\$1、11.11\$1、11.10\$1、11.9\$1、11.8\$1、11.7\$1、11.6\$1、11.5\$1、11.4\$1、11.2\$1、11.1\$1 | [17.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version176)、[17.5](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version175)、[17.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version174)、[17.2](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version172) [16.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1610)、[16.9](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version169)、[16.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version168)、[16.6](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version166)、[16.4](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version164)、[16.3](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version163) [15.14](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1514)、[15.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1513)、[15.12](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1512)、[15.10](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1510)、[15.8](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version158)、[15.7](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version157) [14.19](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1419)、[14.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1418)、[14.17](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1417)、[14.15](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1415)、[14.13](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1413)、[14.12](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1412) [13.22](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1322)、[13.21](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1321)、[13.20](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1320)、[13.18](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1318)、[13.16](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1316)、[13.15](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1315) [12.22](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1222)、[12.22-rds.20250220](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1222rds20250220)、[12.22-rds.20250508](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1222rds20250508) [11.22-rds.20240418](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1122rds20240418)、[11.22-rds.20240509](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1122rds20240509)、[11.22-rds.20240808](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1122rds20240808)、[11.22-rds.20241121](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1122rds20241121)、[11.22-rds.20250220](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1122rds20250220)、[11.22-rds.20250508](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html#postgresql-versions-version1122rds20250508) | 

\$1 現已不支援此版本。

# 如何執行 RDS for PostgreSQL 的主要版本升級
<a name="USER_UpgradeDBInstance.PostgreSQL.MajorVersion.Process"></a>

在 Amazon RDS for PostgreSQL 資料庫上執行主要版本升級時，我們建議採取以下程序：

1. **準備好版本相容的參數群組** – 如果您使用的是自訂參數群組，您有兩個選擇。您可以為新資料庫引擎版本指定預設參數群組。您也可以為新資料庫引擎版本建立自己的自訂參數群組。如需詳細資訊，請參閱[Amazon RDS 的參數群組](USER_WorkingWithParamGroups.md)及[使用多可用區域資料庫叢集的資料庫叢集參數群組](USER_WorkingWithDBClusterParamGroups.md)。

1. **檢查不支援的資料庫類別** - 檢查資料庫的執行個體類別是否與您要升級的目標 PostgreSQL 版本相容。如需詳細資訊，請參閱[資料庫執行個體類別的支援資料庫引擎](Concepts.DBInstanceClass.Support.md)。

1. **檢查是否有不支援的使用：**
   + **備妥交易** – 嘗試升級之前，遞交或轉返所有開啟的備妥交易。

     您可以使用下列查詢來確認資料庫上沒有開啟的預備交易。

     ```
     SELECT count(*) FROM pg_catalog.pg_prepared_xacts;
     ```
   + **Reg\$1 資料類型** – 嘗試升級之前，請移除所有 *reg\$1* 資料類型的使用。除了 `regtype` 和 `regclass`，您無法升級 *reg\$1* 資料類型。`pg_upgrade` 公用程式無法保留此資料類型，Amazon RDS 會使用該資料類型進行升級。

     您可以使用下列查詢，確認在每個資料庫中未使用不支援的 *reg\$1* 資料類型：

     ```
     SELECT count(*) FROM pg_catalog.pg_class c, pg_catalog.pg_namespace n, pg_catalog.pg_attribute a
       WHERE c.oid = a.attrelid
           AND NOT a.attisdropped
           AND a.atttypid IN ('pg_catalog.regproc'::pg_catalog.regtype,
                              'pg_catalog.regprocedure'::pg_catalog.regtype,
                              'pg_catalog.regoper'::pg_catalog.regtype,
                              'pg_catalog.regoperator'::pg_catalog.regtype,
                              'pg_catalog.regconfig'::pg_catalog.regtype,
                              'pg_catalog.regdictionary'::pg_catalog.regtype)
           AND c.relnamespace = n.oid
           AND n.nspname NOT IN ('pg_catalog', 'information_schema');
     ```

1. **檢查是否有無效資料庫：**
   + 確定沒有無效的資料庫。`pg_database` 目錄中的 `datconnlimit` 欄包含值 `-2`，用來將 `DROP DATABASE` 操作期間中斷的資料庫標記為無效。

     使用下列查詢檢查是否有無效的資料庫：

     ```
     SELECT datname FROM pg_database WHERE datconnlimit = - 2;
     ```
   + 前述查詢會傳回無效資料庫的名稱。您可以使用 `DROP DATABASE invalid_db_name;` 捨棄無效的資料庫。您也可以使用下列命令捨棄無效的資料庫：

     ```
     SELECT 'DROP DATABASE ' || quote_ident(datname) || ';' FROM pg_database WHERE datconnlimit = -2 \gexec
     ```

   如需無效資料庫的詳細資訊，請參閱[了解無效資料庫的自動清空行為](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/appendix.postgresql.commondbatasks.autovacuumbehavior.html)。

1. **處理邏輯複寫槽** - 如果資料庫具有任何邏輯複寫槽，就無法進行升級。邏輯複寫槽通常用於 AWS DMS 遷移，以及將資料表從資料庫複寫到資料湖、BI 工具和其他目標。升級之前，請確保您知道任何使用中邏輯複寫槽的用途，並確認可以刪除它們。如果邏輯複寫槽仍在使用，則不應刪除它們，也無法繼續升級。

   如果不需要邏輯複寫槽，可以使用以下 SQL 加以刪除：

   ```
   SELECT * FROM pg_replication_slots WHERE slot_type NOT LIKE 'physical';
   SELECT pg_drop_replication_slot(slot_name);
   ```

   使用 `pglogical` 延伸模組的邏輯複寫設定也必須具有捨棄的插槽，才能成功進行主要版本升級。如需如何識別和捨棄使用 `pglogical` 延伸模組所建立之插槽的相關資訊，請參閱 [管理 RDS for PostgreSQL 的邏輯複寫槽](Appendix.PostgreSQL.CommonDBATasks.pglogical.handle-slots.md)。

   在來源版本 17 和更新版本上，non-read-replicas上的邏輯複寫槽可以透過升級保留。在僅供讀取複本上建立的邏輯複寫槽不會透過升級保留。

   在開始升級之前，請確定已從插槽取用所有交易和邏輯解碼訊息。如果邏輯複寫槽保留了未使用的預先寫入日誌檔案 (WAL)，升級將會失敗，並顯示識別問題槽的訊息。如需更多詳細資訊，請參閱 [PostgreSQL 文件](https://www.postgresql.org/docs/current/logical-replication-upgrade.html)。

   在來源版本早於 17.8 或 18.2 的多可用區域叢集上，請確定 `flow_control` 已停用。如需詳細資訊，請參閱[開啟和關閉多可用區域資料庫叢集的流程控制](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/multi-az-db-clusters-concepts.html#multi-az-db-clusters-concepts-replica-lag)。若要關閉流量控制功能，請從 `shared_preload_libraries` 移除擴充功能並重新啟動資料庫執行個體。

1. **處理僅供讀取複本** - 升級單一可用區域資料庫執行個體或多可用區域資料庫執行個體部署時，也會升級區域內僅供讀取複本以及主要資料庫執行個體。Amazon RDS 不會升級多可用區域資料庫叢集讀取複本。

   您無法個別升級僅供讀取複本。如果可以，它可能會導致主要資料庫和複本資料庫具有不同 PostgreSQL 主要版本的情況。不過，僅供讀取複本升級可能會增加主要資料庫執行個體的停機時間。若要防止僅供讀取複本升級，請將複本提升為獨立執行個體，或在開始升級程序之前刪除複本。

   升級程序會根據僅供讀取複本的目前參數群組，重新建立僅供讀取複本的參數群組。只有在升級完成後，您才能修改僅供讀取複本，以便將自訂參數群組套用至僅供讀取複本。如需僅供讀取複本的詳細資訊，請參閱 [使用 Amazon RDS for PostgreSQL 的僅供讀取複本](USER_PostgreSQL.Replication.ReadReplicas.md)。

1. **處理大型物件** – 在 PostgreSQL 中，大型物件 （也稱為 BLOBs) 用於存放和管理大於一般資料欄資料類型允許大小上限的大型二進位物件 （例如檔案、影像、影片等）。如需詳細資訊，請參閱 [PostgreSQL 大型物件文件](https://www.postgresql.org/docs/current/largeobjects.html)。

   如果有數百萬個大型物件，且執行個體無法在升級期間處理它們，則升級可能會耗盡記憶體並失敗。PostgreSQL 主要版本升級程序包含兩個大階段：透過 pg\$1dump 傾印結構描述，並透過 pg\$1restore 還原結構描述。如果您的資料庫有數百萬個大型物件，您需要確保執行個體在升級期間有足夠的記憶體來處理 pg\$1dump 和 pg\$1restore，並將其擴展到更大的執行個體類型。

   開始升級之前，請檢查您的資料庫是否有任何大型物件。目錄`pg_largeobject_metadata`會保留與大型物件相關聯的中繼資料。實際的大型物件資料會存放在 中`pg_largeobject`。使用下列查詢來檢查大型物件的數量：

   ```
   SELECT count(*) FROM pg_largeobject_metadata;
   ```

   若要清除現有的大型物件或孤立的大型物件，請參閱[使用 lo 模組管理大型物件](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/PostgreSQL_large_objects_lo_extension.html)。

   規劃主要版本升級時，如果您的資料庫包含 2，500 萬到 3，000 萬個大型物件，我們建議您使用具有至少 32 GB 記憶體的執行個體類型。此建議是以我們的測試為基礎，並可能根據您的特定工作負載和資料庫組態而有所不同。如果您的資料庫包含其他物件 （例如資料表、索引或具體化檢視），建議您選取較大的執行個體類型，以確保升級程序期間的最佳效能。

1. **處理零 ETL 整合** – 如果您有現有的[零 ETL 整合](zero-etl.md)，請在執行主要版本升級之前[將其刪除](zero-etl.deleting.md)。然後，在完成升級後重新建立整合。

   在來源版本主要 17 及更高版本上，零 ETL 整合可以透過升級保留。

1. **執行備份** – 建議您先執行備份再執行主要版本升級，以便您的資料庫有已知的還原點。如果您的備份保留期大於 0，在升級前和升級後，升級程序會建立資料庫的資料庫快照。若要變更備份保留期，請參閱 [修改 Amazon RDS 資料庫執行個體](Overview.DBInstance.Modifying.md) 和 [使用 Amazon RDS 修改多可用區域資料庫叢集](modify-multi-az-db-cluster.md)。

   若要手動執行備份，請參閱 [為 Amazon RDS 的單一可用區域資料庫執行個體建立資料庫快照](USER_CreateSnapshot.md) 和 [為 Amazon RDS 建立多可用區域資料庫叢集快照](USER_CreateMultiAZDBClusterSnapshot.md)。

1. **在主要版本升級之前更新特定延伸套件** – 如果您計劃在升級時跳過主要版本，您必須在執行主要版本升級*之前*更新特定延伸套件。例如，從 9.5.x 或 9.6.x 版升級為 11.x 版會跳過主要版本。要更新的擴充功能包括 PostGIS 和用於處理空間資料的相關擴充功能。
   + `address_standardizer`
   + `address_standardizer_data_us`
   + `postgis_raster`
   + `postgis_tiger_geocoder`
   + `postgis_topology`

   如果您使用 `rdkit` 4.6.0 版和較低版本，以及 PostgreSQL 第 16 版和較低版本，由於 `rdkit` 不相容，您將無法直接升級至 PostgreSQL 第 17 版。升級選項如下：
   + 如果您使用 PostgreSQL 第 13 版和較低版本，您必須先執行主要版本升級，升級至 14.14 版和更高的第 14 版、15.9 和更高的第 15 版，或 16.5 和更高的第 16 版，再執行 PostgreSQL 17 的版本升級。
   + 如果您使用 PostgreSQL 第 14、15 或 16 版，則必須先執行次要版本升級，升級至 14.14 和更高的第 14 版、15.9 和更高的第 15 版，或 16.5 和更高的第 16 版，再升級至 PostgreSQL 第 17 版。

   針對您使用的每個擴充功能執行下列命令：

   ```
   ALTER EXTENSION PostgreSQL-extension UPDATE TO 'new-version';
   ```

   如需詳細資訊，請參閱[升級 RDS for PostgreSQL 資料庫中的 PostgreSQL 延伸模組](USER_UpgradeDBInstance.PostgreSQL.ExtensionUpgrades.md)。若要進一步了解 PostGIS 升級的詳細資訊，請參閱 [步驟 6：升級 PostGIS 擴充功能](Appendix.PostgreSQL.CommonDBATasks.PostGIS.md#Appendix.PostgreSQL.CommonDBATasks.PostGIS.Update)。

1. **在主要版本升級之前捨棄特定延伸模組** – 必須捨棄目標版本上不支援的延伸模組，否則升級會失敗。

   從 RDS PostgreSQL 18 開始移除`plrust`延伸模組。由於已知問題 【1[https://trac.osgeo.org/postgis/ticket/5983](https://trac.osgeo.org/postgis/ticket/5983)】、【2】，`postgis_topology`擴充功能不適用於 RDS PostgreSQL 18.1 和 18.[2](https://trac.osgeo.org/postgis/ticket/6016) 版。升級之前，必須先移除這些擴充功能。

   略過主要版本至 11.x 版的升級不支援更新`pgRouting`延伸模組。從 9.4.x、9.5.x 或 9.6.x 版升級為 11.x 版會跳過主要版本。安全的做法是捨棄 `pgRouting` 延伸套件，然後在升級之後再重新安裝該延伸套件的相容版本。有關您可以更新的延伸套件版本，請參閱 [支援的 PostgreSQL 擴充功能版本](PostgreSQL.Concepts.General.FeatureSupport.Extensions.md)。

   PostgreSQL 11 或以上版本不再支援 `tsearch2` 和 `chkpass` 延伸套件。

   您可以檢查是否已使用下列查詢安裝 延伸模組：

   ```
   SELECT * FROM pg_extension WHERE extname in ('extension_name');
   ```

1. **刪除未知的資料類型** – 會根據目標版本丟棄 `unknown` 資料類型。

   PostgreSQL 第 10 版已停止支援 `unknown` 資料類型。如果第 9.6 版資料庫使用 `unknown` 資料類型，升級至版本 10 會顯示錯誤訊息，如下所示：

   ```
   Database instance is in a state that cannot be upgraded: PreUpgrade checks failed:
   The instance could not be upgraded because the 'unknown' data type is used in user tables.
   Please remove all usages of the 'unknown' data type and try again."
   ```

   若要尋找資料庫中的 `unknown` 資料類型，以便移除違規資料行或將其變更為支援的資料類型，請使用下列 SQL：

   ```
   SELECT DISTINCT data_type FROM information_schema.columns WHERE data_type ILIKE 'unknown';
   ```

1. **執行升級停用試轉** – 強烈建議您先在生產資料庫的複本上測試主要版本升級，然後才在生產資料庫上嘗試此升級。您可以監控複寫測試資料庫上的執行計劃，以查看任何可能的執行計劃迴歸，並評估其效能。若要建立複本測試執行個體，您可以從最近快照還原資料庫，或使用時間點將資料庫還原至其最新的可還原時間。

   如需詳細資訊，請參閱「[從快照還原](USER_RestoreFromSnapshot.md#USER_RestoreFromSnapshot.Restoring)」或「[將 Amazon RDS 的資料庫執行個體還原至指定時間](USER_PIT.md)」。若是多可用區域資料庫叢集，請參閱 [從快照還原至多可用區域資料庫叢集](USER_RestoreFromMultiAZDBClusterSnapshot.Restoring.md) 或 [將多可用區域資料庫叢集還原至指定時間](USER_PIT.MultiAZDBCluster.md)。

   如需執行升級的詳細資訊，請參閱 [手動升級引擎版本](USER_UpgradeDBInstance.Upgrading.md#USER_UpgradeDBInstance.Upgrading.Manual)。

   將 9.6 版資料庫升級到第 10 版時，請注意 PostgreSQL 10 會預設啟用平行查詢。升級*之前*，您可以在測試資料庫上將 `max_parallel_workers_per_gather` 參數變更為 2，藉此測試平行處理的影響。
**注意**  
 在 `default.postgresql10` 資料庫參數群組中，`max_parallel_workers_per_gather` 參數的預設值為 2。

   如需詳細資訊，請參閱 PostgreSQL 說明文件中的[平行查詢](https://www.postgresql.org/docs/10/parallel-query.html)。若要在第 10 版上停用平行處理，請將 `max_parallel_workers_per_gather` 參數設為 0。

   在主要版本升級期間，`public` 和 `template1` 資料庫，以及每個資料庫中的 `public` 結構描述都會暫時重新命名。這些物件將連同其原始名稱及附加的隨機字串出現在日誌中。字串會被附加上去，以便在主要版本升級期間保留 `locale` 和 `owner` 之類的自訂設定。升級完成之後，物件就會改回其原始名稱。
**注意**  
在主要版本升級過程中，您不能進行資料庫執行個體或多可用區域資料庫叢集的時間點還原。Amazon RDS 執行升級後，會自動進行資料庫備份。您可以執行時間點還原，以便還原至升級開始之前的時間，以及資料庫的自動備份完成之後的時間。

1. **如果預先檢查程序發生錯誤而升級失敗，請解決這些問題** – 在主要版本升級過程中，Amazon RDS for PostgreSQL 會先執行預先檢查程序，以找出可能導致升級失敗的任何問題。預先檢查程序會檢查執行個體中所有資料庫的所有潛在不相容的狀況。

   如果預先檢查發現問題，會建立日誌事件以表示升級預先檢查失敗。資料庫的所有資料庫預先檢查程序詳細資訊位於名為 `pg_upgrade_precheck.log` 的升級日誌中。Amazon RDS 會將時間戳記附加至檔案名稱。如需檢視日誌檔案的詳細資訊，請參閱[監控 Amazon RDS 日誌檔案](USER_LogAccess.md)。

   如果僅供讀取複本升級在預先檢查時失敗，失敗的僅供讀取複本上的複寫會中斷，而且僅供讀取複本會處於終止狀態。刪除僅供讀取複本並根據升級的主要資料庫執行個體重新建立新的僅供讀取複本。

   解決預先檢查日誌中列出的所有問題，然後重新嘗試主要版本升級。以下是預先檢查日誌範例。

   ```
   ------------------------------------------------------------------------
   Upgrade could not be run on Wed Apr 4 18:30:52 2018
   -------------------------------------------------------------------------
   The instance could not be upgraded from 9.6.11 to 10.6 for the following reasons.
   Please take appropriate action on databases that have usage incompatible with the requested major engine version upgrade and try the upgrade again.
   
   * There are uncommitted prepared transactions. Please commit or rollback all prepared transactions.* One or more role names start with 'pg_'. Rename all role names that start with 'pg_'.
   
   * The following issues in the database 'my"million$"db' need to be corrected before upgrading:** The ["line","reg*"] data types are used in user tables. Remove all usage of these data types.
   ** The database name contains characters that are not supported by RDS for PostgreSQL. Rename the database.
   ** The database has extensions installed that are not supported on the target database version. Drop the following extensions from your database: ["tsearch2"].
   
   * The following issues in the database 'mydb' need to be corrected before upgrading:** The database has views or materialized views that depend on 'pg_stat_activity'. Drop the views.
   ```

1. **如果升級資料庫時僅供讀取複本升級失敗，請解決此問題** - 失敗的僅供讀取複本處於 `incompatible-restore` 狀態，且資料庫上的複寫終止。刪除僅供讀取複本並根據升級的主要資料庫執行個體重新建立新的僅供讀取複本。
**注意**  
Amazon RDS 不會升級多可用區域資料庫叢集的僅供讀取複本。如果您在多可用區域資料庫叢集上執行主要版本升級，則其僅供讀取複本的複寫狀態會變更為**已終止**。

   僅供讀取複本升級可能會因下列原因而失敗：
   + 即使在等待時間之後，它也無法趕上主要資料庫執行個體。
   + 它處於終止或不相容的生命週期狀態，例如儲存已滿、不相容還原等。
   + 當主要資料庫執行個體升級開始時，僅供讀取複本上正在執行個別的次要版本升級。
   + 僅供讀取複本使用的參數不相容。
   + 僅供讀取複本無法與主要資料庫執行個體通訊，以同步處理資料的資料夾。

1. **升級生產資料庫** - 如果停用試轉主要版本升級成功，您應能放心升級生產資料庫。如需詳細資訊，請參閱[手動升級引擎版本](USER_UpgradeDBInstance.Upgrading.md#USER_UpgradeDBInstance.Upgrading.Manual)。

1. 執行 `ANALYZE` 操作以重新整理 `pg_statistic` 資料表。您應為所有 PostgreSQL 資料庫上的每個資料庫執行此操作。主要版本升級期間不會傳輸最佳化工具統計數字，因此您需要重新產生所有統計數字以避免效能問題。在沒有任何參數的情況下執行命令，以產生目前資料庫中所有一般資料表的統計數字，如下所示：

   ```
   ANALYZE VERBOSE;
   ```

   您可選用 `VERBOSE` 旗標，但使用時會顯示進度。如需詳細資訊，請參閱 PostgreSQL 說明文件中的 [ANALYZE](https://www.postgresql.org/docs/10/sql-analyze.html)。

   分析特定資料表而非使用 ANALYZE VERBOSE 時，請對每個資料表執行 ANALYZE 命令，如下所示：

   ```
   ANALYZE table_name;
   ```

   對於分割資料表，一律分析父資料表。此程序：
   + 自動取樣所有分割區的資料列
   + 以遞迴方式更新每個分割區的統計資料
   + 在父層級維護基本的規劃統計資料

   雖然父資料表不會存放實際資料，但分析它們對於查詢最佳化至關重要。僅在個別分割區上執行 ANALYZE 可能會導致查詢效能不佳，因為最佳化工具不會擁有有效跨分割區規劃所需的完整統計資料。
**注意**  
升級後在系統上執行 ANALYZE，以避免效能問題。

主要版本升級完成後，建議您執行以下動作：
+ PostgreSQL 升級並不會升級任何 PostgreSQL 延伸套件。若要升級延伸模組，請參閱 [升級 RDS for PostgreSQL 資料庫中的 PostgreSQL 延伸模組](USER_UpgradeDBInstance.PostgreSQL.ExtensionUpgrades.md)。
+ 或者，使用 Amazon RDS 來檢視 `pg_upgrade` 公用程式產生的兩個日誌。這兩個記錄是 `pg_upgrade_internal.log` 和 `pg_upgrade_server.log`。Amazon RDS 會將時間戳記附加至這些日誌的檔案名稱。您可以如同檢視任何其他日誌一般檢視這些日誌。如需詳細資訊，請參閱 [監控 Amazon RDS 日誌檔案](USER_LogAccess.md)。

  您也可以將升級日誌上傳至 Amazon CloudWatch Logs。如需詳細資訊，請參閱 [將 PostgreSQL 日誌發佈至 Amazon CloudWatch Logs](USER_LogAccess.Concepts.PostgreSQL.md#USER_LogAccess.Concepts.PostgreSQL.PublishtoCloudWatchLogs)。
+ 為了確認所有作業皆符合預期，請在升級後的資料庫上，以類似的工作負載測試您的應用程式。確認升級之後，您可以刪除該測試執行個體。

# RDS for PostgreSQL 的自動次要版本升級
<a name="USER_UpgradeDBInstance.PostgreSQL.Minor"></a>

建立或修改資料庫執行個體或多可用區域資料庫叢集時，如果啟用了**自動次要版本升級**選項，則可讓資料庫自動升級。

Amazon RDS 也支援升級推展政策，以管理跨多個資料庫資源和 的自動次要版本升級 AWS 帳戶。如需詳細資訊，請參閱[使用 AWS Organizations 升級推展政策進行自動次要版本升級](RDS.Maintenance.AMVU.UpgradeRollout.md)。

針對每個 RDS for PostgreSQL 主要版本，RDS 會將一個次要版本指定為自動升級版本。次要版本經過測試，並由 Amazon RDS 核准之後，在您的維護時段期間，會自動發生次要版本升級。RDS 不會自動將較新發行的次要版本設定為自動升級版本。在 RDS 指派較新的自動升級版本之前，會考慮數個準則，例如下列：
+ 已知安全性問題
+ PostgreSQL 社群版本中的錯誤
+ 從發行次要版本以來的整體機群穩定性

您可以使用下列 AWS CLI 命令來判斷特定 中指定 PostgreSQL 次要版本的目前自動次要升級目標版本 AWS 區域。

針對 Linux、macOS 或 Unix：

```
aws rds describe-db-engine-versions \
--engine postgres \
--engine-version minor-version \
--region region \
--query "DBEngineVersions[*].ValidUpgradeTarget[*].{AutoUpgrade:AutoUpgrade,EngineVersion:EngineVersion}" \
--output text
```

在 Windows 中：

```
aws rds describe-db-engine-versions ^
--engine postgres ^
--engine-version minor-version ^
--region region ^
--query "DBEngineVersions[*].ValidUpgradeTarget[*].{AutoUpgrade:AutoUpgrade,EngineVersion:EngineVersion}" ^
--output text
```

例如，下列 AWS CLI 命令會判斷 PostgreSQL 次要版本 16.1 在美國東部 （俄亥俄） AWS 區域 (us-east-2) 的自動次要升級目標。

針對 Linux、macOS 或 Unix：

```
aws rds describe-db-engine-versions \
--engine postgres \
--engine-version 16.1 \
--region us-east-2 \
--query "DBEngineVersions[*].ValidUpgradeTarget[*].{AutoUpgrade:AutoUpgrade,EngineVersion:EngineVersion}" \
--output table
```

在 Windows 中：

```
aws rds describe-db-engine-versions ^
--engine postgres ^
--engine-version 16.1 ^
--region us-east-2 ^
--query "DBEngineVersions[*].ValidUpgradeTarget[*].{AutoUpgrade:AutoUpgrade,EngineVersion:EngineVersion}" ^
--output table
```

輸出類似如下。

```
----------------------------------
|    DescribeDBEngineVersions    |
+--------------+-----------------+
|  AutoUpgrade |  EngineVersion  |
+--------------+-----------------+
|  False       |  16.2           |
|  True       |  16.3          |
|  False       |  16.4           |
|  False       |  16.5           |
|  False       |  16.6           |
|  False       |  17.1           |
|  False       |  17.2           |
+--------------+-----------------+
```

在此範例中，PostgreSQL 16.3 版的 `AutoUpgrade` 值是 `True`。因此，自動次要升級目標是 PostgreSQL 16.3 版，已在輸出中反白顯示。

如果符合下列準則，PostgreSQL 資料庫會在您的維護時段期間自動升級：
+ 資料庫的**自動次要版本升級**選項已啟用。
+ 資料庫執行的次要資料庫引擎版本小於目前的自動升級次要版本。

如需詳細資訊，請參閱[自動升級次要引擎版本](USER_UpgradeDBInstance.Upgrading.md#USER_UpgradeDBInstance.Upgrading.AutoMinorVersionUpgrades)。

**注意**  
PostgreSQL 升級並不會升級 PostgreSQL 延伸套件。若要升級延伸模組，請參閱 [升級 RDS for PostgreSQL 資料庫中的 PostgreSQL 延伸模組](USER_UpgradeDBInstance.PostgreSQL.ExtensionUpgrades.md)。

# 升級 RDS for PostgreSQL 資料庫中的 PostgreSQL 延伸模組
<a name="USER_UpgradeDBInstance.PostgreSQL.ExtensionUpgrades"></a>

PostgreSQL 引擎升級並不會升級大多數 PostgreSQL 延伸套件。若要在版本升級後更新延伸套件，請使用 `ALTER EXTENSION UPDATE` 命令。

**注意**  
如需如何更新 PostGIS 擴充功能的相關資訊，請參閱 [使用 PostGIS 擴充功能管理空間資料](Appendix.PostgreSQL.CommonDBATasks.PostGIS.md) ([步驟 6：升級 PostGIS 擴充功能](Appendix.PostgreSQL.CommonDBATasks.PostGIS.md#Appendix.PostgreSQL.CommonDBATasks.PostGIS.Update))。  
若要更新 `pg_repack` 延伸模組，請捨棄該延伸模組，然後在升級的資料庫中建立新版本。如需詳細資訊，請參閱 `pg_repack` 說明文件中的 [pg\$1repack 安裝](https://reorg.github.io/pg_repack/)。

若要升級擴充功能，請使用下列命令。

```
ALTER EXTENSION extension_name UPDATE TO 'new_version';
```

如需 PostgreSQL 延伸套件支援版本的清單，請參閱 [支援的 PostgreSQL 擴充功能版本](PostgreSQL.Concepts.General.FeatureSupport.Extensions.md)。

若要列出目前已安裝的擴充功能，請在下列命令中使用 PostgreSQL [pg\$1extension](https://www.postgresql.org/docs/current/catalog-pg-extension.html) 目錄。

```
SELECT * FROM pg_extension;
```

若要檢視您的安裝可用的特定擴充功能版本的清單，請在下列命令中使用 PostgreSQL [ pg\$1available\$1extension\$1versions](https://www.postgresql.org/docs/current/view-pg-available-extension-versions.html) 檢視。

```
SELECT * FROM pg_available_extension_versions;
```

# 使用事件監控 RDS for PostgreSQL 引擎升級
<a name="USER_UpgradeDBInstance.PostgreSQL.Monitoring"></a>

當您升級 RDS for PostgreSQL 資料庫的引擎版本時，Amazon RDS 會在程序的每個階段發出特定事件。若要追蹤升級進度，您可以檢視或訂閱這些事件。

 如需 RDS 事件的詳細資訊，請參閱 [監控 Amazon RDS 事件](working-with-events.md)。

如需引擎升級期間發生之特定 Amazon RDS 事件的詳細資訊，請參閱 [ Amazon RDS 事件類別和事件訊息](USER_Events.Messages.md)。

# 升級 PostgreSQL 資料庫快照引擎版本
<a name="USER_UpgradeDBSnapshot.PostgreSQL"></a>

利用 Amazon RDS，您可以為您的 PostgreSQL 資料庫執行個體建立儲存體磁碟區資料庫快照。建立資料庫快照時，該快照會基於您的 Amazon RDS 執行個體使用的引擎版本。您可以升級資料庫快照的引擎版本。

還原升級至新引擎版本的資料庫快照之後，務必測試升級已成功。如需主要版本升級的詳細資訊，請參閱[RDS for PostgreSQL 資料庫引擎的升級](USER_UpgradeDBInstance.PostgreSQL.md)。若要了解如何還原資料庫快照，請參閱[還原至資料庫執行個體](USER_RestoreFromSnapshot.md)。

您可以升級已加密或未加密的手動資料庫快照。

若要檢視 RDS for PostgreSQL 資料庫快照的可用引擎版本，請使用下列 AWS CLI 範例。

```
aws rds describe-db-engine-versions --engine postgres  --engine-version example-engine-version --query "DBEngineVersions[*].ValidUpgradeTarget[*].{EngineVersion:EngineVersion}" --output text --include-all
```

如需 RDS for PostgreSQL 資料庫快照的可用引擎版本的詳細資訊，請參閱 [選擇 RDS for PostgreSQL 升級的主要版本](USER_UpgradeDBInstance.PostgreSQL.MajorVersion.md)。

**注意**  
您不可以升級在自動備份程序期間建立的自動資料庫快照。

## 主控台
<a name="USER_UpgradeDBSnapshot.PostgreSQL.Console"></a>

**升級資料庫快照**

1. 登入 AWS 管理主控台 ，並在 [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/)：// 開啟 Amazon RDS 主控台。

1. 在導覽窗格中，選擇 **Snapshots (快照)**。

1. 選擇您要升級的快照。

1. 針對 **Actions (動作)**，選擇 **Upgrade snapshot (升級快照)**。**Upgrade snapshot (升級快照)** 頁面隨即出現。

1. 選擇要升級到的 **New engine version (新引擎版本)**。

1. 選擇 **Save changes (儲存變更)** 以升級快照。

   升級程序期間，此資料庫快照的所有快照動作會停用。同時，資料庫快照狀態會從 **available (可用)** 變更為 **upgrading (升級中)**，然後在完成時變更為 **active (作用中)**。如果資料庫快照因為快照損毀問題而無法升級，狀態會變更為 **unavailable (無法使用)**。您無法從此狀態復原快照。
**注意**  
如果資料庫升級失敗，快照會轉返至原始版本的原始狀態。

## AWS CLI
<a name="USER_UpgradeDBSnapshot.PostgreSQL.CLI"></a>

若要將資料庫快照升級至新的資料庫引擎版本，請使用 AWS CLI [modify-db-snapshot](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-snapshot.html) 命令。

**Parameters**
+ `--db-snapshot-identifier` – 要升級的資料庫快照識別碼。識別符必須是唯一的 Amazon Resource Name (ARN)。如需詳細資訊，請參閱 [Amazon RDS 中的 Amazon Resource Name (ARN)](USER_Tagging.ARN.md)。
+ `--engine-version` – 資料庫快照會以此引擎版本為目標進行升級。

**Example**  
針對 Linux、macOS 或 Unix：  

```
1. aws rds modify-db-snapshot \
2.     --db-snapshot-identifier my_db_snapshot \
3.     --engine-version new_version
```
在 Windows 中：  

```
1. aws rds modify-db-snapshot ^
2.     --db-snapshot-identifier my_db_snapshot ^
3.     --engine-version new_version
```

## RDS API
<a name="USER_UpgradeDBSnapshot.PostgreSQL.API"></a>

若要將資料庫快照升級為新的資料庫引擎版本，請呼叫 Amazon RDS API [ModifyDBSnapshot](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_ModifyDBSnapshot.html) 操作。
+ `DBSnapshotIdentifier` – 要升級的資料庫快照識別符。識別符必須是唯一的 Amazon Resource Name (ARN)。如需詳細資訊，請參閱 [Amazon RDS 中的 Amazon Resource Name (ARN)](USER_Tagging.ARN.md)。
+ `EngineVersion` – 資料庫快照會以此引擎版本為目標進行升級。

# 使用 Amazon RDS for PostgreSQL 的僅供讀取複本
<a name="USER_PostgreSQL.Replication.ReadReplicas"></a>

您可透過將僅供讀取複本新增至執行個體，以擴展 Amazon RDS for PostgreSQL 資料庫執行個體的讀取。與其他 Amazon RDS 資料庫引擎一樣，RDS for PostgreSQL 會使用 PostgreSQL 的原生複寫機制，使僅供讀取複本與來源資料庫上的變更保持最新狀態。如需僅供讀取複本與 Amazon RDS 的一般資訊，請參閱 [使用資料庫執行個體僅供讀取複本](USER_ReadRepl.md)。

有關如何利用 RDS for PostgreSQL 處理僅供讀取複本，以下提供具體資訊。



## 使用 PostgreSQL 的僅供讀取複本限制
<a name="USER_PostgreSQL.Replication.ReadReplicas.Limitations"></a>

下列為 PostgreSQL 僅供讀取複本的限制：
+ PostgreSQL 僅供讀取複本皆為唯讀。雖然僅供讀取複本不是可寫入資料庫執行個體，但您可將其提升為獨立的 RDS for PostgreSQL 資料庫執行個體。但此程序是不可逆的。
+ 若 RDS for PostgreSQL 資料庫執行個體執行早於 14.1 的 PostgreSQL 版本，則無法從另一個僅供讀取複本建立僅供讀取複本。RDS for PostgreSQL 僅支援 RDS for PostgreSQL 14.1 版和更新版本上的階層式僅供讀取複本。如需詳細資訊，請參閱[使用具 RDS for PostgreSQL 的階層式僅供讀取複本](USER_PostgreSQL.Replication.ReadReplicas.Cascading.md)。
+ 若您提升 PostgreSQL 僅供讀取複本，則會成為可寫入資料庫執行個體。其會停止從來源資料庫執行個體接收預寫日誌 (WAL) 檔案，且不再是個唯讀執行個體。您可從提升的資料庫執行個體建立新的僅供讀取複本，如同對任何 RDS for PostgreSQL 資料庫執行個體所做的一樣。如需詳細資訊，請參閱[提升僅供讀取複本為獨立的資料庫執行個體](USER_ReadRepl.Promote.md)。
+ 若從複寫鏈 (一系列階層式僅供讀取複本) 中提升 PostgreSQL 僅供讀取複本，則任何現有的下游僅供讀取複本皆會繼續自動從提升的執行個體接收 WAL 檔案。如需詳細資訊，請參閱[使用具 RDS for PostgreSQL 的階層式僅供讀取複本](USER_PostgreSQL.Replication.ReadReplicas.Cascading.md)。
+ 如果來源資料庫執行個體上未發生使用者交易，則 PostgreSQL 僅供讀取複本會回報最多五分鐘的複寫延遲。複本滯後的計算方式為 `currentTime - lastCommitedTransactionTimestamp`，亦即未處理任何交易時，複本滯後的值會增加一段時間，直到預寫日誌 (WAL) 區段切換為止。根據預設，RDS for PostgreSQL 每 5 分鐘切換一次 WAL 區段，這會導致交易記錄和報告的延遲減少。
+ 您無法為早於 14.1 的 RDS for PostgreSQL 版本開啟 PostgreSQL 僅供讀取複本的自動備份。RDS for PostgreSQL 14.1 及更新版本僅支援僅供讀取複本的自動備份。對於 RDS for PostgreSQL 13 及更早版本，若您想要備份僅供讀取複本，則請從僅供讀取複本建立快照。
+ 僅供讀取複本不支援時間點復原 (PITR)。您僅可使用具主 (寫入器) 執行個體的 PITR，而非僅供讀取複本。如需詳細資訊，請參閱 [將 Amazon RDS 的資料庫執行個體還原至指定時間](USER_PIT.md)。
+ PostgreSQL 第 12 版和較低版本的僅供讀取複本會在 60-90 天的維護時段內自動重新開機，以套用密碼輪換。複本若在排程的重新開機之前失去與來源的連線，仍會重新開機以繼續複寫。對於 PostgreSQL 第 13 版和更高版本，僅供讀取複本可能會在密碼輪換過程中經歷短暫的複寫中斷連線和重新連線。

# 使用 PostgreSQL 的僅供讀取複本組態
<a name="USER_PostgreSQL.Replication.ReadReplicas.Configuration"></a>

RDS for PostgreSQL 會使用 PostgreSQL 原生串流複寫來建立來源資料庫執行個體的唯讀複本。此僅供讀取複本資料庫執行個體是個非同步建立之來源資料庫執行個體的實體複寫。此由將預寫日誌 (WAL) 資料從來源資料庫執行個體傳輸至僅供讀取複本的特殊連線所建立。如需詳細資訊，請參閱 PostgreSQL 文件中的[串流複寫](https://www.postgresql.org/docs/14/warm-standby.html#STREAMING-REPLICATION)。

PostgreSQL 會將資料庫變更非同步串流至此安全連接，如同其在來源資料庫執行個體上所進行般。您可透過將 `ssl` 參數設定為 `1`，對用戶端應用程式至來源資料庫執行個體或任何僅供讀取複本的通訊進行加密。如需詳細資訊，請參閱 [將 SSL 與 PostgreSQL 資料庫執行個體搭配使用](PostgreSQL.Concepts.General.SSL.md)。

PostgreSQL 會使用*複寫*角色來執行串流複寫。角色有優先權，但無法用來修改任何資料。PostgreSQL 使用單一程序來處理複寫。

您可在不影響來源資料庫執行個體的作業或使用者的狀況下建立 PostgreSQL 僅供讀取複本。Amazon RDS 會為來源資料庫執行個體和僅供讀取複本設定必要的參數和權限，而不會影響服務。將會拍攝來源資料庫執行個體的快照，而此快照會用來建立僅供讀取複本。如於未來的某個時間點刪除僅供讀取複本，則不會發生停機。

您可以從相同區域內的一個來源資料庫執行個體建立至多 15 個僅供讀取複本。從 RDS for PostgreSQL 14.1 開始，您還可從來源資料庫執行個體以鏈結 (階層式) 的形式建立最多三個層級的僅供讀取複本。如需詳細資訊，請參閱[使用具 RDS for PostgreSQL 的階層式僅供讀取複本](USER_PostgreSQL.Replication.ReadReplicas.Cascading.md)。在所有情況下，來源資料庫執行個體皆需設定自動備份。您可將資料庫執行個體上的備份保留期設定為 0 以外的任何值以進行此作業。如需詳細資訊，請參閱[建立僅供讀取複本](USER_ReadRepl.Create.md)。

您可於與來源資料庫執行個體相同的 AWS 區域 中，建立 RDS for PostgreSQL資料庫執行個體的僅供讀取複本。此稱為*區域內*複寫。您也可以在與來源資料庫執行個體 AWS 區域 不同的 中建立僅供讀取複本。此稱為*跨區域*複寫。如需設定跨區域僅供讀取複本的相關資訊，請參閱 [在不同的 中建立僅供讀取複本 AWS 區域](USER_ReadRepl.XRgn.md)。支援「區域內」和「跨區域」複寫程序的各種機制會依 RDS for PostgreSQL 版本而略有不同，此說明於 [串流複寫如何用於不同的 RDS for PostgreSQL 版本](USER_PostgreSQL.Replication.ReadReplicas.Mechanisms-versions.md) 中。

若希望複寫作業順利運作，每個僅供讀取複本具備的運算和儲存資源數量應與來源資料庫執行個體相同。若您擴展來源資料庫執行個體，也請務必擴展僅供讀取複本。

若 Amazon RDS 阻止僅供讀取複本啟動，則期將會覆寫僅供讀取複本上任何不相容的參數。舉例來說，假設在資料庫執行個體的 `max_connections` 參數值高於僅供讀取複本上的值。在此情況下，Amazon RDS 會更新僅供讀取複本上的參數為與來源資料庫執行個體上相同的值。

RDS for PostgreSQL 僅供讀取複本可存取外部資料庫，這些資料庫可經由來源資料庫執行個體上的外部資料包裝函式 (FDW) 取得。例如，假設 RDS for PostgreSQL 資料庫執行個體使用 `mysql_fdw` 包裝函式來存取 RDS for MySQL 的資料。若是如此，您的僅供讀取複本也可存取該資料。其他受支援的 FDW 包括 `oracle_fdw`、`postgres_fdw` 和 `tds_fdw`。如需詳細資訊，請參閱[使用 Amazon RDS for PostgreSQL 支援的外部資料包裝函式](Appendix.PostgreSQL.CommonDBATasks.Extensions.foreign-data-wrappers.md)。

## 使用具多可用區域組態的 RDS for PostgreSQL 僅供讀取複本
<a name="USER_PostgreSQL.Replication.ReadReplicas.Configuration.multi-az"></a>

您可以從單一可用區域或多可用區域的資料庫執行個體建立僅供讀取複本。您可使用異地同步備份部署，利用備用複本來改善重要資料的耐用性和可用性。若來源資料庫進行容錯移轉，則*備用複本*是個可承擔工作負載的專用僅供讀取複本。您無法使用備用複本來提供讀取流量。但是，您可從高流量的多可用區域資料庫執行個體建立僅供讀取複本，藉此卸載唯讀查詢。若要進一步了解異地同步備份部署，請參閱 [Amazon RDS 的多可用區域資料庫執行個體部署](Concepts.MultiAZSingleStandby.md)。

若異地同步備份部署的來源資料庫執行個體容錯移轉至備用複本，則相關聯的僅供讀取複本都會切換為使用備用複本 (現為主要複本) 作為其複寫來源。僅供讀取複本可能需要重新啟動，視 RDS for PostgreSQL 版本而定，如下所示：
+ **PostgreSQL 13 及更新版本** – 無須重新啟動。僅供讀取複本將會自動與新的主要複本同步。但在某些狀況下，您的用戶端應用程式可能會快取僅供讀取複本的網域名稱服務 (DNS) 詳細資訊。若是如此，請將存留時間 (TTL) 值設定為少於 30 秒。這麼做可以防止僅供讀取複本保留過時的 IP 地址 (如此，可防止其與新的主要複本同步)。如需進一步了解有關此及其他最佳實務的詳細資訊，請參閱 [Amazon RDS 基本操作準則](CHAP_BestPractices.md#CHAP_BestPractices.DiskPerformance)。
+ **PostgreSQL 12 及所有早期版本** – 僅供讀取複本在容錯移轉至備用複本後會自動重新啟動，因為備用 (現為主要) 具有不同的 IP 地址和不同的執行個體名稱。重新啟動僅供讀取複本與新的主要複本同步。

如需進一步了解容錯移轉，請參閱 [容錯移轉 Amazon RDS 的多可用區域資料庫執行個體](Concepts.MultiAZ.Failover.md)。若要進一步了解僅供讀取複本如何在異地同步備份部署中運作，請參閱 [使用資料庫執行個體僅供讀取複本](USER_ReadRepl.md)。

如要提供僅供讀取複本的容錯移轉支援，您可將僅供讀取複本建立為多可用區域資料庫執行個體，則 Amazon RDS 會在另一個可用區域 (AZ) 中建立您複本的待命複本。建立您的僅供讀取複本做為多可用區域資料庫執行個體，與來源資料庫是否為多可用區域資料庫執行個體無關。

# 僅供讀取複本上的邏輯解碼
<a name="USER_PostgreSQL.Replication.ReadReplicas.LogicalDecoding"></a>

 RDS for PostgreSQL 支援使用 PostgreSQL 16.1 從待命複本進行邏輯複寫 這可讓您從唯讀待命複本建立邏輯解碼，以減輕主要資料庫執行個體上的負載。您可以為需要在多個系統間同步資料的應用程式實現更高的可用性。此功能可提升資料倉儲和資料分析的效能。

 此外，指定待命複本上的複寫插槽在該待命複本提升為主要複本後會保存下來。這表示，在發生主要資料庫執行個體容錯移轉，或待命複本提升為新的主要複本後，複寫插槽會保存下來，且之前的待命複本訂閱者不會受到影響。

**在僅供讀取複本上建立邏輯解碼**

1. **開啟邏輯複寫** – 若要在待命複本上建立邏輯解碼，您必須在來源資料庫執行個體及其實體複本上開啟邏輯複寫。如需詳細資訊，請參閱[使用 PostgreSQL 的僅供讀取複本組態](USER_PostgreSQL.Replication.ReadReplicas.Configuration.md)。
   + **若要為新建立的 RDS for PostgreSQL 資料庫執行個體開啟邏輯複寫** – 建立新的資料庫自訂參數群組，並將靜態參數 `rds.logical_replication` 設定為 `1`。然後，將此資料庫參數群組與來源資料庫執行個體及其實體僅供讀取複本建立關聯。如需詳細資訊，請參閱[將資料庫參數群組與 Amazon RDS 中的資料庫執行個體建立關聯](USER_WorkingWithParamGroups.Associating.md)。
   + **若要為現有的 RDS for PostgreSQL 資料庫執行個體開啟邏輯複寫** – 修改來源資料庫執行個體及其實體僅供讀取複本的資料庫自訂參數群組，將靜態參數 `rds.logical_replication` 設定為 `1`。如需詳細資訊，請參閱[修改 Amazon RDS 中的資料庫參數群組中的參數](USER_WorkingWithParamGroups.Modifying.md)。
**注意**  
您必須將資料庫執行個體重新開機，以套用這些參數變更。

   您可以使用下列查詢，驗證來源資料庫執行個體及其實體僅供讀取複本上的 `wal_level` 和 `rds.logical_replication` 的值。

   ```
   Postgres=>SELECT name,setting FROM pg_settings WHERE name IN ('wal_level','rds.logical_replication');
               
    name                    | setting 
   -------------------------+---------
    rds.logical_replication | on
    wal_level               | logical
   (2 rows)
   ```

1. **在來源資料庫中建立資料表** – 連線至來源資料庫執行個體中的資料庫。如需詳細資訊，請參閱[連線至執行 PostgreSQL 資料庫引擎的資料庫執行個體](USER_ConnectToPostgreSQLInstance.md)。

   使用下列查詢在來源資料庫中建立資料表，並插入值：

   ```
   Postgres=>CREATE TABLE LR_test (a int PRIMARY KEY);
   CREATE TABLE
   ```

   ```
   Postgres=>INSERT INTO LR_test VALUES (generate_series(1,10000));
   INSERT 0 10000
   ```

1. **建立來源資料表的發行集** – 使用下列查詢，在來源資料庫執行個體上建立資料表的發行集。

   ```
   Postgres=>CREATE PUBLICATION testpub FOR TABLE LR_test;
   CREATE PUBLICATION
   ```

   使用 SELECT 查詢，詳細驗證在來源資料庫執行個體和實體僅供讀取複本執行個體上建立的發行集。

   ```
   Postgres=>SELECT * from pg_publication;
                
   oid    | pubname | pubowner | puballtables | pubinsert | pubupdate | pubdelete | pubtruncate | pubviaroot 
   -------+---------+----------+--------------+-----------+-----------+-----------+-------------+------------
    16429 | testpub |    16413 | f            | t         | t         | t         | t           | f
   (1 row)
   ```

1. **從邏輯複本執行個體建立訂閱** – 建立另一個 RDS for PostgreSQL 資料庫執行個體，做為邏輯複本執行個體。請確認 VPC 已設定正確，以確保此邏輯複本執行個體可存取實體僅供讀取複本執行個體。如需詳細資訊，請參閱[Amazon VPC 和 Amazon RDS](USER_VPC.md)。如果您的來源資料庫執行個體處於閒置狀態，可能會發生連線問題，主要複本不會將資料傳送至待命複本。

   ```
   Postgres=>CREATE SUBSCRIPTION testsub CONNECTION 'host=Physical replica host name port=port 
                   dbname=source_db_name user=user password=password' PUBLICATION testpub;
   NOTICE:  created replication slot "testsub" on publisher
   CREATE SUBSCRIPTION
   ```

   ```
   Postgres=>CREATE TABLE LR_test (a int PRIMARY KEY);
   CREATE TABLE
   ```

   使用 SELECT 查詢，詳細驗證邏輯複本執行個體上的訂閱。

   ```
   Postgres=>SELECT oid,subname,subenabled,subslotname,subpublications FROM pg_subscription;
               
   oid    | subname | subenabled | subslotname | subpublications 
   -------+---------+------------+-------------+-----------------
    16429 | testsub | t          | testsub     | {testpub}
   (1 row)
   postgres=> select count(*) from LR_test;
    count 
   -------
    10000
   (1 row)
   ```

1. **檢查邏輯複寫插槽狀態** – 您只能查看來源資料庫執行個體上的實體複寫插槽。

   ```
   Postgres=>select slot_name, slot_type, confirmed_flush_lsn from pg_replication_slots;
               
   slot_name                                    | slot_type | confirmed_flush_lsn 
   ---------------------------------------------+-----------+---------------------
    rds_us_west_2_db_dhqfsmo5wbbjqrn3m6b6ivdhu4 | physical  | 
   (1 row)
   ```

   不過，在僅供讀取複本執行個體上，您可以查看邏輯複寫插槽，且 `confirmed_flush_lsn` 值會隨著應用程式主動取用邏輯變更而變更。

   ```
   Postgres=>select slot_name, slot_type, confirmed_flush_lsn from pg_replication_slots;
               
   slot_name | slot_type | confirmed_flush_lsn 
   -----------+-----------+---------------------
    testsub   | logical   | 0/500002F0
   (1 row)
   ```

   ```
   Postgres=>select slot_name, slot_type, confirmed_flush_lsn from pg_replication_slots;
               
   slot_name | slot_type | confirmed_flush_lsn 
   -----------+-----------+---------------------
    testsub   | logical   | 0/5413F5C0
   (1 row)
   ```

# 使用具 RDS for PostgreSQL 的階層式僅供讀取複本
<a name="USER_PostgreSQL.Replication.ReadReplicas.Cascading"></a>

從 14.1 版開始，RDS for PostgreSQL 支援階層式僅供讀取複本。利用*階層式僅供讀取複本*，您可以擴展讀取，無須增加來源 RDS for PostgreSQL 資料庫執行個體的額外負荷。來源資料庫執行個體不會將 WAL 日誌的更新傳送至每個僅供讀取複本。反之，階層式系列中的每個僅供讀取複本都會將 WAL 日誌更新傳送至系列中的下一個僅供讀取複本。此會減少來源資料庫執行個體的負擔。

利用階層式僅供讀取複本，您的 RDS for PostgreSQL 資料庫執行個體會將 WAL 資料傳送至鏈結中的第一個僅供讀取複本。之後，該僅供讀取複本會將 WAL 資料傳送至鏈結中的第二個複本，依此類推。最終結果是鏈結中的所有僅供讀取複本皆具有來自 RDS for PostgreSQL 資料庫執行個體的變更，但並無僅在來源資料庫執行個體上的額外負荷。

您可從來源 RDS for PostgreSQL 資料庫執行個體的鏈結中建立一系列最多三個僅供讀取複本。例如，假設您有一個 RDS for PostgreSQL 14.1 資料庫執行個體 `rpg-db-main`。您可以執行下列動作：
+ 從 `rpg-db-main` 開始，建立鏈結中的第一個僅供讀取複本 `read-replica-1`。
+ 接下來，從 `read-replica-1`，建立鏈結中的下一個僅供讀取複本 `read-replica-2`。
+ 最後，從 `read-replica-2`，建立鏈結中的第三個僅供讀取複本 `read-replica-3`。

除了 `rpg-db-main` 系列中的第三個階層式僅供讀取複本之外，您無法建立另一個僅供讀取複本。從 RDS for PostgreSQL 來源資料庫執行個體至一系列階層式僅供讀取複本尾端的完整執行個體系列最多可包含四個資料庫執行個體。

若要使階層式僅供讀取複本正常運作，請開啟 RDS for PostgreSQL 上的自動備份。首先建立僅供讀取複本，然後開啟 RDS for PostgreSQL 資料庫執行個體上的自動備份。此程序與其他 Amazon RDS 資料庫引擎相同。如需詳細資訊，請參閱[建立僅供讀取複本](USER_ReadRepl.Create.md)。

與任何僅供讀取複本一樣，您可提升作為階層式一部分的僅供讀取複本。從僅供讀取複本鏈結中提升僅供讀取複本將會從鏈結中移除該僅供讀取複本。例如，假設您想要將部分工作負載從 `rpg-db-main` 資料庫執行個體移至新的執行個體，僅供會計部門使用。假設範例中的三個僅供讀取複本鏈結，您決定提升 `read-replica-2`。該鏈或受到下列影響：
+ 提升 `read-replica-2` 會將其從複寫鏈結中移除。
  + 其現在是一個完整的讀取/寫入資料庫執行個體。
  + 這會持續複寫至 `read-replica-3`，就像在提升之前所做的一樣。
+ 您的 `rpg-db-main` 會持續複寫至 `read-replica-1`。

如需提升僅供讀取複本的相關詳細資訊，請參閱 [提升僅供讀取複本為獨立的資料庫執行個體](USER_ReadRepl.Promote.md)。

**注意**  
RDS for PostgreSQL 不支援階層式複本的主要版本升級。在執行主要版本升級之前，必須先移除階層式複本。在來源資料庫執行個體和第一層複本上完成升級後，您可以重新建立複本。
對於階層式僅供讀取複本，RDS for PostgreSQL 在第一個複寫層支援每個來源資料庫執行個體 15 個僅供讀取複本，而在第二和第三複寫層支援每個來源資料庫執行個體 5 個僅供讀取複本。

# 建立 RDS for PostgreSQL 的跨區域階層式僅供讀取複本
<a name="USER_PostgreSQL.Replication.ReadReplicas.Xregion"></a>

RDS for PostgreSQL 支援跨區域階層式僅供讀取複本。您可以先從來源資料庫執行個體建立跨區域複本，再從中建立相同區域複本。您也可以先從來源資料庫執行個體建立相同區域複本，再從中建立跨區域複本。

**先建立跨區域複本，再建立相同區域複本**

您可以使用 RDS for PostgreSQL 資料庫執行個體搭配 14.1 版或更高版本 `rpg-db-main` 來執行下列動作：

1. 從 `rpg-db-main` (US-EAST-1) 開始，在鏈結中建立第一個跨區域僅供讀取複本 `read-replica-1` (US-WEST-2)。

1. 使用第一個跨區域 `read-replica-1` (US-WEST-2)，在鏈結中建立第二個僅供讀取複本 `read-replica-2` (US-WEST-2)。

1. 使用 `read-replica-2`，在鏈結中建立第三個僅供讀取複本 `read-replica-3` (US-WEST-2)。

**先建立相同區域複本，再建立跨區域複本**

您可以使用 RDS for PostgreSQL 資料庫執行個體搭配 14.1 版或更高版本 `rpg-db-main` 來執行下列動作：

1. 從 `rpg-db-main` (US-EAST-1) 開始，在鏈結中建立第一個僅供讀取複本 `read-replica-1` (US-WEST-1)。

1. 使用 `read-replica-1` (US-EAST-1) 開始，在鏈結中建立第一個跨區域僅供讀取複本 `read-replica-2` (US-WEST-2)。

1. 使用 `read-replica-2` (US-WEST-2)，在鏈結中建立第三個僅供讀取複本 `read-replica-3` (US-WEST-2)。

**建立跨區域僅供讀取複本的限制**
+ 資料庫複本的跨區域階層式鏈結最多可跨越兩個區域，最多四個層級。四個層級包括資料庫來源和三個僅供讀取複本。

**使用階層式僅供讀取複本的優點**
+ 改善讀取可擴展性 – 階層式複寫可將讀取查詢分散到多個複本，有助於平衡負載。這樣可以減輕寫入器資料庫的壓力，進而改善效能，尤其是在高讀取量應用程式中。
+ 地理分佈 – 階層式複本可位於不同的地理位置。如此，距離主要資料庫較遠的使用者就可以降低延遲，此外也可提供本機僅供讀取複本，進而提升效能和使用者體驗。
+ 高可用性和災難復原 – 在主要伺服器失敗的情況下，複本可以提升為主要伺服器，以確保持續性。階層式複寫可藉由提供多層容錯移轉選項來進一步強化這一點，從而改善系統的整體恢復能力。
+ 彈性和模組化成長 – 隨著系統成長，有以在不同層級新增複本，而無須對主要資料庫進行重大重新設定。這種模組化方法可實現複寫設定可擴展和可管理的增長。

**使用跨區域僅供讀取複本的最佳實務**
+ 在提升複本之前，先建立其他複本。這可以節省時間，並且有效處理工作負載。

# 串流複寫如何用於不同的 RDS for PostgreSQL 版本
<a name="USER_PostgreSQL.Replication.ReadReplicas.Mechanisms-versions"></a>

如 [使用 PostgreSQL 的僅供讀取複本組態](USER_PostgreSQL.Replication.ReadReplicas.Configuration.md) 中所討論，RDS for PostgreSQL 會使用 PostgreSQL 的原生串流複寫協定，從來源資料庫執行個體傳送 WAL 資料。此將來源 WAL 資料傳送至區域內和跨區域僅供讀取複本的僅供讀取複本。在 9.4 版中，PostgreSQL 引入了實體複寫槽，作為複寫程序的支援機制。

*實體複寫槽*會防止來源資料庫執行個體在所有僅供讀取複本使用 WAL 資料之前移除 WAL 資料。每個僅供讀取複本在來源資料庫執行個體上都有自己的實體槽。該插槽會追蹤複本可能需要的最舊 WAL (按邏輯序號，LSN)。在所有插槽和資料庫連接皆超出給定的 WAL (LSN) 之後，該 LSN 會成為下一個檢查點移除的候選項。

Amazon RDS 使用 Amazon S3 來封存 WAL 資料。對於區域內僅供讀取複本，您可於需要時使用此封存資料復原僅供讀取複本。若來源資料庫和僅供讀取複本之間的連接因任何原因而遭中斷，您可能會這麼做的範例。

於下表中，您可以找到 PostgreSQL 版本之間的差異，及 RDS for PostgreSQL 所使用之區域內和跨區域的支援機制摘要。


| 版本 | 區域內 | 跨區域 | 
| --- | --- | --- | 
| PostgreSQL 14.1 和更高版本 |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/USER_PostgreSQL.Replication.ReadReplicas.Mechanisms-versions.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/USER_PostgreSQL.Replication.ReadReplicas.Mechanisms-versions.html)  | 
| PostgreSQL 13 和較低版本 |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/USER_PostgreSQL.Replication.ReadReplicas.Mechanisms-versions.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/USER_PostgreSQL.Replication.ReadReplicas.Mechanisms-versions.html)  | 

如需詳細資訊，請參閱[監控和調校複寫程序](USER_PostgreSQL.Replication.ReadReplicas.Monitor.md)。

## 了解控制 PostgreSQL 複寫的參數
<a name="USER_PostgreSQL.Replication.ReadReplicas.Parameters"></a>

下列參數影響複寫程序，並決定僅供讀取複本與來源資料庫執行個體保持於最新狀態的程度：

**max\$1wal\$1senders**  
`max_wal_senders` 參數指定來源資料庫執行個體可透過串流複寫協定同時支援的最大連接數。  
RDS for PostgreSQL 版本的預設值會有所不同：  
+ 第 13、14 和 15 版的預設值為 20。
+ 第 16 版和更高版本的預設值為 35。
此參數應設定為略高於僅供讀取複本的實際數量。若此參數對僅供讀取複本數量設定過低，則複寫會停止。  
如需詳細資訊，請參閱 PostgreSQL 文件的 [max\$1wal\$1senders](https://www.postgresql.org/docs/devel/runtime-config-replication.html#GUC-MAX-WAL-SENDERS)。  
`max_wal_senders` 是一個靜態參數，需要將資料庫執行個體重新開機，參數才會生效。

**wal\$1keep\$1segments**  
`wal_keep_segments` 參數指定來源資料庫執行個體保存於 `pg_wal` 目錄中預寫日誌 (WAL) 檔案的數量。預設設定為 32。  
若 `wal_keep_segments` 未對您的部署設定足夠大的值，則僅供讀取複本可能遠遠落後於串流複寫停止。若該狀況發生，Amazon RDS 會產生複寫錯誤，並開始在僅供讀取複本上進行復原。透過重複播放來自 Amazon S3 的來源資料庫執行個體的封存 WAL 資料來進行此作業。此還原程序會繼續進行，直到僅供讀取複本跟上進度，以繼續串流複寫。您可於 [範例：僅供讀取複本如何從複寫中斷復原範例：從複寫中斷復原僅供讀取複本](#USER_PostgreSQL.Replication.example-how-it-works) 中看到 PostgreSQL 日誌所擷取的這個程序。  
於 PostgreSQL 13 版中，`wal_keep_segments` 參數稱為 `wal_keep_size`。其用途與 `wal_keep_segments` 相同，但其預設值以 MB (2048 MB) 為單位，而非檔案數。如需詳細資訊，請參閱 PostgreSQL 文件中的 [wal\$1keep\$1segments](https://www.postgresql.org/docs/12/runtime-config-replication.html#GUC-WAL-KEEP-SEGMENTS) 和 [wal\$1keep\$1size](https://www.postgresql.org/docs/current/runtime-config-replication.html#GUC-WAL-KEEP-SIZE)。

**max\$1slot\$1wal\$1keep\$1size**  
`max_slot_wal_keep_size` 參數控制保留於 `pg_wal` 目錄中 RDS for PostgreSQL 資料庫執行個體的 WAL 資料量來處理插槽。此參數用於使用複寫插槽的組態。此參數的預設值為 `-1`，這表示來源資料庫執行個體上保留的 WAL 資料量並無限制。如需監控複寫槽的相關資訊，請參 [監控 RDS for PostgreSQL 資料庫執行個體的複寫槽](USER_PostgreSQL.Replication.ReadReplicas.Monitor.md#USER_PostgreSQL.Replication.ReadReplicas.Monitor-monitor-replication-slots)。  
如需此參數的詳細資訊，請參閱 PostgreSQL 文件中的 [max\$1slot\$1wal\$1keep\$1size](https://www.postgresql.org/docs/devel/runtime-config-replication.html#GUC-MAX-SLOT-WAL-KEEP-SIZE)。

當提供 WAL 資料給僅供讀取複本的串流中斷時，PostgreSQL 將切換為復原模式。它會使用來自 Amazon S3 的封存 WAL 資料或使用與複寫槽相關聯的 WAL 資料，來還原僅供讀取複本。此程序完成時，PostgreSQL 會重新建立串流複寫。

### 範例：僅供讀取複本如何從複寫中斷復原
<a name="USER_PostgreSQL.Replication.example-how-it-works"></a>

於下列範例中，您可以找到示範僅供讀取複本復原程序的日誌詳細資訊。範例來自在與來源資料庫相同的 中執行 PostgreSQL 12.9 版 AWS 區域 的 RDS for PostgreSQL 資料庫執行個體，因此不會使用複寫槽。 PostgreSQL 對於執行早於 14.1 版且具有區域內僅供讀取複本之 PostgreSQL 的其他 RDS for PostgreSQL 資料庫執行個體，復原程序是相同的。

當僅供讀取複本與來源資料庫執行個體失去連線時，Amazon RDS 會在日誌中將問題記錄為 `FATAL: could not receive data from WAL stream` 訊息與 `ERROR: requested WAL segment ... has already been removed`。如粗體行中所示，Amazon RDS 透過重複播放封存的 WAL 檔案來還原複本。

```
2014-11-07 19:01:10 UTC::@:[23180]:DEBUG:  switched WAL source from archive to stream after failure
2014-11-07 19:01:10 UTC::@:[11575]:LOG: started streaming WAL from primary at 1A/D3000000 on timeline 1
2014-11-07 19:01:10 UTC::@:[11575]:FATAL: could not receive data from WAL stream:
ERROR:  requested WAL segment 000000010000001A000000D3 has already been removed
2014-11-07 19:01:10 UTC::@:[23180]:DEBUG: could not restore file "00000002.history" from archive: return code 0
2014-11-07 19:01:15 UTC::@:[23180]:DEBUG: switched WAL source from stream to archive after failure recovering 000000010000001A000000D3
2014-11-07 19:01:16 UTC::@:[23180]:LOG:  restored log file "000000010000001A000000D3" from archive
```

當 Amazon RDS 在複本上重複播放足夠的封存 WAL 資料以補足空間，讓僅供讀取複本再次開始串流。恢復串流時，Amazon RDS 會將一個項目寫入日誌檔案中，類似下列內容。

```
2014-11-07 19:41:36 UTC::@:[24714]:LOG:started streaming WAL from primary at 1B/B6000000 on timeline 1
```

## 設定控制共用記憶體的參數
<a name="USER_PostgreSQL.Replication.ReadReplicas.Parameters.Settings"></a>

您設定的參數會決定用於追蹤交易 ID、鎖定和預備交易的共用記憶體大小。**待命執行個體的共用記憶體結構必須等於或大於主要執行個體的共用記憶體結構。**這樣可以確保前者在復原過程中不會耗盡共用記憶體。如果複本上的參數值小於主要複本上的參數值，Amazon RDS 將自動調整複本參數並重新啟動引擎。

受影響的參數包括：
+ max\$1connections
+ max\$1worker\$1processes
+ max\$1wal\$1senders
+ max\$1prepared\$1transactions
+ max\$1locks\$1per\$1transaction

為避免 RDS 因記憶體不足而將複本重新開機，我們建議採取滾動式重新開機的方式將參數變更套用至每個複本。當您設定參數時，必須套用下列規則：
+ **增加參數值：**
  + 您應一律先增加所有僅供讀取複本的參數值，並執行所有複本的滾動式重新開機。然後再將參數變更套用至主要執行個體，並重新開機。
+  **增加參數值：**
  + 您應該先減少主要執行個體的參數值，並執行重新開機。然後再將參數變更套用至所有相關聯的僅供讀取複本，並執行滾動式重新開機。

# 監控和調校複寫程序
<a name="USER_PostgreSQL.Replication.ReadReplicas.Monitor"></a>

我們強烈建議您定期監控 RDS for PostgreSQL 資料庫執行個體和僅供讀取複本。您需要確保您的僅供讀取複本與來源資料庫執行個體上的變更保持一致。當複寫程序發生中斷時，Amazon RDS 會通透地復原您的僅供讀取複本。但，最好完全避免需要復原。使用複寫槽進行復原比使用 Amazon S3 封存更快，但任何復原程序皆會影響讀取效能。

如要確定僅供讀取複本與來源資料庫執行個體保持一致的程度，可執行下列作業：
+ **檢查來源資料庫執行個體和複本間的 `ReplicaLag` 數量。***複本延遲*指的是讀取複本落後於其來源資料庫執行個體的時間量 (以秒為單位)。此指標會報告下列查詢結果。

  ```
  SELECT extract(epoch from now() - pg_last_xact_replay_timestamp()) AS "ReplicaLag";
  ```

  複本延遲可表示僅供讀取複本與來源資料庫執行個體保持一致的程度。這是來源資料庫執行個體與特定讀取執行個體之間的延遲量。複本延遲值較高可能表示來源資料庫執行個體與其僅供讀取複本所使用的資料庫執行個體類別或儲存體類型 (或兩者) 不相符。資料庫來源執行個體和所有僅供讀取複本的資料庫執行個體類別和儲存體類型應該相同。

  複本延遲也可為儲存體類型連線問題的結果。您可以在 Amazon CloudWatch 中透過檢視 Amazon RDS `ReplicaLag` 指標來監控複寫延遲。如需進一步了解 `ReplicaLag` 和 Amazon RDS 的其他指標，請參閱 [Amazon RDS 的 Amazon CloudWatch 指標](rds-metrics.md)。
+ **檢查 PostgreSQL 日誌，以取得可用來調整設定的資訊。**PostgreSQL 日誌會在每個檢查點擷取回收的交易日誌檔案數量，如下列範例所示。

  ```
  2014-11-07 19:59:35 UTC::@:[26820]:LOG:  checkpoint complete: wrote 376 buffers (0.2%);
  0 transaction log file(s) added, 0 removed, 1 recycled; write=35.681 s, sync=0.013 s, total=35.703 s;
  sync files=10, longest=0.013 s, average=0.001 s
  ```

  您可以使用這些資訊來確定指定時段內會回收多少個交易檔案。隨後，您可視需要變更 `wal_keep_segments` 的設定。例如，假設 PostgreSQL 日誌在 `checkpoint complete` 中顯示 `35 recycled`，間隔為 5 分鐘。於本案例中，`wal_keep_segments` 預設值 32 不足以跟上串流活動的進度，因此您應提高此參數的值。
+ **使用 Amazon CloudWatch 來監控可預測複寫問題的指標。**您可使用 Amazon CloudWatch 檢查已收集的指標，而非直接分析 PostgreSQL 日誌。例如，您可以檢查 `TransactionLogsGeneration` 指標值，來查看來源資料庫執行個體所產生的 WAL 資料量。在某些狀況下，資料庫執行個體上的工作負載可能會產生大量 WAL 資料。若是如此，您可能需要變更來源資料庫執行個體和僅供讀取複本的資料庫執行個體類別。使用具有高 (10 Gbps) 網路效能的執行個體類別可減少複本延遲。

## 監控 RDS for PostgreSQL 資料庫執行個體的複寫槽
<a name="USER_PostgreSQL.Replication.ReadReplicas.Monitor-monitor-replication-slots"></a>

RDS for PostgreSQL 的所有版本皆會對跨區域僅供讀取複本使用複寫槽。RDS for PostgreSQL 14.1 版和較新版本皆會對區域內僅供讀取複本使用複寫槽。區域內僅供讀取複本還會使用 Amazon S3 來封存 WAL 資料。換言之，若您的資料庫執行個體和僅供讀取複本執行 PostgreSQL 14.1 版或更新版本，則複寫槽和 Amazon S3 封存皆可用於復原僅供讀取複本。使用其複寫槽復原僅供讀取複本比從 Amazon S3 封存復原更快。因此，我們建議您監控複寫槽和及相關的指標。

您可檢視 RDS for PostgreSQL 資料庫執行個體上的複寫槽，方法是查詢 `pg_replication_slots` 檢視，如下所示。

```
postgres=> SELECT * FROM pg_replication_slots;
slot_name                  | plugin | slot_type | datoid | database | temporary | active | active_pid | xmin | catalog_xmin | restart_lsn | confirmed_flush_lsn | wal_status | safe_wal_size | two_phase
---------------------------+--------+-----------+--------+----------+-----------+--------+------------+------+--------------+-------------+---------------------+------------+---------------+-----------
rds_us_west_1_db_555555555 |        | physical  |        |          | f         | t      |      13194 |      |              | 23/D8000060 |                     | reserved   |               | f
(1 row)
```

`reserved` 值的 `wal_status` 表示插槽持有的 WAL 資料量在 `max_wal_size` 參數的範圍內。換言之，複寫槽的大小合適。其他可能的狀態值如下：
+ `extended` – 插槽超過 `max_wal_size` 設定，但會保留 WAL 資料。
+ `unreserved` – 插槽不再具有所有必要的 WAL 資料。其中一些將於下一個檢查點移除。
+ `lost` – 部分必要 WAL 資料已遭移除。該插槽不再可用。

只有在 `max_slot_wal_keep_size` 為非負值時，才會顯示 `wal_status` 的 `unreserved` 和 `lost` 狀態。

`pg_replication_slots` 檢視顯示了複寫槽的目前狀態。如要評估複寫槽的效能，您可使用 Amazon CloudWatch 並監控下列指標：
+ **`OldestReplicationSlotLag`** – 顯示來源上未被最延遲複本耗用的預先寫入日誌 (WAL) 資料量。
+ **`TransactionLogsDiskUsage`** – 顯示 WAL 資料正在使用多少儲存空間。僅供讀取複本大幅延遲時，此指標的值可能會顯著提高。

若要進一步了解如何使用 Amazon CloudWatch 及其用於 RDS for PostgreSQL 的指標，請參閱 [使用 Amazon CloudWatch 監控 Amazon RDS 指標](monitoring-cloudwatch.md)。如需有關監視 RDS for PostgreSQL 資料庫執行個體上串流複寫的詳細資訊，請參閱 *AWS 資料庫部落格*上的 [Amazon RDS PostgreSQL 複寫的最佳實務](https://aws.amazon.com/blogs/database/best-practices-for-amazon-rds-postgresql-replication/)。

# 設定 RDS for PostgreSQL 的延遲複寫
<a name="rpg-delayed-replication"></a>

## 概觀和優點
<a name="rpg-delayed-replication-overview"></a>

RDS for PostgreSQL 中的延遲複寫功能，可讓您刻意延遲將主要資料庫的資料變更複寫到一或多個待命 (僅供讀取複本) 伺服器的作業。藉此可以獲得防止資料損毀、意外資料遺失或錯誤交易的重要機制，以免所有複本立即受到影響。

下列 RDS for PostgreSQL 版本支援延遲複寫：
+ 14.19 和更高的 14 版本
+ 15.14 和更高的 15 版本
+ 16.10 和更高的 16 版本
+ 17.6 和更高的 17 版本

在複寫程序中導入時間延遲後，您將有機會在資料相關事件影響到整個資料庫叢集之前加以偵測並且回應。延遲複寫的主要優點如下：
+ 可讓您在意外刪除、更新或其他邏輯錯誤之後復原。
+ 提供緩衝，防止損毀的資料擴散到您整個資料庫叢集。
+ 提供額外的復原點選項，補強您的傳統備份策略。
+ 可讓您根據組織的特定需求和風險承受能力設定延遲期間。

## 啟用和設定延遲複寫
<a name="enabling-rpg-delayed-replication"></a>

若要在 RDS for PostgreSQL 僅供讀取複本上啟用延遲複寫，請依照下列步驟操作：

**注意**  
對於串聯僅供讀取複本，請使用如下所述的相同 `recovery_min_apply_delay` 參數和步驟。

**啟用延遲複寫**

1. 建立新的自訂參數群組，或修改現有群組。如需詳細資訊，請參閱[Amazon RDS 資料庫執行個體的資料庫參數群組](USER_WorkingWithDBInstanceParamGroups.md)。

1. 在新的參數群組中，設定 `recovery_min_apply_delay` 參數：
   + 將值設定為所需的延遲 (以毫秒為單位)。例如，3600000 代表 1 小時的延遲。
   + 允許的範圍：0 到 86400000 毫秒 (0 到 24 小時)
   + 預設：0

1. 將參數群組套用至要為延遲複寫設定的僅供讀取複本執行個體。

1. 將僅供讀取複本執行個體重新開機，讓變更生效。
**注意**  
此 `recovery_min_apply_delay` 參數是動態的。如果您修改的是已連接至執行個體的現有參數群組，則變更會立即生效，而不需要重新開機。不過，將新的參數群組套用至執行個體時，必須重新開機變更才會生效。

## 管理延遲複寫復原
<a name="managing-rpg-delayed-replication"></a>

在使用傳統時間點復原方法可能不足夠或太耗時的情況下，延遲複寫尤有效用。

在延遲複寫期間，您可以使用下列 PostgreSQL 函數來管理復原程序：
+ `pg_wal_replay_pause()`：要求暫停延遲複本上的復原程序。
+ `pg_wal_replay_resume()`：在復原程序先前已暫停的情況下，予以重新啟動。
+ `pg_is_wal_replay_paused()`：檢查復原程序目前是否暫停。
+ `pg_get_wal_replay_pause_state()`：取得復原程序的目前狀態 (未暫停、已要求暫停或已暫停)。

具有 `rds_superuser` 角色的使用者在 `pg_wal_replay_pause()` 和 `pg_wal_replay_resume()` 上具有 EXECUTE 權限。如果其他資料庫使用者需要存取這些函數，您必須為他們授予 `rds_superuser` 角色。如需 `rds_superuser` 角色的詳細資訊，請參閱 [了解 rds\$1superuser 角色](Appendix.PostgreSQL.CommonDBATasks.Roles.rds_superuser.md)。

存取其他函數 (例如 `pg_is_wal_replay_paused()` 和 `pg_get_wal_replay_pause_state()`) 不需要 `rds_superuser` 角色。

您可以使用下列復原目標參數，精確控制延遲複本要復原到的時間點。這些參數是靜態的，必須將資料庫重新開機才能套用變更：
+ recovery\$1target
+ recovery\$1target\$1lsn
+ recovery\$1target\$1name
+ recovery\$1target\$1time
+ recovery\$1target\$1xid
+ recovery\$1target\$1inclusive

**重要**  
您一次只能指定一個復原目標參數。在組態檔中設定多個復原目標參數，會導致錯誤。

## 規劃考量
<a name="rpg-delayed-replication-considerations"></a>

規劃 RDS for PostgreSQL 的延遲複寫時，請考量下列事項：
+ 在 `rdsrepladmin` 憑證的自動輪換期間 (每 90 天發生一次)，延遲的僅供讀取複本可能會暫時進入 `REPLICATION_ERROR` 狀態。如果延遲複本有足夠的 WAL 日誌可維持設定的延遲，則可能會暫停 WAL 接收器程序，而在來源上導致 WAL 累積。您應監控複本上的複寫狀態，以及來源上的儲存體耗用量，以避免達到儲存已滿狀態。
+ 延遲的僅供讀取複本在經歷系統事件 (例如重新開機或重新啟動) 時，會進入 WAL 接收器程序保持非作用中的 `REPLICATION_ERROR` 狀態，直到設定的延遲期間到期為止。此行為可能會造成來源執行個體上的 WAL 累積，進而導致儲存體耗盡。請考量下列預防措施：
  + 設定 CloudWatch 警示，以監控來源執行個體上的儲存體使用率。
  + 啟用儲存體自動調整功能，以處理非預期的 WAL 增長。
  + 在來源執行個體上設定 `max_slot_wal_keep_size` 參數，以限制每個複寫插槽的 WAL 保留期。
  + 定期監控複寫延遲和插槽狀態。
+ 較長的延遲會增加複本上的 WAL 日誌，而耗用更多儲存體。使用 CloudWatch 警示監控儲存空間、啟用自動調整，或在需要時同步複本。
+ 在提升延遲的僅供讀取複本時不會接受 `recovery_min_apply_delay` 參數，且會立即套用所有待處理的 WAL 記錄。
+ `recovery_min_apply_delay` 參數在階層式複寫設定的各個層級是獨立的。在複本上設定的延遲，並不會新增至任何階層式複本的延遲。

如需詳細資訊，請參閱 [RDS for PostgreSQL 僅供讀取複本文件](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_ReadRepl.html)和 [RDS for PostgreSQL 災難復原文件](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_PostgreSQL.Disaster-Recovery.html)。

## 了解限制
<a name="rpg-delayed-replication-limitations"></a>

Amazon RDS for PostgreSQL 的延遲複寫功能有下列限制：
+ 在設定延遲複寫時，藍/綠部署有下列限制：
  + **綠色來源執行個體** — 即使設定於參數群組中，`recovery_min_apply_delay parameter` 仍會被忽略。綠色來源執行個體上的任何延遲設定都不會生效。
  + **綠色複本執行個體** — `recovery_min_apply_delay parameter` 完全受支援，且會套用至 PostgreSQL 組態檔。在轉換工作流程期間，延遲設定會正常運作。
  + 主要版本升級的 RDS 藍/綠部署
+ 在主要版本升級期間，任何延遲的僅供讀取複本都會自動終止，以允許來源執行個體繼續升級程序，確保能盡可能縮短停機時間。來源執行個體完成升級後，您必須手動重新建立延遲的複本。
+  延遲複寫與下列功能不相容。
  + RDS for PostgreSQL 邏輯複寫
  + RDS for PostgreSQL 多可用區域叢集 (包括傳入和傳出複寫)
  + Aurora PostgreSQL

# RDS for PostgreSQL 僅供讀取複本的疑難排解
<a name="USER_PostgreSQL.Replication.ReadReplicas.Troubleshooting"></a>

您可以在下面找到一些常見 RDS for PostgreSQL 僅供讀取複本問題的疑難排解建議。

**終止導致僅供讀取複本延遲的查詢**  
處於作用中或閒置狀態、且在資料庫中長時間執行的交易可能會干擾 WAL 複寫程序，進而增加複寫延遲。因此，請務必使用 PostgreSQL `pg_stat_activity` 檢視來監控這些交易的執行時間。  
對主要執行個體執行如下的查詢，找出長時間執行之查詢的程序 ID (PID)：  

```
SELECT datname, pid,usename, client_addr, backend_start,
xact_start, current_timestamp - xact_start AS xact_runtime, state,
backend_xmin FROM pg_stat_activity WHERE state='active';
```

```
SELECT now() - state_change as idle_in_transaction_duration, now() - xact_start as xact_duration,* 
FROM  pg_stat_activity 
WHERE state  = 'idle in transaction'
AND   xact_start is not null
ORDER BY 1 DESC;
```
識別查詢的 PID 之後，您可以選擇結束查詢。  
對主要執行個體執行如下的查詢，以終止長時間執行的查詢：  

```
SELECT pg_terminate_backend(PID);
```

# 使用 Amazon RDS Optimized Reads 改善 RDS for PostgreSQL 的查詢效能
<a name="USER_PostgreSQL.optimizedreads"></a>

您可以使用 Amazon RDS Optimized Reads，為 RDS for PostgreSQL 實現更快的查詢處理。使用 RDS Optimized Reads 的 RDS for PostgreSQL 資料庫執行個體或多可用區域資料庫叢集，相較於不使用的情況，查詢處理速度最多可提高 50%。

**Topics**
+ [PostgreSQL 中 RDS Optimized Reads 的概觀](#USER_PostgreSQL.optimizedreads-overview)
+ [RDS Optimized Reads 的使用案例](#USER_PostgreSQL.optimizedreads-use-cases)
+ [RDS Optimized Reads 的最佳實務](#USER_PostgreSQL.optimizedreads-best-practices)
+ [使用 RDS Optimized Reads](#USER_PostgreSQL.optimizedreads-using)
+ [監控使用 RDS Optimized Reads 的資料庫執行個體](#USER_PostgreSQL.optimizedreads-monitoring)
+ [PostgreSQL 中 RDS Optimized Reads 的限制](#USER_PostgreSQL.optimizedreads-limitations)

## PostgreSQL 中 RDS Optimized Reads 的概觀
<a name="USER_PostgreSQL.optimizedreads-overview"></a>

在使用 NVMe 型資料庫執行個體類別時，Optimized Reads 依預設可在 RDS for PostgreSQL 15.2 和更高版本、14.7 和更高版本以及 13.10 和更高版本上使用。如需指出哪些執行個體使用 NVMe 的硬體規格，請參閱 [ 資料庫執行個體類別的硬體規格](Concepts.DBInstanceClass.Summary.md)。

當您使用已開啟 RDS Optimized Reads 的 RDS for PostgreSQL 資料庫執行個體或多可用區域資料庫叢集時，其可透過使用本機非揮發性記憶體儲存裝置 (NVMe) 固態硬碟 (SSD) 區塊層級儲存體，將查詢效能最多提高 50%。您可以將 PostgreSQL 產生的暫存資料表放置在本機儲存體上，藉此減少透過網路傳送至 Elastic Block Storage (EBS) 的流量，以達到更快的查詢處理速度。

在 PostgreSQL 中，臨時物件被指派到暫時命名空間，該命名空間會在工作階段結束時自動丟棄。丟棄時的暫時命名空間會移除任何與工作階段相關的物件，包括結構描述限定物件，例如資料表、函數、運算子，甚至延伸。

在 RDS for PostgreSQL 中，會針對儲存臨時物件的暫存工作區域設定 `temp_tablespaces` 參數。

下列查詢會傳回資料表空間的名稱及其位置。

```
postgres=> show temp_tablespaces;
temp_tablespaces
---------------------
rds_temp_tablespace
(1 row)
```

`rds_temp_tablespace` 是 RDS 設定的資料表空間，指向 NVMe 本機儲存體。您隨時可以使用AWS 管理主控台修改 `Parameter group` 中的這個參數為指向 `rds_temp_tablespace` 以外的任何資料表空間，來切換回 Amazon EBS 儲存體。如需詳細資訊，請參閱 [修改 Amazon RDS 中的資料庫參數群組中的參數](USER_WorkingWithParamGroups.Modifying.md)。您也可以使用 SET 命令，在工作階段層級使用 SET 命令將 `temp_tablespaces` 參數的值修改為 `pg_default`。修改參數會將暫存工作區域重新導向至 Amazon EBS。當 RDS 執行個體或叢集的本機儲存空間不足以執行特定 SQL 操作時，切換回 Amazon EBS 會有所幫助。

```
postgres=> SET temp_tablespaces TO 'pg_default';
SET
```

```
postgres=> show temp_tablespaces;
            
 temp_tablespaces
------------------
 pg_default
```

## RDS Optimized Reads 的使用案例
<a name="USER_PostgreSQL.optimizedreads-use-cases"></a>

下列是可從 Optimized Reads 中受益的一些使用案例：
+ 分析查詢，包括一般資料表表達式 (CTE)、衍生資料表和群組操作。
+ 處理應用程式未最佳化查詢的僅供讀取複本。
+ 具有複雜操作的隨需或動態報告查詢 (例如 GROUP BY 和 ORDER BY)，無法始終使用適當的索引。
+ 使用內部暫存資料表的其他工作負載
+ 用於排序的 `CREATE INDEX` 或 `REINDEX` 操作。

## RDS Optimized Reads 的最佳實務
<a name="USER_PostgreSQL.optimizedreads-best-practices"></a>

請使用 RDS Optimized Reads 的下列最佳實務：
+ 針對唯讀查詢新增重試邏輯，以防這些查詢在執行期間由於執行個體儲存體已滿而失敗。
+ 使用 CloudWatch 指標 `FreeLocalStorage` 監控執行個體儲存體上的可用儲存空間。如果執行個體儲存體由於資料庫執行個體或多可用區域資料庫叢集的工作負載而達到其限制，請對其修改以使用較大的資料庫執行個體類別。

## 使用 RDS Optimized Reads
<a name="USER_PostgreSQL.optimizedreads-using"></a>

當您在單一可用區域資料庫執行個體部署、多可用區域資料庫執行個體部署或多可用區域資料庫叢集部署中，佈建具有 NVMe 基礎其中一個資料庫執行個體類別的 RDS for PostgreSQL 資料庫執行個體時，資料庫執行個體會自動使用 RDS Optimized Reads：

如需多可用區域部署的詳細資訊，請參閱 [設定及管理 Amazon RDS 的多可用區域部署](Concepts.MultiAZ.md)。

若要開啟 RDS Optimized Reads，請執行下列其中一項：
+ 使用其中一個 NVMe 為基礎的資料庫執行個體類別，建立 RDS for PostgreSQL 資料庫執行個體或多可用區域資料庫叢集。如需詳細資訊，請參閱 [建立 Amazon RDS 資料庫執行個體](USER_CreateDBInstance.md)。
+ 修改現有的 RDS for PostgreSQL 資料庫執行個體或多可用區資料庫叢集，以使用其中一個 NVMe 為基礎的資料庫執行個體類別。如需詳細資訊，請參閱 [修改 Amazon RDS 資料庫執行個體](Overview.DBInstance.Modifying.md)。

RDS Optimized Reads 適用於支援其中一或多個具有本機 NVMe SSD 儲存體的資料庫執行個體類別之所有AWS 區域。如需詳細資訊，請參閱 [ 資料庫執行個體類別](Concepts.DBInstanceClass.md)。

若要切換回非最佳化讀取 RDS 執行個體，請將 RDS 執行個體或叢集的資料庫執行個體類別修改為僅支援資料庫工作負載 EBS 儲存體的類似執行個體類別。例如，如果目前的資料庫執行個體類別是 db.r6gd.4xlarge，請選擇 db.r6g.4xlarge 以切換回來。如需詳細資訊，請參閱 [修改 Amazon RDS 資料庫執行個體](Overview.DBInstance.Modifying.md)。

## 監控使用 RDS Optimized Reads 的資料庫執行個體
<a name="USER_PostgreSQL.optimizedreads-monitoring"></a>

您可以透過下列 CloudWatch 指標，監控使用 RDS Optimized Reads 的資料庫執行個體：
+ `FreeLocalStorage`
+ `ReadIOPSLocalStorage`
+ `ReadLatencyLocalStorage`
+ `ReadThroughputLocalStorage`
+ `WriteIOPSLocalStorage`
+ `WriteLatencyLocalStorage`
+ `WriteThroughputLocalStorage`

這些指標提供可用執行個體儲存體、IOPS 和輸送量的相關資料。如需這些指標的詳細資訊，請參閱 [Amazon RDS 的 Amazon CloudWatch 執行個體層級指標](rds-metrics.md#rds-cw-metrics-instance)。

若要監控本機儲存體的目前使用狀況，請執行下列查詢以登入資料庫：

```
SELECT
    spcname AS "Name",
    pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS "size"
FROM
    pg_catalog.pg_tablespace
WHERE
    spcname IN ('rds_temp_tablespace');
```

如需暫存檔案及其使用情況的詳細資訊，請參閱 [使用 PostgreSQL 管理暫存檔案](PostgreSQL.ManagingTempFiles.md)。

## PostgreSQL 中 RDS Optimized Reads 的限制
<a name="USER_PostgreSQL.optimizedreads-limitations"></a>

下列限制適用於 PostgreSQL 中的 RDS Optimized Reads：
+ 執行個體儲存體已滿時，交易會失敗。

# 將資料匯入 Amazon RDS 上的 PostgreSQL
<a name="PostgreSQL.Procedural.Importing"></a>

假設有要移動到 Amazon RDS 的現有 PostgreSQL 部署。任務的複雜性取決於資料庫大小以及要傳輸的資料庫物件類型。例如，假設一個資料庫包含大約數 GB 的資料集，以及預存程序和觸發條件。此類資料庫會比僅含少量 GB 測試資料且沒有觸發條件或預存程序的簡單資料庫更複雜。

在下列情況中，建議您使用原生 PostgreSQL 資料庫遷移工具：
+ 您準備進行同質遷移，亦即遷移的來源資料庫使用與目標資料庫相同的資料庫引擎。
+ 您想要遷移整個資料庫。
+ 原生工具可讓您以最短的停機時間來遷移系統。

在大多數其他情況下，使用 AWS Database Migration Service (AWS DMS) 執行資料庫遷移是最佳方法。 AWS DMS 可以在不停機的情況下遷移資料庫，而且對於許多資料庫引擎而言，會持續複寫，直到您準備好切換到目標資料庫為止。您可以使用 DMS AWS 遷移至相同的資料庫引擎或不同的資料庫引擎。如果您要遷移至與來源資料庫不同的資料庫引擎，您可以使用 AWS Schema Conversion Tool (AWS SCT)。您可以使用 AWS SCT 來遷移未由 遷移的結構描述物件 AWS DMS。如需 AWS DMS 的詳細資訊，請參閱[什麼是 AWS Database Migration Service？](https://docs.aws.amazon.com/dms/latest/userguide/Welcome.html)

*僅針對您的匯入*，修改資料庫參數群組來包含下列設定。您應該測試參數設定，以根據資料庫執行個體大小找出最有效率的設定。匯入完成之後，您也需要將這些參數回復為生產值。

將資料庫執行個體設定修改為下列：
+ 停用資料庫執行個體備份 (將 backup\$1retention 設為 0)。
+ 停用多個可用區。

修改資料庫參數群組來包含下列設定。您應該僅在匯入資料時才使用這些設定。您應該測試參數設定，以根據資料庫執行個體大小找出最有效率的設定。匯入完成之後，您也需要將這些參數回復為生產值。


| 參數 | 匯入時的建議值 | 描述 | 
| --- | --- | --- | 
|  `maintenance_work_mem`  |  524288、1048576、2097152 或 4194304 (KB)。這些設定相當於 512 MB、1 GB、2 GB 和 4 GB。  |  此設定的值取決於主機大小。CREATE INDEX 陳述式期間會使用此參數，每個平行命令皆可使用這麼多的記憶體。計算最佳值，以免將此值設得太高而耗盡記憶體。  | 
|  `max_wal_size`  |  256 (適用於 9.6 版)、4096 (適用於 10 版及更新版本)  |  將尺寸提高至最大，讓 WAL 能在自動檢查點期間成長。增加此參數可增加損毀復原所需的時間。此參數會將 `checkpoint_segments` 取代為 PostgreSQL 9.6 及更新版本。 若為 PostgreSQL 9.6 版，此數值是以 16 MB 為單位。若為更新的版本，該數值是以 1 MB 為單位。例如，在 9.6 版中，128 表示 128 個達到 16 MB 的區塊。在 12.4 版中，2048 表示 2048 個尺寸各為 1 MB 的區塊。  | 
|  `checkpoint_timeout`  |  1800  |  此設定的值可減少 WAL 輪換次數。  | 
|  `synchronous_commit`  |  關閉  |  停用此設定可加速寫入。關閉此參數會在伺服器當機時增加資料遺失的風險 (請勿關閉 FSYNC)。  | 
|  `wal_buffers`  |   8192  |  此值以 8 KB 為單位。這同樣可加速產生 WAL  | 
|  `autovacuum`  |  0  |  載入資料時停用 PostgreSQL 自動清理參數，以免浪費資源  | 

使用 `pg_dump -Fc` (壓縮) 或 `pg_restore -j` (平行) 命令搭配這些設定。

**注意**  
PostgreSQL 命令 `pg_dumpall` 需要 super\$1user 許可，但建立資料庫執行個體時並未授予此許可，因此無法用來匯入資料。

**Topics**
+ [從 Amazon EC2 執行個體匯入 PostgreSQL 資料庫](PostgreSQL.Procedural.Importing.EC2.md)
+ [使用 \$1copy 命令將資料匯入 PostgreSQL 資料庫執行個體上的資料表](PostgreSQL.Procedural.Importing.Copy.md)
+ [將資料從 Amazon S3 匯入 RDS for PostgreSQL 資料庫執行個體](USER_PostgreSQL.S3Import.md)
+ [在 與資料庫執行個體之間傳輸 PostgreSQL 資料庫](PostgreSQL.TransportableDB.md)

# 從 Amazon EC2 執行個體匯入 PostgreSQL 資料庫
<a name="PostgreSQL.Procedural.Importing.EC2"></a>

如果您在 Amazon EC2 執行個體上的 PostgreSQL 伺服器中有資料，且想要將資料移至 PostgreSQL 資料庫執行個體，您可以依照下列程序來遷移資料。

1. 使用 pg\$1dump 建立檔案，其中包含要載入的資料

1. 建立目標資料庫執行個體

1. 使用 *psql* 在資料庫執行個體上建立資料庫並載入資料

1. 建立資料庫執行個體的資料庫快照

以下幾節提供上述各個步驟的詳細資訊。

## 步驟 1：使用 pg\$1dump 建立檔案，其中包含要載入的資料
<a name="PostgreSQL.Procedural.Importing.EC2.Step1"></a>

`pg_dump` 公用程式會使用 COPY 命令建立 PostgreSQL 資料庫的結構描述和資料傾印。`pg_dump` 產生的傾印指令碼會將資料載入相同名稱的資料庫中，並重新建立資料表、索引和外部索引鍵。您可以使用 `pg_restore` 命令和 `-d` 參數將資料還原至不同名稱的資料庫。

建立資料傾印之前，您應該查詢要傾印的資料表來取得資料列計數，以確認目標資料庫執行個體上的計數。

 下列命令為資料庫 mydb2 建立名為 mydb2dump.sql 的傾印檔案。

```
prompt>pg_dump dbname=mydb2 -f mydb2dump.sql 
```

## 步驟 2：建立目標資料庫執行個體
<a name="PostgreSQL.Procedural.Importing.EC2.Step2"></a>

您可以使用 Amazon RDS 主控台、 AWS CLI或 API 來建立目標 PostgreSQL 資料庫執行個體。建立將備份保留期設為 0 的執行個體，並停用多個可用區。這麼做可以加速匯入資料。您必須先在執行個體上建立資料庫，才能傾印資料。此資料庫與包含傾印資料的資料庫可以具有相同名稱。或者，您可以建立不同名稱的資料庫。在此情況下，您可以使用 `pg_restore` 命令和 `-d` 參數將資料還原至新命名的資料庫。

例如，下列命令可用來傾印、還原和重新命名資料庫。

```
pg_dump -Fc -v -h [endpoint of instance] -U [master username] [database] > [database].dump
createdb [new database name]
pg_restore -v -h [endpoint of instance] -U [master username] -d [new database name] [database].dump
```

## 步驟 3：使用 psql 在資料庫執行個體上建立資料庫並載入資料
<a name="PostgreSQL.Procedural.Importing.EC2.Step3"></a>

您可以使用原本用來執行 pg\$1dump 命令的相同連線，以連線至目標資料庫執行個體並重新建立資料庫。透過 *psql*，您可以使用主要使用者名稱和主要密碼在資料庫執行個體上建立資料庫

下列範例使用 *psql* 和名為 mydb2dump.sql 的傾印檔案，在稱為 mypginstance 的 PostgreSQL 資料庫執行個體上建立名為 mydb2 的資料庫：

針對 Linux、macOS 或 Unix：

```
psql \
   -f mydb2dump.sql \
   --host mypginstance.555555555555.aws-region.rds.amazonaws.com \
   --port 8199 \
   --username myawsuser \
   --password password \
   --dbname mydb2
```

在 Windows 中：

```
psql ^
   -f mydb2dump.sql ^
   --host mypginstance.555555555555.aws-region.rds.amazonaws.com ^
   --port 8199 ^
   --username myawsuser ^
   --password password ^
   --dbname mydb2
```

**注意**  
指定此處所顯示提示以外的密碼，作為安全最佳實務。

## 步驟 4：建立資料庫執行個體的資料庫快照
<a name="PostgreSQL.Procedural.Importing.EC2.Step4"></a>

在確認資料已載入至資料庫執行個體後，建議您建立目標 PostgreSQL 資料庫執行個體的資料庫快照。資料庫快照是您資料庫執行個體的完整備份，可將您的資料庫執行個體還原至已知狀態。若能在載入後立即拍攝資料庫快照，萬一發生事故，就不必重新載入資料。您也可使用快照植入新的資料庫執行個體。如需有關建立資料庫快照的資訊，請參閱[為 Amazon RDS 的單一可用區域資料庫執行個體建立資料庫快照](USER_CreateSnapshot.md)。

# 使用 \$1copy 命令將資料匯入 PostgreSQL 資料庫執行個體上的資料表
<a name="PostgreSQL.Procedural.Importing.Copy"></a>

PostgreSQL `\copy` 命令是中繼命令，可從 `psql` 互動式用戶端工具使用。您可以使用 `\copy` 將資料匯入至 RDS for PostgreSQL 資料庫執行個體上的資料表。若要使用 `\copy` 命令，首先需在目標資料庫執行個體上建立資料表結構，讓 `\copy` 具有複製資料的目的地。

您可以使用 `\copy` 從逗點分隔值 (CSV) 檔案 (例如已匯出並儲存到用戶端工作站的檔案) 載入資料。

若要將 CSV 資料匯入至目標 RDS for PostgreSQL 資料庫執行個體，需先使用 `psql` 連線至目標資料庫執行個體。

```
psql --host=db-instance.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=target-db
```

然後執行 `\copy` 命令搭配下列參數，以識別資料的目標及其格式。
+ `target_table` – 應接收從 CSV 檔案所複製資料的資料表之名稱。
+ `column_list` – 資料表的資料欄規格。
+ `'filename'` – 您本機工作站上 CSV 檔案的完整路徑。

```
 \copy target_table from '/path/to/local/filename.csv' WITH DELIMITER ',' CSV;
```

如果 CSV 檔案包含資料欄標題資訊，您可以使用此版本的命令和參數。

```
\copy target_table (column-1, column-2, column-3, ...)
    from '/path/to/local/filename.csv' WITH DELIMITER ',' CSV HEADER;
```

 如果 `\copy` 命令失敗，PostgreSQL 會輸出錯誤訊息。

使用 `\copy` 中繼命令，在資料庫預覽環境中使用 `psql` 命令建立新的資料庫執行個體，如下列範例所示。此範例使用 *source-table* 做為來源資料表名稱、*source-table.csv* 做為 .csv 檔案，而 *target-db* 做為目標資料庫：

針對 Linux、macOS 或 Unix：

```
$psql target-db \
    -U <admin user> \
    -p <port> \
    -h <DB instance name> \
    -c "\copy source-table from 'source-table.csv' with DELIMITER ','"
```

在 Windows 中：

```
$psql target-db ^
    -U <admin user> ^
    -p <port> ^
    -h <DB instance name> ^
    -c "\copy source-table from 'source-table.csv' with DELIMITER ','"
```

如需有關 `\copy` 命令的完整詳細資訊，請參閱 PostgreSQL說明文件裡*中繼命令*中區段的 [psql](http://www.postgresql.org/docs/current/static/app-psql.html) 頁面。

# 將資料從 Amazon S3 匯入 RDS for PostgreSQL 資料庫執行個體
<a name="USER_PostgreSQL.S3Import"></a>

您可以將使用 Amazon Simple Storage Service 儲存的資料匯入 RDS for PostgreSQL 資料庫執行個體。要執行此操作，您首先安裝 RDS for PostgreSQL `aws_s3` 擴充功能。此擴充功能提供可用於從 Amazon S3 儲存貯體匯入資料的函數。*儲存貯體*是物件或檔案的 Amazon S3 容器。資料可以是逗號分隔值 (CSV) 檔案、文字檔案或壓縮 (gzip) 檔案。從下文中，您可以了解如何安裝擴充功能，以及如何將資料從 Amazon S3 匯入資料表。

您的資料庫必須執行 PostgreSQL 10.7 版或更高版本，才能從 Simple Storage Service (Amazon S3) 匯入 RDS for PostgreSQL。

如果您沒有資料儲存於 Amazon S3 上，您需要先建立儲存貯體並儲存資料。如需詳細資訊，請參閱《*Amazon Simple Storage Service 使用者指南*》中的下列主題：
+ [建立儲存貯體](https://docs.aws.amazon.com/AmazonS3/latest/userguide/GetStartedWithS3.html#creating-bucket)
+ [將物件新增到儲存貯體](https://docs.aws.amazon.com/AmazonS3/latest/userguide/GetStartedWithS3.html#uploading-an-object-bucket) 

支援從 Amazon S3 匯入跨帳戶。如需更多詳細資訊，請參閱《Amazon Simple Storage Service 使用者指南》**中的[授予跨帳戶許可](https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-walkthroughs-managing-access-example2.html)。

從 S3 匯入資料時，您可以使用客戶受管金鑰進行加密。如需詳細資訊，請參閱《Amazon Simple Storage Service 使用者指南》**中的 [儲存在 AWS KMS 中的 KMS 金鑰](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingKMSEncryption.html)。

**Topics**
+ [安裝 aws\$1s3 擴充功能](USER_PostgreSQL.S3Import.InstallExtension.md)
+ [從 Amazon S3 資料匯入資料的概觀](USER_PostgreSQL.S3Import.Overview.md)
+ [設定對 Amazon S3 儲存貯體的存取權](USER_PostgreSQL.S3Import.AccessPermission.md)
+ [將資料從 Amazon S3 匯入 RDS for PostgreSQL 資料庫執行個體](USER_PostgreSQL.S3Import.FileFormats.md)
+ [函數參考](USER_PostgreSQL.S3Import.Reference.md)

# 安裝 aws\$1s3 擴充功能
<a name="USER_PostgreSQL.S3Import.InstallExtension"></a>

您需要先安裝 `aws_s3` 擴充功能，才能將 Amazon S3 與 RDS for PostgreSQL 資料庫執行個體搭配使用。此擴充功能提供從 Amazon S3 匯入資料的函數。它還提供了從 RDS for PostgreSQL 資料庫執行個體中匯出資料到 Amazon S3 儲存貯體的功能。如需更多詳細資訊，請參閱 [將資料從 RDS for PostgreSQL 資料庫執行個體匯出至 Amazon S3](postgresql-s3-export.md)。`aws_s3` 擴充功能取決於 `aws_commons` 擴充功能中的一些輔助函數，需要時會自動安裝。

**安裝 `aws_s3` 擴充功能**

1. 使用 psql (或 pgAdmin) 以具有 `rds_superuser` 權限的使用者身分連接到 RDS for PostgreSQL 資料庫執行個體。若您在安裝程序期間保留預設名稱，則連接為 `postgres`。

   ```
   psql --host=111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password
   ```

1. 若要安裝擴充功能，請執行下列命令。

   ```
   postgres=> CREATE EXTENSION aws_s3 CASCADE;
   NOTICE: installing required extension "aws_commons"
   CREATE EXTENSION
   ```

1. 若要驗證是否已經安裝擴充功能，可以使用 psql `\dx` 中繼命令。

   ```
   postgres=> \dx
          List of installed extensions
       Name     | Version |   Schema   |                 Description
   -------------+---------+------------+---------------------------------------------
    aws_commons | 1.2     | public     | Common data types across AWS services
    aws_s3      | 1.1     | public     | AWS S3 extension for importing data from S3
    plpgsql     | 1.0     | pg_catalog | PL/pgSQL procedural language
   (3 rows)
   ```

現在可以使用從 Amazon S3 匯入和匯出資料的功能。

# 從 Amazon S3 資料匯入資料的概觀
<a name="USER_PostgreSQL.S3Import.Overview"></a>

**將 S3 資料匯入 Amazon RDS**

首先，收集您需要提供給函數的詳細資訊。其中包括 RDS for PostgreSQL 資料庫執行個體，以及儲存貯體名稱、檔案路徑、檔案類型，以及 Amazon S3 資料的存放 AWS 區域 位置。如需詳細資訊，請參閱 *Amazon Simple Storage Service 使用者指南*中的[檢視物件](https://docs.aws.amazon.com/AmazonS3/latest/userguide/OpeningAnObject.html)。
**注意**  
目前不支援從 Amazon S3 匯入多重部分資料。

1. 取得 `aws_s3.table_import_from_s3` 函數要匯入資料的資料表名稱。舉例來說，下列命令建立的資料表 `t1`，可用於之後的步驟中。

   ```
   postgres=> CREATE TABLE t1 
       (col1 varchar(80), 
       col2 varchar(80), 
       col3 varchar(80));
   ```

1. 取得 Amazon S3 儲存貯體以及要匯入資料的詳細資料。要執行此操作，請在以下網址開啟 Amazon S3 主控台：[https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/)，然後選擇 **Buckets** (儲存貯體)。在清單中尋找包含您資料的儲存貯體。選擇儲存貯體，開啟其物件概觀頁面，然後選擇 Properties (屬性)。

   請記下儲存貯體名稱、路徑 AWS 區域、 和 檔案類型。您稍後需要 Amazon Resource Name (ARN)，以設定透過 IAM 角色對 Amazon S3 的存取權限。如需詳細資訊，請參閱 [設定對 Amazon S3 儲存貯體的存取權](USER_PostgreSQL.S3Import.AccessPermission.md)。下圖顯示範例。  
![\[Amazon S3 儲存貯體中檔案物件的影像。\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/images/aws_s3_import-export_s3_bucket-info.png)

1. 您可以使用 AWS CLI 命令 來驗證 Amazon S3 儲存貯體上資料的路徑`aws s3 cp`。如果資訊正確，此命令會下載 Amazon S3 檔案的副本。

   ```
   aws s3 cp s3://amzn-s3-demo-bucket/sample_file_path ./ 
   ```

1. 設定 RDS for PostgreSQL 資料庫執行個體的許可，以允許存取 Amazon S3 儲存貯體上的檔案。若要這樣做，您可以使用 AWS Identity and Access Management (IAM) 角色或安全登入資料。如需詳細資訊，請參閱[設定對 Amazon S3 儲存貯體的存取權](USER_PostgreSQL.S3Import.AccessPermission.md)。

1. 將收集到的路徑和其他 Amazon S3 物件詳細資訊 (請參閱步驟 2) 提供給 `create_s3_uri` 函數，以建構 Amazon S3 URI 物件。若要進一步了解此函數，請參閱 [aws\$1commons.create\$1s3\$1uri](USER_PostgreSQL.S3Import.Reference.md#USER_PostgreSQL.S3Import.create_s3_uri)。以下是在 psql 工作階段中建構此物件的範例。

   ```
   postgres=> SELECT aws_commons.create_s3_uri(
      'docs-lab-store-for-rpg',
      'versions_and_jdks_listing.csv',
      'us-west-1'
   ) AS s3_uri \gset
   ```

   在下一個步驟中，您將此物件 (`aws_commons._s3_uri_1`) 傳遞到 `aws_s3.table_import_from_s3` 函數，將資料匯入資料表。

1. 調用 `aws_s3.table_import_from_s3` 函數，將資料從 Amazon S3 匯入資料表。如需參考資訊，請參閱 [aws\$1s3.table\$1import\$1from\$1s3](USER_PostgreSQL.S3Import.Reference.md#aws_s3.table_import_from_s3)。如需範例，請參閱 [將資料從 Amazon S3 匯入 RDS for PostgreSQL 資料庫執行個體](USER_PostgreSQL.S3Import.FileFormats.md)。

# 設定對 Amazon S3 儲存貯體的存取權
<a name="USER_PostgreSQL.S3Import.AccessPermission"></a>

若要從 Amazon S3 檔案匯入資料，請為 RDS for PostgreSQL 資料庫執行個體提供許可，以便存取檔案所在的 Amazon S3 儲存貯體。您可以透過以下兩個方式中的一個提供存取給 Amazon S3 儲存貯體，如下列主題中所述。

**Topics**
+ [使用 IAM 角色存取 Amazon S3 儲存貯體](#USER_PostgreSQL.S3Import.ARNRole)
+ [使用安全登入資料存取 Amazon S3 儲存貯體](#USER_PostgreSQL.S3Import.Credentials)
+ [對 Amazon S3 的存取進行故障診斷](#USER_PostgreSQL.S3Import.troubleshooting)

## 使用 IAM 角色存取 Amazon S3 儲存貯體
<a name="USER_PostgreSQL.S3Import.ARNRole"></a>

在您由 Amazon S3 檔案載入資料之前，請為 RDS for PostgreSQL 資料庫執行個體提供許可，以便存取檔案所在的 Amazon S3 儲存貯體。這樣您就不必管理額外的登入資料資訊或在 [aws\$1s3.table\$1import\$1from\$1s3](USER_PostgreSQL.S3Import.Reference.md#aws_s3.table_import_from_s3) 函數呼叫中提供它。

若要執行此動作，請建立可提供 Amazon S3 儲存貯體存取的 IAM 政策。建立 IAM 角色，並將政策連接到該角色。然後將 IAM 角色指派到您的資料庫執行個體。

**透過 IAM 角色將 RDS for PostgreSQL 資料庫執行個體的存取權授予 Amazon S3**

1. 建立 IAM 政策。

   此政策可提供儲存貯體及物件許可，讓 RDS for PostgreSQL 資料庫執行個體能夠存取 Amazon S3。

   在政策中納入下列必要動作，以允許由 Amazon S3 儲存貯體傳輸檔案至 Amazon RDS：
   + `s3:GetObject` 
   + `s3:ListBucket` 

   在政策中包含下列資源，以識別 Amazon S3 儲存貯體和儲存貯體中的物件。這會顯示用於存取 Amazon S3 的 Amazon Resource Name (ARN) 格式。
   + arn:aws:s3:::*amzn-s3-demo-bucket*
   + arn:aws:s3:::*amzn-s3-demo-bucket*/\$1

   如需建立 Amazon RDS for PostgreSQL IAM 政策的詳細資訊，請參閱 [建立並使用 IAM 政策進行 IAM 資料庫存取](UsingWithRDS.IAMDBAuth.IAMPolicy.md)。另請參閱《*IAM 使用者指南*》中的[教學：建立和連接您的第一個客戶受管原則](https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_managed-policies.html)。

   下列 AWS CLI 命令會使用這些選項建立名為 `rds-s3-import-policy`的 IAM 政策。其將存取權授予名為 *amzn-s3-demo-bucket* 的儲存貯體。
**注意**  
請記下此命令所傳回政策的 Amazon Resource Name (ARN)。在後續步驟中將政策連接至 IAM 角色時，您會需要此 ARN。  
**Example**  

   針對 Linux、macOS 或 Unix：

   ```
   aws iam create-policy \
      --policy-name rds-s3-import-policy \
      --policy-document '{
        "Version": "2012-10-17",		 	 	 
        "Statement": [
          {
            "Sid": "s3import",
            "Action": [
              "s3:GetObject",
              "s3:ListBucket"
            ],
            "Effect": "Allow",
            "Resource": [
              "arn:aws:s3:::amzn-s3-demo-bucket", 
              "arn:aws:s3:::amzn-s3-demo-bucket/*"
            ] 
          }
        ] 
      }'
   ```

   在 Windows 中：

   ```
   aws iam create-policy ^
      --policy-name rds-s3-import-policy ^
      --policy-document '{
        "Version": "2012-10-17",		 	 	 
        "Statement": [
          {
            "Sid": "s3import",
            "Action": [
              "s3:GetObject",
              "s3:ListBucket"
            ], 
            "Effect": "Allow",
            "Resource": [
              "arn:aws:s3:::amzn-s3-demo-bucket", 
              "arn:aws:s3:::amzn-s3-demo-bucket/*"
            ] 
          }
        ] 
      }'
   ```

1. 建立 IAM 角色。

   這麼做是為了讓 Amazon RDS 擔任此 IAM 角色，以存取您的 Amazon S3 儲存貯體。如需詳細資訊，請參閱《IAM 使用者指南》**中的[建立角色以將許可委派給 IAM 使用者](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user.html)。

   建議您在資源型政策中使用 `[aws:SourceArn](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn)` 和 `[aws:SourceAccount](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount)` 全域條件內容金鑰，將服務的許可限定於特定資源。這是防止[混淆代理人問題](https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html)最有效的方式。

   如果同時使用這兩個全域條件內容索引鍵，且 `aws:SourceArn` 值包含帳戶 ID，則在相同政策陳述式中使用 `aws:SourceAccount` 值和 `aws:SourceArn` 值中的帳戶時，必須使用相同的帳戶 ID。
   + 如果您想要跨服務存取單一資源，請使用 `aws:SourceArn`。
   + 如果您想要允許該帳戶中的任何資源與跨服務使用相關聯，請使用 `aws:SourceAccount`。

   在政策中，請務必搭配資源的完整 ARN 來使用 `aws:SourceArn` 全域條件內容金鑰。下列範例示範如何使用 AWS CLI 命令來建立名為 的角色`rds-s3-import-role`。  
**Example**  

   針對 Linux、macOS 或 Unix：

   ```
   aws iam create-role \
      --role-name rds-s3-import-role \
      --assume-role-policy-document '{
        "Version": "2012-10-17",		 	 	 
        "Statement": [
          {
            "Effect": "Allow",
            "Principal": {
               "Service": "rds.amazonaws.com"
             },
            "Action": "sts:AssumeRole",
            "Condition": {
                "StringEquals": {
                   "aws:SourceAccount": "111122223333",
                   "aws:SourceArn": "arn:aws:rds:us-east-1:111122223333:db:dbname"
                   }
                }
          }
        ] 
      }'
   ```

   在 Windows 中：

   ```
   aws iam create-role ^
      --role-name rds-s3-import-role ^
      --assume-role-policy-document '{
        "Version": "2012-10-17",		 	 	 
        "Statement": [
          {
            "Effect": "Allow",
            "Principal": {
               "Service": "rds.amazonaws.com"
             },
            "Action": "sts:AssumeRole",
            "Condition": {
                "StringEquals": {
                   "aws:SourceAccount": "111122223333",
                   "aws:SourceArn": "arn:aws:rds:us-east-1:111122223333:db:dbname"
                   }
                }
          }
        ] 
      }'
   ```

1. 將您建立的 IAM 政策附加至您建立的 IAM 角色。

   下列 AWS CLI 命令會將上一個步驟中建立的政策連接至名為 `rds-s3-import-role` Replace `your-policy-arn` with the policy ARN 的角色，該角色是您在先前步驟中記下的政策 ARN。  
**Example**  

   針對 Linux、macOS 或 Unix：

   ```
   aws iam attach-role-policy \
      --policy-arn your-policy-arn \
      --role-name rds-s3-import-role
   ```

   在 Windows 中：

   ```
   aws iam attach-role-policy ^
      --policy-arn your-policy-arn ^
      --role-name rds-s3-import-role
   ```

1. 將 IAM 角色新增至資料庫執行個體。

   您可以使用 AWS 管理主控台 或 來執行此操作 AWS CLI，如下所述。

### 主控台
<a name="collapsible-section-1"></a>

**使用主控台為 PostgreSQL 資料庫執行個體新增 IAM 角色**

1. 登入 AWS 管理主控台 ，並在 [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/)：// 開啟 Amazon RDS 主控台。

1. 選擇 PostgreSQL 資料庫執行個體名稱以顯示其詳細資訊。

1. 在 **Connectivity & security (連線能力與安全)** 標籤上，在 **Manage IAM roles (管理 IAM 角色)** 區段中，在 **Add IAM roles to this instance (將 IAM 角色新增到此叢集執行個體)** 下方，選擇要新增的角色。

1. 請在 **Feature** (功能) 下，選擇 **s3Import**。

1. 選擇 **Add role (新增角色)**。

### AWS CLI
<a name="collapsible-section-2"></a>

**使用 CLI 為 PostgreSQL 資料庫執行個體新增 IAM 角色**
+ 使用下列命令將角色新增至名為 `my-db-instance` 的 PostgreSQL 資料庫執行個體。將 *`your-role-arn`* 替換為您前個步驟記下的角色 ARN。使用 `s3Import` 作為 `--feature-name` 選項的值。  
**Example**  

  針對 Linux、macOS 或 Unix：

  ```
  aws rds add-role-to-db-instance \
     --db-instance-identifier my-db-instance \
     --feature-name s3Import \
     --role-arn your-role-arn   \
     --region your-region
  ```

  在 Windows 中：

  ```
  aws rds add-role-to-db-instance ^
     --db-instance-identifier my-db-instance ^
     --feature-name s3Import ^
     --role-arn your-role-arn ^
     --region your-region
  ```

### RDS API
<a name="collapsible-section-3"></a>

若要使用 Amazon RDS API 為 PostgreSQL 資料庫執行個體新增 IAM 角色，請呼叫 [AddRoleToDBInstance](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_AddRoleToDBInstance.html) 操作。

## 使用安全登入資料存取 Amazon S3 儲存貯體
<a name="USER_PostgreSQL.S3Import.Credentials"></a>

如果想要，可以使用安全登入資料來提供 Amazon S3 儲存貯體的存取，而非使用 IAM 角色提供存取。要執行此操作，您可以指定 [aws\$1s3.table\$1import\$1from\$1s3](USER_PostgreSQL.S3Import.Reference.md#aws_s3.table_import_from_s3) 函數呼叫中的 `credentials` 參數。

`credentials` 參數是類型 的結構`aws_commons._aws_credentials_1`，其中包含 AWS 登入資料。請使用 [aws\$1commons.create\$1aws\$1credentials](USER_PostgreSQL.S3Import.Reference.md#USER_PostgreSQL.S3Import.create_aws_credentials) 函數在 `aws_commons._aws_credentials_1` 結構設定存取金鑰及秘密金鑰，如下所示。

```
postgres=> SELECT aws_commons.create_aws_credentials(
   'sample_access_key', 'sample_secret_key', '')
AS creds \gset
```

建立 `aws_commons._aws_credentials_1 ` 結構之後，請使用 [aws\$1s3.table\$1import\$1from\$1s3](USER_PostgreSQL.S3Import.Reference.md#aws_s3.table_import_from_s3) 函數搭配 `credentials` 參數來匯入資料，如下所示。

```
postgres=> SELECT aws_s3.table_import_from_s3(
   't', '', '(format csv)',
   :'s3_uri', 
   :'creds'
);
```

或是您可在 [aws\$1commons.create\$1aws\$1credentials](USER_PostgreSQL.S3Import.Reference.md#USER_PostgreSQL.S3Import.create_aws_credentials) 函數呼叫之中內嵌 `aws_s3.table_import_from_s3` 函數呼叫。

```
postgres=> SELECT aws_s3.table_import_from_s3(
   't', '', '(format csv)',
   :'s3_uri', 
   aws_commons.create_aws_credentials('sample_access_key', 'sample_secret_key', '')
);
```

## 對 Amazon S3 的存取進行故障診斷
<a name="USER_PostgreSQL.S3Import.troubleshooting"></a>

如果您在嘗試從 Amazon S3 匯入資料時遇到問題，請參閱下文以取得建議：
+ [對 Amazon RDS 身分與存取進行故障診斷](security_iam_troubleshoot.md)
+ 《*Amazon Simple Storage Service 使用者指南*》中的[針對 Amazon S3 進行故障診斷](https://docs.aws.amazon.com/AmazonS3/latest/userguide/troubleshooting.html)。
+ 《*IAM 使用者指南*》中的[針對 Amazon S3 和 IAM 進行故障診斷](https://docs.aws.amazon.com/IAM/latest/UserGuide/troubleshoot_iam-s3.html)

# 將資料從 Amazon S3 匯入 RDS for PostgreSQL 資料庫執行個體
<a name="USER_PostgreSQL.S3Import.FileFormats"></a>

您可以使用 aws\$1s3 擴充功能的 `table_import_from_s3` 函數，由 Amazon S3 儲存貯體匯入資料。如需參考資訊，請參閱 [aws\$1s3.table\$1import\$1from\$1s3](USER_PostgreSQL.S3Import.Reference.md#aws_s3.table_import_from_s3)。

**注意**  
下列範例使用 IAM 角色方法，允許對 Amazon S3 儲存貯體的存取。因此，`aws_s3.table_import_from_s3` 函數呼叫不包含登入資料參數。

以下顯示一個典型範例。

```
postgres=> SELECT aws_s3.table_import_from_s3(
   't1',
   '', 
   '(format csv)',
   :'s3_uri'
);
```

參數如下：
+ `t1` – PostgreSQL 資料庫執行個體的表格名稱，資料會複製到此表格。
+ `''` – 資料庫表格之中選用的欄清單。您可使用此參數指出哪些 S3 資料欄要置於哪些表格欄。如果沒有指定欄，所有欄都會複製到表格中。如需使用欄清單的範例，請參閱 [匯入使用自訂分隔符號的 Amazon S3 檔案](#USER_PostgreSQL.S3Import.FileFormats.CustomDelimiter)。
+ `(format csv)` – PostgreSQL COPY 引數。複製程序使用 [PostgreSQL COPY](https://www.postgresql.org/docs/current/sql-copy.html) 命令的引數及格式匯入資料。格式的選擇包括逗號分隔值 (CSV)、文字和二進位。預設為文字。
+  `s3_uri` – 包含識別 Amazon S3 檔案資訊的結構。如需使用 [aws\$1commons.create\$1s3\$1uri](USER_PostgreSQL.S3Import.Reference.md#USER_PostgreSQL.S3Import.create_s3_uri) 函數來建立 `s3_uri` 結構的範例，請參閱 [從 Amazon S3 資料匯入資料的概觀](USER_PostgreSQL.S3Import.Overview.md)。

如需此函數狀態的詳細資訊，請參閱 [aws\$1s3.table\$1import\$1from\$1s3](USER_PostgreSQL.S3Import.Reference.md#aws_s3.table_import_from_s3)。

`aws_s3.table_import_from_s3` 函數傳回文字。若要指定從 Amazon S3 儲存貯體匯入的其他檔案類型，請參閱下列其中一個範例。

**注意**  
匯入 0 位元組檔案將導致錯誤。

**Topics**
+ [匯入使用自訂分隔符號的 Amazon S3 檔案](#USER_PostgreSQL.S3Import.FileFormats.CustomDelimiter)
+ [匯入 Amazon S3 壓縮 (gzip) 檔案](#USER_PostgreSQL.S3Import.FileFormats.gzip)
+ [匯入編碼的 Amazon S3 檔案](#USER_PostgreSQL.S3Import.FileFormats.Encoded)

## 匯入使用自訂分隔符號的 Amazon S3 檔案
<a name="USER_PostgreSQL.S3Import.FileFormats.CustomDelimiter"></a>

下列範例顯示如何匯入使用自訂分隔符號的檔案。其中也顯示如何使用 `column_list` 函數的 [aws\$1s3.table\$1import\$1from\$1s3](USER_PostgreSQL.S3Import.Reference.md#aws_s3.table_import_from_s3) 參數，控制資料放置於資料庫表格的位置。

我們在此範例假設下列資訊整理至 Amazon S3 檔案之中的縱線分隔欄。

```
1|foo1|bar1|elephant1
2|foo2|bar2|elephant2
3|foo3|bar3|elephant3
4|foo4|bar4|elephant4
...
```

**匯入使用自訂分隔符號的檔案**

1. 在資料庫為匯入資料建立表格。

   ```
   postgres=> CREATE TABLE test (a text, b text, c text, d text, e text);
   ```

1. 使用以下的 [aws\$1s3.table\$1import\$1from\$1s3](USER_PostgreSQL.S3Import.Reference.md#aws_s3.table_import_from_s3) 函數格式由 Amazon S3 檔案匯入資料。

   您可在 [aws\$1commons.create\$1s3\$1uri](USER_PostgreSQL.S3Import.Reference.md#USER_PostgreSQL.S3Import.create_s3_uri) 函數呼叫之中內嵌 `aws_s3.table_import_from_s3` 函數呼叫以指定檔案。

   ```
   postgres=> SELECT aws_s3.table_import_from_s3(
      'test',
      'a,b,d,e',
      'DELIMITER ''|''', 
      aws_commons.create_s3_uri('amzn-s3-demo-bucket', 'pipeDelimitedSampleFile', 'us-east-2')
   );
   ```

資料目前位於下列欄的表格中。

```
postgres=> SELECT * FROM test;
a | b | c | d | e 
---+------+---+---+------+-----------
1 | foo1 | | bar1 | elephant1
2 | foo2 | | bar2 | elephant2
3 | foo3 | | bar3 | elephant3
4 | foo4 | | bar4 | elephant4
```

## 匯入 Amazon S3 壓縮 (gzip) 檔案
<a name="USER_PostgreSQL.S3Import.FileFormats.gzip"></a>

下列範例顯示如何由以 gzip 壓縮的 Amazon S3 匯入檔案。匯入的檔案需具有以下 Amazon S3 中繼資料：
+ 索引鍵：`Content-Encoding`
+ 值：`gzip`

如果您使用 上傳檔案 AWS 管理主控台，系統通常會套用中繼資料。如需有關使用 AWS 管理主控台、 AWS CLI或 API 將檔案上傳至 Amazon S3 的資訊，請參閱《*Amazon Simple Storage Service 使用者指南*》中的[上傳物件](https://docs.aws.amazon.com/AmazonS3/latest/userguide/upload-objects.html)。

如需 Amazon S3 中繼資料的詳細資訊以及系統所提供中繼資料的詳細資訊，請參閱《*Amazon Simple Storage Service 使用者指南*》中的[在 Amazon S3 主控台中編輯物件中繼資料](https://docs.aws.amazon.com/AmazonS3/latest/userguide/add-object-metadata.html)。

請依據以下所示內容，將 gzip 檔案匯入 RDS for PostgreSQL 資料庫執行個體。

```
postgres=> CREATE TABLE test_gzip(id int, a text, b text, c text, d text);
postgres=> SELECT aws_s3.table_import_from_s3(
 'test_gzip', '', '(format csv)',
 'amzn-s3-demo-bucket', 'test-data.gz', 'us-east-2'
);
```

## 匯入編碼的 Amazon S3 檔案
<a name="USER_PostgreSQL.S3Import.FileFormats.Encoded"></a>

下列範例顯示如何由採用 Windows-1252 編碼的 Amazon S3 匯入檔案。

```
postgres=> SELECT aws_s3.table_import_from_s3(
 'test_table', '', 'encoding ''WIN1252''',
 aws_commons.create_s3_uri('amzn-s3-demo-bucket', 'SampleFile', 'us-east-2')
);
```

# 函數參考
<a name="USER_PostgreSQL.S3Import.Reference"></a>

**Topics**
+ [aws\$1s3.table\$1import\$1from\$1s3](#aws_s3.table_import_from_s3)
+ [aws\$1commons.create\$1s3\$1uri](#USER_PostgreSQL.S3Import.create_s3_uri)
+ [aws\$1commons.create\$1aws\$1credentials](#USER_PostgreSQL.S3Import.create_aws_credentials)

## aws\$1s3.table\$1import\$1from\$1s3
<a name="aws_s3.table_import_from_s3"></a>

將 Amazon S3 資料匯入 Amazon RDS 表。`aws_s3` 擴充功能提供 `aws_s3.table_import_from_s3` 函數。傳回值為文字。

### 語法
<a name="aws_s3.table_import_from_s3-syntax"></a>

必要的參數為 `table_name`、`column_list` 及 `options`。這些參數可識別資料庫表格，並指定資料要如何複製到表格中。

您也可以使用下列參數：
+ `s3_info` 參數指定要匯入的 Amazon S3 檔案。您使用此參數時，IAM 角色會將 Amazon S3 存取權提供給 PostgreSQL 資料庫執行個體。

  ```
  aws_s3.table_import_from_s3 (
     table_name text, 
     column_list text, 
     options text, 
     s3_info aws_commons._s3_uri_1
  )
  ```
+ `credentials` 參數指定登入資料以存取 Amazon S3。您使用此項參數時，不必使用 IAM 角色。

  ```
  aws_s3.table_import_from_s3 (
     table_name text, 
     column_list text, 
     options text, 
     s3_info aws_commons._s3_uri_1,
     credentials aws_commons._aws_credentials_1
  )
  ```

### Parameters
<a name="aws_s3.table_import_from_s3-parameters"></a>

 *table\$1name*   
必要的文字字串，其中含有要匯入資料的 PostgreSQL 資料庫表格名稱。

 *column\$1list*   
必要的文字字串，其中含有要複製資料的 PostgreSQL 資料庫表格欄選用清單。如果字串為空白，就會使用表格的所有欄。如需範例，請參閱 [匯入使用自訂分隔符號的 Amazon S3 檔案](USER_PostgreSQL.S3Import.FileFormats.md#USER_PostgreSQL.S3Import.FileFormats.CustomDelimiter)。

 *options*   
必要的文字字串，含有 PostgreSQL `COPY` 命令引數。這些引數指定資料要如何複製到 PostgreSQL 表格中。詳細資訊請參閱 [PostgreSQL COPY 文件](https://www.postgresql.org/docs/current/sql-copy.html)。

 *s3\$1info*   
`aws_commons._s3_uri_1` 複合類型，含有下列 S3 物件相關資訊：  
+ `bucket` – 含有檔案的 Amazon S3 儲存貯體名稱。
+ `file_path` – 包括檔案路徑的 Amazon S3 檔案名稱。
+ `region` – 檔案所在的 AWS 區域。如需 AWS 區域名稱和相關值的清單，請參閱 [區域、可用區域和 Local Zones](Concepts.RegionsAndAvailabilityZones.md)。

 *登入資料*   
`aws_commons._aws_credentials_1` 複合類型，含有下列登入資料以用於匯入作業：  
+ 存取金鑰
+ 私密金鑰
+ 工作階段字符
如需建立 `aws_commons._aws_credentials_1` 複合結構的詳細資訊，請參閱 [aws\$1commons.create\$1aws\$1credentials](#USER_PostgreSQL.S3Import.create_aws_credentials)。

### 替代語法
<a name="aws_s3.table_import_from_s3-alternative-syntax"></a>

為了協助進行測試，您可使用一組更大的參數取代 `s3_info` 及 `credentials` 參數。以下是 `aws_s3.table_import_from_s3` 函數的額外語法變化：
+ 請不要使用 `s3_info` 參數識別 Amazon S3 檔案，而是使用 `bucket`、`file_path` 及 `region` 參數組合進行。使用這種形式的函數，Amazon S3 存取權會由 IAM 角色在 PostgreSQL 資料庫執行個體提供。

  ```
  aws_s3.table_import_from_s3 (
     table_name text, 
     column_list text, 
     options text, 
     bucket text, 
     file_path text, 
     region text 
  )
  ```
+ 請不要使用 `credentials` 參數識別 Amazon S3 存取，而是使用 `access_key`、`session_key` 及 `session_token` 參數組合進行。

  ```
  aws_s3.table_import_from_s3 (
     table_name text, 
     column_list text, 
     options text, 
     bucket text, 
     file_path text, 
     region text, 
     access_key text, 
     secret_key text, 
     session_token text 
  )
  ```

### 替代參數
<a name="aws_s3.table_import_from_s3-alternative-parameters"></a>

*bucket*  
文字字串，其中含有包含檔案的 Amazon S3 儲存貯體名稱。

*file\$1path*  
包含 Amazon S3 檔案名稱 (包括檔案路徑) 的文字字串。

*region*  
識別檔案 AWS 區域 位置的文字字串。如需 AWS 區域 名稱和相關值的清單，請參閱 [區域、可用區域和 Local Zones](Concepts.RegionsAndAvailabilityZones.md)。

*access\$1key*  
文字字串，其中含有用於匯入作業的存取金鑰。預設值為 NULL。

*secret\$1key*  
文字字串，其中含有用於匯入作業的秘密金鑰。預設值為 NULL。

*session\$1token*  
(選用) 文字字串，其中含有用於匯入作業的工作階段金鑰。預設值為 NULL。

## aws\$1commons.create\$1s3\$1uri
<a name="USER_PostgreSQL.S3Import.create_s3_uri"></a>

建立 `aws_commons._s3_uri_1` 結構以保留 Amazon S3 檔案資訊。使用 `aws_commons.create_s3_uri` 函數 `s3_info` 參數的 [aws\$1s3.table\$1import\$1from\$1s3](#aws_s3.table_import_from_s3) 函數結果。

### 語法
<a name="USER_PostgreSQL.S3Import.create_s3_uri-syntax"></a>

```
aws_commons.create_s3_uri(
   bucket text,
   file_path text,
   region text
)
```

### Parameters
<a name="USER_PostgreSQL.S3Import.create_s3_uri-parameters"></a>

*bucket*  
必要的文字字串，其中含有檔案的 Amazon S3 儲存貯體名稱。

*file\$1path*  
包含 Amazon S3 檔案名稱 (包括檔案路徑) 的必要文字字串。

*region*  
必要的文字字串 AWS 區域 ，其中包含 檔案所在的 。如需 AWS 區域 名稱和相關值的清單，請參閱 [區域、可用區域和 Local Zones](Concepts.RegionsAndAvailabilityZones.md)。

## aws\$1commons.create\$1aws\$1credentials
<a name="USER_PostgreSQL.S3Import.create_aws_credentials"></a>

在 `aws_commons._aws_credentials_1` 結構設定存取金鑰及秘密金鑰。使用 `aws_commons.create_aws_credentials` 函數 `credentials` 參數的 [aws\$1s3.table\$1import\$1from\$1s3](#aws_s3.table_import_from_s3) 函數結果。

### 語法
<a name="USER_PostgreSQL.S3Import.create_aws_credentials-syntax"></a>

```
aws_commons.create_aws_credentials(
   access_key text,
   secret_key text,
   session_token text
)
```

### Parameters
<a name="USER_PostgreSQL.S3Import.create_aws_credentials-parameters"></a>

*access\$1key*  
必要的文字字串，其中含有用於匯入 Amazon S3 檔案的存取金鑰。預設值為 NULL。

*secret\$1key*  
必要的文字字串，其中含有用於匯入 Amazon S3 檔案的秘密金鑰。預設值為 NULL。

*session\$1token*  
選用的文字字串，其中含有用於匯入 Amazon S3 檔案的工作階段字符。預設值為 NULL。如果您提供選用的 `session_token`，就可以使用臨時登入資料。

# 在 與資料庫執行個體之間傳輸 PostgreSQL 資料庫
<a name="PostgreSQL.TransportableDB"></a>

針對 Amazon RDS 使用 PostgreSQL 可傳輸資料庫，您可以在兩個資料庫執行個體之間移動 PostgreSQL 資料庫。這是在不同資料庫執行個體之間遷移大型資料庫的一種非常快速的方法。若要使用此方式，您的資料庫執行個體必須皆執行相同的 PostgreSQL 主要版本。

此功能要求您在來源資料庫執行個體和目的地資料庫執行個體上都安裝 `pg_transport` 擴充功能。`pg_transport` 擴充功能提供實體傳輸機制，使用最少的方式移動資料庫檔案。此機制移動資料的速度比傳統的傾印和載入程序更快，而且停機時間更短。

**注意**  
RDS for PostgreSQL 11.5 版和更高版本、RDS for PostgreSQL 10.10 版和更高版本中提供 PostgreSQL 可傳輸資料庫。

若要將 PostgreSQL 資料庫執行個體從一個 RDS for PostgreSQL 資料庫執行個體傳輸到另一個執行個體，請先設定來源和目的地執行個體，如 [ 設定用於傳輸的資料庫執行個體](PostgreSQL.TransportableDB.Setup.md) 中所述。然後，您可以使用 [ 傳輸 PostgreSQL 資料庫](PostgreSQL.TransportableDB.Transporting.md) 中描述的函數傳輸資料庫。

**Topics**
+ [資料庫傳輸期間發生的事](#PostgreSQL.TransportableDB.DuringTransport)
+ [使用 PostgreSQL 可傳輸資料庫的限制](#PostgreSQL.TransportableDB.Limits)
+ [設定傳輸 PostgreSQL 資料庫](PostgreSQL.TransportableDB.Setup.md)
+ [將 PostgreSQL 資料庫從來源傳輸至目的地](PostgreSQL.TransportableDB.Transporting.md)
+ [可傳輸資料庫函數參考](PostgreSQL.TransportableDB.transport.import_from_server.md)
+ [可傳輸資料庫參數參考](PostgreSQL.TransportableDB.Parameters.md)

## 資料庫傳輸期間發生的事
<a name="PostgreSQL.TransportableDB.DuringTransport"></a>

PostgreSQL 可傳輸資料庫功能使用提取模式將資料庫從來源匯入目的地資料庫執行個體。`transport.import_from_server` 功能在目的地資料庫執行個體上建立傳輸中資料庫。無法存取傳輸進行期間目的地資料庫執行個體上的傳輸中資料庫。

當傳輸開始時，所有目前來源資料庫上的工作階段皆會終止。任何其他不在來源資料庫執行個體上的資料庫，不會受到傳輸的影響。

來源資料庫會變成特定的唯讀模式。當進入此模式時，您可以連接來源資料庫且執行唯獨模式查詢。然而，會封鎖寫入啟用查詢和其他類型的命令。只有開始進行傳輸的特定來源資料庫會受到此限制的影響。

傳輸期間，您不能重新恢復目的地資料庫執行個體的還原時間點。這是因為傳輸並非交易，且不會使用 PostgreSQL 預寫紀錄來紀錄變更。如果目的地資料庫執行個體有啟用自動備份，會在傳輸完成後自動進行備份。還原時間點會在備份完成*後*可用。

如果傳輸失敗，`pg_transport` 擴充套件會試圖對來源和目的地資料庫執行個體重做所有變更。這包含移除目的地已經部分傳輸的資料庫。根據錯誤的類型，來源資料庫可能會持續拒絕寫入啟用查詢。若發生這種情況，請使用下列命令以允許寫入啟用查詢。

```
ALTER DATABASE db-name SET default_transaction_read_only = false;
```

## 使用 PostgreSQL 可傳輸資料庫的限制
<a name="PostgreSQL.TransportableDB.Limits"></a>

可傳輸的資料庫有以下限制：
+ **僅供讀取複本** – 您無法使用傳送僅供讀取複本或僅供讀取複本的上層執行個體資料庫。
+ **不支援的欄位類型** – 您無法在任何計畫使用此方法傳輸的資料庫表格中使用 `reg` 資料類型。這些類型取決於系統上目錄物件 ID (OIDs)，通常會在傳輸時變更。
+ **資料表空間** – 所有來源資料庫物件必須在預設 `pg_default` 資料表空間中。
+ **相容性** – 來源與目的地資料庫執行個體都必須執行相同的 PostgreSQL 主要版本。
+ **擴充功能**：來源資料庫執行個體只能安裝 `pg_transport`。
+ **角色和 ACL** – 來源資料庫的存取權和擁有者資訊，不會一併傳輸至目的地資料庫。所有資料庫物件會由傳輸目的地的使用者建立和擁有。
+ **並行傳輸**：如果工作者程序設定正確，單個資料庫執行個體最多可支援 32 個並行傳輸，包括匯入和匯出。
+ **僅限 RDS for PostgreSQL 資料庫執行個體**：僅 RDS for PostgreSQL 資料庫執行個體上支援 PostgreSQL 可傳輸資料庫。您無法將其與內部部署資料庫或在 Amazon EC2 上執行的資料庫搭配使用。

# 設定傳輸 PostgreSQL 資料庫
<a name="PostgreSQL.TransportableDB.Setup"></a>

開始之前，請確定 RDS for PostgreSQL 資料庫執行個體符合下列要求：
+ 來源與目的地的 RDS for PostgreSQL 資料庫執行個體都必須執行相同的 PostgreSQL 版本。
+ 目的地資料庫不能具有與要傳輸的來源資料庫名稱相同的資料庫。
+ 用於執行傳輸作業的帳戶在來源資料庫和目的地資料庫上均需要 `rds_superuser` 權限。
+ 來源資料庫執行個體的安全群組必須允許來自目的地資料庫執行個體的傳入存取。如果來源和目的地資料庫執行個體位於 VPC 中，則可能已經存在這種情況。如需安全群組的詳細資訊，請參閱[使用安全群組控制存取](Overview.RDSSecurityGroups.md)。

將資料庫從來源資料庫執行個體傳輸至目的地資料庫執行個體，需要對與每個執行個體相關聯的資料庫參數群組進行多次變更。這意味著您必須為來源資料庫執行個體建立自訂資料庫參數群組，並為目的地資料庫執行個體建立自訂資料庫參數群組。

**注意**  
如果您的資料庫執行個體已使用自訂資料庫參數群組進行設定，則可從下列程序中的步驟 2 開始。

**設定用於傳輸資料庫的自訂資料庫群組參數**

若要執行以下步驟，請使用具有 `rds_superuser` 權限的帳戶。

1. 如果來源和目的地資料庫執行個體使用預設的資料庫參數群組，則需要使用執行個體的適當版本來建立自訂資料庫參數群組。您可以執行此操作，以便變更數個參數的值。如需詳細資訊，請參閱 [Amazon RDS 的參數群組](USER_WorkingWithParamGroups.md)。

1. 在自訂資料庫參數群組中，變更下列參數的值：
   + `shared_preload_libraries`：將 `pg_transport` 新增至程式庫清單中。
   + `pg_transport.num_workers`：預設值為 3。根據資料庫的需要增加或減少此值。對於 200 GB 的資料庫，建議此值不大於 8。請記住，如果增加此參數的預設值，還應同時增加 `max_worker_processes` 的值。
   + `pg_transport.work_mem`：預設值為 128 MB 或 256 MB，具體取決於 PostgreSQL 版本。預設設定通常可保持不變。
   + `max_worker_processes` – 需要使用以下計算設定此參數值：

     ```
     (3 * pg_transport.num_workers) + 9
     ```

     目的地需要此值來處理傳輸中涉及的各種後台工作程序。如要進一步了解 `max_worker_processes,`，請參閱 PostgreSQL 文件中的[資源耗用](https://www.postgresql.org/docs/current/runtime-config-resource.html)。

   如需 `pg_transport` 參數的詳細資訊，請參閱 [可傳輸資料庫參數參考](PostgreSQL.TransportableDB.Parameters.md)。

1. 重新啟動來源 RDS for PostgreSQL 資料庫執行個體和目的地執行個體，以便讓參數的設定生效。

1. 連接至 RDS for PostgreSQL 來源資料庫執行個體。

   ```
   psql --host=source-instance.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password
   ```

1. 從資料庫執行個體的公有架構中移除無關的擴充功能。在實際傳輸操作期間僅允許 `pg_transport` 擴充功能。

1. 安裝 `pg_transport` 擴充功能，如下所示：

   ```
   postgres=> CREATE EXTENSION pg_transport;
   CREATE EXTENSION
   ```

1. 連接至 RDS for PostgreSQL 目的地資料庫執行個體。刪除任何無關的擴充功能，然後安裝 `pg_transport` 擴充功能。

   ```
   postgres=> CREATE EXTENSION pg_transport;
   CREATE EXTENSION
   ```

# 將 PostgreSQL 資料庫從來源傳輸至目的地
<a name="PostgreSQL.TransportableDB.Transporting"></a>

在您完成 [設定傳輸 PostgreSQL 資料庫](PostgreSQL.TransportableDB.Setup.md) 中的描述程序，您可以開始進行傳輸。若要這麼做，請執行目的地資料庫執行個體上的 `transport.import_from_server` 功能。您可以在下列語法中找到函數參數。

```
SELECT transport.import_from_server( 
   'source-db-instance-endpoint', 
    source-db-instance-port, 
   'source-db-instance-user', 
   'source-user-password', 
   'source-database-name', 
   'destination-user-password', 
   false);
```

範例中顯示的 `false` 值告訴函數這並非試轉。若要測試傳輸設定，您可以在呼叫函數時為 `dry_run` 選項指定 `true`，如下所示：

```
postgres=> SELECT transport.import_from_server(
    'docs-lab-source-db.666666666666aws-region.rds.amazonaws.com', 5432,
    'postgres', '********', 'labdb', '******', true);
INFO:  Starting dry-run of import of database "labdb".
INFO:  Created connections to remote database        (took 0.03 seconds).
INFO:  Checked remote cluster compatibility          (took 0.05 seconds).
INFO:  Dry-run complete                         (took 0.08 seconds total).
 import_from_server
--------------------

(1 row)
```

輸出 INFO 行是因為 `pg_transport.timing` 參數設定為其預設值 `true`。在執行命令時將 `dry_run` 設定為 `false`，來源資料庫即會匯入目的地，如下所示：

```
INFO:  Starting import of database "labdb".
INFO:  Created connections to remote database        (took 0.02 seconds).
INFO:  Marked remote database as read only           (took 0.13 seconds).
INFO:  Checked remote cluster compatibility          (took 0.03 seconds).
INFO:  Signaled creation of PITR blackout window     (took 2.01 seconds).
INFO:  Applied remote database schema pre-data       (took 0.50 seconds).
INFO:  Created connections to local cluster          (took 0.01 seconds).
INFO:  Locked down destination database              (took 0.00 seconds).
INFO:  Completed transfer of database files          (took 0.24 seconds).
INFO:  Completed clean up                            (took 1.02 seconds).
INFO:  Physical transport complete              (took 3.97 seconds total).
import_from_server
--------------------
(1 row)
```

此功能需要提供資料庫使用者密碼。因此，我們建議您在傳輸完成之後變更您所使用的使用者密碼。或者，您可以使用 SQL 繫結變數建立暫時的使用者角色。使用暫時的角色進行傳輸，並在之後捨棄該角色。

如果傳輸失敗，您可能會看到類似以下內容的錯誤訊息：

```
pg_transport.num_workers=8 25% of files transported failed to download file data
```

"Failed to download file data" (下載檔案資料失敗) 錯誤訊息表示工作者程序的數量未正確設定為資料庫的大小。您可能需要增加或減少為 `pg_transport.num_workers` 設定的值。每次失敗都會報告完成的百分比，以便您可以查看變更的影響。例如，在一種情況下，將設定從 8 變更為 4 會導致以下結果：

```
pg_transport.num_workers=4 75% of files transported failed to download file data
```

請記住，在傳輸過程中也會考慮 `max_worker_processes` 參數。換言之，您可能需要修改 `pg_transport.num_workers` 和 `max_worker_processes` 才能成功傳輸資料庫。當 `pg_transport.num_workers` 設定為 2 時，顯示的範例最終可運作：

```
pg_transport.num_workers=2 100% of files transported
```

如需有關 `transport.import_from_server` 功能及其參數的詳細資訊，請參閱 [可傳輸資料庫函數參考](PostgreSQL.TransportableDB.transport.import_from_server.md)。

# 可傳輸資料庫函數參考
<a name="PostgreSQL.TransportableDB.transport.import_from_server"></a>

`transport.import_from_server` 函數透過輸入來源資料庫執行個體至目的地資料庫執行個體，來傳輸 PostgreSQL 資料庫。藉由實體資料庫連接傳輸機制做到此功能。

在開始傳輸之前，此函數將驗證來源和目的地資料庫執行個體的版本是否相同，並且是否與遷移相容。同時還會確認目的地資料庫執行個體有足夠的空間供來源資料庫執行個體使用。

**語法**

```
transport.import_from_server(
   host text,
   port int,
   username text,
   password text,
   database text,
   local_password text,
   dry_run bool
)
```

**傳回值**

無。

**參數**

您可以在下表尋找 `transport.import_from_server` 功能參數的說明。


****  

| 參數 | 描述 | 
| --- | --- | 
| host |  來源資料庫執行個體的端點。  | 
| port | 整數代表來源資料庫執行個體的連接埠。PostgreSQL 資料庫執行個體通常使用 5432 連接埠。 | 
| username |  來源資料庫執行個體的使用者。該使用者必須為 `rds_superuser` 角色的成員。  | 
| password |  來源資料庫執行個體的使用者密碼。  | 
| database |  來源資料庫執行個體中要傳輸的資料庫名稱。  | 
| local\$1password |  目的地資料庫執行個體目前使用者的本地密碼。該使用者必須為 `rds_superuser` 角色的成員。  | 
| dry\$1run | 選用的布林值指定是否試執行。預設為 `false`，代表傳輸繼續。若要確認來源與目的地資料庫執行個體間的相容性，而不執行實際傳輸，請設定 dry\$1run 為 true。 | 

**範例**

如需範例，請參閱[將 PostgreSQL 資料庫從來源傳輸至目的地](PostgreSQL.TransportableDB.Transporting.md)。

# 可傳輸資料庫參數參考
<a name="PostgreSQL.TransportableDB.Parameters"></a>

有幾個參數控制 `pg_transport` 擴充功能的行為。您可以在下面找到這些參數的說明。

**`pg_transport.num_workers`**  
用於傳輸流程的工作者數量。預設為 3。有效值為 1–32。最大的資料庫傳輸通常會用到的工作者也少於 8 個。傳輸期間，目的地資料庫執行個體上的此設定值會由目的地和來源使用。

**`pg_transport.timing` **  
指定是否在傳輸期間回報時間資訊。預設為 `true`，表示報告計時資訊。建議將此參數保留為設定的 `true`，以便您監控進度。如需了解輸出範例，請參閱 [將 PostgreSQL 資料庫從來源傳輸至目的地](PostgreSQL.TransportableDB.Transporting.md)。

**`pg_transport.work_mem`**  
配置給每個工作者最大的記憶體數量。預設值為 131,072 KB 或 262,144 KB (256 MB)，具體取決於 PostgreSQL 版本。最小值為 64 MB (65,536 KB)。有效的值以 kb (KB) 為單位，且為二進位制，即 1 KB = 1024 位元組。  
傳輸可能使用比此參數指定的記憶體更少。即使是大型資料庫傳輸，每個工作者會用到的記憶體通常少於 256 MB (262,144 KB)。

# 將資料從 RDS for PostgreSQL 資料庫執行個體匯出至 Amazon S3
<a name="postgresql-s3-export"></a>

您可以從 RDS for PostgreSQL 資料庫執行個體中查詢資料，然後將資料直接匯出至 Amazon S3 儲存貯體中存放的檔案中。若要這麼做，首先要安裝 RDS for PostgreSQL `aws_s3` 擴充功能。此擴充功能提供函數，可用於匯出資料至 Amazon S3。接著，您可以了解如何安裝擴充功能，以及如何將資料匯出至 Amazon S3。

**注意**  
不支援跨帳戶匯出至 Amazon S3。

所有目前可用的 RDS for PostgreSQL 版本都支援將快照資料匯出至 Amazon 簡單儲存服務。如需詳細版本資訊，請參閱《Amazon RDS for PostgreSQL 版本資訊》**中的 [Amazon RDS for PostgreSQL 版本更新](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-versions.html)。

如果您沒有為匯出設定儲存貯體，請參閱下列主題 *Amazon Storage Service 使用者指南*。
+ [設定 Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/setting-up-s3.html)
+ [建立儲存貯體](https://docs.aws.amazon.com/AmazonS3/latest/userguide/create-bucket-overview.html)

根據預設，從 RDS for PostgreSQL 匯出至 Amazon S3 的資料會使用伺服器端加密搭配 AWS 受管金鑰。如果您使用儲存貯體加密，Amazon S3 儲存貯體必須使用 AWS Key Management Service (AWS KMS) 金鑰 (SSE-KMS) 加密。目前不支援使用 Amazon S3 受管金鑰 (SSE-S3) 加密的儲存貯體。

**注意**  
您可以使用 AWS 管理主控台 AWS CLI或 Amazon RDS API 將資料庫快照資料儲存至 Amazon S3。如需詳細資訊，請參閱[為 Amazon RDS 將資料庫快照資料匯出至 Amazon S3](USER_ExportSnapshot.md)。

**Topics**
+ [安裝 aws\$1s3 擴充功能](#USER_PostgreSQL.S3Export.InstallExtension)
+ [將資料匯出至 Amazon S3 的概觀](#postgresql-s3-export-overview)
+ [指定要匯出的 Amazon S3 檔案路徑](#postgresql-s3-export-file)
+ [設定對 Amazon S3 儲存貯體的存取權](postgresql-s3-export-access-bucket.md)
+ [使用 aws\$1s3.query\$1export\$1to\$1s3 函數匯出查詢資料](postgresql-s3-export-examples.md)
+ [函數參考](postgresql-s3-export-functions.md)
+ [對 Amazon S3 的存取進行故障診斷](postgresql-s3-export-troubleshoot.md)

## 安裝 aws\$1s3 擴充功能
<a name="USER_PostgreSQL.S3Export.InstallExtension"></a>

在您可以使用 Amazon Simple Storage Service 搭配 RDS for PostgreSQL 資料庫執行個體之前，您需要安裝 `aws_s3` 擴充功能。此擴充功能提供從 ，RDS for PostgreSQL 資料庫執行個體匯出資料至 Amazon S3 儲存貯體的功能。它還提供可從 Amazon S3 匯入資料的函數。如需詳細資訊，請參閱[將資料從 Amazon S3 匯入 RDS for PostgreSQL 資料庫執行個體](USER_PostgreSQL.S3Import.md)。`aws_s3` 擴充功能取決於 `aws_commons` 擴充功能中的一些輔助函數，需要時會自動安裝。

**安裝 `aws_s3` 擴充功能**

1. 使用 psql (或 pgAdmin) 以具有 `rds_superuser` 權限的使用者身分連接到 RDS for PostgreSQL 資料庫執行個體。若您在安裝程序期間保留預設名稱，則連接為 `postgres`。

   ```
   psql --host=111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password
   ```

1. 若要安裝擴充功能，請執行下列命令。

   ```
   postgres=> CREATE EXTENSION aws_s3 CASCADE;
   NOTICE: installing required extension "aws_commons"
   CREATE EXTENSION
   ```

1. 若要驗證是否已經安裝擴充功能，可以使用 psql `\dx` 中繼命令。

   ```
   postgres=> \dx
          List of installed extensions
       Name     | Version |   Schema   |                 Description
   -------------+---------+------------+---------------------------------------------
    aws_commons | 1.2     | public     | Common data types across AWS services
    aws_s3      | 1.1     | public     | AWS S3 extension for importing data from S3
    plpgsql     | 1.0     | pg_catalog | PL/pgSQL procedural language
   (3 rows)
   ```

現在可以使用從 Amazon S3 匯入和匯出資料的功能。

### 確認您的 RDS for PostgreSQL 版本支援匯出至 Amazon S3
<a name="postgresql-s3-supported"></a>

您可以使用 `describe-db-engine-versions` 命令，驗證您的 RDS for PostgreSQL 版本是否支援匯出至 Amazon S3。下列範例會驗證 10.14 版本的支援。

```
aws rds describe-db-engine-versions --region us-east-1
--engine postgres --engine-version 10.14 | grep s3Export
```

如果輸出包含字串 `"s3Export"`，則引擎支援 Amazon S3 匯出。否則，引擎不支援它們。

## 將資料匯出至 Amazon S3 的概觀
<a name="postgresql-s3-export-overview"></a>

如果要將儲存在 RDS for PostgreSQL 資料庫中的資料匯出至 Amazon S3 儲存貯體，請使用以下程序。

**將 RDS for PostgreSQL 資料匯出至 S3**

1. 識別用於匯出資料的 Amazon S3 檔案路徑。如需此程序的詳細資訊，請參閱[指定要匯出的 Amazon S3 檔案路徑](#postgresql-s3-export-file)。

1. 提供許可，以存取 Amazon S3 儲存貯體。

   如果要將資料匯出至 Amazon S3 檔案，請為 RDS for PostgreSQL 資料庫執行個體提供許可，以便存取匯出將用來儲存的 Amazon S3 儲存貯體。這麼做包括以下步驟︰

   1. 建立 IAM 政策來為您要匯出的 Amazon S3 儲存貯體提供存取權。

   1. 建立 IAM 角色。

   1. 請將您建立的政策連接到您建立的角色。

   1. 將此 IAM 角色新增至您的 資料庫叢集。

   如需此程序的詳細資訊，請參閱[設定對 Amazon S3 儲存貯體的存取權](postgresql-s3-export-access-bucket.md)。

1. 識別資料庫查詢以取得資料。呼叫 `aws_s3.query_export_to_s3` 函數來匯出查詢資料。

   完成上述的準備工作後，請使用 [aws\$1s3.query\$1export\$1to\$1s3](postgresql-s3-export-functions.md#aws_s3.export_query_to_s3) 函數將查詢結果匯出至 Amazon S3。如需此程序的詳細資訊，請參閱[使用 aws\$1s3.query\$1export\$1to\$1s3 函數匯出查詢資料](postgresql-s3-export-examples.md)。

## 指定要匯出的 Amazon S3 檔案路徑
<a name="postgresql-s3-export-file"></a>

指定下列資訊來識別 Amazon S3 中您要匯出資料的位置：
+ 儲存貯體名稱 – *儲存貯體*是 Amazon S3 物件或檔案的容器。

  如需使用 Amazon S3 存放資料的詳細資訊，請參閱《Amazon Simple Storage Service 使用者指南》**中的[建立儲存貯體](https://docs.aws.amazon.com/AmazonS3/latest/userguide/create-bucket-overview.html)和[使用物件](https://docs.aws.amazon.com/AmazonS3/latest/userguide/uploading-downloading-objects.html)。
+ 檔案路徑 – 檔案路徑會識別匯出項目儲存在 Amazon S3 儲存貯體中的位置。檔案路徑由以下項目組成：
  + 識別虛擬資料夾路徑的選擇性路徑字首。
  + 識別一或多個要儲存檔案的檔案字首。較大的匯出項目會儲存在多個檔案中，每個檔案的大小上限約為 6 GB。其他檔案名稱具有相同的檔案字首，但會加上 `_partXX`。`XX` 代表 2，接著是 3，以此類推

  舉例來說，具有 `exports` 資料夾和 `query-1-export` 檔案字首的檔案路徑為 `/exports/query-1-export`。
+ AWS 區域 （選用） – Amazon S3 儲存貯體所在的 AWS 區域。如果您未指定 AWS 區域值，則 Amazon RDS 會將您的檔案儲存在與匯出資料庫執行個體相同的 AWS 區域中的 Amazon S3。
**注意**  
目前， AWS 區域必須與匯出資料庫執行個體的區域相同。

  如需 AWS 區域名稱和相關值的清單，請參閱 [區域、可用區域和 Local Zones](Concepts.RegionsAndAvailabilityZones.md)。

如果要保留匯出項目儲存之位置的 Amazon S3 檔案資訊，可以使用 [aws\$1commons.create\$1s3\$1uri](postgresql-s3-export-functions.md#aws_commons.create_s3_uri) 函數建立 `aws_commons._s3_uri_1` 複合結構，如下所示。

```
psql=> SELECT aws_commons.create_s3_uri(
   'amzn-s3-demo-bucket',
   'sample-filepath',
   'us-west-2'
) AS s3_uri_1 \gset
```

您稍後可以在對 `s3_uri_1` 函數的呼叫中以參數形式提供此 [aws\$1s3.query\$1export\$1to\$1s3](postgresql-s3-export-functions.md#aws_s3.export_query_to_s3) 值。如需範例，請參閱「[使用 aws\$1s3.query\$1export\$1to\$1s3 函數匯出查詢資料](postgresql-s3-export-examples.md)」。

# 設定對 Amazon S3 儲存貯體的存取權
<a name="postgresql-s3-export-access-bucket"></a>

如果要將資料匯出至 Amazon S3，請為 PostgreSQL DB 執行個體提供許可，以便存取用來放置檔案的 Amazon S3 儲存貯體。

若要執行此操作，請使用下列程序。

**透過 IAM 角色授與 PostgreSQL 資料庫執行個體的 Amazon S3 存取權**

1. 建立 IAM 政策。

   此政策可提供儲存貯體及物件許可，讓 PostgreSQL 資料庫執行個體能夠存取 Amazon S3。

   在建立此原則的過程中，請採取下列步驟：

   1. 在政策中納入下列必要動作，以允許從 PostgreSQL 資料庫叢集執行個體傳輸檔案至 Amazon S3 儲存貯體：
      + `s3:PutObject`
      + `s3:AbortMultipartUpload`

   1. 包含用於識別 Amazon S3 儲存貯體和物件的 Amazon Resource Name (ARN)。存取 Amazon S3 的 ARN 格式為︰`arn:aws:s3:::amzn-s3-demo-bucket/*`

   如需如何建立 Amazon RDS for PostgreSQL IAM 政策的詳細資訊，請參閱[建立並使用 IAM 政策進行 IAM 資料庫存取](UsingWithRDS.IAMDBAuth.IAMPolicy.md)。另請參閱《*IAM 使用者指南*》中的[教學：建立和連接您的第一個客戶受管原則](https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_managed-policies.html)。

   下列 AWS CLI 命令會使用這些選項建立名為 `rds-s3-export-policy`的 IAM 政策。其將存取權授予名為 *amzn-s3-demo-bucket* 的儲存貯體。
**警告**  
建議您在設有可存取特定儲存貯體之端點原則的私有 VPC 中設定資料庫。如需詳細資訊，請參閱《Amazon VPC 使用者指南》中的[對 Amazon S3 使用端點政策](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-endpoints-s3.html#vpc-endpoints-policies-s3)。  
強烈建議您不要建立具有全資源存取權的政策。這個存取權可能會對資料安全構成威脅。如果您建立的原則能為 `S3:PutObject` 提供使用 `"Resource":"*"` 存取所有資源的存取權，則具有匯出許可的使用者可將資料匯出至您帳戶中的所有儲存貯體。此外，使用者可以將資料匯出至*您 AWS 區域內可公開寫入的所有儲存貯體*。

   政策建立後，請記下政策的 Amazon Resource Name (ARN)。在後續步驟中將政策附加至 IAM 角色時，您會需要此 ARN。

   ```
   aws iam create-policy  --policy-name rds-s3-export-policy  --policy-document '{
        "Version": "2012-10-17",		 	 	 
        "Statement": [
          {
            "Sid": "s3export",
            "Action": [
              "s3:PutObject*",
              "s3:ListBucket",
              "s3:GetObject*",
              "s3:DeleteObject*",
              "s3:GetBucketLocation",
              "s3:AbortMultipartUpload"
            ],
            "Effect": "Allow",
            "Resource": [
              "arn:aws:s3:::amzn-s3-demo-bucket/*"
            ] 
          }
        ] 
      }'
   ```

1. 建立 IAM 角色。

   您會執行此動作，使得 Amazon RDS 可以代表您擔任此 IAM 角色，以存取您的 Amazon S3 儲存貯體。如需更多詳細資訊，請參閱《*IAM 使用者指南*》中的[建立角色以將許可委派給 IAM 使用者](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user.html)。

   建議您在資源型政策中使用 `[aws:SourceArn](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn)` 和 `[aws:SourceAccount](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount)` 全域條件內容金鑰，將服務的許可限定於特定資源。這是防止[混淆代理人問題](https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html)最有效的方式。

   如果同時使用這兩個全域條件內容索引鍵，且 `aws:SourceArn` 值包含帳戶 ID，則在相同政策陳述式中使用 `aws:SourceAccount` 值和 `aws:SourceArn` 值中的帳戶時，必須使用相同的帳戶 ID。
   + 如果您想要跨服務存取單一資源，請使用 `aws:SourceArn`。
   + 如果您想要允許該帳戶中的任何資源與跨服務使用相關聯，請使用 `aws:SourceAccount`。

    在政策中，請務必搭配資源的完整 ARN 來使用 `aws:SourceArn` 全域條件內容金鑰。下列範例示範如何使用 AWS CLI 命令來建立名為 的角色`rds-s3-export-role`。  
**Example**  

   針對 Linux、macOS 或 Unix：

   ```
   aws iam create-role  \
       --role-name rds-s3-export-role  \
       --assume-role-policy-document '{
        "Version": "2012-10-17",		 	 	 
        "Statement": [
          {
            "Effect": "Allow",
            "Principal": {
               "Service": "rds.amazonaws.com"
             },
            "Action": "sts:AssumeRole",
            "Condition": {
                "StringEquals": {
                   "aws:SourceAccount": "111122223333",
                   "aws:SourceArn": "arn:aws:rds:us-east-1:111122223333:db:dbname"
                   }
                }
          }
        ] 
      }'
   ```

   在 Windows 中：

   ```
   aws iam create-role  ^
       --role-name rds-s3-export-role  ^
       --assume-role-policy-document '{
        "Version": "2012-10-17",		 	 	 
        "Statement": [
          {
            "Effect": "Allow",
            "Principal": {
               "Service": "rds.amazonaws.com"
             },
            "Action": "sts:AssumeRole",
            "Condition": {
                "StringEquals": {
                   "aws:SourceAccount": "111122223333",
                   "aws:SourceArn": "arn:aws:rds:us-east-1:111122223333:db:dbname"
                   }
                }
          }
        ] 
      }'
   ```

1. 將您建立的 IAM 政策附加至您建立的 IAM 角色。

   下列 AWS CLI 命令會將先前建立的政策連接至名為 `rds-s3-export-role.` Replace 的角色，`your-policy-arn`取代為您在先前步驟中記下的政策 ARN。

   ```
   aws iam attach-role-policy  --policy-arn your-policy-arn  --role-name rds-s3-export-role  
   ```

1. 將 IAM 角色新增至資料庫執行個體。您可以使用 AWS 管理主控台 或 來執行此操作 AWS CLI，如下所述。

## 主控台
<a name="collapsible-section-1"></a>

**使用主控台為 PostgreSQL 資料庫執行個體新增 IAM 角色**

1. 登入 AWS 管理主控台 ，並在 [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/)：// 開啟 Amazon RDS 主控台。

1. 選擇 PostgreSQL 資料庫執行個體名稱以顯示其詳細資訊。

1. 在 **Connectivity & security (連線能力與安全性)** 標籤上的 **Manage IAM roles (管理 IAM 角色)** 區段中，選擇要在 **Add IAM roles to this instance (新增 IAM 角色到此執行個體)** 下新增的角色。

1. 請在 **Feature** (功能) 下，選擇 **s3Export**。

1. 選擇 **Add role (新增角色)**。

## AWS CLI
<a name="collapsible-section-2"></a>

**使用 CLI 為 PostgreSQL 資料庫執行個體新增 IAM 角色**
+ 使用下列命令將角色新增至名為 `my-db-instance` 的 PostgreSQL 資料庫執行個體。將 *`your-role-arn`* 替換為您前個步驟記下的角色 ARN。使用 `s3Export` 作為 `--feature-name` 選項的值。  
**Example**  

  針對 Linux、macOS 或 Unix：

  ```
  aws rds add-role-to-db-instance \
     --db-instance-identifier my-db-instance \
     --feature-name s3Export \
     --role-arn your-role-arn   \
     --region your-region
  ```

  在 Windows 中：

  ```
  aws rds add-role-to-db-instance ^
     --db-instance-identifier my-db-instance ^
     --feature-name s3Export ^
     --role-arn your-role-arn ^
     --region your-region
  ```

# 使用 aws\$1s3.query\$1export\$1to\$1s3 函數匯出查詢資料
<a name="postgresql-s3-export-examples"></a>

呼叫 [aws\$1s3.query\$1export\$1to\$1s3](postgresql-s3-export-functions.md#aws_s3.export_query_to_s3) 函數來將 PostgreSQL 資料匯出至 Amazon S3。

**Topics**
+ [先決條件](#postgresql-s3-export-examples-prerequisites)
+ [正在呼叫 aws\$1s3.query\$1export\$1to\$1s3](#postgresql-s3-export-examples-basic)
+ [匯出至使用自訂分隔符號的 CSV 檔案](#postgresql-s3-export-examples-custom-delimiter)
+ [利用編碼匯出至二進位檔案](#postgresql-s3-export-examples-encoded)

## 先決條件
<a name="postgresql-s3-export-examples-prerequisites"></a>

使用 `aws_s3.query_export_to_s3` 函數前，請先完成下列必要條件：
+ 安裝需要的 PostgreSQL 延伸，如[將資料匯出至 Amazon S3 的概觀](postgresql-s3-export.md#postgresql-s3-export-overview) 中所述。
+ 決定要將資料匯出至 Amazon S3 的位置，如[指定要匯出的 Amazon S3 檔案路徑](postgresql-s3-export.md#postgresql-s3-export-file)中所述。
+ 確認資料庫執行個體如 [設定對 Amazon S3 儲存貯體的存取權](postgresql-s3-export-access-bucket.md) 中所述，有對 Amazon S3 的匯出存取權。

下列範例會使用稱為 `sample_table` 的資料庫資料表。這些範例會將資料匯出至名為 *amzn-s3-demo-bucket* 的儲存貯體。範例資料表和資料會以下列 psql 形式的 SQL 陳述式建立。

```
psql=> CREATE TABLE sample_table (bid bigint PRIMARY KEY, name varchar(80));
psql=> INSERT INTO sample_table (bid,name) VALUES (1, 'Monday'), (2,'Tuesday'), (3, 'Wednesday');
```

## 正在呼叫 aws\$1s3.query\$1export\$1to\$1s3
<a name="postgresql-s3-export-examples-basic"></a>

以下示範呼叫 [aws\$1s3.query\$1export\$1to\$1s3](postgresql-s3-export-functions.md#aws_s3.export_query_to_s3) 函數的基本方式。

這些範例會使用變數 `s3_uri_1` 來識別包含識別 Amazon S3 檔案資訊的結構。使用 [aws\$1commons.create\$1s3\$1uri](postgresql-s3-export-functions.md#aws_commons.create_s3_uri) 函數來建立結構。

```
psql=> SELECT aws_commons.create_s3_uri(
   'amzn-s3-demo-bucket',
   'sample-filepath',
   'us-west-2'
) AS s3_uri_1 \gset
```

雖然下列兩個 `aws_s3.query_export_to_s3` 函數呼叫的參數有所不同，但這些範例的結果是相同的。`sample_table` 資料表的所有列都會匯出至名為 *amzn-s3-demo-bucket* 的儲存貯體。

```
psql=> SELECT * FROM aws_s3.query_export_to_s3('SELECT * FROM sample_table', :'s3_uri_1');

psql=> SELECT * FROM aws_s3.query_export_to_s3('SELECT * FROM sample_table', :'s3_uri_1', options :='format text');
```

參數說明如下：
+ `'SELECT * FROM sample_table'` – 第一個字串是包含 SQL 查詢的文字字串。PostgreSQL 引擎會執行此查詢。查詢結果會複製到其他參數中識別的 S3 儲存貯體。
+ `:'s3_uri_1'` – 此參數是識別 Amazon S3 檔案的結構。此範例使用變數來識別先前建立的結構。您可以改為透過在 `aws_commons.create_s3_uri` 函數呼叫中包含內嵌 `aws_s3.query_export_to_s3` 函數呼叫來建立結構，如下所示。

  ```
  SELECT * from aws_s3.query_export_to_s3('select * from sample_table', 
     aws_commons.create_s3_uri('amzn-s3-demo-bucket', 'sample-filepath', 'us-west-2') 
  );
  ```
+ `options :='format text'` – `options` 是包含 PostgreSQL `COPY` 引數的選用文字字串。複製程序使用 [PostgreSQL COPY](https://www.postgresql.org/docs/current/sql-copy.html) 命令的引數及格式。

如果指定的檔案不存在於 Amazon S3 儲存貯體內，就會建立。如果檔案已存在，即會遭到覆寫。以下是存取 Amazon S3 中已匯出資料的語法。

```
s3-region://bucket-name[/path-prefix]/file-prefix
```

較大的匯出項目會儲存在多個檔案中，每個檔案的大小上限約為 6 GB。其他檔案名稱具有相同的檔案字首，但會加上 `_partXX`。`XX` 代表 2，接著是 3，以此類推 舉例來說，假設您要指定儲存資料檔案的路徑，如下所示。

```
s3-us-west-2://amzn-s3-demo-bucket/my-prefix
```

如果匯出必須建立三個資料檔案，則 Amazon S3 儲存貯體會包含下列資料檔案。

```
s3-us-west-2://amzn-s3-demo-bucket/my-prefix
s3-us-west-2://amzn-s3-demo-bucket/my-prefix_part2
s3-us-west-2://amzn-s3-demo-bucket/my-prefix_part3
```

如需此函數的完整參考以及其他呼叫方式，請參閱 [aws\$1s3.query\$1export\$1to\$1s3](postgresql-s3-export-functions.md#aws_s3.export_query_to_s3)。如需存取 Amazon S3 中檔案的詳細資訊，請參閱《*Amazon Simple Storage Service 使用者指南*》中的[檢視物件](https://docs.aws.amazon.com/AmazonS3/latest/userguide/OpeningAnObject.html)。

## 匯出至使用自訂分隔符號的 CSV 檔案
<a name="postgresql-s3-export-examples-custom-delimiter"></a>

下列範例示範如何呼叫使用自訂分隔符號來將資料匯入檔案的 [aws\$1s3.query\$1export\$1to\$1s3](postgresql-s3-export-functions.md#aws_s3.export_query_to_s3) 函數。範例使用了 [PostgreSQL COPY](https://www.postgresql.org/docs/current/sql-copy.html) 命令的引數，來指定逗號分隔值 (CSV) 格式和冒號 (:) 分隔符號。

```
SELECT * from aws_s3.query_export_to_s3('select * from basic_test', :'s3_uri_1', options :='format csv, delimiter $$:$$');
```

## 利用編碼匯出至二進位檔案
<a name="postgresql-s3-export-examples-encoded"></a>

下列範例示範如何呼叫 [aws\$1s3.query\$1export\$1to\$1s3](postgresql-s3-export-functions.md#aws_s3.export_query_to_s3) 函數來將資料匯出至使用 Windows-1253 編碼的二進位檔案。

```
SELECT * from aws_s3.query_export_to_s3('select * from basic_test', :'s3_uri_1', options :='format binary, encoding WIN1253');
```

# 函數參考
<a name="postgresql-s3-export-functions"></a>

**Topics**
+ [aws\$1s3.query\$1export\$1to\$1s3](#aws_s3.export_query_to_s3)
+ [aws\$1commons.create\$1s3\$1uri](#aws_commons.create_s3_uri)

## aws\$1s3.query\$1export\$1to\$1s3
<a name="aws_s3.export_query_to_s3"></a>

將 PostgreSQL 查詢結果匯出至 Amazon S3 儲存貯體。`aws_s3` 延伸提供 `aws_s3.query_export_to_s3` 函數。

兩個必要參數為 `query` 及 `s3_info`。這些參數會定義要匯出的查詢，以及要匯出至的 Amazon S3 儲存貯體。名為 `options` 的選用參數會提供來定義各種匯出參數。如需使用 `aws_s3.query_export_to_s3` 函數的範例，請參閱 [使用 aws\$1s3.query\$1export\$1to\$1s3 函數匯出查詢資料](postgresql-s3-export-examples.md)。

**語法**

```
aws_s3.query_export_to_s3(
    query text,    
    s3_info aws_commons._s3_uri_1,    
    options text,
    kms_key text
)
```輸入參數

*query*  
包含 PostgreSQL 引擎執行之 SQL 查詢的必要文字字串。此查詢的結果會複製到 `s3_info` 參數中識別的 S3 儲存貯體。

*s3\$1info*  
`aws_commons._s3_uri_1` 複合類型，含有下列 S3 物件相關資訊：  
+ `bucket` – 包含檔案的 Amazon S3 儲存貯體名稱。
+ `file_path` – Amazon S3 檔案名稱和路徑。
+ `region` – 儲存貯體所在的 AWS 區域。如需 AWS 區域名稱和相關值的清單，請參閱 [區域、可用區域和 Local Zones](Concepts.RegionsAndAvailabilityZones.md)。

  目前，此值必須與匯出資料庫執行個體 AWS 的區域相同。預設值為匯出資料庫執行個體 AWS 的區域。
如果要建立 `aws_commons._s3_uri_1` 複合結構，請參閱 [aws\$1commons.create\$1s3\$1uri](#aws_commons.create_s3_uri) 函數。

*options*  
選用的文字字串，含有 PostgreSQL `COPY` 命令引數。這些引數指定資料要如何在匯出時複製。詳細資訊請參閱 [PostgreSQL COPY 文件](https://www.postgresql.org/docs/current/sql-copy.html)。

*kms\$1key 文字*  
選用的文字字串，其中包含要將資料匯出至其中的 S3 儲存貯體之客戶受管 KMS 金鑰。

### 替代輸入參數
<a name="aws_s3.export_query_to_s3-alternate-parameters"></a>

為了協助進行測試，您可使用一組更大的參數取代 `s3_info` 參數。以下是 `aws_s3.query_export_to_s3` 函數的其他語法變化。

請不要使用 `s3_info` 參數識別 Amazon S3 檔案，而是使用 `bucket`、`file_path` 及 `region` 參數組合進行。

```
aws_s3.query_export_to_s3(
    query text,    
    bucket text,    
    file_path text,    
    region text,    
    options text,
    kms_key text
)
```

*query*  
包含 PostgreSQL 引擎執行之 SQL 查詢的必要文字字串。此查詢的結果會複製到 `s3_info` 參數中識別的 S3 儲存貯體。

*bucket*  
必要文字字串，其中含有包含檔案的 Amazon S3 儲存貯體名稱。

*file\$1path*  
包含 Amazon S3 檔案名稱 (包括檔案路徑) 的必要文字字串。

*region*  
選用的文字字串，其中包含儲存貯體所在的 AWS 區域。如需 AWS 區域名稱和相關值的清單，請參閱 [區域、可用區域和 Local Zones](Concepts.RegionsAndAvailabilityZones.md)。  
目前，此值必須與匯出資料庫執行個體 AWS 的區域相同。預設值為匯出資料庫執行個體 AWS 的區域。

*options*  
選用的文字字串，含有 PostgreSQL `COPY` 命令引數。這些引數指定資料要如何在匯出時複製。詳細資訊請參閱 [PostgreSQL COPY 文件](https://www.postgresql.org/docs/current/sql-copy.html)。

*kms\$1key 文字*  
選用的文字字串，其中包含要將資料匯出至其中的 S3 儲存貯體之客戶受管 KMS 金鑰。

### 輸出參數
<a name="aws_s3.export_query_to_s3-output-parameters"></a>

```
aws_s3.query_export_to_s3(
    OUT rows_uploaded bigint,
    OUT files_uploaded bigint,
    OUT bytes_uploaded bigint
)
```

*rows\$1uploaded*  
指定查詢成功上傳至 Amazon S3 的資料表列數。

*files\$1uploaded*  
上傳至 Amazon S3 的檔案數。建立的檔案大小約為 6 GB。每個額外建立的檔案，名稱都會加上 `_partXX`。`XX` 代表 2，接著是 3，視需要以此類推。

*bytes\$1uploaded*  
上傳至 Amazon S3 的總位元組數。

### 範例
<a name="aws_s3.export_query_to_s3-examples"></a>

```
psql=> SELECT * from aws_s3.query_export_to_s3('select * from sample_table', 'amzn-s3-demo-bucket', 'sample-filepath');
psql=> SELECT * from aws_s3.query_export_to_s3('select * from sample_table', 'amzn-s3-demo-bucket', 'sample-filepath','us-west-2');
psql=> SELECT * from aws_s3.query_export_to_s3('select * from sample_table', 'amzn-s3-demo-bucket', 'sample-filepath','us-west-2','format text');
```

## aws\$1commons.create\$1s3\$1uri
<a name="aws_commons.create_s3_uri"></a>

建立 `aws_commons._s3_uri_1` 結構以保留 Amazon S3 檔案資訊。您使用 `aws_commons.create_s3_uri` 函數 `s3_info` 參數之中的 [aws\$1s3.query\$1export\$1to\$1s3](#aws_s3.export_query_to_s3) 函數結果。如需使用 `aws_commons.create_s3_uri` 函數的範例，請參閱 [指定要匯出的 Amazon S3 檔案路徑](postgresql-s3-export.md#postgresql-s3-export-file)。

**語法**

```
aws_commons.create_s3_uri(
   bucket text,
   file_path text,
   region text
)
```輸入參數

*bucket*  
必要的文字字串，其中含有檔案的 Amazon S3 儲存貯體名稱。

*file\$1path*  
包含 Amazon S3 檔案名稱 (包括檔案路徑) 的必要文字字串。

*region*  
必要的文字字串，其中包含檔案所在的 AWS 區域。如需 AWS 區域名稱和相關值的清單，請參閱 [區域、可用區域和 Local Zones](Concepts.RegionsAndAvailabilityZones.md)。

# 對 Amazon S3 的存取進行故障診斷
<a name="postgresql-s3-export-troubleshoot"></a>

如果您在嘗試將資料匯出至 Amazon S3 時遇到連線問題，請先確認與資料庫執行個體關聯之 VPC 安全群組的輸出存取規則允許網路連線。明確的說，安全群組必須擁有允許資料庫執行個體傳至連接埠 443 和任何 IPv4 地址 (0.0.0.0/0)。如需更多詳細資訊，請參閱 [建立安全群組以存取在您的 VPC 中您的資料庫執行個體](CHAP_SettingUp.md#CHAP_SettingUp.SecurityGroup)。

另請參閱以下內容中的建議：
+ [對 Amazon RDS 身分與存取進行故障診斷](security_iam_troubleshoot.md)
+ 《*Amazon Simple Storage Service 使用者指南*》中的[針對 Amazon S3 進行故障診斷](https://docs.aws.amazon.com/AmazonS3/latest/userguide/troubleshooting.html)。
+ 《*IAM 使用者指南*》中的[針對 Amazon S3 和 IAM 進行故障診斷](https://docs.aws.amazon.com/IAM/latest/UserGuide/troubleshoot_iam-s3.html)

# 從 RDS for PostgreSQL 資料庫執行個體叫用 AWS Lambda 函數
<a name="PostgreSQL-Lambda"></a>

AWS Lambda 是一種事件驅動的運算服務，可讓您執行程式碼，而無需佈建或管理伺服器。它可用於許多 AWS 服務，包括 RDS for PostgreSQL。例如，您可以使用 Lambda 函數處理來自資料庫的事件通知，或在新檔案上傳到 Simple Storage Service (Amazon S3) 時從檔案中載入資料。若要進一步了解 Lambda，請參閱《 開發人員指南》中的[什麼是 AWS Lambda？](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html)。 *AWS Lambda *

**注意**  
這些 RDS for PostgreSQL 版本支援叫用 AWS Lambda 函數：  
所有 PostgreSQL 18 版本
所有 PostgreSQL 17 版本
所有 PostgreSQL 16 版本
所有 PostgreSQL 15 版本
PostgreSQL 14.1 版和更高次要版本
PostgreSQL 13.2 版和更新次要版本
PostgreSQL 12.6 版和更新次要版本

設定 RDS for PostgreSQL 以使用 Lambda 函數是涉及 IAM AWS Lambda、VPC 和 RDS for PostgreSQL 資料庫執行個體的多步驟程序。以下提供必要步驟的摘要。

如需有關 Lambda 函數的詳細資訊，請參閱《 *AWS Lambda 開發人員指南*》中的 [Lambda 入門](https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html)和 [AWS Lambda 函數](https://docs.aws.amazon.com/lambda/latest/dg/lambda-foundation.html)。

**Topics**
+ [步驟 1：為您的 RDS for PostgreSQL 資料庫執行個體設定傳出連線 AWS Lambda](#PostgreSQL-Lambda-network)
+ [步驟 2：為您的 RDS for PostgreSQL 資料庫執行個體和 設定 IAM AWS Lambda](#PostgreSQL-Lambda-access)
+ [步驟 3：安裝 RDS for PostgreSQL 資料庫執行個體的`aws_lambda`擴充功能](#PostgreSQL-Lambda-install-extension)
+ [步驟 4：搭配 RDS for PostgreSQL 資料庫執行個體使用 Lambda helper 函數 (選用)](#PostgreSQL-Lambda-specify-function)
+ [步驟 5：從 RDS for PostgreSQL 資料庫執行個體叫用 Lambda 函數。](#PostgreSQL-Lambda-invoke)
+ [步驟 6：授予其他使用者呼叫 Lambda 函數的許可權限](#PostgreSQL-Lambda-grant-users-permissions)
+ [範例：從 RDS for PostgreSQL 資料庫執行個體叫用 Lambda 函數](PostgreSQL-Lambda-examples.md)
+ [Lambda 函數錯誤訊息](PostgreSQL-Lambda-errors.md)
+ [AWS Lambda 函數和參數參考](PostgreSQL-Lambda-functions.md)

## 步驟 1：為您的 RDS for PostgreSQL 資料庫執行個體設定傳出連線 AWS Lambda
<a name="PostgreSQL-Lambda-network"></a>

Lambda 函數一律會在 AWS Lambda 服務擁有的 Amazon VPC 內執行。Lambda 會將網路存取和安全性規則套用至此 VPC，並自動維護和監控 VPC。您的 RDS for PostgreSQL 資料庫執行個體會將網路流量傳送到 Lambda 服務的 VPC。具體設定取決於 資料庫執行個體是公有的或私有。
+ **公有 RDS for PostgreSQL 資料庫執行個體** – 如果執行個體位於公有子網路中，且執行個體的「PubliclyAccessible able」屬性為 `true`，則資料庫執行個體為公有的。若要尋找此屬性的值，您可以使用 [describe-db-instances](https://docs.aws.amazon.com/cli/latest/reference/rds/describe-db-instances.html) AWS CLI 命令。或者可以使用 AWS 管理主控台 開啟 **Connectivity & security** (連線與安全性) 索引標籤，檢查 **Publicly accessible** (可公開存取) 是否為 **Yes** (是)。若要驗證執行個體是否在您的 VPC 公有子網路中，您可以使用 AWS 管理主控台 或 AWS CLI。

  若要設定 Lambda 的存取權，您可以使用 AWS 管理主控台 或 AWS CLI 在您的 VPC 安全群組上建立傳出規則。傳出規則會指定 TCP 可以使用連接埠 443 將封包傳至任何 IPv4 位址 (0.0.0.0/0)。
+ **私有 RDS for PostgreSQL 資料庫執行個體** – 在此情況下，執行個體的「PubliclyAccessible」屬性為 `false`，或者位於私有子網路中。若要允許執行個體使用 Lambda，您可以使用網路位址轉譯 (NAT) 閘道。如需更多詳細資訊，請參閱 [NAT 閘道](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html)。或者，您可以使用 Lambda 的 VPC 端點來設定 VPC。如需詳細資訊，請參閱《Amazon VPC 使用者指南》**中的 [VPC 端點](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-endpoints.html)。端點將 RDS for PostgreSQL 資料庫執行個體所發出呼叫的回傳至 Lambda 函數。VPC 端點使用自己的私有 DNS 解析。RDS for PostgreSQL 無法使用 Lambda VPC 端點，除非您將 `rds.custom_dns_resolution` 從預設值 0 (未啟用) 改為 1。若要這麼做：
  + 建立自訂資料庫參數群組。
  + 將參數 `rds.custom_dns_resolution` 從預設值 `0` 變更為 `1`。
  + 修改資料庫執行個體以使用自訂資料庫參數群組。
  + 為了讓修改過的參數生效，請重新啟動執行個體。

您的 VPC 現在可以在網路層級與 AWS Lambda VPC 互動。下一步，您需要使用 IAM 來設定許可。

## 步驟 2：為您的 RDS for PostgreSQL 資料庫執行個體和 設定 IAM AWS Lambda
<a name="PostgreSQL-Lambda-access"></a>

從 RDS for PostgreSQL 資料庫執行個體叫用 Lambda 函數需要某些權限。若要設定必要的權限，建議您建立允許叫用 Lambda 函數的 IAM 政策，將政策指派給一個角色，然後將該角色套用至資料庫執行個體。此做法會提供資料庫執行個體權限，允許代表您叫用指定的 Lambda 函數。下列步驟說明如何在 AWS CLI中執行此操作。

**設定 IAM 許可以搭配 Lambda 使用Amazon RDS 執行個體**

1. 使用 [create-policy](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/create-policy.html) AWS CLI 命令建立 IAM 政策，允許 RDS for PostgreSQL 資料庫執行個體叫用指定的 Lambda 函數。(陳述式 ID (Sid) 是政策陳述式的選用描述，不會影響使用。) 此政策為 資料庫執行個體提供叫用指定 Lambda 函數所需的最低許可。

   ```
   aws iam create-policy  --policy-name rds-lambda-policy --policy-document '{
       "Version": "2012-10-17",		 	 	 
       "Statement": [
           {
           "Sid": "AllowAccessToExampleFunction",
           "Effect": "Allow",
           "Action": "lambda:InvokeFunction",
           "Resource": "arn:aws:lambda:aws-region:444455556666:function:my-function"
           }
       ]
   }'
   ```

   或者，您可以使用預先定義的 `AWSLambdaRole` 政策，該政策允許叫用任何 Lambda 函數。如需詳細資訊，請參閱[適用於 Lambda 的身分型 IAM 政策](https://docs.aws.amazon.com/lambda/latest/dg/access-control-identity-based.html#access-policy-examples-aws-managed)。

1. 使用 [create-role](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/create-role.html) AWS CLI 命令來建立政策可在執行時間擔任的 IAM 角色。

   ```
   aws iam create-role  --role-name rds-lambda-role --assume-role-policy-document '{
       "Version": "2012-10-17",		 	 	 
       "Statement": [
           {
           "Effect": "Allow",
           "Principal": {
               "Service": "rds.amazonaws.com"
           },
           "Action": "sts:AssumeRole"
           }
       ]
   }'
   ```

1. 使用 [attach-role-policy](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/attach-role-policy.html) AWS CLI 命令將政策套用至角色。

   ```
   aws iam attach-role-policy \
       --policy-arn arn:aws:iam::444455556666:policy/rds-lambda-policy \
       --role-name rds-lambda-role --region aws-region
   ```

1. 使用  [add-role-to-db-instance](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/rds/add-role-to-db-instance.html) AWS CLI 命令，將角色套用至 RDS for PostgreSQL 資料庫執行個體。最後這個步驟允許資料庫執行個體的資料庫使用者叫用 Lambda 函數。

   ```
   aws rds add-role-to-db-instance \
          --db-instance-identifier my-instance-name \
          --feature-name Lambda \
          --role-arn  arn:aws:iam::444455556666:role/rds-lambda-role   \
          --region aws-region
   ```

完成 VPC 和 IAM 設定後，現在可以安裝 `aws_lambda` 擴充功能。(請注意，您可以隨時安裝擴充功能，但在設定正確的 VPC 支援和 IAM 權限之前，`aws_lambda` 擴充功能不會為 RDS for PostgreSQL 資料庫執行個體的功能新增任何項目。)

## 步驟 3：安裝 RDS for PostgreSQL 資料庫執行個體的`aws_lambda`擴充功能
<a name="PostgreSQL-Lambda-install-extension"></a>

若要 AWS Lambda 搭配 RDS for PostgreSQL 資料庫執行個體使用 ，請將 `aws_lambda` PostgreSQL 延伸模組新增至 RDS for PostgreSQL 資料庫執行個體。此擴充功能讓 RDS for PostgreSQL 資料庫執行個體能夠從 PostgreSQL 呼叫 Lambda 函數。

**在 RDS for PostgreSQL 資料庫執行個體中安裝`aws_lambda`擴充功能**

使用 PostgreSQL `psql` 命令列或 pgAdmin 工具連線到 RDS for PostgreSQL 資料庫執行個體。

1. 以具有 `rds_superuser` 權限的使用者身分連線至 RDS for PostgreSQL 資料庫執行個體。預設 `postgres` 使用者顯示於範例中。

   ```
   psql -h instance.444455556666.aws-region.rds.amazonaws.com -U postgres -p 5432
   ```

1. 安裝 `aws_lambda` 擴充功能。另外也需要 `aws_commons` 擴充功能。它為 `aws_lambda` 提供了 helper 函數和 PostgreSQL 的許多其他 Aurora 擴充功能。如果尚未裝在 RDS for PostgreSQL 資料庫執行個體上，會透過 `aws_lambda` 進行安裝，如下所示。

   ```
   CREATE EXTENSION IF NOT EXISTS aws_lambda CASCADE;
   NOTICE:  installing required extension "aws_commons"
   CREATE EXTENSION
   ```

`aws_lambda` 擴充功能已安裝在 資料庫執行個體上。您現在可以建立便利的結構，用於叫用 Lambda 函數。

## 步驟 4：搭配 RDS for PostgreSQL 資料庫執行個體使用 Lambda helper 函數 (選用)
<a name="PostgreSQL-Lambda-specify-function"></a>

您可以在 `aws_commons` 擴充功能中使用 helper 函數，準備可更輕鬆從 PostgreSQL 叫用的實體。若要執行此操作，您需要以下有關 Lambda 函數的資訊：
+ **函數名稱** – Lambda 函數的名稱、Amazon 資源名稱 (ARN)、版本或別名。在 [步驟 2：為 執行個體和 Lambda 設定 IAM](#PostgreSQL-Lambda-access) 中建立的 IAM 政策需要 ARN，因此建議您使用函數的 ARN。
+ **AWS 區域** – （選用） 如果 AWS Lambda 函數不在與 RDS for PostgreSQL 資料庫執行個體相同的區域中，則 Lambda 函數所在的區域。

若要保存 Lambda 函數名稱資訊，可使用 [aws\$1commons.create\$1lambda\$1function\$1arn](PostgreSQL-Lambda-functions.md#aws_commons.create_lambda_function_arn) 函數。此 helper 函數會建立一個 `aws_commons._lambda_function_arn_1` 複合結構，其中包含叫用函數所需的詳細資訊。接下來說明設定此複合結構的三種替代做法。

```
SELECT aws_commons.create_lambda_function_arn(
   'my-function',
   'aws-region'
) AS aws_lambda_arn_1 \gset
```

```
SELECT aws_commons.create_lambda_function_arn(
   '111122223333:function:my-function',
   'aws-region'
) AS lambda_partial_arn_1 \gset
```

```
SELECT aws_commons.create_lambda_function_arn(
   'arn:aws:lambda:aws-region:111122223333:function:my-function'
) AS lambda_arn_1 \gset
```

這些值全部都可以用於 [aws\$1lambda.invoke](PostgreSQL-Lambda-functions.md#aws_lambda.invoke) 函數呼叫。如需範例，請參閱 [步驟 5：從 RDS for PostgreSQL 資料庫執行個體叫用 Lambda 函數。](#PostgreSQL-Lambda-invoke)。

## 步驟 5：從 RDS for PostgreSQL 資料庫執行個體叫用 Lambda 函數。
<a name="PostgreSQL-Lambda-invoke"></a>

`aws_lambda.invoke` 函數採同步或異步行為，具體取決於 `invocation_type`。此參數的兩個替代項目是 `RequestResponse` (預設值) 和 `Event`，如下所示：
+ **`RequestResponse`** – 此叫用類型為*同步*。這是在未指定叫用類型的情況下進行呼叫時的預設行為。回應承載包括 `aws_lambda.invoke` 函數的結果。如果您的工作流程需要接收 Lambda 函數的結果才能繼續執行，請使用此叫用類型。
+ **`Event`** – 此叫用類型為*非同步*。回應不包括含有結果的承載。如果您的工作流程不需要 Lambda 函數的結果即可繼續執行，請使用此叫用類型。

如要簡單測試您的設定，可以使用 `psql` 連線至資料庫執行個體，並從命令列叫用範例函數。假設您在 Lambda 服務上設定了一個基本函數，例如下方螢幕擷取畫面中顯示的簡單 Python 函數。

![\[for 中顯示的範例 Lambda AWS CLI 函數 AWS Lambda\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/images/lambda_simple_function.png)


**叫用範例函數**

1. 使用 `psql` 或 pgAdmin 連線至資料庫執行個體。

   ```
   psql -h instance.444455556666.aws-region.rds.amazonaws.com -U postgres -p 5432
   ```

1. 使用函數的 ARN 叫用函數。

   ```
   SELECT * from aws_lambda.invoke(aws_commons.create_lambda_function_arn('arn:aws:lambda:aws-region:444455556666:function:simple', 'us-west-1'), '{"body": "Hello from Postgres!"}'::json );
   ```

   回應如下所示。

   ```
   status_code |                        payload                        | executed_version | log_result
   -------------+-------------------------------------------------------+------------------+------------
            200 | {"statusCode": 200, "body": "\"Hello from Lambda!\""} | $LATEST          |
   (1 row)
   ```

如果您的叫用嘗試未成功，請參閱 [Lambda 函數錯誤訊息](PostgreSQL-Lambda-errors.md)。

## 步驟 6：授予其他使用者呼叫 Lambda 函數的許可權限
<a name="PostgreSQL-Lambda-grant-users-permissions"></a>

在程序中的這一點上，只有身為 `rds_superuser` 的您可以叫用 Lambda 函式。如要允許其他使用者呼叫您建立的任何函數，您需要授予其許可權限。

**如要授予叫用 Lambda 函數的許可權限**

1. 使用 `psql` 或 pgAdmin 連線至資料庫執行個體。

   ```
   psql -h instance.444455556666.aws-region.rds.amazonaws.com -U postgres -p 5432
   ```

1. 執行下列 SQL 命令：

   ```
   postgres=>  GRANT USAGE ON SCHEMA aws_lambda TO db_username;
   GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA aws_lambda TO db_username;
   ```

# 範例：從 RDS for PostgreSQL 資料庫執行個體叫用 Lambda 函數
<a name="PostgreSQL-Lambda-examples"></a>

以下提供幾個呼叫 [aws\$1lambda.invoke](PostgreSQL-Lambda-functions.md#aws_lambda.invoke) 函數的範例。大部分範例使用您在 [步驟 4：搭配 RDS for PostgreSQL 資料庫執行個體使用 Lambda helper 函數 (選用)](PostgreSQL-Lambda.md#PostgreSQL-Lambda-specify-function) 中建立的複合結構 `aws_lambda_arn_1` 來簡化函數詳細資訊的傳遞。如需非同步叫用的範例，請參閱[範例：Lambda 函數的非同步 (Event) 叫用](#PostgreSQL-Lambda-Event)。列出的所有其他範例都使用同步叫用。

若要進一步了解 Lambda 叫用類型，請參閱《*AWS Lambda 開發人員指南*》中的[叫用 Lambda 函數](https://docs.aws.amazon.com/lambda/latest/dg/lambda-invocation.html)。如需 `aws_lambda_arn_1` 的相關資訊，請參閱 [aws\$1commons.create\$1lambda\$1function\$1arn](PostgreSQL-Lambda-functions.md#aws_commons.create_lambda_function_arn)。

**Topics**
+ [範例：Lambda 函數的同步 (RequestResponse) 叫用](#PostgreSQL-Lambda-RequestResponse)
+ [範例：Lambda 函數的非同步 (Event) 叫用](#PostgreSQL-Lambda-Event)
+ [範例：在函數回應中擷取 Lambda 執行日誌](#PostgreSQL-Lambda-log-response)
+ [範例：在 Lambda 函數中包含用戶端內容](#PostgreSQL-Lambda-client-context)
+ [範例：叫用特定版本的 Lambda 函數](#PostgreSQL-Lambda-function-version)

## 範例：Lambda 函數的同步 (RequestResponse) 叫用
<a name="PostgreSQL-Lambda-RequestResponse"></a>

下面是同步 Lambda 函數叫用的兩個範例。這些 `aws_lambda.invoke` 函數的結果相同。

```
SELECT * FROM aws_lambda.invoke('aws_lambda_arn_1', '{"body": "Hello from Postgres!"}'::json);
```

```
SELECT * FROM aws_lambda.invoke('aws_lambda_arn_1', '{"body": "Hello from Postgres!"}'::json, 'RequestResponse');
```

參數說明如下：
+ `:'aws_lambda_arn_1'` – 此參數識別 [步驟 4：搭配 RDS for PostgreSQL 資料庫執行個體使用 Lambda helper 函數 (選用)](PostgreSQL-Lambda.md#PostgreSQL-Lambda-specify-function) 中使用 `aws_commons.create_lambda_function_arn` helper 函數建立的複合結構。您也可以在 `aws_lambda.invoke` 呼叫中建立這個結構，如下所示。

  ```
  SELECT * FROM aws_lambda.invoke(aws_commons.create_lambda_function_arn('my-function', 'aws-region'),
  '{"body": "Hello from Postgres!"}'::json
  );
  ```
+ `'{"body": "Hello from PostgreSQL!"}'::json` – 要傳遞給 Lambda 函數的 JSON 承載。
+ `'RequestResponse'` – Lambda 叫用類型。

## 範例：Lambda 函數的非同步 (Event) 叫用
<a name="PostgreSQL-Lambda-Event"></a>

以下是非同步 Lambda 函數叫用的範例。`Event` 叫用類型會使用指定的輸入承載，來排程 Lambda 函數叫用並立即傳回。在某些工作流程中，使用不依賴於 Lambda 函數結果的 `Event` 叫用類型。

```
SELECT * FROM aws_lambda.invoke('aws_lambda_arn_1', '{"body": "Hello from Postgres!"}'::json, 'Event');
```

## 範例：在函數回應中擷取 Lambda 執行日誌
<a name="PostgreSQL-Lambda-log-response"></a>

在 `aws_lambda.invoke` 函數呼叫中使用 `log_type` 參數，即可讓函數回應中包含執行日誌的最後 4 KB。此參數預設為 `None`，但您可指定 `Tail` 以在回應中擷取 Lambda 執行日誌的結果，如下所示。

```
SELECT *, select convert_from(decode(log_result, 'base64'), 'utf-8') as log FROM aws_lambda.invoke(:'aws_lambda_arn_1', '{"body": "Hello from Postgres!"}'::json, 'RequestResponse', 'Tail');
```

將 [aws\$1lambda.invoke](PostgreSQL-Lambda-functions.md#aws_lambda.invoke) `log_type` 函數的 `Tail` 參數設定為在回應中包含執行日誌。`log_type` 參數的預設值為 `None`。

`log_result` 傳回的是 `base64` 編碼字串。您可以使用 `decode` 和 `convert_from` PostgreSQL 函數的組合，來解碼內容。

如需 `log_type` 的相關資訊，請參閱 [aws\$1lambda.invoke](PostgreSQL-Lambda-functions.md#aws_lambda.invoke)。

## 範例：在 Lambda 函數中包含用戶端內容
<a name="PostgreSQL-Lambda-client-context"></a>

`aws_lambda.invoke` 函數具有 `context` 參數，可用來獨立於承載之外傳遞資訊，如下所示。

```
SELECT *, convert_from(decode(log_result, 'base64'), 'utf-8') as log FROM aws_lambda.invoke(:'aws_lambda_arn_1', '{"body": "Hello from Postgres!"}'::json, 'RequestResponse', 'Tail');
```

若要包含用戶端內容，請使用 JSON 物件作為 [aws\$1lambda.invoke](PostgreSQL-Lambda-functions.md#aws_lambda.invoke) 函數的 `context` 參數。

如需 `context` 參數的詳細資訊，請參閱 [aws\$1lambda.invoke](PostgreSQL-Lambda-functions.md#aws_lambda.invoke) 參考。

## 範例：叫用特定版本的 Lambda 函數
<a name="PostgreSQL-Lambda-function-version"></a>

使用 `aws_lambda.invoke` 呼叫加入 `qualifier` 參數，即可指定特定版本的 Lambda 函數。以下提供使用 `'custom_version'` 作為版本別名的範例。

```
SELECT * FROM aws_lambda.invoke('aws_lambda_arn_1', '{"body": "Hello from Postgres!"}'::json, 'RequestResponse', 'None', NULL, 'custom_version');
```

也可改為提供含有函數名稱的 Lambda 函數限定詞，如下所示。

```
SELECT * FROM aws_lambda.invoke(aws_commons.create_lambda_function_arn('my-function:custom_version', 'us-west-2'),
'{"body": "Hello from Postgres!"}'::json);
```

如需 `qualifier` 和其他參數的詳細資訊，請參閱 [aws\$1lambda.invoke](PostgreSQL-Lambda-functions.md#aws_lambda.invoke) 參考。

# Lambda 函數錯誤訊息
<a name="PostgreSQL-Lambda-errors"></a>

於下列清單中，您可找到有關錯誤訊息的資訊，及可能的原因和解決方案。
+ **VPC 組態問題**

  嘗試連線時，VPC 組態問題可能會引發下列錯誤訊息：

  ```
  ERROR:  invoke API failed
  DETAIL: AWS Lambda client returned 'Unable to connect to endpoint'.
  CONTEXT:  SQL function "invoke" statement 1
  ```

  此錯誤的常見原因是未正確設定 VPC 安全群組。務必在您的 VPC 安全群組連接埠 443 上開啟 TCP 的傳出規則，讓 VPC 可連線至 Lambda VPC。

  如果您的資料庫執行個體是私有的，請檢查 VPC 的私有 DNS 設定。請務必將 `rds.custom_dns_resolution` 參數設定為 1 和 setup AWS PrivateLink，如 中所述[步驟 1：為您的 RDS for PostgreSQL 資料庫執行個體設定傳出連線 AWS Lambda](PostgreSQL-Lambda.md#PostgreSQL-Lambda-network)。如需詳細資訊，請參閱[介面 VPC 端點 (AWS PrivateLink)](https://docs.aws.amazon.com/vpc/latest/privatelink/vpce-interface.html#vpce-private-dns)。
+ **缺乏叫用 Lambda 函式所需的許可權限**

  若您看到下列其中一個錯誤訊息，則叫用該函數的使用者 (角色) 並無適當的許可權限。

  ```
  ERROR:  permission denied for schema aws_lambda
  ```

  ```
  ERROR:  permission denied for function invoke
  ```

  使用者 (角色) 必須取得特定授權才可叫用 Lambda 函數 如需詳細資訊，請參閱[步驟 6：授予其他使用者呼叫 Lambda 函數的許可權限](PostgreSQL-Lambda.md#PostgreSQL-Lambda-grant-users-permissions)。
+ **不正確處理 Lambda 函數中的錯誤**

  如果 Lambda 函數在請求處理期間拋出異常，則 `aws_lambda.invoke` 會失敗並顯示如下所示 PostgreSQL 錯誤。

  ```
  SELECT * FROM aws_lambda.invoke('aws_lambda_arn_1', '{"body": "Hello from Postgres!"}'::json);
  ERROR:  lambda invocation failed
  DETAIL:  "arn:aws:lambda:us-west-2:555555555555:function:my-function" returned error "Unhandled", details: "<Error details string>".
  ```

  請務必處理 Lambda 函數或 PostgreSQL 應用程式中的錯誤。

# AWS Lambda 函數和參數參考
<a name="PostgreSQL-Lambda-functions"></a>

以下是函數用於以 RDS for PostgreSQL 調用 Lambda 之函數和參數的參考。

**Topics**
+ [aws\$1lambda.invoke](#aws_lambda.invoke)
+ [aws\$1commons.create\$1lambda\$1function\$1arn](#aws_commons.create_lambda_function_arn)
+ [aws\$1lambda 參數](#aws_lambda.parameters)

## aws\$1lambda.invoke
<a name="aws_lambda.invoke"></a>

為 RDS for PostgreSQL 資料庫執行個體執行 Lambda 函數。

如需有關叫用 Lambda 函數的詳細資訊，請參閱 *AWS Lambda 開發人員指南*中的[叫用](https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html)。

**語法**

------
#### [ JSON ]

```
aws_lambda.invoke(
IN function_name TEXT,
IN payload JSON,
IN region TEXT DEFAULT NULL,
IN invocation_type TEXT DEFAULT 'RequestResponse',
IN log_type TEXT DEFAULT 'None',
IN context JSON DEFAULT NULL,
IN qualifier VARCHAR(128) DEFAULT NULL,
OUT status_code INT,
OUT payload JSON,
OUT executed_version TEXT,
OUT log_result TEXT)
```

```
aws_lambda.invoke(
IN function_name aws_commons._lambda_function_arn_1,
IN payload JSON,
IN invocation_type TEXT DEFAULT 'RequestResponse',
IN log_type TEXT DEFAULT 'None',
IN context JSON DEFAULT NULL,
IN qualifier VARCHAR(128) DEFAULT NULL,
OUT status_code INT,
OUT payload JSON,
OUT executed_version TEXT,
OUT log_result TEXT)
```

------
#### [ JSONB ]

```
aws_lambda.invoke(
IN function_name TEXT,
IN payload JSONB,
IN region TEXT DEFAULT NULL,
IN invocation_type TEXT DEFAULT 'RequestResponse',
IN log_type TEXT DEFAULT 'None',
IN context JSONB DEFAULT NULL,
IN qualifier VARCHAR(128) DEFAULT NULL,
OUT status_code INT,
OUT payload JSONB,
OUT executed_version TEXT,
OUT log_result TEXT)
```

```
aws_lambda.invoke(
IN function_name aws_commons._lambda_function_arn_1,
IN payload JSONB,
IN invocation_type TEXT DEFAULT 'RequestResponse',
IN log_type TEXT DEFAULT 'None',
IN context JSONB DEFAULT NULL,
IN qualifier VARCHAR(128) DEFAULT NULL,
OUT status_code INT,
OUT payload JSONB,
OUT executed_version TEXT,
OUT log_result TEXT
)
```

------輸入參數

**function\$1name**  
識別 Lambda 函數的名稱。該值可以是函數名稱、ARN 或部分 ARN。如需適用格式的清單，請參閱 *AWS Lambda 開發人員指南*中的 [Lambda 函數名稱格式](https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_RequestParameters)。

*payload*  
Lambda 函數的輸入。格式可以是 JSON 或 JSONB。如需詳細資訊，請參閱 PostgreSQL 文件中的 [JSON 類型](https://www.postgresql.org/docs/current/datatype-json.html)。

*區域*  
(選用) 函數的 Lambda 區域。根據預設，RDS 會從 AWS 中的完整 ARN 解析 `function_name` 區域，或使用 RDS for PostgreSQL 資料庫執行個體區域。如果此區域值與 `function_name` ARN 中提供的值衝突，則會引發錯誤。

*invocation\$1type*  
Lambda 函數的叫用類型。 值會區分大小寫。可能的值包括以下：  
+ `RequestResponse` – 預設值。Lambda 函數的這種叫用類型是同步的，並在結果中傳回回應承載。若您的工作流程依賴於立即接收 Lambda 函數，請使用 `RequestResponse` 叫用類型。
+ `Event` – Lambda 函數這種叫用類型是非同步的，並且在立即傳回時不含承載。若您在工作流程繼續進行之前不需要 Lambda 函數的結果，請使用 `Event` 叫用類型。
+ `DryRun` – 這種類型的叫用會測試存取而不執行該 Lambda 函數。

*log\$1type*  
`log_result` 輸出參數中要傳回的 Lambda 日誌類型。 值會區分大小寫。可能的值包括以下：  
+ 結尾 – 傳回的 `log_result` 輸出參數會包含執行日誌的最後 4 KB。
+ 無 – 沒有傳回 Lambda 日誌資訊。

*context*  
JSON 或 JSONB 格式的用戶端內容。要使用的欄位包括 `custom` 和 `env`。

*限定詞*  
識別待叫用 Lambda 函數版本的限定詞。如果該值與 `function_name` ARN 中提供的值衝突，則會引發錯誤。輸出參數

*status\$1code*  
HTTP 狀態回應代碼。如需更多詳細資訊，請參閱 *AWS Lambda 開發人員指南*中的 [Lambda 叫用回應元素](https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_ResponseElements)。

*payload*  
從執行的 Lambda 函數傳回的資訊。格式是 JSON 或 JSONB。

*executed\$1version*  
Lambda 函數執行的版本。

*log\$1result*  
如果 `log_type` 值是叫用 Lambda 函數時的 `Tail`，則會傳回執行日誌資訊。結果包含以 Base64 編碼的執行日誌的最後 4 KB。

## aws\$1commons.create\$1lambda\$1function\$1arn
<a name="aws_commons.create_lambda_function_arn"></a>

建立 `aws_commons._lambda_function_arn_1` 結構來保存 Lambda 函數名稱資訊。您可以在 aws\$1lambda.invoke `aws_commons.create_lambda_function_arn` 函數的 `function_name` 參數中，使用 [aws\$1lambda.invoke](#aws_lambda.invoke) 函數的結果。

**語法**

```
aws_commons.create_lambda_function_arn(
    function_name TEXT,
    region TEXT DEFAULT NULL
    )
    RETURNS aws_commons._lambda_function_arn_1
```輸入參數

*function\$1name*  
包含 Lambda 函數名稱的必要文字字串。該值可以是函數名稱、部分 ARN 或完整 ARN。

*區域*  
選用文字字串，其中含有 Lambda 函數所在的 AWS 區域。如需區域名稱和相關聯值的清單，請參閱[區域、可用區域和 Local Zones](Concepts.RegionsAndAvailabilityZones.md)。

## aws\$1lambda 參數
<a name="aws_lambda.parameters"></a>

在資料表中，您可以尋找與 `aws_lambda` 函數相關聯的參數。


| 參數 | 描述 | 
| --- | --- | 
| `aws_lambda.connect_timeout_ms` | 這是動態參數，其會設定連線到 AWS Lambda 時的最長等待時間。預設值為 `1000`。此參數的允許值為 1 - 900000。 | 
| `aws_lambda.request_timeout_ms` | 這是動態參數，其會設定在等待 AWS Lambda 回應時的最長等待時間。預設值為 `3000`。此參數的允許值為 1 - 900000。 | 
| `aws_lambda.endpoint_override` | 指定可用來連線至 AWS Lambda 的端點。空字串會選取區域的預設 AWS Lambda 端點。您必須重新啟動資料庫，此靜態參數變更才能產生作用。 | 

# Amazon RDS for PostgreSQL 的常用 DBA 任務
<a name="Appendix.PostgreSQL.CommonDBATasks"></a>

資料庫管理員 (DBA) 在管理 Amazon RDS for PostgreSQL 資料庫執行個體時執行各種任務。若您是已經熟悉 PostgreSQL 的 DBA，則需要了解在硬體上執行 PostgreSQL 和 RDS for PostgreSQL 之間的一些重要差異。例如，由於 Amazon RDS 為受管服務，因此不允許 Shell 存取資料庫執行個體。這表示您無法直接存取 `pg_hba.conf` 和其他組態檔。對於 RDS for PostgreSQL，會對與 RDS for PostgreSQL 資料庫執行個體相關聯的自訂資料庫參數群組，進行通常對內部部署執行個體的 PostgreSQL 組態檔所做的變更。如需詳細資訊，請參閱[Amazon RDS 的參數群組](USER_WorkingWithParamGroups.md)。

您也無法以您對內部部署 PostgreSQL 執行個體所做的相同方式存取日誌檔。如要進一步了解記錄，請參閱 [ RDS for PostgreSQL 資料庫日誌檔案](USER_LogAccess.Concepts.PostgreSQL.md)。

如同另一個範例，您無法存取 PostgreSQL `superuser` 帳戶。在 RDS for PostgreSQL 上，`rds_superuser` 角色是最具特權的角色，且其在設定時間授予 `postgres`。無論您是熟悉於內部部署使用 PostgreSQL 還是對 RDS for PostgreSQL 完全陌生，我們都建議您了解 `rds_superuser` 角色，及如何使用角色、使用者、群組和許可權限。如需詳細資訊，請參閱[了解 PostgreSQL 角色和許可](Appendix.PostgreSQL.CommonDBATasks.Roles.md)。

下文將介紹 RDS for PostgreSQL 的一些常用 DBA 任務。

**Topics**
+ [RDS for PostgreSQL 支援的定序](PostgreSQL-Collations.md)
+ [了解 PostgreSQL 角色和許可](Appendix.PostgreSQL.CommonDBATasks.Roles.md)
+ [PostgreSQL 中的無效連線處理](Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.md)
+ [在 Amazon RDS for PostgreSQL 上使用 PostgreSQL 自動清空](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.md)
+ [在 Amazon RDS for PostgreSQL 中管理高物件計數](PostgreSQL.HighObjectCount.md)
+ [在 Amazon RDS for PostgreSQL 中管理 TOAST OID 爭用](Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.md)
+ [搭配使用 RDS for PostgreSQL 支援的記錄機制](#Appendix.PostgreSQL.CommonDBATasks.Auditing)
+ [使用 PostgreSQL 管理暫存檔案](PostgreSQL.ManagingTempFiles.md)
+ [使用 pgBadger 進行 PostgreSQL 的日誌分析](#Appendix.PostgreSQL.CommonDBATasks.Badger)
+ [使用 PgSNAPPER 監控 PostgreSQL](#Appendix.PostgreSQL.CommonDBATasks.Snapper)
+ [在 RDS for PostgreSQL 中管理自訂轉換](PostgreSQL.CustomCasts.md)
+ [RDS for PostgreSQL 中平行查詢的最佳實務](PostgreSQL.ParallelQueries.md)
+ [在 RDS for PostgreSQL 資料庫執行個體上搭配使用參數](Appendix.PostgreSQL.CommonDBATasks.Parameters.md)

# RDS for PostgreSQL 支援的定序
<a name="PostgreSQL-Collations"></a>

定序是一組規則，用來決定如何排序和比較存放在資料庫中的字元字串。定序在電腦系統中扮演著基本角色，並包含為作業系統的一部分。隨著新字元加入至語言或排序規則變更時，定序也會變更。

定序程式庫會定義定序的特定規則和演算法。PostgreSQL 內使用的最熱門定序程式庫是 GNU C (glibc)和 Unicode 國際化元件 (ICU)。依預設，RDS for PostgreSQL 會使用 glibc 定序，其中包含多位元組字元序列的 Unicode 字元排序順序。

當您在 RD for PostgreSQL 中建立新的資料庫執行個體 時，它會檢查作業系統是否有可用的定序。`CREATE DATABASE` 命令 `LC_COLLATE` 和 `LC_CTYPE` 的 PostgreSQL 參數用來指定一個定序，其作為該資料庫中的預設定序。或者，您也可以使用 `CREATE DATABASE` 中的 `LOCALE` 參數來設定這些參數。這會決定資料庫中字元字串的預設定序，以及將字元分類為字母、數字或符號的規則。您也可以選擇要在資料欄、索引或查詢上使用的定序。

RDS for PostgreSQL 取決於作業系統中的 glibc 程式庫是否支援定序。RDS for PostgreSQL 執行個體會定期使用最新版本的作業系統進行更新。這些更新有時會包含較新版本的 glibc 程式庫。較新版本的 glibc 很少會變更某些字元的排序順序或定序，這可能導致資料以不同的方式排序或產生無效的索引項目。如果您在更新期間發現定序的排序順序問題，您可能需要重建索引。

為了 glibc 更新可能造成的影響，RDS for PostgreSQL 現在包含獨立的預設定序程式庫。此定序程式庫可在 RDS for PostgreSQL 14.6、13.9、12.13、11.18、10.23 和較新的次要版本中使用。它與 glibc 2.26-59.amzn2 相容，並提供排序順序穩定性以防止出現不正確的查詢結果。

# 了解 PostgreSQL 角色和許可
<a name="Appendix.PostgreSQL.CommonDBATasks.Roles"></a>

當您使用 RDS for PostgreSQL 資料庫執行個體時 AWS 管理主控台，會同時建立管理員帳戶。依預設，其名稱為 `postgres`，如下列螢幕擷取畫面所示：

![\[Create database (建立資料庫) 頁面中的憑證預設登入身分為 postgres。\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/images/default-login-identity-apg-rpg.png)


您可以選擇其他名稱，而不是接受預設值 (`postgres`)。若是如此，則選擇的名稱必須以字母開頭，且介於 1 到 16 個英數字元之間。為簡單起見，我們在本指南中使用主要使用者帳戶的預設值 (`postgres`)，來指稱主要使用者帳戶。

如果您使用 `create-db-instance` AWS CLI 而非 AWS 管理主控台，您可以在 命令中使用 `master-username` 參數來傳遞名稱，以建立名稱。如需詳細資訊，請參閱 [建立 Amazon RDS 資料庫執行個體](USER_CreateDBInstance.md)。

無論您是使用 AWS 管理主控台、 AWS CLI或 Amazon RDS API，還是使用預設`postgres`名稱或選擇不同的名稱，這個第一個資料庫使用者帳戶都是 `rds_superuser`群組的成員，並且具有 `rds_superuser` 權限。

**Topics**
+ [了解 rds\$1superuser 角色](Appendix.PostgreSQL.CommonDBATasks.Roles.rds_superuser.md)
+ [控制使用者對 PostgreSQL 資料庫的存取](Appendix.PostgreSQL.CommonDBATasks.Access.md)
+ [委派和控制使用者密碼管理](Appendix.PostgreSQL.CommonDBATasks.RestrictPasswordMgmt.md)
+ [使用 SCRAM 進行 PostgreSQL 密碼加密](PostgreSQL_Password_Encryption_configuration.md)

# 了解 rds\$1superuser 角色
<a name="Appendix.PostgreSQL.CommonDBATasks.Roles.rds_superuser"></a>

於 PostgreSQL 中，*角色*可定義使用者、群組或授予群組或使用者對資料庫中各種物件的一組特定權限。`CREATE USER` 和 `CREATE GROUP` 的 PostgreSQL 命令已為更為通用的 `CREATE ROLE` 所取代，其具有可區分資料庫使用者的特定屬性。資料庫使用者可視為具有 LOGIN 權限的角色。

**注意**  
`CREATE USER` 和 `CREATE GROUP` 命令仍可使用。如需詳細資訊，請參閱 PostgreSQL 文件中的[資料庫角色](https://www.postgresql.org/docs/current/user-manag.html)。

`postgres` 使用者是 RDS for PostgreSQL 資料庫執行個體上具最高權限的資料庫使用者。其具有下列 `CREATE ROLE` 陳述式所定義的特性。

```
CREATE ROLE postgres WITH LOGIN NOSUPERUSER INHERIT CREATEDB CREATEROLE NOREPLICATION VALID UNTIL 'infinity'
```

屬性 `NOSUPERUSER`、`NOREPLICATION`、`INHERIT`，和 `VALID UNTIL 'infinity'` 為 CREATE ROLE 的預設選項，除非另有指定。

根據預設，`postgres` 具有授與 `rds_superuser` 角色的權限，以及建立角色和資料庫的許可。`rds_superuser` 角色可讓 `postgres` 使用者執行下列動作：
+ 新增可與 Amazon RDS 搭配使用的擴充功能。如需詳細資訊，請參閱 [使用 Amazon RDS for PostgreSQL 支援的 PostgreSQL 功能](PostgreSQL.Concepts.General.FeatureSupport.md) 
+ 建立使用者的角色，並授予使用者權限。如需詳細資訊，請參閱 PostgreSQL 文件中的 [CREATE ROLE](https://www.postgresql.org/docs/current/sql-createrole.html) 和 [GRANT](https://www.postgresql.org/docs/14/sql-grant.html)。
+ 建立資料庫。如需詳細資訊，請參閱 PostgreSQL 文件中的 [CREATE DATABASE](https://www.postgresql.org/docs/14/sql-createdatabase.html)。
+ 將 `rds_superuser` 權限授予並無這些權限的使用者角色，並視需要撤銷這些權限。建議您僅將此角色授予執行超級使用者任務的使用者。換句話說，您可以將此角色授予資料庫管理員 (DBA) 或系統管理員。
+ 對不具 `rds_replication` 角色的資料庫使用者授予 (和撤銷) `rds_superuser` 角色。
+ 對不具 `rds_password` 角色的資料庫使用者授予 (和撤銷) `rds_superuser` 角色。
+ 使用 `pg_stat_activity` 檢視，取得有關所有資料庫連線的狀態資訊。如有需要，`rds_superuser` 可使用 `pg_terminate_backend` 或 `pg_cancel_backend` 停止任何連線。

於 `CREATE ROLE postgres...` 陳述式中，您可看到 `postgres` 使用者角色明確禁止 PostgreSQL `superuser` 權限。RDS for PostgreSQL 為受管服務，因此您無法存取主機作業系統，也無法使用 PostgreSQL `superuser` 帳户進行連線。許多需要在獨立 PostgreSQL 上進行 `superuser` 存取的任務是由 Amazon RDS 自動管理。

如需有關授予權限的詳細資訊，請參閱 PostgreSQL 文件中的 [GRANT](http://www.postgresql.org/docs/current/sql-grant.html)。

`rds_superuser` 角色是 中數個*預先定義*角色的其中一個。RDS for PostgreSQL 資料庫執行個體。

**注意**  
在 PostgreSQL 13 和更早版本中，*預先定義*角色稱為*預設*角色。

於下列清單中，您可以找到為新的 自動建立的一些其他預先定義角色。RDS for PostgreSQL 資料庫執行個體。預先定義的角色及其權限無法進行變更。您無法為這些預先定義角色停止、重新命名或修改權限。嘗試這麼做會造成錯誤。
+ **rds\$1password** – 可變更密碼並為資料庫使用者設定密碼約束的角色。依預設授予此角色 `rds_superuser` 角色，並可授予資料庫使用者該角色。如需詳細資訊，請參閱[控制使用者對 PostgreSQL 資料庫的存取控制使用者對 PostgreSQL 的存取](Appendix.PostgreSQL.CommonDBATasks.Access.md)。
  + 對於 14 之前的 RDS for PostgreSQL 版本，`rds_password` 角色可以變更密碼，並為資料庫使用者和具有 `rds_superuser` 角色的使用者設定密碼限制。從 RDS for PostgreSQL 第 14 版及更新版本，`rds_password` 角色可以變更密碼，並僅為資料庫使用者設定密碼限制。只有具有 `rds_superuser` 角色的使用者才能對具有 `rds_superuser` 角色的其他使用者執行這些動作。
+ **rdsadmin** – 為處理具有 `superuser` 權限的管理員將在獨立 PostgreSQL 資料庫上執行的許多管理任務而建立的角色。此角色由 RDS for PostgreSQL 在內部用於許多管理任務。
+ **rdstopmgr**— Amazon RDS 內部使用的一個角色，可支援異地同步備份部署。
+ **rds\$1reserved** – Amazon RDS 在內部用來保留資料庫連線的角色。

# 檢視角色及其權限
<a name="Appendix.PostgreSQL.CommonDBATasks.Roles.View"></a>

您可以根據 PostgreSQL 版本，使用不同的命令在 RDS for PostgreSQL 資料庫執行個體中檢視預先定義的角色及其權限。若要查看所有預先定義的角色，您可以連線至 RDS for PostgreSQL 資料庫執行個體，並使用 `psql` 執行下列命令。

**對於 `psql` 第 15 版和更早版本**

連線至 RDS for PostgreSQL 資料庫執行個體，並在 psql 中使用 `\du` 命令：

```
postgres=> \du
                                                               List of roles
    Role name    |                         Attributes                         |                          Member of
-----------------+------------------------------------------------------------+------------------------------------------------------
 postgres        | Create role, Create DB                                    +| {rds_superuser}
                 | Password valid until infinity                              |
 rds_ad          | Cannot login                                               | {}
 rds_iam         | Cannot login                                               | {}
 rds_password    | Cannot login                                               | {}
 rds_replication | Cannot login                                               | {}
 rds_superuser   | Cannot login                                               | {pg_monitor,pg_signal_backend,rds_password,rds_replication}
 rdsadmin        | Superuser, Create role, Create DB, Replication, Bypass RLS+| {}
                 | Password valid until infinity                              |
```

**對於 `psql` 第 16 版和更新版本**

```
postgres=> \drg+
                             List of role grants
   Role name   |          Member of          |       Options       | Grantor
---------------+-----------------------------+---------------------+----------
 postgres      | rds_superuser               | INHERIT, SET        | rdsadmin
 rds_superuser | pg_checkpoint               | ADMIN, INHERIT, SET | rdsadmin
 rds_superuser | pg_monitor                  | ADMIN, INHERIT, SET | rdsadmin
 rds_superuser | pg_signal_backend           | ADMIN, INHERIT, SET | rdsadmin
 rds_superuser | pg_use_reserved_connections | ADMIN, INHERIT, SET | rdsadmin
 rds_superuser | rds_password                | ADMIN, INHERIT, SET | rdsadmin
 rds_superuser | rds_replication             | ADMIN, INHERIT, SET | rdsadmin
```

若要在沒有版本相依性的情況下檢查角色成員資格，您可以使用下列 SQL 查詢：

```
SELECT m.rolname AS "Role name", r.rolname AS "Member of"
FROM pg_catalog.pg_roles m
JOIN pg_catalog.pg_auth_members pam ON (pam.member = m.oid)
LEFT JOIN pg_catalog.pg_roles r ON (pam.roleid = r.oid)
LEFT JOIN pg_catalog.pg_roles g ON (pam.grantor = g.oid)
WHERE m.rolname !~ '^pg_'
ORDER BY 1, 2;
```

於輸出中，您可看到 `rds_superuser` 並非資料庫使用者角色 (無法登入)，但其具有許多其他角色的權限。您還可以看到資料庫使用者 `postgres` 是 `rds_superuser` 角色的成員。如前所述，`postgres` 是 Amazon RDS 主控台 **Create database (建立資料庫)** 頁面中的預設值。若選擇其他名稱，則該名稱將顯示於角色清單中。

# 控制使用者對 PostgreSQL 資料庫的存取
<a name="Appendix.PostgreSQL.CommonDBATasks.Access"></a>

PostgreSQL 中的新資料庫會永遠使用資料庫 `public` 結構描述中的一組預設權限建立，允許所有資料庫使用者和角色建立物件。例如，這些權限可讓資料庫使用者連接至資料庫，並在連線時建立暫存資料表。

為了對您在 RDS for PostgreSQL 資料庫執行個體上建立之資料庫執行個體的使用者存取進行更好地控制，我們建議您撤消這些預設的 `public` 權限。完成此作業後，您可更精細地為資料庫使用者授予特定權限，如下列程序所示。

**如要設定新資料庫執行個體的角色和權限**

假設您正在一個剛建立的 RDS for PostgreSQL 資料庫執行個體上設定資料庫，以供多位研究人員使用，其皆需要資料庫的讀寫存取權。

1. 使用 `psql` (或 pgAdmin) 連接至 您的 RDS for PostgreSQL 資料庫執行個體：

   ```
   psql --host=your-db-instance.666666666666.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password
   ```

   出現提示時，輸入您的密碼。`psql` 用戶端連接並顯示預設管理連接資料庫 `postgres=>` 作為提示。

1. 如要防止資料庫使用者在 `public` 結構描述中建立物件，請執行下列動作：

   ```
   postgres=> REVOKE CREATE ON SCHEMA public FROM PUBLIC;
   REVOKE
   ```

1. 接下來，您會建立新的資料庫執行個體：

   ```
   postgres=> CREATE DATABASE lab_db;
   CREATE DATABASE
   ```

1. 從此新資料庫上 `PUBLIC` 結構描述撤消所有權限。

   ```
   postgres=> REVOKE ALL ON DATABASE lab_db FROM public;
   REVOKE
   ```

1. 建立一個資料庫使用者的角色。

   ```
   postgres=> CREATE ROLE lab_tech;
   CREATE ROLE
   ```

1. 使具有此角色的資料庫使用者可連接至資料庫。

   ```
   postgres=> GRANT CONNECT ON DATABASE lab_db TO lab_tech;
   GRANT
   ```

1. 授予具 `lab_tech` 角色的所有使用者此資料庫的所有權限。

   ```
   postgres=> GRANT ALL PRIVILEGES ON DATABASE lab_db TO lab_tech;
   GRANT
   ```

1. 建立資料庫使用者，如下所示：

   ```
   postgres=> CREATE ROLE lab_user1 LOGIN PASSWORD 'change_me';
   CREATE ROLE
   postgres=> CREATE ROLE lab_user2 LOGIN PASSWORD 'change_me';
   CREATE ROLE
   ```

1. 授予這兩個使用者與 lab\$1tech 角色關聯的權限：

   ```
   postgres=> GRANT lab_tech TO lab_user1;
   GRANT ROLE
   postgres=> GRANT lab_tech TO lab_user2;
   GRANT ROLE
   ```

至此，`lab_user1` 和 `lab_user2` 便可連接 `lab_db` 資料庫。此範例並未遵循企業使用的最佳實務，其中可能包括建立多個資料庫執行個體、不同的結構描述，及授予有限的權限。如需更多完整資訊和其他方案，請參閱[管理 PostgreSQL 使用者和角色](https://aws.amazon.com/blogs//database/managing-postgresql-users-and-roles/)。

如需有關 PostgreSQL 資料庫中權限的詳細資訊，請參閱 PostgreSQL 文件中的 [GRANT](https://www.postgresql.org/docs/current/static/sql-grant.html) 命令。

# 委派和控制使用者密碼管理
<a name="Appendix.PostgreSQL.CommonDBATasks.RestrictPasswordMgmt"></a>

作為 DBA，您可能想要委派管理使用者密碼。或者，您可能想要防止資料庫使用者變更其密碼或重新設定密碼約束 (例如密碼生命週期)。如要確保只有您選擇的資料庫使用者才可變更密碼設定，您可開啟受限制的密碼管理功能。啟動此功能時，只有那些已被授予 `rds_password` 角色的資料庫使用者才可管理密碼。

**注意**  
如要使用受限制的密碼管理，您的 RDS for PostgreSQL 資料庫執行個體必須執行 PostgreSQL 10.6 或更新版本。

依預設，此功能為 `off`，如下列所示：

```
postgres=> SHOW rds.restrict_password_commands;
  rds.restrict_password_commands
--------------------------------
 off
(1 row)
```

如要開啟此功能，請使用自訂參數群組，並將 `rds.restrict_password_commands` 的設定變更為 1。請務必重新啟動您的 RDS for PostgreSQL 資料庫執行個體，以使設定生效。

啟用此功能後，下列 SQL 命令需要 `rds_password` 權限：

```
CREATE ROLE myrole WITH PASSWORD 'mypassword';
CREATE ROLE myrole WITH PASSWORD 'mypassword' VALID UNTIL '2023-01-01';
ALTER ROLE myrole WITH PASSWORD 'mypassword' VALID UNTIL '2023-01-01';
ALTER ROLE myrole WITH PASSWORD 'mypassword';
ALTER ROLE myrole VALID UNTIL '2023-01-01';
ALTER ROLE myrole RENAME TO myrole2;
```

若密碼使用 MD5 雜湊演算法，則重新命名角色 (`ALTER ROLE myrole RENAME TO newname`) 也會受到限制。

啟用此功能後，嘗試使用任何這些 SQL 命令，而不使用 `rds_password` 角色權限會產生下列錯誤：

```
ERROR: must be a member of rds_password to alter passwords
```

建議您僅對專用於密碼管理的一些角色授予 `rds_password`。若您授予不具 `rds_superuser` 權限之資料庫使用者 `rds_password` 權限，則還需要授予其 `CREATEROLE` 屬性。

確定您驗證用戶端上的密碼需求，例如到期時間和需要的複雜度。若您使用自己的用戶端公用程式進行與密碼相關的變更，則該公用程式必須為 `rds_password` 的成員並具有 `CREATE ROLE` 權限。

# 使用 SCRAM 進行 PostgreSQL 密碼加密
<a name="PostgreSQL_Password_Encryption_configuration"></a>

*Salted Challenge Response Authentication Mechanism (SCRAM)* 是 PostgreSQL 預設訊息摘要 (MD5) 演算法的替代選項，用於加密密碼。SCRAM 身分驗證機制被認為比 MD5 更安全。若要進一步了解這兩種不同的密碼保護方法，請參閱 PostgreSQL 文件中的 [Password Authentication](https://www.postgresql.org/docs/14/auth-password.html) (密碼身分驗證)。

建議您使用 SCRAM 作為 的密碼加密配置，而不是使用 MD5。RDS for PostgreSQL 資料庫執行個體。這是一種加密的挑戰回應機制，使用 scram-sha-256 演算法進行密碼身分驗證和加密。

您可能需要更新程式庫，用戶端應用程式才會支援 SCRAM。例如，42.2.0 之前的 JDBC 版本不支援 SCRAM。如需詳細資訊，請參閱 PostgreSQL JDBC 驅動程式文件中的 [PostgreSQL JDBC Driver](https://jdbc.postgresql.org/changelogs/2018-01-17-42.2.0-release/) (PostgreSQL JDBC 驅動程式)。如需其他 PostgreSQL 驅動程式和 SCRAM 支援的清單，請參閱 PostgreSQL 文件中的 [List of drivers](https://wiki.postgresql.org/wiki/List_of_drivers) (驅動程式清單)。

RDS for PostgreSQL 13.1 版和更新版本支援 scram-sha-256。這些版本亦允許您將資料庫執行個體設定為需要 SCRAM，如以下程序所述。

## 設定 RDS for PostgreSQL 資料庫執行個體以要求 SCRAM
<a name="PostgreSQL_Password_Encryption_configuration.preliminary"></a>

，您可以要求  RDS for PostgreSQL 資料庫執行個體僅接受使用 scram-sha-256 演算法的密碼。

**重要**  
對於 PostgreSQL 資料庫的現有 RDS 代理，如果您將資料庫驗證修改為僅使用 `SCRAM`，則該代理會變成無法使用，最多持續 60 秒。若要避免發生此問題，請執行下列其中一項：  
確定資料庫同時允許 `SCRAM` 和 `MD5` 身分驗證。
若只要使用 `SCRAM` 身分驗證，請建立新代理、將應用程式流量遷移至新代理，然後刪除先前與資料庫相關聯的代理。

在對系統進行變更之前，請確保您了解完整過程，如下所示：
+ 獲得所有資料庫使用者的所有角色與密碼加密相關資訊。
+ 針對控制密碼加密的參數，再次檢查 RDS for PostgreSQL 資料庫執行個體的參數設定。
+ 如果您的 RDS for PostgreSQL 資料庫執行個體使用預設參數群組，則需要建立自訂資料庫參數群組，並將其套用到 RDS for PostgreSQL 資料庫執行個體，讓您可以在需要時修改參數。如果您的 RDS for PostgreSQL 資料庫執行個體使用自訂參數群組，則您稍後可以視需要在過程中修改必要參數。
+ 將 `password_encryption` 參數變更為 `scram-sha-256`。
+ 通知所有資料庫使用者他們必須更新密碼。針對您的 `postgres` 帳戶進行相同的動作。系統會使用 scram-sha-256 演算法加密與儲存新密碼。
+ 驗證確認使用加密類型將所有密碼加密。
+ 如果所有密碼都使用 scram-sha-256，您可以將 `rds.accepted_password_auth_method` 參數從 `md5+scram` 變更為 `scram-sha-256`。

**警告**  
在您僅將 `rds.accepted_password_auth_method` 變更為 scram-sha-256 後，則任何具有 `md5` 加密密碼的使用者 (角色) 將無法連線。

### 準備好為您的 RDS for PostgreSQL 資料庫執行個體要求 SCRAM
<a name="PostgreSQL_Password_Encryption_configuration.getting-ready"></a>

對  RDS for PostgreSQL 資料庫執行個體進行任何變更之前，請檢查所有現有的資料庫使用者帳戶。另外，請檢查用於密碼的加密類型。您可以使用 `rds_tools` 擴充功能執行這些任務。若要查看哪些 PostgreSQL 版本支援 `rds_tools`，請參閱 [Amazon RDS for PostgreSQL 的延伸版本](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html)。

**獲得資料庫使用者 (角色) 與密碼加密方法清單**

1. 使用 `psql` 連線至 RDS for PostgreSQL 資料庫執行個體，如下所示。

   ```
   psql --host=db-name.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password
   ```

1. 安裝 `rds_tools` 擴充功能。

   ```
   postgres=> CREATE EXTENSION rds_tools;
   CREATE EXTENSION
   ```

1. 取得角色和加密清單。

   ```
   postgres=> SELECT * FROM 
         rds_tools.role_password_encryption_type();
   ```

   您會看到類似下列的輸出。

   ```
          rolname        | encryption_type
   ----------------------+-----------------
    pg_monitor           |
    pg_read_all_settings |
    pg_read_all_stats    |
    pg_stat_scan_tables  |
    pg_signal_backend    |
    lab_tester           | md5
    user_465             | md5
    postgres             | md5
   (8 rows)
   ```

### 建立自訂資料庫參數群組
<a name="PostgreSQL_Password_Encryption_configuration.custom-parameter-group"></a>

**注意**  
如果您的 RDS for PostgreSQL 資料庫執行個體已使用自訂參數群組，則不需要建立新的群組。

如需 Amazon RDS 的參數群組概觀，請參閱 [在 RDS for PostgreSQL 資料庫執行個體上搭配使用參數](Appendix.PostgreSQL.CommonDBATasks.Parameters.md)。

用於密碼的密碼加密類型是在某一個參數 (亦即 `password_encryption`) 中設定的。RDS for PostgreSQL 資料庫執行個體允許的加密則是在另一個參數 (亦即 `rds.accepted_password_auth_method`) 中設定的。若要從這些預設值變更，則需要您建立自訂資料庫參數群組，並套用到您的執行個體。

您也可以使用 AWS 管理主控台 或 RDS API 來建立自訂資料庫參數群組。如需詳細資訊，請參閱 

您可以使用資料庫執行個體與自訂參數群組建立關聯。

**建立自訂資料庫參數群組**

1. 使用 CLI `[create-db-parameter-group](https://docs.aws.amazon.com/cli/latest/reference/rds/create-db-parameter-group.html) ` 命令建立自訂資料庫參數群組。此範例使用 `postgres13` 作為此自訂參數群組的來源。

   對於 Linux、macOS 或 Unix：

   ```
   aws rds create-db-parameter-group --db-parameter-group-name 'docs-lab-scram-passwords' \
     --db-parameter-group-family postgres13  --description 'Custom parameter group for SCRAM'
   ```

   在 Windows 中：

   ```
   aws rds create-db-parameter-group --db-parameter-group-name "docs-lab-scram-passwords" ^
     --db-parameter-group-family postgres13  --description "Custom DB parameter group for SCRAM"
   ```

1. 使用 `[modify-db-instance](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-instance.html)` CLI 命令將此自訂參數群組套用至您的 RDS for PostgreSQL 資料庫叢集。

   對於 Linux、macOS 或 Unix：

   ```
   aws rds modify-db-instance --db-instance-identifier 'your-instance-name' \
           --db-parameter-group-name "docs-lab-scram-passwords
   ```

   在 Windows 中：

   ```
   aws rds modify-db-instance --db-instance-identifier "your-instance-name" ^
           --db-parameter-group-name "docs-lab-scram-passwords
   ```

   若要將 RDS for PostgreSQL 資料庫執行個體與自訂資料庫參數群組重新同步，您需要重新啟動叢集的主要與所有其他執行個體。為了盡量降低對使用者的影響，排程在一般維護時段期間進行此操作。

### 設定密碼加密以使用 SCRAM
<a name="PostgreSQL_Password_Encryption_configuration.configure-password-encryption"></a>

 RDS for PostgreSQL 資料庫執行個體使用的密碼加密機制是在資料庫參數群組的 `password_encryption` 參數中設定的。允許的值為未設定、`md5` 或 `scram-sha-256`。預設值視 RDS for PostgreSQL 版本而定，如下所示：
+ RDS for PostgreSQL 14 和更新版本 - 預設值是 `scram-sha-256`
+ RDS for PostgreSQL 13 – 預設值是 `md5`

透過將自訂資料庫參數群組連接至 RDS for PostgreSQL 資料庫執行個體，您可以修改密碼加密參數的值。

![\[接著，RDS 主控台顯示 RDS for PostgreSQL 其 password_encryption 參數的預設值。\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/images/rpg-pwd-encryption-md5-scram-1.png)


**將密碼加密設定變更為 scram-sha-256**
+ 將密碼加密的值變更為 scram-sha-256，如下所示。變更會立即套用，因為參數是動態的，因此不需要重新啟動即可使變更生效。

  對於 Linux、macOS 或 Unix：

  ```
  aws rds modify-db-parameter-group --db-parameter-group-name \
    'docs-lab-scram-passwords' --parameters 'ParameterName=password_encryption,ParameterValue=scram-sha-256,ApplyMethod=immediate'
  ```

  在 Windows 中：

  ```
  aws rds modify-db-parameter-group --db-parameter-group-name ^
    "docs-lab-scram-passwords" --parameters "ParameterName=password_encryption,ParameterValue=scram-sha-256,ApplyMethod=immediate"
  ```

### 將使用者角色的密碼遷移至 SCRAM
<a name="PostgreSQL_Password_Encryption_configuration.migrating-users"></a>

您可以將使用者角色的密碼遷移至 SCRAM，如下說明：

**將資料庫使用者 (角色) 密碼從 MD5 遷移至 SCRAM**

1. 以管理員使用者身分 (預設使用者名稱 `postgres`) 登入，如下所示。

   ```
   psql --host=db-name.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password
   ```

1. 使用下列命令檢查 RDS for PostgreSQL 資料庫執行個體上 `password_encryption` 參數的設定。

   ```
   postgres=> SHOW password_encryption;
    password_encryption
   ---------------------
    md5
    (1 row)
   ```

1. 將此參數的值變更為 scram-sha-256。如需詳細資訊，請參閱[設定密碼加密以使用 SCRAM](#PostgreSQL_Password_Encryption_configuration.configure-password-encryption)。

1.  再次檢查該值以確定它現在已設定為 `scram-sha-256`，如下所示。

   ```
   postgres=> SHOW password_encryption;
    password_encryption
   ---------------------
    scram-sha-256
    (1 row)
   ```

1. 通知所有資料庫使用者變更自己的密碼。務必亦為帳戶 `postgres` (具有 `rds_superuser` 權限的資料庫使用者) 變更您自己的密碼。

   ```
   labdb=> ALTER ROLE postgres WITH LOGIN PASSWORD 'change_me';
   ALTER ROLE
   ```

1. 對 上所有的資料庫重複此程序。RDS for PostgreSQL 資料庫執行個體。

### 變更參數為需要 SCRAM
<a name="PostgreSQL_Password_Encryption_configuration.require-scram"></a>

這是程序中的最後一個步驟。在以下程序中進行變更後，仍然使用 `md5` 將密碼加密的任何使用者帳戶 (角色) 將無法登入 RDS for PostgreSQL 資料庫執行個體。

`rds.accepted_password_auth_method` 指定 RDS for PostgreSQL 資料庫執行個體在登入程序期間接受的使用者密碼加密方法。預設值為 `md5+scram`，這意味著任何一種方法都接受。在下圖中，您可以找到此參數的預設設定。

![\[顯示 rds.accepted_password_auth_method 參數其預設值與允許值的 RDS 主控台。\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/images/pwd-encryption-md5-scram-2.png)


此參數的允許值為 `md5+scram` 或僅 `scram`。將此參數值變更為 `scram` 會使此成為一個需求。

**將參數值變更為需要對密碼進行 SCRAM 身分驗證**

1. 確認 RDS for PostgreSQL 資料庫執行個體上所有資料庫的所有資料庫使用者密碼使用 `scram-sha-256` 進行密碼加密。若要這麼做，請向 `rds_tools` 查詢角色 (使用者) 和加密類型，如下所示。

   ```
   postgres=> SELECT * FROM rds_tools.role_password_encryption_type();
     rolname        | encryption_type
     ----------------------+-----------------
     pg_monitor           |
     pg_read_all_settings |
     pg_read_all_stats    |
     pg_stat_scan_tables  |
     pg_signal_backend    |
     lab_tester           | scram-sha-256
     user_465             | scram-sha-256
     postgres             | scram-sha-256
     ( rows)
   ```

1. 針對您的 中所有的資料庫執行個體重複此查詢。RDS for PostgreSQL 資料庫執行個體。

   如果所有密碼都使用 scram-sha-256，您可以繼續進行。

1. 將接受的密碼身分驗證值變更為 scram-sha-256，如下所示。

   對於 Linux、macOS 或 Unix：

   ```
   aws rds modify-db-parameter-group --db-parameter-group-name 'docs-lab-scram-passwords' \
     --parameters 'ParameterName=rds.accepted_password_auth_method,ParameterValue=scram,ApplyMethod=immediate'
   ```

   在 Windows 中：

   ```
   aws rds modify-db-parameter-group --db-parameter-group-name "docs-lab-scram-passwords" ^
     --parameters "ParameterName=rds.accepted_password_auth_method,ParameterValue=scram,ApplyMethod=immediate"
   ```

# PostgreSQL 中的無效連線處理
<a name="Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling"></a>

即使用戶端應用程式異常捨棄或終止，資料庫工作階段仍在伺服器上保持作用中狀態時，就會發生無效連線。當用戶端處理當機或意外終止，且未正確關閉其資料庫連線或取消持續請求時，通常會發生這種情況。

當伺服器程序閒置或嘗試將資料傳送至用戶端時，PostgreSQL 可有效識別和清除無效連線。不過，對於閒置、等待用戶端輸入或主動執行查詢的工作階段而言，偵測具有挑戰性。為了處理這些案例，PostgreSQL 提供 `tcp_keepalives_*`、`tcp_user_timeout` 和 `client_connection_check_interval` 參數。

**Topics**
+ [了解 TCP 保持連線](#Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.Understanding)
+ [RDS for PostgreSQL 中的金鑰 TCP 保持連線參數](#Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.Parameters)
+ [TCP 保持連線設定的使用案例](#Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.UseCases)
+ [最佳實務](#Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.BestPractices)

## 了解 TCP 保持連線
<a name="Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.Understanding"></a>

TCP 保持連線是一種通訊協定層級機制，可協助維護和確認連線完整性。每個 TCP 連線都會維護控制保持連線行為的核心層級設定。當保持連線計時器過期時，系統會執行下列動作：
+ 傳送未設定資料和 ACK 旗標的探查封包。
+ 根據 TCP/IP 規格，預期來自遠端端點的回應。
+ 根據回應或缺乏回應來管理連線狀態。

## RDS for PostgreSQL 中的金鑰 TCP 保持連線參數
<a name="Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.Parameters"></a>


| 參數 | Description | 預設值 | 
| --- |--- |--- |
| tcp\$1keepalives\$1idle | Specifies number of seconds of inactivity before sending keepalive message. | 300 | 
| tcp\$1keepalives\$1interval | Specifies number of seconds between retransmissions of unacknowledged keepalive messages. | 30 | 
| tcp\$1keepalives\$1count | Maximum lost keepalive messages before declaring connection dead | 2 | 
| tcp\$1user\$1timeout | Specifies how long (in Milliseconds) unacknowledged data can remain before forcibly closing the connection. | 0 | 
| client\$1connection\$1check\$1interval | Sets the interval (in Milliseconds) for checking client connection status during long-running queries. This ensures quicker detection of closed connections. | 0 | 

## TCP 保持連線設定的使用案例
<a name="Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.UseCases"></a>

### 保持閒置工作階段持續運作
<a name="Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.UseCases.KeepingAlive"></a>

若要防止防火牆或路由器因閒置而終止閒置連線：
+ 設定 `tcp_keepalives_idle` 以定期傳送保持連線封包。

### 偵測無效連線
<a name="Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.UseCases.DetectingDead"></a>

若要立即偵測無效連線：
+ 調整 `tcp_keepalives_idle`、`tcp_keepalives_interval` 和 `tcp_keepalives_count`。例如，使用 Aurora PostgreSQL 預設值時，偵測無效連線大約需要一分鐘 (2 次探查 × 30 秒）。降低這些值可以加快偵測速度。
+ 使用 `tcp_user_timeout` 指定確認的最長等待時間。

TCP 保持連線設定可協助核心偵測無效連線，但在使用通訊端之前，PostgreSQL 可能不會運作。如果工作階段執行長查詢，只有在查詢完成後才會偵測到無效連線。在 PostgreSQL 14 和更高版本中，`client_connection_check_interval` 可以在查詢執行期間定期輪詢通訊端，以加速無效連線偵測。

## 最佳實務
<a name="Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.BestPractices"></a>
+ **設定合理的保持連線間隔：**調校 `tcp_user_timeout`、`tcp_keepalives_idle`、`tcp_keepalives_count` 和 `tcp_keepalives_interval`，以平衡偵測速度和資源使用。
+ **為您的環境最佳化：**使設定與網路行為、防火牆政策和工作階段需求保持一致。
+ **利用 PostgreSQL 功能：**在 PostgreSQL 14 和更高版本中使用 `client_connection_check_interval`，以進行有效的連線檢查。

# 在 Amazon RDS for PostgreSQL 上使用 PostgreSQL 自動清空
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum"></a>

強烈建議您使用自動資料清理功能，以維護 PostgreSQL 資料庫執行個體的運作狀態。自動資料清理會自動啟動 VACUUM 和 ANALYZE 指令。此功能會檢查含有大量輸入、更新或刪除元組的資料表。完成檢查後，即會透過從 PostgreSQL 資料庫移除已淘汰的資料或元組回收儲存空間。

預設情況下，使用任何預設 PostgreSQL 資料庫參數群組建立的 RDS for PostgreSQL 資料庫執行個體上，都開啟了自動清空功能。預設情況下，還會設定與自動資料清理功能相關聯的其他組態參數。因為這些預設值相當泛用，針對特定的工作負載調校與自動資料清理功能相關聯的某些參數，對您會有所幫助。

接下來，您可以找到更多有關自動清空功能以及如何在您的 RDS for PostgreSQL 資料庫執行個體上調校該功能一些參數的資訊。如需高階資訊，請參閱 [使用 PostgreSQL 的最佳實務](CHAP_BestPractices.md#CHAP_BestPractices.PostgreSQL)。

**Topics**
+ [配置自動資料清理的記憶體](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum.WorkMemory)
+ [降低交易 ID 包圍的可能性](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AdaptiveAutoVacuuming)
+ [判斷資料庫中的資料表是否需要清理](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.NeedVacuuming.md)
+ [判斷哪些資料表目前適合進行自動資料清理](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.EligibleTables.md)
+ [判斷自動資料清理目前是否執行中且執行多久時間](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AutovacuumRunning.md)
+ [執行手動清理凍結](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.VacuumFreeze.md)
+ [在自動資料清理執行時重新為資料表建立索引](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.Reindexing.md)
+ [使用大型索引管理自動清空](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.LargeIndexes.md)
+ [影響自動資料清理的其他參數](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.OtherParms.md)
+ [設定自動資料清理參數資料表層級](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.TableParameters.md)
+ [記錄清理和自動資料清理活動](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.Logging.md)
+ [了解具有無效資料庫的自動清空行為](appendix.postgresql.commondbatasks.autovacuumbehavior.md)
+ [在 RDS for PostgreSQL 中識別並解決積極的清空封鎖程式](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.md)

## 配置自動資料清理的記憶體
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.WorkMemory"></a>

[https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-AUTOVACUUM-WORK-MEM](https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-AUTOVACUUM-WORK-MEM) 參數是影響自動資料清理效能的最重要參數之一。在 RDS for PostgreSQL 第 14 版及更舊版本中，`autovacuum_work_mem` 參數會設定為 -1，表示改用 `maintenance_work_mem` 的設定。對於所有其他版本，`autovacuum_work_mem` 是由 GREATEST(\$1DBInstanceClassMemory/32768\$1, 65536) 決定。

手動清空操作一律會使用 `maintenance_work_mem` 設定，預設設定為 GREATEST(\$1DBInstanceClassMemory/63963136\$11024\$1, 65536)，也可以使用 `SET` 命令在工作階段層級進行調整，以進行更精準的手動 `VACUUM` 操作。

`autovacuum_work_mem` 會決定自動清空的記憶體，以保留無效元組 (`pg_stat_all_tables.n_dead_tup`) 的識別符來清空索引。

執行計算以判斷 `autovacuum_work_mem` 參數的值時，請注意下列事項：
+ 如果您將參數設得太低，則清理程序可能必須掃描資料表多次才能完成其工作。多次的掃描可能會對效能產生負面影響。對於較大的執行個體，將 `maintenance_work_mem`或 `autovacuum_work_mem` 設定為至少 1 GB 可以改善清空具有大量無效元組之資料表的效能。不過，在 PostgreSQL 第 16 版和之前版本中，清空的記憶體用量上限為 1 GB，這足以在單次通過中處理大約 1.79 億個無效元組。如果資料表的無效元組超過此值，清空將需要多次通過資料表的索引，大幅增加所需的時間。從 PostgreSQL 第 17 版開始，沒有 1 GB 的限制，而自動清空可以透過使用基數樹來處理超過 1.79 億個元組。

  元組識別符的大小為 6 個位元組。若要預估清空資料表索引所需的記憶體，請查詢 `pg_stat_all_tables.n_dead_tup` 以尋找無效元組的數量，然後將此數字乘以 6，以判斷在單次通過中清空索引所需的記憶體。您可以使用下列查詢：

  ```
  SELECT
      relname AS table_name,
      n_dead_tup,
      pg_size_pretty(n_dead_tup * 6) AS estimated_memory
  FROM
      pg_stat_all_tables
  WHERE
      relname = 'name_of_the_table';
  ```
+ `autovacuum_work_mem` 參數會搭配 `autovacuum_max_workers` 參數運作。`autovacuum_max_workers` 中的每個背景工作者可以使用您配置的記憶體。如果您有許多小型資料表，請配置較多 `autovacuum_max_workers` 和較少 `autovacuum_work_mem`。如果您有大型資料表 (大於 100 GB)，請配置較多記憶體和較少背景工作者處理程序。您必須配置足夠的記憶體，才能在最大的資料表上順利執行作業。因此，請確保背景工作者處理程序與記憶體的組合等於您想要配置的總記憶體。

## 降低交易 ID 包圍的可能性
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AdaptiveAutoVacuuming"></a>

在一些狀況中，自動資料清理相關的參數群組設定可能不夠積極以防止交易 ID 包圍。為了解決此問題，RDS for PostgreSQL 提供自動調整自動清空參數值的機制。*自動清空參數彈性調整*是 RDS for PostgreSQL 的孤能。PostgreSQL 文件中有詳細的 [交易 ID 包圍](https://www.postgresql.org/docs/current/static/routine-vacuuming.html#VACUUM-FOR-WRAPAROUND) 的說明。

預設開啟 RDS for PostgreSQL 執行個體的自動清空參數彈性調整功能，且動態參數 `rds.adaptive_autovacuum` 設定為 [開啟]。我們強烈建議您開啟此選項。不過，若要關閉參數彈性調校功能，請將參數 `rds.adaptive_autovacuum` 設定為 0 或 OFF (關閉)。

Amazon RDS 調校自動清空參數時，交易 ID 包圍仍可能發生。我們鼓勵您實施交易 ID 包圍的Amazon CloudWatch 警報。如需詳細資訊，請參閱 AWS 資料庫部落格上的文章在 [RDS for PostgreSQL 中實作交易 ID 包裝的提早警告系統](https://aws.amazon.com/blogs/database/implement-an-early-warning-system-for-transaction-id-wraparound-in-amazon-rds-for-postgresql/)。

若開啟自動資料清理參數彈性調校，當 CloudWatch 指標 `MaximumUsedTransactionIDs` 達到 `autovacuum_freeze_max_age` 參數的值或 500,000,000 時 (以較大者為準)，Amazon RDS 將開始調整自動資料清理參數。

如果資料表繼續有交易 ID 包圍的趨勢，則 Amazon RDS 會繼續調整自動資料清理的參數。每次調整都提供更多自動資料清理的資源以避免包圍。Amazon RDS 會更新下列自動資料清理相關參數：
+ [autovacuum\$1vacuum\$1cost\$1delay](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-DELAY)
+ [ autovacuum\$1vacuum\$1cost\$1limit](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-LIMIT)
+  [https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-AUTOVACUUM-WORK-MEM](https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-AUTOVACUUM-WORK-MEM) 
+  [autovacuum\$1naptime](https://www.postgresql.org/docs/current/runtime-config-autovacuum.html#GUC-AUTOVACUUM-NAPTIME) 

RDS 只會在新的值能夠使自動資料清理更為積極時修改這些參數。參數在資料庫執行個體上的記憶體中修改。參數群組中的值不會變更。若要檢視目前的使用中記憶體設定，請使用 PostgreSQL [SHOW (顯示)](https://www.postgresql.org/docs/current/sql-show.html) SQL 指令。

當 Amazon RDS 修改任何自動資料清理參數時，即會對受影響的資料庫執行個體產生事件。此事件會顯示在 上， AWS 管理主控台 並透過 Amazon RDS API 顯示。`MaximumUsedTransactionIDs` CloudWatch 指標回到閥值以下時，Amazon RDS 就會將記憶體中的自動資料清理參數重設回參數群組中指定的值。系統隨即會產生與此變更相對應的另一個事件。

# 判斷資料庫中的資料表是否需要清理
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.NeedVacuuming"></a>

您可以使用以下查詢可用來顯示資料庫中未凍結的交易數目。資料庫 `datfrozenxid` 列的 `pg_database` 欄是顯示於該資料庫正常交易 ID 的下線。此欄位是資料庫內每個資料表 `relfrozenxid` 最小的值。

```
SELECT datname, age(datfrozenxid) FROM pg_database ORDER BY age(datfrozenxid) desc limit 20;
```

例如，執行上述查詢的結果可能如下所示。

```
datname    | age
mydb       | 1771757888
template0  | 1721757888
template1  | 1721757888
rdsadmin   | 1694008527
postgres   | 1693881061
(5 rows)
```

當交易 ID 包圍的存留期觸及 20 億，則會發生交易 ID 包圍 (XID)，且資料庫將變成唯獨狀態。您可使用此查詢來產生指標且一天執行數次。根據預設，自動資料清理已將交易的存留期設定為不超過 200,000,000 ([https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-FREEZE-MAX-AGE](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-FREEZE-MAX-AGE))。

範例監視策略可能如下所示：
+ 設定 `autovacuum_freeze_max_age` 值到 2 億交易數目
+ 如果資料表達到 5 億的未凍結交易，則觸發低安全性警報。這並非不合理的值，但可以表示該自動資料清理並未保持啟動狀態。
+ 如果資料表存留達到 10 億，這應視為採取動作的警報。一般而言，您會基於效能理由，而想讓存留期比較接近 `autovacuum_freeze_max_age`。我們建議您使用下列建議調查。
+ 如果資料表達到 15 億的未清理交易，則觸發高安全性警報。視資料庫使用交易的速度而定，此警報可指出系統來不及執行自動資料清理。在此情況下，我們建議您立即解決此問題。

如果資料表不斷違反這些閾值，請進一步修改自動資料清理參數。依預設，手動使用 VACUUM (已停用或以成本為基礎的延遲) 比使用預設自動資料清理更積極，但總體上對系統的干擾也更加嚴重。

我們建議下列作法：
+ 請注意並開啟監控機制，如此您才會注意最舊交易的存留期。

  如需建立程序以警告您交易 ID 包裝的相關資訊，請參閱 AWS 資料庫部落格文章在 [Amazon RDS for PostgreSQL 中實作交易 ID 包裝的早期警告系統](https://aws.amazon.com/blogs/database/implement-an-early-warning-system-for-transaction-id-wraparound-in-amazon-rds-for-postgresql/)。
+ 對於比較忙碌的資料表，除了依賴自動資料清理以外，請在維護時段定期執行手動清理凍結。如需執行手動清理凍結的資訊，請參閱 [執行手動清理凍結](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.VacuumFreeze.md)。

# 判斷哪些資料表目前適合進行自動資料清理
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.EligibleTables"></a>

通常有一或兩個資料表需要清理。表單中 `relfrozenxid` 的值大於 `autovacuum_freeze_max_age` 中交易的值，總是會成為自動資料清理的目標。否則，如果元組數因為最後一個 VACUUM 超出清理閾值而過時，則會清理資料表。

[自動資料清理閾值](https://www.postgresql.org/docs/current/static/routine-vacuuming.html#AUTOVACUUM)已定義如下：

```
Vacuum-threshold = vacuum-base-threshold + vacuum-scale-factor * number-of-tuples
```

其中 `vacuum base threshold`是 `autovacuum_vacuum_threshold`，`vacuum scale factor`是 `autovacuum_vacuum_scale_factor`，而 `number of tuples`是 `pg_class.reltuples`。

當您連線到資料庫時，執行以下查詢可查看自動資料清理功能認為符合清理條件的資料表清單。

```
WITH vbt AS (SELECT setting AS autovacuum_vacuum_threshold FROM 
pg_settings WHERE name = 'autovacuum_vacuum_threshold'),
vsf AS (SELECT setting AS autovacuum_vacuum_scale_factor FROM 
pg_settings WHERE name = 'autovacuum_vacuum_scale_factor'), 
fma AS (SELECT setting AS autovacuum_freeze_max_age FROM pg_settings WHERE name = 'autovacuum_freeze_max_age'),
sto AS (select opt_oid, split_part(setting, '=', 1) as param,
split_part(setting, '=', 2) as value from (select oid opt_oid, unnest(reloptions) setting from pg_class) opt)
SELECT '"'||ns.nspname||'"."'||c.relname||'"' as relation,
pg_size_pretty(pg_table_size(c.oid)) as table_size,
age(relfrozenxid) as xid_age,
coalesce(cfma.value::float, autovacuum_freeze_max_age::float) autovacuum_freeze_max_age,
(coalesce(cvbt.value::float, autovacuum_vacuum_threshold::float) +
coalesce(cvsf.value::float,autovacuum_vacuum_scale_factor::float) * c.reltuples)
AS autovacuum_vacuum_tuples, n_dead_tup as dead_tuples FROM
pg_class c join pg_namespace ns on ns.oid = c.relnamespace 
join pg_stat_all_tables stat on stat.relid = c.oid join vbt on (1=1) join vsf on (1=1) join fma on (1=1)
left join sto cvbt on cvbt.param = 'autovacuum_vacuum_threshold' and c.oid = cvbt.opt_oid 
left join sto cvsf on cvsf.param = 'autovacuum_vacuum_scale_factor' and c.oid = cvsf.opt_oid
left join sto cfma on cfma.param = 'autovacuum_freeze_max_age' and c.oid = cfma.opt_oid
WHERE c.relkind = 'r' and nspname <> 'pg_catalog'
AND (age(relfrozenxid) >= coalesce(cfma.value::float, autovacuum_freeze_max_age::float)
OR coalesce(cvbt.value::float, autovacuum_vacuum_threshold::float) + 
coalesce(cvsf.value::float,autovacuum_vacuum_scale_factor::float) * 
c.reltuples <= n_dead_tup)
ORDER BY age(relfrozenxid) DESC LIMIT 50;
```

# 判斷自動資料清理目前是否執行中且執行多久時間
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AutovacuumRunning"></a>

如果您需要手動清理資料表，請判斷目前是否在執行自動資料清理功能。若是，您可能需要調整參數，使其更有效率地執行，或暫時關閉自動資料清理功能，以便您手動執行 VACUUM。

使用以下查詢來判斷自動資料清理是否執行中、已執行多久時間，以及是否正等待另一個工作階段。

```
SELECT datname, usename, pid, state, wait_event, current_timestamp - xact_start AS xact_runtime, query
FROM pg_stat_activity 
WHERE upper(query) LIKE '%VACUUM%' 
ORDER BY xact_start;
```

在執行此查詢之後，您應會看到類似底下的輸出：

```
 datname | usename  |  pid  | state  | wait_event |      xact_runtime       | query  
 --------+----------+-------+--------+------------+-------------------------+--------------------------------------------------------------------------------------------------------
 mydb    | rdsadmin | 16473 | active |            | 33 days 16:32:11.600656 | autovacuum: VACUUM ANALYZE public.mytable1 (to prevent wraparound)
 mydb    | rdsadmin | 22553 | active |            | 14 days 09:15:34.073141 | autovacuum: VACUUM ANALYZE public.mytable2 (to prevent wraparound)
 mydb    | rdsadmin | 41909 | active |            | 3 days 02:43:54.203349  | autovacuum: VACUUM ANALYZE public.mytable3
 mydb    | rdsadmin |   618 | active |            | 00:00:00                | SELECT datname, usename, pid, state, wait_event, current_timestamp - xact_start AS xact_runtime, query+
         |          |       |        |            |                         | FROM pg_stat_activity                                                                                 +
         |          |       |        |            |                         | WHERE query like '%VACUUM%'                                                                           +
         |          |       |        |            |                         | ORDER BY xact_start;                                                                                  +
```

有幾個問題可能造成長時間執行自動資料清理階段 (長達數天)。最常見的問題就是資料表大小或更新率的 [https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM) 參數值設得太低。

建議您依照下列公式來設定 `maintenance_work_mem` 參數值。

```
GREATEST({DBInstanceClassMemory/63963136*1024},65536)
```

短時間執行的自動資料清理工作階段也可以指出問題：
+ 它可指出您的工作負載沒有足夠的 `autovacuum_max_workers`。在此情況下，您需要指出工作者數目。
+ 它可指出有索引損毀 (自動資料清理會當機並以相同的關聯重新啟動，但沒有任何進度)。在這種情況下，請手動執行 `vacuum freeze verbose table` 來查看確切原因。

# 執行手動清理凍結
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.VacuumFreeze"></a>

您可以在清理程序已在執行中的資料表上執行手動清理。如果您已辨識出表單的交易將近 20 億 (或超出您所監控的任何閾值) 的資料表，此功能將很實用。

下列步驟是準則，而程序會有多種變化。例如，在測試期間，假設您會發現 [https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM) 參數值設定的太小而您需要對資料表採取立即行動。不過，或許您當下不想退回執行個體。使用上個區段所列的查詢，您可判斷哪個資料表有問題，並注意長時間執行的自動資料清理工作階段。您知道您必須變更 `maintenance_work_mem` 參數設定，但您也需要採取立即動作並清理有問題的資料表。以下程序說明在此情況下的處理方式。

**手動執行清理凍結**

1. 對包含要清理之資料表的資料庫，開啟兩個工作階段。在第二個工作階段中，如果連線中斷，請使用 "screen" 或其他公用程式來維持此工作階段。

1. 在第一個工作階段中，取得在資料表上執行之自動資料清理工作階段的處理程序 ID (PID)。

   執行以下查詢來取得自動資料清理工作階段的 PID。

   ```
   SELECT datname, usename, pid, current_timestamp - xact_start 
   AS xact_runtime, query
   FROM pg_stat_activity WHERE upper(query) LIKE '%VACUUM%' ORDER BY 
   xact_start;
   ```

1. 在第二個工作階段中，計算您需要用於此作業的記憶體數量。在此範例中，我們判斷我們可以將最多 2 GB 的記憶體使用於此作業，所以將目前工作階段的 [https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM) 設定為 2 GB。

   ```
   SET maintenance_work_mem='2 GB';
   SET
   ```

1. 在第二個工作階段中，對表格發佈 `vacuum freeze verbose` 指令。詳細資訊設定很實用，因為即使 PostgreSQL 中目前沒有此工作階段的進度報告，您仍可查看活動。

   ```
   \timing on
   Timing is on.
   vacuum freeze verbose pgbench_branches;
   ```

   ```
   INFO:  vacuuming "public.pgbench_branches"
   INFO:  index "pgbench_branches_pkey" now contains 50 row versions in 2 pages
   DETAIL:  0 index row versions were removed.
   0 index pages have been deleted, 0 are currently reusable.
   CPU 0.00s/0.00u sec elapsed 0.00 sec.
   INFO:  index "pgbench_branches_test_index" now contains 50 row versions in 2 pages
   DETAIL:  0 index row versions were removed.
   0 index pages have been deleted, 0 are currently reusable.
   CPU 0.00s/0.00u sec elapsed 0.00 sec.
   INFO:  "pgbench_branches": found 0 removable, 50 nonremovable row versions 
        in 43 out of 43 pages
   DETAIL:  0 dead row versions cannot be removed yet.
   There were 9347 unused item pointers.
   0 pages are entirely empty.
   CPU 0.00s/0.00u sec elapsed 0.00 sec.
   VACUUM
   Time: 2.765 ms
   ```

1. 在第一個工作階段，如果自動清空封鎖清空工作階段，`pg_stat_activity` 會顯示清空工作階段的等待為 `T`。在此情況下，請按如下方式結束自動清空程序。

   ```
   SELECT pg_terminate_backend('the_pid'); 
   ```
**注意**  
某些較低版本的 Amazon RDS 無法使用上述命令終止自動清空程序，並失敗並顯示下列錯誤：`ERROR: 42501: must be a superuser to terminate superuser process LOCATION: pg_terminate_backend, signalfuncs.c:227`。

   此時，您的工作階段會開始。自動清空會立即重新啟動，因為此資料表可能排在其工作清單的最前面。

1. 在第二個工作階段中啟動您的 `vacuum freeze verbose` 命令，然後在第一個工作階段中結束自動資料清理程序。

# 在自動資料清理執行時重新為資料表建立索引
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.Reindexing"></a>

如果索引毀損，自動資料清理會繼續處理資料表並且失敗。如果您在此情況下嘗試手動清理，則會收到如下錯誤訊息。

```
postgres=>  vacuum freeze pgbench_branches;
ERROR: index "pgbench_branches_test_index" contains unexpected 
   zero page at block 30521
HINT: Please REINDEX it.
```

當索引毀損且自動資料清理嘗試在資料表上執行時，您全力應付已在執行中的自動資料清理工作階段。當您發佈 [REINDEX](https://www.postgresql.org/docs/current/static/sql-reindex.html) 指令，您開啟表單上的獨佔鎖定。寫入操作遭到封鎖，也使用特定索引讀取操作。

**在資料表上執行自動資料清理時重新為資料表建立索引**

1. 對包含要清理之資料表的資料庫，開啟兩個工作階段。在第二個工作階段中，如果連線中斷，請使用 "screen" 或其他公用程式來維持此工作階段。

1. 在第一個工作階段中，取得在資料表上執行之自動資料清理工作階段的 PID。

   執行以下查詢來取得自動資料清理工作階段的 PID。

   ```
   SELECT datname, usename, pid, current_timestamp - xact_start 
   AS xact_runtime, query
   FROM pg_stat_activity WHERE upper(query) like '%VACUUM%' ORDER BY 
   xact_start;
   ```

1. 在第二個工作階段中，發出 reindex 命令。

   ```
   \timing on
   Timing is on.
   reindex index pgbench_branches_test_index;
   REINDEX
     Time: 9.966 ms
   ```

1. 在第一個工作階段中，如果自動資料清理封鎖處理程序，您會在 `pg_stat_activity` 中看見清理工作階段的等待為 "T"。在此情況下，您就結束自動資料清理程序。

   ```
   SELECT pg_terminate_backend('the_pid');
   ```

   此時，您的工作階段會開始。請特別注意，自動資料清理會立即重新啟動，因為此資料表可能排在其工作清單的最前面。

1. 在第二個工作階段中啟動您的命令，然後在第一個工作階段中結束自動資料清理程序。

# 使用大型索引管理自動清空
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.LargeIndexes"></a>

作為其操作的一部分，*自動清空*會在資料表上執行時執行數個[清空階段](https://www.postgresql.org/docs/current/progress-reporting.html#VACUUM-PHASES)。在清除資料表之前，首先會清空其所有索引。移除多個大型索引時，此階段會耗用大量的時間和資源。因此，最佳實務是務必控制資料表上的索引數目，並清除未使用的索引。

在此程序中，首先檢查整體索引大小。然後，判斷是否有可以移除的潛在未用索引，如下列範例所示。

**檢查資料表及其索引的大小**

```
postgres=> select pg_size_pretty(pg_relation_size('pgbench_accounts'));
pg_size_pretty
6404 MB
(1 row)
```

```
postgres=> select pg_size_pretty(pg_indexes_size('pgbench_accounts'));
pg_size_pretty
11 GB
(1 row)
```

在此範例中，索引的大小大於資料表。這種差異可能會導致性能問題，因為索引膨脹或未使用，這會影響自動清空以及插入操作。

**檢查是否有未使用的索引**

使用 [https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-ALL-INDEXES-VIEW](https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-ALL-INDEXES-VIEW) 檢視，您可以檢查索引與 `idx_scan` 資料欄搭配使用的頻率。在下列範例中，未使用的索引的 `idx_scan` 值為 `0`。

```
postgres=> select * from pg_stat_user_indexes where relname = 'pgbench_accounts' order by idx_scan desc;
    
relid  | indexrelid | schemaname | relname          | indexrelname          | idx_scan | idx_tup_read | idx_tup_fetch
-------+------------+------------+------------------+-----------------------+----------+--------------+---------------
16433  | 16454      | public     | pgbench_accounts | index_f               | 6        | 6            | 0
16433  | 16450      | public     | pgbench_accounts | index_b               | 3        | 199999       | 0
16433  | 16447      | public     | pgbench_accounts | pgbench_accounts_pkey | 0        | 0            | 0
16433  | 16452      | public     | pgbench_accounts | index_d               | 0        | 0            | 0
16433  | 16453      | public     | pgbench_accounts | index_e               | 0        | 0            | 0
16433  | 16451      | public     | pgbench_accounts | index_c               | 0        | 0            | 0
16433  | 16449      | public     | pgbench_accounts | index_a               | 0        | 0            | 0
(7 rows)
```

```
postgres=> select schemaname, relname, indexrelname, idx_scan from pg_stat_user_indexes where relname = 'pgbench_accounts' order by idx_scan desc;
    
schemaname  | relname          | indexrelname          | idx_scan
------------+------------------+-----------------------+----------
public      | pgbench_accounts | index_f               | 6
public      | pgbench_accounts | index_b               | 3
public      | pgbench_accounts | pgbench_accounts_pkey | 0
public      | pgbench_accounts | index_d               | 0
public      | pgbench_accounts | index_e               | 0
public      | pgbench_accounts | index_c               | 0
public      | pgbench_accounts | index_a               | 0
(7 rows)
```

**注意**  
這些統計資訊是從統計資訊重設時開始累計的。假設您有僅在營業季度結束時使用的索引，或僅用於特定報告的索引。自統計資訊重設以來，可能尚未使用此索引。如需詳細資訊，請參閱[統計資訊函數](https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-STATS-FUNCTIONS)。用來強制執行唯一性的索引不會執行掃描，也不應將其識別為未使用的索引。若要識別未使用的索引，您應該對應用程式及其查詢有深入的理解。

若要檢查上次何時重設資料庫的統計資訊，請使用 [ https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW]( https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW)

```
postgres=> select datname, stats_reset from pg_stat_database where datname = 'postgres';
    
datname   | stats_reset
----------+-------------------------------
postgres  | 2022-11-17 08:58:11.427224+00
(1 row)
```

## 盡快清空資料表
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.LargeIndexes.Executing"></a>

**RDS for PostgreSQL 12 和更新版本**

如果大型資料表中有太多索引，您的資料庫執行個體可能接近交易 ID 包圍 (XID)，也就是當 XID 計數器包圍至零時。若保持取消核取的狀態，此情況可能會導致資料遺失。不過，您可以在不清除索引的情況下快速清空資料表。在 RDS for PostgreSQL 12 及更新版本中，您可以使用 VACUUM 搭配 [https://www.postgresql.org/docs/current/sql-vacuum.html](https://www.postgresql.org/docs/current/sql-vacuum.html) 子句。

```
postgres=> VACUUM (INDEX_CLEANUP FALSE, VERBOSE TRUE) pgbench_accounts;
        
INFO: vacuuming "public.pgbench_accounts"
INFO: table "pgbench_accounts": found 0 removable, 8 nonremovable row versions in 1 out of 819673 pages
DETAIL: 0 dead row versions cannot be removed yet, oldest xmin: 7517
Skipped 0 pages due to buffer pins, 0 frozen pages.
CPU: user: 0.01 s, system: 0.00 s, elapsed: 0.01 s.
```

如果自動清空工作階段已在執行中，您必須終止它才能開始手動 VACUUM。如需執行手動清空凍結的相關資訊，請參閱 [執行手動清理凍結](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.VacuumFreeze.md)。

**注意**  
定期略過索引清除可能會導致索引膨脹，這會降低掃描效能。索引會保留無效資料列，而資料表會保留無效資料行指標。因此，`pg_stat_all_tables.n_dead_tup` 會增加，直到自動清空或手動 VACUUM 搭配索引清除執行為止。作為最佳實務，只使用此程序來防止交易 ID 包圍。

**RDS for PostgreSQL 11 和更舊版本**

不過，在 RDS for PostgreSQL 11 和更舊版本中，允許清空更快完成的唯一方法是減少資料表上的索引數目。捨棄索引可能會影響查詢計畫。我們建議您先捨棄未使用的索引，然後在 XID 包圍非常接近時捨棄索引。在清空程序完成之後，您可以重新建立這些索引。

# 影響自動資料清理的其他參數
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.OtherParms"></a>

以下查詢顯示會直接影響自動資料清理及其行為的某些參數值。PostgreSQL 文件會完整說明[自動資料清理參數](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html)。

```
SELECT name, setting, unit, short_desc
FROM pg_settings
WHERE name IN (
'autovacuum_max_workers',
'autovacuum_analyze_scale_factor',
'autovacuum_naptime',
'autovacuum_analyze_threshold',
'autovacuum_analyze_scale_factor',
'autovacuum_vacuum_threshold',
'autovacuum_vacuum_scale_factor',
'autovacuum_vacuum_threshold',
'autovacuum_vacuum_cost_delay',
'autovacuum_vacuum_cost_limit',
'vacuum_cost_limit',
'autovacuum_freeze_max_age',
'maintenance_work_mem',
'vacuum_freeze_min_age');
```

雖然這些全都會影響自動資料清理，其中最重要的參數如下：
+ [maintenance\$1work\$1mem](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE_WORK_MEM)
+ [autovacuum\$1freeze\$1max\$1age](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-FREEZE-MAX-AGE)
+ [autovacuum\$1max\$1workers](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-MAX-WORKERS)
+ [autovacuum\$1vacuum\$1cost\$1delay](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-DELAY)
+ [ autovacuum\$1vacuum\$1cost\$1limit](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-LIMIT)

# 設定自動資料清理參數資料表層級
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.TableParameters"></a>

您可以在資料表層級設定自動資料清理相關的[儲存參數](https://www.postgresql.org/docs/current/static/sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS)，這比改變整個資料庫的行為更理想。對於大型資料表，您可能需要設定積極的設定值，而且不想讓自動資料清理以那種方式對待所有的資料表。

以下查詢顯示哪些資料表目前已備妥資料表層級選項。

```
SELECT relname, reloptions
FROM pg_class
WHERE reloptions IS NOT null;
```

在比您其餘的資料表大許多的資料表範例上，此查詢可能很實用。假設您有一個 300 GB 的表單，及 30 個少於 1 GB 的其他表單。在此情況下，您可以為大型資料表設定一些特定參數，您就不會改變整個系統的行為。

```
ALTER TABLE mytable set (autovacuum_vacuum_cost_delay=0);
```

這麼做會針對此資料表關閉成本型自動資料清理延遲，代價是在您系統上使用更多資源。通常情況下，每次達到 `autovacuum_cost_limit` 時，自動資料清理都會暫停 `autovacuum_vacuum_cost_delay`。如需詳細資訊，請參閱 PostgreSQL 文件中的[成本型清理](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-VACUUM-COST)。

# 記錄清理和自動資料清理活動
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.Logging"></a>

有關自動資料清理活動的資訊將根據 `rds.force_autovacuum_logging_level` 參數中指定的層級傳送到 `postgresql.log`。以下是此參數允許的值，以及預設為該值的 PostgreSQL 版本：
+ `disabled` (PostgreSQL 10、PostgreSQL 9.6)
+ `debug5`, `debug4`, `debug3`, `debug2`, `debug1`
+ `info` (PostgreSQL 12、PostgreSQL 11)
+ `notice`
+ `warning` (PostgreSQL 13 及以上)
+ `error`、日誌、`fatal`、`panic`

`rds.force_autovacuum_logging_level` 使用 `log_autovacuum_min_duration` 參數。`log_autovacuum_min_duration` 參數的值是記錄自動資料清理動作的閾值 (以毫秒為單位)。設定為 `-1`，表示不會記錄任何內容；設定為 0，則會記錄所有動作。如同 `rds.force_autovacuum_logging_level`，`log_autovacuum_min_duration` 的預設值取決於版本，如下所示：
+ `10000 ms`：PostgreSQL 14、PostgreSQL 13、PostgreSQL 12 和 PostgreSQL 11 
+ `(empty)`：PostgreSQL 10 和 PostgreSQL 9.6 沒有預設值

建議您將 `rds.force_autovacuum_logging_level` 設定為 `WARNING`。我們也建議您將 `log_autovacuum_min_duration` 設定為 1000 到 5000 之間的值。設定為 5000，表示會記錄時間超過 5,000 毫秒的活動。如果鎖定衝突或同時刪除關係導致跳過自動資料清理動作，-1 以外的任何設定也會記錄訊息。如需詳細資訊，請參閱 PostgreSQL 文件中的[自動資料清理](https://www.postgresql.org/docs/current/runtime-config-autovacuum.html)。

若要解決問題，您可以將 `rds.force_autovacuum_logging_level` 參數變更為其中一個除錯等級 (從 `debug1` 至 `debug5`)，以取得詳盡資訊。我們建議您在短時間內使用除錯設定，並且僅用於疑難排解目的。如需進一步了解，請參閱 PostgreSQL 文件中的[何時記錄](https://www.postgresql.org/docs/current/static/runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHEN)。

**注意**  
PostgreSQL 可讓 `rds_superuser` 帳戶檢視 `pg_stat_activity` 中的自動資料清理工作階段。例如，您可以找出並終止會阻擋命令執行的自動資料清理工作階段，或是執行速度比手動發出的清理命令還要慢的自動資料清理工作階段。

# 了解具有無效資料庫的自動清空行為
<a name="appendix.postgresql.commondbatasks.autovacuumbehavior"></a>

 系統會將新值 `-2` 引入 `pg_database` 目錄中的 `datconnlimit` 欄，以指出在 DROP DATABASE 操作中間中斷的資料庫無效。

 此新值可從下列 RDS for PostgreSQL 版本取得：
+ 15.4 版和所有更新版本
+ 14.9 和更新版本
+ 13.12 和更新版本
+ 12.16 和更新版本
+ 11.21 和更新版本

無效的資料庫不會影響自動清空凍結有效資料庫功能的能力。自動清空會忽略無效的資料庫。因此，定期清空操作將繼續對 PostgreSQL 環境中的所有有效資料庫正常運作且有效率地運作。

**Topics**
+ [監控交易 ID](#appendix.postgresql.commondbatasks.autovacuum.monitorxid)
+ [調整監控查詢](#appendix.postgresql.commondbatasks.autovacuum.monitoradjust)
+ [解決無效的資料庫問題](#appendix.postgresql.commondbatasks.autovacuum.connissue)

## 監控交易 ID
<a name="appendix.postgresql.commondbatasks.autovacuum.monitorxid"></a>

 `age(datfrozenxid)` 函數通常用於監控資料庫的交易 ID (XID) 存留期，以防止交易 ID 包圍。

 由於自動清空會排除無效的資料庫，因此其交易 ID (XID) 計數器可以達到 `2 billion` 的最大值、包裝至 `- 2 billion`，並無限期地繼續此週期。用於監控交易 ID 包圍的典型查詢可能如下所示：

```
SELECT max(age(datfrozenxid)) FROM pg_database;
```

不過，隨著引入 `datconnlimit` 的 -2 值，無效的資料庫可能會扭曲此查詢的結果。由於這些資料庫無效，且不應成為定期維護檢查的一部分，因此可能會導致誤報，造成您認為 `age(datfrozenxid)` 高於實際值。

## 調整監控查詢
<a name="appendix.postgresql.commondbatasks.autovacuum.monitoradjust"></a>

 為了確保準確的監控，您應該調整監控查詢以排除無效的資料庫。遵循以下建議的查詢：

```
SELECT
    max(age(datfrozenxid))
FROM
    pg_database
WHERE
    datconnlimit <> -2;
```

此查詢可確保 `age(datfrozenxid)` 計算中只會考慮有效的資料庫，以提供 PostgreSQL 環境中交易 ID 存留期的真實反映。

## 解決無效的資料庫問題
<a name="appendix.postgresql.commondbatasks.autovacuum.connissue"></a>

 嘗試連線至無效的資料庫時，您可能會遇到類似以下的錯誤訊息：

```
postgres=> \c db1
connection to server at "mydb.xxxxxxxxxx.us-west-2.rds.amazonaws.com" (xx.xx.xx.xxx), port xxxx failed: FATAL:  cannot connect to invalid database "db1"
HINT:  Use DROP DATABASE to drop invalid databases.
Previous connection kept
```

 此外，如果 `log_min_messages` 參數設定為 `DEBUG2` 或更高版本，您可能會注意到下列日誌項目，指出自動清空程序正在略過無效的資料庫：

```
       
2024-07-30 05:59:00 UTC::@:[32000]:DEBUG:  autovacuum: skipping invalid database "db6"
2024-07-30 05:59:00 UTC::@:[32000]:DEBUG:  autovacuum: skipping invalid database "db1"
```

若要解決問題，請遵循連線嘗試期間提供的 `HINT`。使用 RDS 主帳戶或具有 `rds_superuser` 角色的資料庫帳戶 (RDS 主帳戶) 連線到任何有效的資料庫，並捨棄無效的資料庫。

```
SELECT
    'DROP DATABASE ' || quote_ident(datname) || ';'
FROM
    pg_database
WHERE
    datconnlimit = -2 \gexec
```

# 在 RDS for PostgreSQL 中識別並解決積極的清空封鎖程式
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring"></a>

在 PostgreSQL 中，清空對於確保資料庫在回收儲存體時的運作狀態，並防止[交易 ID 包圍](https://www.postgresql.org/docs/current/routine-vacuuming.html#VACUUM-FOR-WRAPAROUND)問題至關重要。不過，有時候可以視需要防止清空操作，這可能會導致效能降低、儲存膨脹，甚至影響資料庫執行個體透過交易 ID 包圍的可用性。因此，識別和解決這些問題對於最佳的資料庫效能和可用性至關重要。閱讀[了解 Amazon RDS for PostgreSQL 環境中的自動清空功能](https://aws.amazon.com/blogs/database/understanding-autovacuum-in-amazon-rds-for-postgresql-environments/)以進一步了解自動清空功能。

`postgres_get_av_diag()` 函數有助於識別防止或延遲積極清空進度的問題。提供建議，其中可能包括用於解決可辨識問題的命令，或用於無法辨識問題之進一步診斷的指引。當存留期超過 RDS 的[彈性自動清空](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AdaptiveAutoVacuuming)閾值 5 億筆交易 ID 時，就會報告積極的清空封鎖程式。

**交易 ID 的存留期為何？**

交易 ID 的 `age()` 函數會計算自資料庫 (`pg_database.datfrozenxid`) 或資料表 (`pg_class.relfrozenxid`) 最舊的未凍結交易 ID 以來發生的交易數量。此值表示自上次積極清空操作以來的資料庫活動，並強調近期 VACUUM 程序的可能工作負載。

**什麼是積極清空？**

積極的 VACUUM 操作會全面掃描資料表中的所有頁面，包括在一般 VACUUM 期間通常會略過的頁面。此徹底掃描旨在「凍結」接近其最長存留期的交易 ID，有效防止稱為[交易 ID 包圍](https://www.postgresql.org/docs/current/routine-vacuuming.html#VACUUM-FOR-WRAPAROUND)的情況。

若要讓 `postgres_get_av_diag()` 報告封鎖程式，封鎖程式必須至少有 5 億筆舊的交易。

**Topics**
+ [在 RDS for PostgreSQL 中安裝自動清空監控和診斷工具](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Installation.md)
+ [RDS for PostgreSQL 中 postgres\$1get\$1av\$1diag() 的函數](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Functions.md)
+ [解決 RDS for PostgreSQL 中可識別的清空封鎖程式](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md)
+ [解決 RDS for PostgreSQL 中無法識別的清空封鎖程式](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Unidentifiable_blockers.md)
+ [解決 RDS for PostgreSQL 中的清空效能問題](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Performance.md)
+ [RDS for PostgreSQL 中的通知訊息說明](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.NOTICE.md)

# 在 RDS for PostgreSQL 中安裝自動清空監控和診斷工具
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Installation"></a>

`postgres_get_av_diag()` 函數目前可在下列 RDS for PostgreSQL 版本中使用：
+ 17.2 版和更新的 17 版本
+ 16.7 版和更新的 16 版本
+ 15.11 版和更新的 15 版本
+ 14.16 版和更新的 14 版本
+ 13.19 版和更新的 13 版本

 若要使用 `postgres_get_av_diag()`，請建立 `rds_tools` 延伸模組。

```
postgres=> CREATE EXTENSION rds_tools ;
CREATE EXTENSION
```

確認已安裝延伸模組。

```
postgres=> \dx rds_tools
             List of installed extensions
   Name    | Version |  Schema   |                    Description
 ----------+---------+-----------+----------------------------------------------------------
 rds_tools |   1.8   | rds_tools | miscellaneous administrative functions for RDS PostgreSQL
 1 row
```

確認已建立函數。

```
postgres=> SELECT
    proname function_name,
    pronamespace::regnamespace function_schema,
    proowner::regrole function_owner
FROM
    pg_proc
WHERE
    proname = 'postgres_get_av_diag';
    function_name     | function_schema | function_owner
----------------------+-----------------+----------------
 postgres_get_av_diag | rds_tools       | rds_superuser
(1 row)
```

# RDS for PostgreSQL 中 postgres\$1get\$1av\$1diag() 的函數
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Functions"></a>

`postgres_get_av_diag()` 函數會擷取在 RDS for PostgreSQL 資料庫中封鎖或落後之自動清空程序的診斷資訊。查詢需要在具有最舊交易 ID 的資料庫中執行，以獲得準確的結果。如需使用具有最舊交易 ID 的資料庫的詳細資訊，請參閱[未連線至具有最舊交易 ID 存留期的資料庫](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.NOTICE.md)

```
SELECT
    blocker,
    DATABASE,
    blocker_identifier,
    wait_event,
    TO_CHAR(autovacuum_lagging_by, 'FM9,999,999,999') AS autovacuum_lagging_by,
    suggestion,
    suggested_action
FROM (
    SELECT
        *
    FROM
        rds_tools.postgres_get_av_diag ()
    ORDER BY
        autovacuum_lagging_by DESC) q;
```

`postgres_get_av_diag()` 函數會傳回具有下列資訊的資料表。

**封鎖程式**  
指定封鎖清空的資料庫活動類別。  
+ [作用中陳述式](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Active_statement)
+ [交易閒置](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Idle_in_transaction)
+ [備妥交易](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Prepared_transaction)
+ [邏輯複寫槽](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Logical_replication_slot)
+ [僅供讀取複本和實體複寫槽](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Read_replicas)
+ [具有串流複寫的僅供讀取複本](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Read_replicas)
+ [暫時資料表](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Temporary_tables)

**資料庫**  
指定適用且支援的資料庫名稱。這是活動正在進行並封鎖或將封鎖自動清空的資料庫。這是您需要連線並採取動作的資料庫。

**blocker\$1identifier**  
指定封鎖或將封鎖自動清空之活動的識別符。識別符可以是程序 ID 以及 SQL 陳述式、備妥交易、僅供讀取複本的 IP 位址，以及複寫槽的名稱，可以是邏輯或實體。

**wait\$1event**  
指定封鎖工作階段的[等待事件](PostgreSQL.Tuning.md)，並適用於下列封鎖程式：  
+ 作用中陳述式
+ 交易閒置

**autovacum\$1lagging\$1by**  
指定自動清空在每個類別的待處理項目工作中落後的交易數量。

**建議**  
指定解決封鎖程式的建議。這些指示包括適用時活動所在的資料庫名稱、適用時工作階段的程序 ID (PID)，以及要採取的動作。

**suggested\$1action**  
建議解決封鎖程式所需採取的動作。

# 解決 RDS for PostgreSQL 中可識別的清空封鎖程式
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers"></a>

自動清空會執行積極的清空，並將交易 IDs 的存留期降至低於 RDS 執行個體 `autovacuum_freeze_max_age` 參數指定的閾值。您可以使用 Amazon CloudWatch 指標來追蹤此存留期。`MaximumUsedTransactionIDs`

若要尋找 Amazon RDS 執行個體的 `autovacuum_freeze_max_age` 設定 (預設為 2 億筆交易 ID)，您可以使用下列查詢：

```
SELECT
    TO_CHAR(setting::bigint, 'FM9,999,999,999') autovacuum_freeze_max_age
FROM
    pg_settings
WHERE
    name = 'autovacuum_freeze_max_age';
```

請注意，只有在存留期超過 Amazon RDS 的 5 億筆交易 ID 的[彈性自動清空](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AdaptiveAutoVacuuming)閾值時，`postgres_get_av_diag()` 才會檢查積極的清空封鎖程式。若要讓 `postgres_get_av_diag()` 偵測封鎖程式，封鎖程式必須至少有 5 億筆舊的交易。

`postgres_get_av_diag()` 函數會識別下列類型的封鎖程式：

**Topics**
+ [作用中陳述式](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Active_statement)
+ [交易閒置](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Idle_in_transaction)
+ [備妥交易](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Prepared_transaction)
+ [邏輯複寫槽](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Logical_replication_slot)
+ [僅供讀取複本](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Read_replicas)
+ [暫時資料表](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Temporary_tables)

## 作用中陳述式
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Active_statement"></a>

在 PostgreSQL 中，作用中陳述式是目前正在由資料庫執行的 SQL 陳述式。這包括查詢、交易或任何進行中的操作。透過 `pg_stat_activity` 監控時，狀態欄會指出具有對應 PID 的程序處於作用中狀態。

該 `postgres_get_av_diag()` 函數會在識別為作用中陳述式的陳述式時顯示類似下列的輸出。

```
blocker               | Active statement
database              | my_database
blocker_identifier    | SELECT pg_sleep(20000);
wait_event            | Timeout:PgSleep
autovacuum_lagging_by | 568,600,871
suggestion            | Connect to database "my_database", review carefully and you may consider terminating the process using suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.
suggested_action      | {"SELECT pg_terminate_backend (29621);"}
```

**建議動作**

遵循 `suggestion` 欄中的指引，使用者可以連線到存在作用中陳述式的資料庫，並且如 `suggested_action` 欄中所指定，建議您仔細檢閱終止工作階段的選項。如果終止是安全的，您可以使用 `pg_terminate_backend()` 函數來終止工作階段。此動作可由管理員 (例如 RDS 主帳戶） 或具有必要`pg_terminate_backend()` 權限的使用者執行。

**警告**  
終止的工作階段將復原 (`ROLLBACK`) 其所做的變更。根據您的需求，您可能想要重新執行陳述式。不過，建議只在自動清空程序完成其積極的清空操作之後才執行此操作。

## 交易閒置
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Idle_in_transaction"></a>

交易陳述式的閒置是指已開啟明確交易 (例如透過發出 `BEGIN` 陳述式）、已執行一些工作，且現在正在等待用戶端透過發出 `COMMIT`、`ROLLBACK` 或 `END` (這會導致隱含 `COMMIT`) 傳遞更多工作或發出交易結束訊號的任何工作階段。

將 `idle in transaction` 陳述式識別為封鎖程式時，`postgres_get_av_diag()` 函數會顯示類似以下的輸出。

```
blocker               | idle in transaction
database              | my_database
blocker_identifier    | INSERT INTO tt SELECT * FROM tt;
wait_event            | Client:ClientRead
autovacuum_lagging_by | 1,237,201,759
suggestion            | Connect to database "my_database", review carefully and you may consider terminating the process using suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.
suggested_action      | {"SELECT pg_terminate_backend (28438);"}
```

**建議動作**

如 `suggestion` 欄中所示，您可以連線到交易工作階段中存在閒置的資料庫，並使用 `pg_terminate_backend()` 函數終止工作階段。使用者可以是您的管理員 (RDS 主帳戶） 使用者或具有 `pg_terminate_backend()` 權限的使用者。

**警告**  
終止的工作階段將復原 (`ROLLBACK`) 其所做的變更。根據您的需求，您可能想要重新執行陳述式。不過，建議只在自動清空程序完成其積極的清空操作之後才執行此操作。

## 備妥交易
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Prepared_transaction"></a>

PostgreSQL 允許屬於兩個階段遞交策略的交易，稱為[備妥交易](https://www.postgresql.org/docs/current/sql-prepare-transaction.html)。這些是透過將 `max_prepared_transactions` 參數設定為非零值來啟用。備妥交易旨在確保交易耐用性，即使在資料庫當機、重新啟動或用戶端中斷連線後仍然可用。與一般交易一樣，它們會獲指派交易 ID，並可能影響自動清空。如果保持備妥狀態，則自動清空無法執行凍結，並可能導致交易 ID 包圍。

當交易無限期準備而不由交易管理員解決時，它們會變成孤立的備妥交易。修正此問題的唯一方法是分別使用 `COMMIT PREPARED` 或 `ROLLBACK PREPARED` 命令遞交或轉返交易。

**注意**  
請注意，在準備交易期間進行的備份在還原後仍會包含該交易。請參閱下列有關如何尋找和關閉此類交易的資訊。

該 `postgres_get_av_diag()` 函數會在識別為備妥交易的封鎖程式時顯示下列輸出。

```
blocker               | Prepared transaction
database              | my_database
blocker_identifier    | myptx
wait_event            | Not applicable
autovacuum_lagging_by | 1,805,802,632
suggestion            | Connect to database "my_database" and consider either COMMIT or ROLLBACK the prepared transaction using suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.
suggested_action      | {"COMMIT PREPARED 'myptx';",[OR],"ROLLBACK PREPARED 'myptx';"}
```

**建議動作**

如建議欄中所述，連線至備妥交易所在的資料庫。根據 `suggested_action` 欄，仔細檢閱是否執行 `COMMIT` 或 `ROLLBACK`，以及相應動作。

若要監控一般備妥交易，PostgreSQL 提供稱為 `pg_prepared_xacts` 的目錄檢視。您可以使用下列查詢來尋找準備好的交易。

```
SELECT
    gid,
    prepared,
    owner,
    database,
    transaction AS oldest_xmin
FROM
    pg_prepared_xacts
ORDER BY
    age(transaction) DESC;
```

## 邏輯複寫槽
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Logical_replication_slot"></a>

複寫槽的目的是保留未使用的變更，直到這些變更複寫到目標伺服器為止。如需詳細資訊，請參閱 PostgreSQL 的[邏輯複寫](https://www.postgresql.org/docs/current/logical-replication.html)。

邏輯複寫槽有兩種類型。

**非作用中邏輯複寫槽**

複寫終止時，無法移除未使用的交易日誌，且複寫槽會變成非作用中。雖然訂閱者目前未使用非作用中的邏輯複寫槽，但其會保留在伺服器上，導致 WAL 檔案的保留，並防止移除舊的交易日誌。這可能會增加磁碟使用量，尤其是封鎖自動清空清除內部目錄資料表，因為系統必須保留 LSN 資訊以免遭到覆寫。如果未解決，這可能會導致目錄膨脹、效能降低，以及包圍清空的風險增加，進而可能導致交易停機時間。

**作用中但緩慢的邏輯複寫槽**

有時候，由於邏輯複寫的效能降低，移除目錄的無效元組會延遲。此複寫延遲會減緩更新 `catalog_xmin` 的速度，並可能導致目錄膨脹和包圍清空。

當 `postgres_get_av_diag()` 函數找到邏輯複寫插槽作為封鎖程式時，會顯示類似下列的輸出。

```
blocker               | Logical replication slot
database              | my_database
blocker_identifier    | slot1
wait_event            | Not applicable
autovacuum_lagging_by | 1,940,103,068
suggestion            | Ensure replication is active and resolve any lag for the slot if active. If inactive, consider dropping it using the command in suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.
suggested_action      | {"SELECT pg_drop_replication_slot('slot1') FROM pg_replication_slots WHERE active = 'f';"}
```

**建議動作**

若要解決此問題，請檢查複寫組態是否有可能終止套用程序之目標結構描述或資料的問題。最常見的原因如下：
+ 遺失資料欄
+ 不相容的資料類型
+ 資料不符
+ 遺失資料表

如果問題與基礎設施問題有關：
+ 網路問題 - [如何解決網路狀態不相容的 Amazon RDS 資料庫問題？](https://repost.aws/knowledge-center/rds-incompatible-network)
+ 由於下列原因，資料庫或資料庫執行個體無法使用：
  + 複本執行個體的用盡儲存體 - 檢閱 [Amazon RDS 資料庫執行個體用盡儲存體](https://repost.aws/knowledge-center/rds-out-of-storage)，以取得新增儲存體的相關資訊。
  + 不相容參數 - 檢閱[如何修正停滯在不相容參數狀態的 Amazon RDS 資料庫執行個體？](https://repost.aws/knowledge-center/rds-incompatible-parameters)以取得如何解決問題的詳細資訊。

如果您的執行個體不在 AWS 網路或 AWS EC2 上，請洽詢您的管理員，了解如何解決可用性或基礎設施相關問題。

**捨棄非作用中插槽**

**警告**  
注意：捨棄複寫槽之前，請仔細確認它沒有進行中的複寫、處於非作用中狀態，而且處於無法復原的狀態。提早捨棄插槽可能會中斷複寫或導致資料遺失。

確認不再需要複寫槽後，請將其捨棄以允許自動清空繼續。條件 `active = 'f'` 可確保只會捨棄非作用中的插槽。

```
SELECT pg_drop_replication_slot('slot1') WHERE active ='f'
```

## 僅供讀取複本
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Read_replicas"></a>

為 [Amazon RDS 僅供讀取複本](USER_PostgreSQL.Replication.ReadReplicas.md)啟用 `hot_standby_feedback` 設定時，可防止主要資料庫上的自動清空移除在讀取複本上執行的查詢仍可能需要的無效資料列。這會影響所有類型的實體讀取複本，包括具有或沒有複寫插槽的複本。此行為是必要的，因為在待命複本上執行的查詢需要這些資料列在主要 上保持可用，以防止[查詢衝突](https://www.postgresql.org/docs/current/hot-standby.html#HOT-STANDBY-CONFLICT)和取消。

**僅供讀取複本和實體複寫槽**  
具有實體複寫槽的僅供讀取複本可大幅增強 RDS for PostgreSQL 中複寫的可靠性和穩定性。這些槽可確保主要資料庫會保留必要的預先寫入日誌檔案，直到複本處理它們為止，即使在網路中斷期間也能維持資料一致性。

從 RDS for PostgreSQL 第 14 版開始，所有複本都會使用複寫插槽。在舊版中，只有跨區域複本使用複寫槽。

當找到具有實體複寫槽作為封鎖程式的讀取複本時，`postgres_get_av_diag()` 函數會顯示類似以下的輸出。

```
blocker               | Read replica with physical replication slot
database              |
blocker_identifier    | rds_us_west_2_db_xxxxxxxxxxxxxxxxxxxxx
wait_event            | Not applicable
autovacuum_lagging_by | 554,080,689
suggestion            | Run the following query on the replica "rds_us_west_2_db_xxxxxxxxxxxxxxxxxxxx" to find the long running query:                           
                      | SELECT * FROM pg_catalog.pg_stat_activity WHERE backend_xmin::text::bigint = 757989377;                                                       
                      | Review carefully and you may consdier terminating the query on read replica using suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.                                 +                      |
suggested_action      | {"SELECT pg_terminate_backend(pid) FROM pg_catalog.pg_stat_activity WHERE backend_xmin::text::bigint = 757989377;","                                                                                 +
                      | [OR]                                                                                                                                                                                                 +
                      | ","Disable hot_standby_feedback","                                                                                                                                                                   +
                      | [OR]                                                                                                                                                                                                 +
                      | ","Delete the read replica if not needed"}
```

**具有串流複寫的僅供讀取複本**  
Amazon RDS 允許在舊版中設定沒有實體複寫槽的僅供讀取複本，直到 13 版為止。這種方法允許主要資料庫更積極地回收 WAL 檔案以減少額外負荷，這在磁碟空間有限的環境中是有利的，並且可以容忍偶爾的 ReplicaLag。不過，如果沒有插槽，則待命必須保持同步，以避免缺少 WAL 檔案。Amazon RDS 使用封存的 WAL 檔案，協助複本在落後時趕上進度，但此程序需要仔細監控，而且速度可能很慢。

當 `postgres_get_av_diag()` 函數找到串流僅供讀取複本作為封鎖程式時，會顯示類似以下的輸出。

```
blocker               | Read replica with streaming replication slot
database              | Not applicable
blocker_identifier    | xx.x.x.xxx/xx
wait_event            | Not applicable
autovacuum_lagging_by | 610,146,760
suggestion            | Run the following query on the replica "xx.x.x.xxx" to find the long running query:                                                                                                                                                         +
                      | SELECT * FROM pg_catalog.pg_stat_activity WHERE backend_xmin::text::bigint = 348319343;                                                                                                                                                     +
                      | Review carefully and you may consdier terminating the query on read replica using suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.                                       +
                      |
suggested_action      | {"SELECT pg_terminate_backend(pid) FROM pg_catalog.pg_stat_activity WHERE backend_xmin::text::bigint = 348319343;","                                                                                                                        +
                      | [OR]                                                                                                                                                                                                                                        +
                      | ","Disable hot_standby_feedback","                                                                                                                                                                                                          +
                      | [OR]                                                                                                                                                                                                                                        +
                      | ","Delete the read replica if not needed"}
```

**建議動作**

如 `suggested_action` 欄中的建議，請仔細檢閱這些選項以解除封鎖自動清空。
+ **終止查詢** – 根據建議欄中的指引，您可以連線到僅限讀取複本，如 suggested\$1action 欄中所指定，建議您仔細檢閱終止工作階段的選項。如果終止被視為安全，您可以使用 `pg_terminate_backend()` 函數來終止工作階段。此動作可由管理員 (例如 RDS 主帳戶） 或具有必要 pg\$1terminate\$1backend() 權限的使用者執行。

  您可以在僅限讀取複本上執行下列 SQL 命令，以終止導致主要資料庫上的清空無法清除舊資料列的查詢。`backend_xmin` 的值會在函數的輸出中報告：

  ```
  SELECT
      pg_terminate_backend(pid)
  FROM
      pg_catalog.pg_stat_activity
  WHERE
      backend_xmin::text::bigint = backend_xmin;
  ```
+ **停用熱待命回饋** – 如果參數造成嚴重的清空延遲，請考慮停用 `hot_standby_feedback` 參數。

  `hot_standby_feedback` 參數允許僅供讀取複本通知主要資料庫其查詢活動，防止主要資料庫清空待命資料庫上使用的資料表或資料列。雖然這可確保待命資料庫上的查詢穩定性，但可能會大幅延遲主要資料庫上的清空。停用此功能可讓主要資料庫繼續進行清空，而無需等待待命資料庫趕上。不過，如果嘗試存取已由主要資料庫清空的資料列，這可能會導致查詢取消或待命資料庫失敗。
+ **如果不需要，請刪除僅供讀取複本** – 如果不再需要僅供讀取複本，您可以將其刪除。這將移除相關聯的複寫額外負荷，並允許主要資料庫回收交易日誌，而不會被複本保留。

## 暫時資料表
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Temporary_tables"></a>

使用 `TEMPORARY` 關鍵字建立的[暫時資料表](https://www.postgresql.org/docs/current/sql-createtable.html)位於臨時結構描述中，例如 pg\$1temp\$1xxx，並且只能由建立它們的工作階段存取。暫時資料表會在工作階段結束時捨棄。不過，PostgreSQL 的自動清空程序看不到這些資料表，而且必須由建立它們的工作階段手動清空。嘗試從另一個工作階段清空暫時資料表沒有效果。

在異常情況下，暫時資料表存在，而沒有作用中的工作階段擁有它。如果擁有工作階段由於嚴重損毀、網路問題或類似事件意外結束，則可能無法清除暫時資料表，將其保留為「孤立」資料表。當 PostgreSQL 自動清空程序偵測到孤立的暫時資料表時，它會記錄下列訊息：

```
LOG: autovacuum: found orphan temp table \"%s\".\"%s\" in database \"%s\"
```

`postgres_get_av_diag()` 函數將暫存資料表識別為封鎖程式時，會顯示類似下列的輸出。為了讓函數正確顯示與暫時資料表相關的輸出，它需要在存在這些資料表的相同資料庫中執行。

```
blocker               | Temporary table
database              | my_database
blocker_identifier    | pg_temp_14.ttemp
wait_event            | Not applicable
autovacuum_lagging_by | 1,805,802,632
suggestion            | Connect to database "my_database". Review carefully, you may consider dropping temporary table using command in suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.
suggested_action      | {"DROP TABLE ttemp;"}
```

**建議動作**

遵循輸出 `suggestion` 欄中提供的指示，以識別和移除防止自動清空執行的暫時資料表。使用以下命令捨棄 `postgres_get_av_diag()` 報告的暫時資料表。根據 `postgres_get_av_diag()` 函數提供的輸出取代資料表名稱。

```
DROP TABLE my_temp_schema.my_temp_table;
```

下列查詢可用來識別暫時資料表：

```
SELECT
    oid,
    relname,
    relnamespace::regnamespace,
    age(relfrozenxid)
FROM
    pg_class
WHERE
relpersistence = 't'
ORDER BY
    age(relfrozenxid) DESC;
```

# 解決 RDS for PostgreSQL 中無法識別的清空封鎖程式
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Unidentifiable_blockers"></a>

本節會探索其他可能阻止清空進行的原因。`postgres_get_av_diag()` 函數目前無法直接識別這些問題。

**Topics**
+ [無效的頁面](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Invalid_pages)
+ [索引不一致](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Index_inconsistency)
+ [異常高的交易速率](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.High_transaction_rate)

## 無效的頁面
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Invalid_pages"></a>

當 PostgreSQL 在存取頁面時偵測到頁面檢查總和不相符時，會發生無效的頁面錯誤。內容無法讀取，防止自動清空凍結元組。這會有效停止清除程序。下列錯誤會寫入 PostgreSQL 的日誌：

```
WARNING:  page verification failed, calculated checksum YYYYY but expected XXXX
ERROR:  invalid page in block ZZZZZ of relation base/XXXXX/XXXXX
CONTEXT:  automatic vacuum of table myschema.mytable
```

**判斷物件類型**

```
ERROR: invalid page in block 4305910 of relation base/16403/186752608 
WARNING: page verification failed, calculated checksum 50065 but expected 60033
```

從錯誤訊息中，路徑 `base/16403/186752608` 會提供下列資訊：
+ "base" 是 PostgreSQL 資料目錄下的目錄名稱。
+ "16403" 是資料庫 OID，您可以在 `pg_database` 系統目錄中查詢。
+ "186752608" 是 `relfilenode`，可用來查詢 `pg_class` 系統目錄中的結構描述和物件名稱。

透過檢查受影響資料庫中下列查詢的輸出，您可以判斷物件類型。下列查詢會擷取 OID 186752608 的物件資訊。將 OID 取代為與您所遇到錯誤相關的 OID。

```
SELECT
    relname AS object_name,
    relkind AS object_type,
    nspname AS schema_name
FROM
    pg_class c
    JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE
    c.oid = 186752608;
```

如需詳細資訊，請參閱 PostgreSQL 文件 [https://www.postgresql.org/docs/current/catalog-pg-class.html](https://www.postgresql.org/docs/current/catalog-pg-class.html)，以了解所有支援的物件類型，如 `pg_class` 中的 `relkind` 欄所述。

**指引**

此問題最有效的解決方案取決於特定 Amazon RDS 執行個體的組態，以及受不一致頁面影響的資料類型。

**如果物件類型是索引：**

建議重建索引。
+ **使用 `CONCURRENTLY` 選項** – 在 PostgreSQL 第 12 版之前，重建索引需要獨佔資料表鎖定，以限制對資料表的存取。使用 PostgreSQL 第 12 版和更新版本時，`CONCURRENTLY` 選項允許資料列層級鎖定，以大幅改善資料表的可用性。以下是命令：

  ```
  REINDEX INDEX ix_name CONCURRENTLY;
  ```

  雖然 `CONCURRENTLY` 干擾性較低，但在忙碌的資料表上可能會變慢。如果可能，請考慮在低流量期間建立索引。

  如需詳細資訊，請參閱 PostgreSQL [REINDEX](https://www.postgresql.org/docs/current/sql-reindex.html) 文件。
+ **使用 `INDEX_CLEANUP FALSE` 選項** – 如果索引較大且估計需要大量時間才能完成，您可以在排除索引的同時執行手動 `VACUUM FREEZE` 來解除封鎖自動清空。此功能可在 PostgreSQL 第 12 版及更新版本中使用。

  略過索引可讓您略過不一致索引的清空程序，並減輕包圍問題。不過，這無法解決基本的無效頁面問題。若要完全處理和解決無效的頁面問題，您仍然需要重建索引。

**如果物件類型是具體化視觀表：**

如果具體化視觀表發生無效頁面錯誤，請登入受影響的資料庫並重新整理以解決無效頁面：

重新整理具體化視觀表：

```
REFRESH MATERIALIZED VIEW schema_name.materialized_view_name;
```

如果重新整理失敗，請嘗試重新建立：

```
DROP MATERIALIZED VIEW schema_name.materialized_view_name;
CREATE MATERIALIZED VIEW schema_name.materialized_view_name AS query;
```

重新整理或重新建立具體化視觀表會將其還原，而不會影響基礎資料表資料。

**對於所有其他物件類型：**

對於所有其他物件類型，請聯絡 AWS 支援。

## 索引不一致
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Index_inconsistency"></a>

邏輯上不一致的索引會防止自動清空進行。在索引的清空階段或 SQL 陳述式存取索引時，系統會記錄下列錯誤或類似錯誤。

```
ERROR: right sibling's left-link doesn't match:block 5 links to 10 instead of expected 2 in index ix_name
```

```
ERROR: failed to re-find parent key in index "XXXXXXXXXX" for deletion target page XXX
CONTEXT:  while vacuuming index index_name of relation schema.table
```

**指引**

在手動 `VACUUM FREEZE` 上使用 `INDEX_CLEANUP` 重建索引或略過索引。如需如何重建索引的資訊，請參閱[如果物件類型是索引](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Invalid_pages)。
+ **使用 CONCURRENTLY 選項** – 在 PostgreSQL 第 12 版之前，重建索引需要獨佔資料表鎖定，以限制對資料表的存取。透過 PostgreSQL 第 12 版和更新版本，CONCURRENTLY 選項允許資料列層級鎖定，以大幅改善資料表的可用性。以下是命令：

  ```
  REINDEX INDEX ix_name CONCURRENTLY;
  ```

  雖然 CONCURRENTLY 干擾性較低，但在忙碌的資料表上可能會變慢。如果可能，請考慮在低流量期間建立索引。如需詳細資訊，請參閱 *PostgreSQL* 文件中的 [REINDEX](https://www.postgresql.org/docs/current/sql-reindex.html)。
+ **使用 INDEX\$1CLEANUP FALSE 選項** – 如果索引較大且估計需要大量時間才能完成，您可以在排除索引的同時執行手動 VACUUM FREEZE 來解除封鎖自動清空。此功能可在 PostgreSQL 第 12 版及更新版本中使用。

  略過索引可讓您略過不一致索引的清空程序，並減輕包圍問題。不過，這無法解決基本的無效頁面問題。若要完全處理和解決無效的頁面問題，您仍然需要重建索引。

## 異常高的交易速率
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.High_transaction_rate"></a>

在 PostgreSQL 中，高交易速率可能會大幅影響自動清空的效能，導致清除無效元組的速度變慢，並提高交易 ID 包圍的風險。您可以透過測量兩個時段之間的 `max(age(datfrozenxid))` 差異來監控交易速率，通常是每秒。此外，您可以使用 RDS Performance Insights 的下列計數器指標來測量交易速率 (xact\$1commit 和 xact\$1rollback 的總和)，這是交易的總數。


|  計數器  |  類型  |  單位  |  指標  | 
| --- | --- | --- | --- | 
|  xact\$1commit  |  交易  |  每秒遞交數  |  db.Transactions.xact\$1commit  | 
|  xact\$1rollback  |  交易  |  每秒轉返數  |  db.Transactions.xact\$1rollback  | 

快速增加表示交易負載很高，可能會自動清空不堪負荷，導致膨脹、鎖定爭用和潛在的效能問題。這可能會在幾個方面對自動清空程序產生負面影響：
+ **資料表活動：**正在清空的特定資料表可能遇到大量交易，因而導致延遲。
+ **系統資源**整體系統可能會超載，導致自動清空難以存取必要的資源以有效率地運作。

請考慮下列策略，以允許自動清空更有效地運作並跟上其任務：

1. 如果可能，請降低交易速率。考慮在可行的情況下批次處理或分組類似的交易。

1. 以經常更新的資料表為目標，在離峰時段內每夜、每週或每兩週手動 `VACUUM FREEZE` 操作一次。

1. 考慮擴展執行個體類別以配置更多系統資源，以處理高交易量和自動清空。

# 解決 RDS for PostgreSQL 中的清空效能問題
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Performance"></a>

本節討論通常會導致降低清空效能的因素，以及如何解決這些問題。

**Topics**
+ [清空大型索引](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Large_indexes)
+ [要清空的資料表或資料庫過多](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Multiple_tables)
+ [積極清空 (以防止包圍) 正在執行](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Aggressive_vacuum)

## 清空大型索引
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Large_indexes"></a>

VACUUM 會執行循序階段：初始化、堆積掃描、索引和堆積清空、索引清除、堆積截斷和最終清除。在堆積掃描期間，程序會刪除頁面、重組並凍結頁面。完成堆積掃描後，VACUUM 會清除索引、將空白頁面傳回至作業系統，並執行最終清除任務，例如清空可用空間貼圖和更新統計資料。

當 `maintenance_work_mem` (或 `autovacuum_work_mem`) 不足以處理索引時，索引清空可能需要多次通過。在 PostgreSQL 16 和更早版本中，用於儲存無效元組的 ID 1 GB 記憶體限制通常會強制在大型索引上多次通過。PostgreSQL 17 推出 `TidStore`，可動態配置記憶體，而不是使用單一配置陣列。這可消除 1 GB 限制、更有效率地使用記憶體，並減少每個索引進行多次索引掃描的需求。

如果可用的記憶體無法同時容納整個索引處理，大型索引仍可能需要 PostgreSQL 17 中的多次通過。一般而言，較大的索引包含更多需要多次通過的無效元組。

**偵測緩慢清空操作**

`postgres_get_av_diag()` 函數可以偵測清空操作何時因為記憶體不足而緩慢執行。如需該功能的詳細資訊，請參閱[在 RDS for PostgreSQL 中安裝自動清空監控和診斷工具](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Installation.md)。

當可用的記憶體不足以在單次通過中完成索引清空時， `postgres_get_av_diag()` 函數會發出下列通知。

**`rds_tools` 1.8**

```
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound and it might be slow.
```

```
NOTICE: The current setting of autovacuum_work_mem is "XXX" and might not be sufficient. Consider increasing the setting, and if necessary, scaling up the Amazon RDS instance class for more memory. 
        Additionally, review the possibility of manual vacuum with exclusion of indexes using (VACUUM (INDEX_CLEANUP FALSE, VERBOSE TRUE) table_name;).
```

**`rds_tools` 1.9**

```
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound and it might be slow.
```

```
NOTICE: The current setting of autovacuum_work_mem is XX might not be sufficient. Consider increasing the setting to XXX, and if necessary, scaling up the RDS instance class for more 
        memory. The suggested value is an estimate based on the current number of dead tuples for the table being vacuumed, which might not fully reflect the latest state. Additionally, review the possibility of manual 
        vacuum with exclusion of indexes using (VACUUM (INDEX_CLEANUP FALSE, VERBOSE TRUE) table_name;). For more information, see 
        [Working with PostgreSQL autovacuum in the Amazon Amazon RDS User Guide](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.html)
        .
```

**注意**  
`postgres_get_av_diag()` 函數依賴 `pg_stat_all_tables.n_dead_tup` 來估計索引清空所需的記憶體量。

當 `postgres_get_av_diag()` 函數識別由於 `autovacuum_work_mem` 不足而需要多個索引掃描的緩慢清空操作時，會產生下列訊息：

```
NOTICE: Your vacuum is performing multiple index scans due to insufficient autovacuum_work_mem:XXX for index vacuuming. 
        For more information, see [Working with PostgreSQL autovacuum in the Amazon Amazon RDS User Guide](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.html).
```

**指引**

您可以使用手動 `VACUUM FREEZE` 來套用下列解決方法，以加速凍結資料表。

**增加清空的記憶體**

如 `postgres_get_av_diag()` 函數所建議，建議增加 `autovacuum_work_mem` 參數以解決執行個體層級的潛在記憶體限制。雖然 `autovacuum_work_mem` 是動態參數，但請務必注意，若要讓新的記憶體設定生效，自動清空精靈需要重新啟動其工作者。若要完成此操作：

1. 確認新的設定已就緒。

1. 終止目前正在執行自動清空的程序。

此方法可確保調整後的記憶體配置套用至新的自動清空操作。

如需更立即的結果，請考慮在工作階段中手動執行增加 `maintenance_work_mem` 設定的 `VACUUM FREEZE` 操作：

```
SET maintenance_work_mem TO '1GB';
VACUUM FREEZE VERBOSE table_name;
```

如果您使用 Amazon RDS 並發現需要額外的記憶體以支援 `maintenance_work_mem` 或 `autovacuum_work_mem` 的更高值，請考慮升級至具有更多記憶體的執行個體類別。這可提供必要的資源來增強手動和自動清空操作，進而改善整體清空和資料庫效能。

**停用 INDEX\$1CLEANUP**

PostgreSQL 第 12 版和更新版本中的手動 `VACUUM` 允許略過索引清除階段，而 PostgreSQL 第 14 版和更新版本中的緊急自動清空會根據 [https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-VACUUM-FAILSAFE-AGE](https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-VACUUM-FAILSAFE-AGE) 參數自動執行此操作。

**警告**  
略過索引清除可能會導致索引膨脹，並對查詢效能產生負面影響。若要緩解這種情況，請考慮在維護時段重新編製索引或清空受影響的索引。

如需處理大型索引的其他指引，請參閱 [使用大型索引管理自動清空](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.LargeIndexes.md) 上的文件。

**平行索引清空**

從 PostgreSQL 13 開始，根據預設可以使用手動 `VACUUM` 平行清空和清理索引，並為每個索引指派一個清空工作者程序。不過，對於 PostgreSQL 判斷清空操作是否符合平行執行的資格，必須符合特定條件：
+ 必須至少有兩個索引。
+ 應將 `max_parallel_maintenance_workers` 參數設定為至少 2。
+ 索引大小必須超過 `min_parallel_index_scan_size` 限制，預設為 512KB。

您可以根據 Amazon RDS 執行個體上可用的 vCPU 數目和資料表上的索引數目來調整 `max_parallel_maintenance_workers` 設定，以最佳化清空周轉時間。

如需詳細資訊，請參閱 [Amazon RDS for PostgreSQL 和 Amazon Aurora PostgreSQL 中的平行清空](https://aws.amazon.com/blogs/database/parallel-vacuuming-in-amazon-rds-for-postgresql-and-amazon-aurora-postgresql/)。

## 要清空的資料表或資料庫過多
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Multiple_tables"></a>

如 PostgreSQL 的[自動清空精靈](https://www.postgresql.org/docs/current/routine-vacuuming.html#AUTOVACUUM')文件所述，自動清空精靈會透過多個程序運作。這包括持久性自動清空啟動器，負責為系統中的每個資料庫啟動自動清空工作者程序。啟動器會排程這些工作者，每個資料庫大約每 `autovacuum_naptime` 秒啟動一次。

使用「N」個資料庫時，新工作者大約每 [`autovacuum_naptime`/N 秒] 開始一次。不過，並行工作者的總數會受到 `autovacuum_max_workers` 設定的限制。如果需要清空的資料庫或資料表數量超過此限制，則在工作者一變成可用時，就會立即處理下一個資料庫或資料表。

當許多大型資料表或資料庫需要同時清空時，所有可用的自動清空工作者可能會長時間佔用，進而延遲其他資料表和資料庫的維護。在交易速率較高的環境中，此瓶頸可能會快速提升，並可能導致 Amazon RDS 執行個體中的包圍清空問題。

當 `postgres_get_av_diag()` 偵測到大量資料表或資料庫時，會提供下列建議：

```
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound and it might be slow.
```

```
NOTICE: The current setting of autovacuum_max_workers:3 might not be sufficient. Consider increasing the setting and, if necessary, consider scaling up the Amazon RDS instance class for more workers.
```

**指引**

**增加 autovacuum\$1max\$1workers**

為了加速清空，建議您調整 `autovacuum_max_workers` 參數，以允許更多並行自動清空工作者。如果效能瓶頸持續存在，請考慮將 Amazon RDS 執行個體擴展到具有更多 vCPU 的類別，這可以進一步改善平行處理功能。

## 積極清空 (以防止包圍) 正在執行
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Aggressive_vacuum"></a>

PostgreSQL 中資料庫 (MaximumUsedTransactionIDs) 的存留期只會在積極清空 (防止包圍) 成功完成時減少。在此清空完成之前，存留期會根據交易速率繼續增加。

當 `postgres_get_av_diag()` 函數偵測到積極的清空時，會產生下列 `NOTICE`。不過，它只會在清空作用中至少兩分鐘後觸發此輸出。

```
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound, monitor autovacuum performance.
```

如需積極清空的詳細資訊，請參閱[積極清空已執行時](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.NOTICE.md)。

您可以使用下列查詢來確認積極清空是否正在進行中：

```
SELECT
    a.xact_start AS start_time,
    v.datname "database",
    a.query,
    a.wait_event,
    v.pid,
    v.phase,
    v.relid::regclass,
    pg_size_pretty(pg_relation_size(v.relid)) AS heap_size,
    (
        SELECT
            string_agg(pg_size_pretty(pg_relation_size(i.indexrelid)) || ':' || i.indexrelid::regclass || chr(10), ', ')
        FROM
            pg_index i
        WHERE
            i.indrelid = v.relid
    ) AS index_sizes,
    trunc(v.heap_blks_scanned * 100 / NULLIF(v.heap_blks_total, 0)) AS step1_scan_pct,
    v.index_vacuum_count || '/' || (
        SELECT
            count(*)
        FROM
            pg_index i
        WHERE
            i.indrelid = v.relid
    ) AS step2_vacuum_indexes,
    trunc(v.heap_blks_vacuumed * 100 / NULLIF(v.heap_blks_total, 0)) AS step3_vacuum_pct,
    age(CURRENT_TIMESTAMP, a.xact_start) AS total_time_spent_sofar
FROM
    pg_stat_activity a
    INNER JOIN pg_stat_progress_vacuum v ON v.pid = a.pid;
```

您可以透過檢查輸出中的查詢欄來判斷是否為積極的清空 (以防止包圍)。片語「防止包圍」表示它是積極的清空。

```
query                  | autovacuum: VACUUM public.t3 (to prevent wraparound)
```

例如，假設您有交易存留期為 10 億的封鎖程式和需要積極清空的資料表，以防止在相同的交易存留期進行包圍。此外，有另一個交易存留期為 7.5 億的封鎖程式。在交易存留期 10 億時清除封鎖程式後，交易存留期不會立即降至 7.5 億。它將保持很高，直到需要積極清空的資料表或任何存留期超過 7.5 億的交易完成為止。在此期間，PostgreSQL 叢集的交易存留期將繼續增加。清空程序完成後，交易存留期將降至 7.5 億，但會再次開始增加，直到進一步清空完成為止。只要這些條件持續存在，此週期就會繼續，直到交易存留期最終降至由 `autovacuum_freeze_max_age` 所指定為 Amazon RDS 執行個體設定的層級為止。

# RDS for PostgreSQL 中的通知訊息說明
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.NOTICE"></a>

 `postgres_get_av_diag()` 函數提供下列通知訊息：

**當存留期尚未達到監控閾值時**  
用於 `postgres_get_av_diag()` 識別封鎖程式的監控閾值預設為 5 億筆交易。如果 `postgres_get_av_diag()`產生下列通知，則表示交易存留期尚未達到此閾值。  

```
NOTICE: postgres_get_av_diag() checks for blockers that prevent aggressive vacuums only, it does so only after exceeding dvb_threshold which is 500,000,000 and age of this PostgreSQL cluster is currently at 2.
```

**未連線至具有最舊交易 ID 存留期的資料庫**  
`postgres_get_av_diag()` 函數會在連接至具有最舊交易 ID 存留期的資料庫時，提供最準確的輸出。`postgres_get_av_diag()` 所報告之交易 ID 存留期最早的資料庫，將與您案例中的「my\$1database」不同。如果您未連線到正確的資料庫，會產生下列通知：  

```
NOTICE: You are not connected to the database with the age of oldest transaction ID. Connect to my_database database and run postgres_get_av_diag() for accurate reporting.
```
連線具有最舊交易存留期的資料庫非常重要，原因如下：  
+ **識別暫時資料表封鎖程式：**由於暫時資料表的中繼資料專屬於每個資料庫，因此它們通常會在建立它們的資料庫中找到。不過，如果暫存資料表剛好是最熱門的封鎖程式，並且位於具有最舊交易的資料庫中，則可能會誤導。連線到正確的資料庫可確保正確識別暫時資料表封鎖程式。
+ **診斷緩慢清空：**索引中繼資料和資料表計數資訊是資料庫特定的，且為診斷緩慢清空問題的必要項目。

**具有依存留期最舊交易的資料庫位於 rdsadmin 或 template0 資料庫**  
在某些情況下，`rdsadmin`或 `template0` 資料庫可能會識別為具有最舊交易 ID 存留期的資料庫。如果發生這種情況，`postgres_get_av_diag()` 會發出下列通知：  

```
NOTICE: The database with the age of oldest transaction ID is rdsadmin or template0, reach out to support if the reported blocker is in rdsadmin or template0.
```
確認列出的封鎖程式不是來自這兩個資料庫。如果報告封鎖程式出現在 `rdsadmin`或 `template0` 中，請聯絡支援，因為這些資料庫無法供使用者存取且需要介入。  
`rdsadmin` 或 `template0` 資料庫不太可能包含最熱門的封鎖程式。

**當積極清空已在執行時**  
`postgres_get_av_diag()` 函數旨在報告積極清空程序何時執行，但只會在清空作用中至少 1 分鐘後觸發此輸出。此刻意延遲有助於降低誤報的機會。透過等待，函數可確保僅報告有效且重要的清空，進而更準確且可靠地監控清空活動。  
當 `postgres_get_av_diag()` 函數偵測到一或多個進行中的積極清空時，會產生下列通知。  

```
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound, monitor autovacuum performance.
```
如通知所示，繼續監控清空的效能。如需積極清空的詳細資訊，請參閱 [積極清空 (以防止包圍) 正在執行](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Performance.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Aggressive_vacuum)

**當自動清空關閉時**  
如果資料庫執行個體上已停用自動清空，`postgres_get_av_diag()` 函數會產生下列通知：  

```
NOTICE: Autovacuum is OFF, we strongly recommend to enable it, no restart is necessary.
```
自動清空是 RDS for PostgreSQL 資料庫執行個體的重要功能，可確保順暢的資料庫操作。它會自動移除舊的資料列版本、回收儲存空間，並防止資料表膨脹，有助於保持資料表和索引的效率，以獲得最佳效能。此外，它可以防止交易 ID 包圍，這會停止 Amazon RDS 執行個體上的交易。停用自動清空可能會導致資料庫效能和穩定性的長期下降。我們建議您隨時將其保留。如需詳細資訊，請參閱[了解 RDS for PostgreSQL 環境中的自動清空](https://aws.amazon.com/blogs/database/understanding-autovacuum-in-amazon-rds-for-postgresql-environments/)。  
關閉自動清空不會停止積極的清空。這些仍會在您的資料表達到 `autovacuum_freeze_max_age` 閾值時發生。

**剩餘的交易數量非常低**  
當包圍清空即將關閉時，`postgres_get_av_diag()` 函數會產生下列通知。當您的 Amazon RDS 執行個體有 1 億筆交易且不可能拒絕新交易時，就會發出此通知。  

```
WARNING: Number of transactions remaining is critically low, resolve issues with autovacuum or perform manual VACUUM FREEZE before your instance stops accepting transactions.
```
您需要立即採取動作，以避免資料庫停機時間。您應該密切監控您的清空操作，並考慮在受影響的資料庫上手動啟動 `VACUUM FREEZE`，以防止交易失敗。

# 在 Amazon RDS for PostgreSQL 中管理高物件計數
<a name="PostgreSQL.HighObjectCount"></a>

雖然 PostgreSQL 限制是理論上的，但資料庫中具有極高的物件計數會對各種操作造成顯著的效能影響。本文件涵蓋數種常見的物件類型，當總計數過高時，可能會導致數種影響。

下表提供物件類型及其潛在影響的摘要：


**物件類型和潛在影響**  

| 物件的類型 | 自動清空 | 邏輯複寫 | 主要版本升級 | pg\$1dump / pg\$1restore | 一般效能 | 執行個體重新啟動 | 
| --- | --- | --- | --- | --- | --- | --- | 
| [關係](#PostgreSQL.HighObjectCount.Relations) | x |  | x | x | x |  | 
| [暫時資料表](#PostgreSQL.HighObjectCount.TempTables) | x |  |  |  | x |  | 
| [未記錄的資料表](#PostgreSQL.HighObjectCount.UnloggedTables) |  | x |  |  |  | x | 
| [分區](#PostgreSQL.HighObjectCount.Partitions) |  |  |  |  | x |  | 
| [暫存檔案](#PostgreSQL.HighObjectCount.TempFiles) |  |  |  |  | x |  | 
| [序列](#PostgreSQL.HighObjectCount.Sequences) |  | x |  |  |  |  | 
| [大型物件](#PostgreSQL.HighObjectCount.LargeObjects) |  | x | x |  |  |  | 

## 關係
<a name="PostgreSQL.HighObjectCount.Relations"></a>

PostgreSQL 資料庫中的資料表數量沒有特定的硬性限制。理論限制非常高，但在資料庫設計期間需要記住其他實際限制。

**影響：自動清空落後**  
與工作量相比，自動清空可能會難以跟上交易 ID 成長或資料表膨脹的情況。  
**建議的動作：**調整自動清空有幾個因素，可以正確跟上指定數量的資料表和指定工作負載。如需如何判斷適當自動清空設定的建議[，請參閱使用 PostgreSQL autovacuum](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.html) 。使用 [postgres\$1get\$1av\$1diag utility](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Functions.html)來監控交易 ID 成長的問題。

**影響：主要版本升級/pg\$1dump 和還原**  
Amazon RDS 在 pg\$1upgrade 執行期間使用「--link」選項，以避免必須複製資料檔案，結構描述中繼資料仍需要還原至新版本的資料庫。即使使用平行 pg\$1restore，如果有大量關聯，這也會增加停機時間。

**影響：一般效能降低**  
由於目錄大小而降低的一般效能。每個資料表及其相關聯的資料欄都會新增至 `pg_attribute`，`pg_class`以及常用於一般資料庫操作的`pg_depend`資料表。不會顯示特定的等待事件，但共用緩衝區效率會受到影響。  
**建議的動作：**定期檢查這些特定資料表的資料表膨脹，並偶爾在這些特定資料表`VACUUM FULL`上執行 。請注意，在目錄資料表`VACUUM FULL`上需要`ACCESS EXCLUSIVE`鎖定，這表示在操作完成之前，其他查詢都無法存取它們。

**影響：檔案描述項耗盡**  
錯誤：「檔案描述項不足：系統中開啟的檔案太多；發行並重試」。PostgreSQL 參數`max_files_per_process`會決定每個程序可以開啟的檔案數量。如果連接大量資料表的連線數量較多，則可能達到此限制。  
**建議的動作：**  
+ 降低 參數的值`max_files_per_process`可能有助於減輕此錯誤。每個程序和子程序 （例如平行查詢） 都可以開啟此數量的檔案，如果查詢正在聯結多個資料表，則會耗盡此限制。
+ 減少連線總數，並使用連線集區，例如 [Amazon RDS Proxy](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-proxy.html) 或其他解決方案，例如 PgBouncer。如需進一步了解，請參閱 [PgBouncer](https://www.pgbouncer.org/) 網站。

**影響：Inode 耗盡**  
錯誤：「裝置上沒有剩餘空間」。如果觀察到這種情況，表示有足夠的可用儲存空間，這是因為索引用盡。[Amazon RDS 增強型監控](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_Monitoring.OS.html)可為使用中的節點提供可見性，以及主機可用的最大數量。

**大約閾值：**[百萬](#PostgreSQL.HighObjectCount.Note)

## 暫時資料表
<a name="PostgreSQL.HighObjectCount.TempTables"></a>

使用暫存資料表對於測試資料或中繼結果很有用，而且是許多資料庫引擎中常見的模式。必須了解 PostgreSQL 中大量使用的影響，以避免某些陷阱。每個暫存資料表的建立和捨棄都會將資料列新增至系統目錄資料表，當資料表膨脹時，會導致一般效能問題。

**影響：自動清空落後**  
暫時資料表不會由自動清空清空，但會在交易 IDs存在期間保留，若未移除，可能會導致包裝。  
**建議的動作：**暫時資料表會在建立它們的工作階段期間持續運作，或可以手動捨棄。避免使用暫存資料表長時間執行交易的最佳實務，可防止這些資料表產生最大使用的交易 ID 成長。

**影響：一般效能降低**  
由於目錄大小而降低的一般效能。當工作階段持續建立和捨棄暫存資料表時，它會新增至 `pg_attribute`，`pg_class`以及常用於一般資料庫操作的`pg_depend`資料表。不會顯示特定的等待事件，但共用緩衝區效率會受到影響。  
**建議的動作：**  
+ 定期檢查這些特定資料表的資料表膨脹，並偶爾在這些特定資料表`VACUUM FULL`上執行 。請注意，在目錄資料表`VACUUM FULL`上需要`ACCESS EXCLUSIVE`鎖定，這表示在操作完成之前，其他查詢都無法存取它們。
+ 如果大量使用暫存資料表，在主要版本升級之前，強烈建議使用這些特定目錄資料表`VACUUM FULL`的 ，以減少停機時間。

**一般最佳實務：**
+ 使用常見的資料表表達式來產生中繼結果，以減少暫時資料表的使用。這些有時可能會使所需的查詢複雜化，但會消除上述影響。
+ 使用 `TRUNCATE`命令來清除內容，而不是執行捨棄/建立步驟，以重複使用暫存資料表。這也會消除暫時資料表造成交易 ID 成長的問題。

**大約閾值：**[數十萬](#PostgreSQL.HighObjectCount.Note)

## 未記錄的資料表
<a name="PostgreSQL.HighObjectCount.UnloggedTables"></a>

未記錄的資料表可以提供效能提升，因為它們不會產生任何 WAL 資訊。必須仔細使用它們，因為它們在資料庫損毀復原期間不會提供任何耐用性，因為它們將被截斷。這是 PostgreSQL 中的昂貴操作，因為每個未記錄的資料表都是序列截斷的。雖然對少量未記錄的資料表而言，此操作速度很快，但當它們以千為單位編號時，它可以開始在啟動期間新增顯著的延遲。

**影響：邏輯複寫**  
邏輯複寫通常不包含未記錄的資料表，包括[藍/綠部署](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/blue-green-deployments.html)，因為邏輯複寫依賴 WAL 來擷取和傳輸變更。

  


**影響：復原期間延長停機時間**  
在涉及資料庫損毀復原的任何資料庫狀態期間，例如具有容錯移轉的異地同步備份重新啟動、Amazon RDS point-in-time復原和 Amazon RDS 主要版本升級，將發生截斷未記錄資料表的序列化操作。這可能會導致比預期高出許多的停機時間體驗。  
**建議的動作：**  
+ 將未記錄資料表的使用量降至最低，僅限於資料庫損毀復原操作期間可遺失的資料。
+ 將未記錄資料表的使用降至最低，因為序列截斷的目前行為可能會導致資料庫啟動需要大量時間。

**一般最佳實務：**
+ 未記錄的資料表不會安全當機。啟動涉及損毀復原point-in-time復原會在 PostgreSQL 中花費大量時間，因為這是截斷每個資料表的序列程序。相較於標準 PostgreSQL，

**大約閾值：**[數千](#PostgreSQL.HighObjectCount.Note)

## 分區
<a name="PostgreSQL.HighObjectCount.Partitions"></a>

分割可以提高查詢效能並提供資料的邏輯組織。在理想情況下，會組織分割區，以便在查詢規劃和執行期間使用分割區剔除。使用太多分割區可能會對查詢效能和資料庫維護產生負面影響。應謹慎選擇如何分割資料表，因為查詢規劃和執行的效能可能會受到設計不佳的負面影響。如需分割的詳細資訊，請參閱 [PostgreSQL 文件](https://www.postgresql.org/docs/current/ddl-partitioning.html)。

**影響：一般效能降低**  
有時，規劃時間額外負荷會增加，並解釋查詢的計劃會變得更加複雜，導致難以識別調校機會。對於 18 之前的 PostgreSQL 版本，具有高工作負載的許多分割區可能會導致`LWLock:LockManager`等待。  
**建議動作：**判斷可讓您完成資料組織，同時提供效能查詢執行的分割區數量下限。

**影響：維護複雜性**  
非常大量的分割區會導致維護問題，例如建立前和移除。自動清空會將分割區視為一般關係，且必須執行定期清除，因此需要足夠的工作者來完成任務。  
**建議的動作：**  
+ 請確定您預先建立分割區，以便在需要新分割區 （例如，每月型分割區） 且舊分割區推出時，不會封鎖工作負載。
+ 確保您有足夠的自動清空工作者，可執行所有分割區的正常清除維護。

**大約閾值：**[數百](#PostgreSQL.HighObjectCount.Note)

## 暫存檔案
<a name="PostgreSQL.HighObjectCount.TempFiles"></a>

與上述的暫存資料表不同，當複雜的查詢可能同時執行數個排序或雜湊操作時，PostgreSQL 會建立暫存檔案，每個操作會使用執行個體記憶體將結果儲存到 `work_mem` 參數中指定的值。當執行個體記憶體不足時，會建立暫存檔來儲存結果。如需[暫存](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/PostgreSQL.ManagingTempFiles.html)檔案的詳細資訊，請參閱管理暫存檔案如果您的工作負載產生大量這些檔案，可能會有數種影響。

  


**影響：檔案描述項耗盡**  
錯誤：「檔案描述項不足：系統中開啟的檔案太多；發行並重試」。PostgreSQL 參數`max_files_per_process`會決定每個程序可以開啟的檔案數量。如果連接大量資料表的連線數量很高，則可能達到此限制。  
**建議的動作：**  
+ 降低 參數的值`max_files_per_process`可能有助於緩解此錯誤。每個程序和子程序 （例如平行查詢） 都可以開啟此數量的檔案，如果查詢正在聯結多個資料表，則會耗盡此限制。
+ 減少連線的整體數量，並使用連線集區器，例如 [Amazon RDS Proxy](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-proxy.html) 或其他解決方案，例如 PgBouncer。如需進一步了解，請參閱 [PgBouncer](https://www.pgbouncer.org/) 網站。

**影響：Inode 耗盡**  
錯誤：「裝置上沒有剩餘空間」。如果觀察到這種情況，表示有足夠的可用儲存空間，這是因為索引用盡。[Amazon RDS 增強型監控](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_Monitoring.OS.html)可為使用中的節點提供可見性，以及主機可用的最大數量。

**一般最佳實務：**
+ 使用 [Performance Insights](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_PerfInsights.html)監控您的暫存檔案用量。
+ 調校正在產生重要暫存檔案的查詢，以查看是否可以減少暫存檔案的總數。

**大約閾值：**[數千](#PostgreSQL.HighObjectCount.Note)

## 序列
<a name="PostgreSQL.HighObjectCount.Sequences"></a>

序列是用於在 PostgreSQL 中自動遞增資料欄的基礎物件，可為資料提供唯一性和金鑰。這些可用於個別資料表，在正常操作期間不會產生任何後果，但邏輯複寫除外。

在 PostgreSQL 中，邏輯複寫目前不會將序列的目前值複寫至任何訂閱者。若要進一步了解，請參閱 [ PostgreSQL 文件中的限制頁面](https://www.postgresql.org/docs/current/logical-replication-restrictions.html)。

**影響：延長切換時間**  
如果您計劃將 [Amazon RDS 藍/綠部署](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/blue-green-deployments.html)用於任何類型的組態變更或升級，請務必了解大量序列對切換的影響。切換的最後一個階段之一將同步序列的目前值，如果有數千個，這將增加整體切換時間。  
**建議的動作：**如果您的資料庫工作負載允許使用共用 UUID 而非sequence-per-table的方法，這會在切換期間減少同步步驟。

**大約閾值：**[數千](#PostgreSQL.HighObjectCount.Note)

## 大型物件
<a name="PostgreSQL.HighObjectCount.LargeObjects"></a>

大型物件存放在名為 pg\$1largeobject 的單一系統資料表中。每個大型物件在系統資料表 pg\$1largeobject\$1metadata 中也有一個項目。這些物件的建立、修改和清除與標準關係截然不同。大型物件不是由自動清空處理，必須透過稱為 vacuumlo 的個別程序定期清理。如需管理大型物件的範例，請參閱使用 lo 模組管理大型物件。

**影響：邏輯複寫**  
在邏輯複寫期間，目前不會在 PostgreSQL 中複寫大型物件。若要進一步了解，請參閱 [ PostgreSQL 文件中的限制頁面](https://www.postgresql.org/docs/current/logical-replication-restrictions.html)。在[藍色/綠色](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/blue-green-deployments.html)組態中，這表示藍色環境中的大型物件不會複寫至綠色環境。

**影響：主要版本升級**  
如果有數百萬個大型物件，且執行個體無法在升級期間處理它們，則升級可能會耗盡記憶體並失敗。PostgreSQL 主要版本升級程序包含兩個大階段：透過 pg\$1dump 傾印結構描述，並透過 pg\$1restore 還原結構描述。如果您的資料庫有數百萬個大型物件，您需要確保您的執行個體在升級期間有足夠的記憶體來處理 pg\$1dump 和 pg\$1restore，並將其擴展到更大的執行個體類型。

**一般最佳實務：**
+ 定期使用 vacuumlo 公用程式移除您可能擁有的任何孤立大型物件。
+ 考慮使用 BYTEA 資料類型將大型物件存放在資料庫中。

**大約閾值：**[百萬](#PostgreSQL.HighObjectCount.Note)

## 大約閾值
<a name="PostgreSQL.HighObjectCount.Note"></a>

本主題中提到的大約閾值僅用於提供特定資源可擴展程度的估計。它們代表一般範圍，其中描述的影響變得更有可能，但實際行為取決於您的特定工作負載、執行個體大小和組態。雖然可能超過這些預估值，但必須遵守注意和維護，以避免列出的影響。

# 在 Amazon RDS for PostgreSQL 中管理 TOAST OID 爭用
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID"></a>

TOAST （超大型屬性儲存技術） 是一種 PostgreSQL 功能，旨在處理超過一般 8KB 資料庫區塊大小的大型資料值。PostgreSQL 不允許實體資料列跨越多個區塊。區塊大小可做為資料列大小的上限。TOAST 透過將大型欄位值分割為較小的區塊來克服此限制。它將它們分別存放在連結到主資料表的專用 TOAST 資料表中。如需詳細資訊，請參閱 [PostgreSQL TOAST 儲存機制和實作文件](https://www.postgresql.org/docs/current/storage-toast.html)。

**Topics**
+ [了解 TOAST 操作](#Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.HowWorks)
+ [識別效能挑戰](#Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.PerformanceChallenges)
+ [建議](#Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.Recommendations)
+ [監控](#Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.Monitoring)

## 了解 TOAST 操作
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.HowWorks"></a>

TOAST 會執行壓縮，並離線存放大型欄位值。TOAST 會將唯一的 OID （物件識別符） 指派給儲存在 TOAST 資料表中的每個超大型資料區塊。主資料表會將 TOAST 值 ID 和關係 ID 存放在頁面上，以參考 TOAST 資料表中對應的資料列。這可讓 PostgreSQL 有效率地尋找和管理這些 TOAST 區塊。不過，隨著 TOAST 資料表的成長，系統可能會耗盡可用的 OIDs，導致效能降低和因 OID 耗盡而可能停機。

### TOAST 中的物件識別符
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.ObjectIdentifiers"></a>

物件識別符 (OID) 是 PostgreSQL 用於參考資料庫物件的全系統唯一識別符，例如資料表、索引和函數。這些識別符在 PostgreSQL 的內部操作中扮演重要角色，可讓資料庫有效率地尋找和管理物件。

對於具有合格資料集的資料表，PostgreSQL 會指派 OIDs，以唯一識別存放在相關聯 TOAST 資料表中的每個超大型資料區塊。系統會將每個區塊與 建立關聯`chunk_id`，這有助於 PostgreSQL 在 TOAST 資料表中有效率地組織和尋找這些區塊。

## 識別效能挑戰
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.PerformanceChallenges"></a>

PostgreSQL 的 OID 管理倚賴全域 32 位元計數器，以便在產生 40 億個唯一值之後進行包裝。當資料庫叢集共用此計數器時，OID 配置在 TOAST 操作期間涉及兩個步驟：
+ 用於**配置的全域計數器** – 全域計數器會跨叢集指派新的 OID。
+ **本機搜尋衝突** – TOAST 資料表可確保新的 OID 不會與該特定資料表中已使用的現有 OIDs 衝突。

發生下列情況時，可能會發生效能降低：
+ TOAST 資料表具有高分段或密集的 OID 用量，導致指派 OID 時發生延遲。
+ 系統經常在具有大量使用 TOAST 的高資料流失或寬資料表的環境中配置和重複使用 OIDs。

如需詳細資訊，請參閱 [PostgreSQL TOAST 資料表大小限制和 OID 配置文件](https://wiki.postgresql.org/wiki/TOAST#Total_table_size_limit)：

全域計數器會產生 OIDs 並包圍每 40 億個值，因此系統偶爾會再次產生已使用的值。PostgreSQL 偵測到 ，並使用下一個 OID 再次嘗試。如果使用過的 OID 值執行非常長，且在 TOAST 資料表中沒有間隙，則可能會發生緩慢的 INSERT。隨著 OID 空間填滿，這些挑戰變得更加明顯，導致插入和更新速度變慢。

### 識別問題
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.IdentifyingProblem"></a>
+ 簡單`INSERT`陳述式會以不一致且隨機的方式，花費比平常更長的時間。
+ 只有涉及 TOAST 操作的 `INSERT`和 `UPDATE`陳述式才會發生延遲。
+ 當系統難以在 TOAST 資料表中尋找可用的 OIDs時，以下日誌項目會出現在 PostgreSQL 日誌中：

  ```
  LOG: still searching for an unused OID in relation "pg_toast_20815"
  DETAIL: OID candidates have been checked 1000000 times, but no unused OID has been found yet.
  ```
+ Performance Insights 指出與 `LWLock:buffer_io`和`LWLock:OidGenLock`等待事件相關聯的大量平均作用中工作階段 (AAS)。

  您可以執行下列 SQL 查詢，以識別具有等待事件的長期執行 INSERT 交易：

  ```
  SELECT
      datname AS database_name,
      usename AS database_user,
      pid,
      now() - pg_stat_activity.xact_start AS transaction_duration,
      concat(wait_event_type, ':', wait_event) AS wait_event,
      substr(query, 1, 30) AS TRANSACTION,
      state
  FROM
      pg_stat_activity
  WHERE (now() - pg_stat_activity.xact_start) > INTERVAL '60 seconds'
      AND state IN ('active', 'idle in transaction', 'idle in transaction (aborted)', 'fastpath function call', 'disabled')
      AND pid <> pg_backend_pid()
  AND lower(query) LIKE '%insert%'
  ORDER BY
      transaction_duration DESC;
  ```

  顯示具有延長等待時間的 INSERT 操作的查詢結果範例：

  ```
   database_name |  database_user  |  pid  | transaction_duration |     wait_event      |          transaction           | state
  ---------------+-----------------+-------+----------------------+---------------------+--------------------------------+--------
   postgres       | db_admin_user| 70965 | 00:10:19.484061      | LWLock:buffer_io    | INSERT INTO "products" (......... | active
   postgres       | db_admin_user| 69878 | 00:06:14.976037      | LWLock:buffer_io    | INSERT INTO "products" (......... | active
   postgres       | db_admin_user| 68937 | 00:05:13.942847      | :                   | INSERT INTO "products" (......... | active
  ```

### 隔離問題
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.IsolatingProblem"></a>
+ **測試小型插入** – 插入小於`toast_tuple_target`閾值的記錄。請記住，壓縮會在 TOAST 儲存體之前套用。如果此操作沒有效能問題，則問題與 TOAST 操作有關。
+ **測試新資料表** – 建立具有相同結構的新資料表，並插入大於 的記錄`toast_tuple_target`。如果這樣做沒有問題，問題會本地化為原始資料表的 OID 配置。

## 建議
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.Recommendations"></a>

下列方法有助於解決 TOAST OID 爭用問題。
+ **資料清除和封存** – 檢閱和刪除任何過時或不必要的資料，以釋出 OIDs 以供日後使用，或封存資料。考量下列限制：
  + 可擴展性有限，因為未來可能不一定可以進行清理。
  + 可能長時間執行的 VACUUM 操作，以移除產生的無效元組。
+ **寫入新資料表** – 為未來的插入建立新的資料表，並使用`UNION ALL`檢視來合併查詢的舊資料和新資料。此檢視會顯示舊資料表和新資料表的合併資料，允許查詢以單一資料表的形式存取它們。考量下列限制：
  + 舊資料表的更新仍可能導致 OID 耗盡。
+ **分割區或碎片** – 分割資料表或碎片資料，以獲得更佳的可擴展性和效能。考量下列限制：
  + 查詢邏輯和維護的複雜性更高，可能需要應用程式變更才能正確處理分割的資料。

## 監控
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.Monitoring"></a>

### 使用系統資料表
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.SystemTables"></a>

您可以使用 PostgreSQL 的系統資料表來監控 OID 用量的成長。

**警告**  
根據 TOAST 資料表中的 OIDs 數量，可能需要一些時間才能完成。建議您在非上班時間排定監控，以將影響降至最低。

下列匿名區塊會計算每個 TOAST 資料表中使用的不同 OIDs 數目，並顯示父資料表資訊：

```
DO $$
DECLARE
    r record;
    o bigint;
    parent_table text;
    parent_schema text;
BEGIN
    SET LOCAL client_min_messages TO notice;
    FOR r IN
    SELECT
        c.oid,
        c.oid::regclass AS toast_table
    FROM
        pg_class c
    WHERE
        c.relkind = 't'
        AND c.relowner != 10 LOOP
            -- Fetch the number of distinct used OIDs (chunk IDs) from the TOAST table
            EXECUTE 'SELECT COUNT(DISTINCT chunk_id) FROM ' || r.toast_table INTO o;
            -- If there are used OIDs, find the associated parent table and its schema
            IF o <> 0 THEN
                SELECT
                    n.nspname,
                    c.relname INTO parent_schema,
                    parent_table
                FROM
                    pg_class c
                    JOIN pg_namespace n ON c.relnamespace = n.oid
                WHERE
                    c.reltoastrelid = r.oid;
                -- Raise a concise NOTICE message
                RAISE NOTICE 'Parent schema: % | Parent table: % | Toast table: % | Number of used OIDs: %', parent_schema, parent_table, r.toast_table, TO_CHAR(o, 'FM9,999,999,999,999');
            END IF;
        END LOOP;
END
$$;
```

依 TOAST 資料表顯示 OID 用量統計資料的範例輸出：

```
NOTICE:  Parent schema: public | Parent table: my_table | Toast table: pg_toast.pg_toast_16559 | Number of used OIDs: 45,623,317
NOTICE:  Parent schema: public | Parent table: my_table1 | Toast table: pg_toast.pg_toast_45639925 | Number of used OIDs: 10,000
NOTICE:  Parent schema: public | Parent table: my_table2 | Toast table: pg_toast.pg_toast_45649931 | Number of used OIDs: 1,000,000
DO
```

下列匿名區塊會擷取每個非空白 TOAST 資料表指派的 OID 上限：

```
DO $$
DECLARE
    r record;
    o bigint;
    parent_table text;
    parent_schema text;
BEGIN
    SET LOCAL client_min_messages TO notice;
    FOR r IN
    SELECT
        c.oid,
        c.oid::regclass AS toast_table
    FROM
        pg_class c
    WHERE
        c.relkind = 't'
        AND c.relowner != 10 LOOP
            -- Fetch the max(chunk_id) from the TOAST table
            EXECUTE 'SELECT max(chunk_id) FROM ' || r.toast_table INTO o;
            -- If there's at least one TOASTed chunk, find the associated parent table and its schema
            IF o IS NOT NULL THEN
                SELECT
                    n.nspname,
                    c.relname INTO parent_schema,
                    parent_table
                FROM
                    pg_class c
                    JOIN pg_namespace n ON c.relnamespace = n.oid
                WHERE
                    c.reltoastrelid = r.oid;
                -- Raise a concise NOTICE message
                RAISE NOTICE 'Parent schema: % | Parent table: % | Toast table: % | Max chunk_id: %', parent_schema, parent_table, r.toast_table, TO_CHAR(o, 'FM9,999,999,999,999');
            END IF;
        END LOOP;
END
$$;
```

顯示 TOAST 資料表最大區塊 IDs的範例輸出：

```
NOTICE:  Parent schema: public | Parent table: my_table | Toast table: pg_toast.pg_toast_16559 | Max chunk_id: 45,639,907
NOTICE:  Parent schema: public | Parent table: my_table1 | Toast table: pg_toast.pg_toast_45639925 | Max chunk_id: 45,649,929
NOTICE:  Parent schema: public | Parent table: my_table2 | Toast table: pg_toast.pg_toast_45649931 | Max chunk_id: 46,649,935
DO
```

### 使用 Performance Insights
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.PerformanceInsights"></a>

在需要指派新物件識別符 (OIDs) 的操作期間，等待事件`LWLock:buffer_io`和 `LWLock:OidGenLock`會出現在績效詳情中。這些事件的高平均作用中工作階段 (AAS) 通常會在 OID 指派和資源管理期間指向爭用。這在具有高資料流失、大量大數據用量或頻繁建立物件的環境中特別常見。

#### LWLock：buffer\$1io
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.LWLockBufferIO"></a>

`LWLock:buffer_io` 是當 PostgreSQL 工作階段正在等待共用緩衝區上的 I/O 操作完成時發生的等待事件。當資料庫將資料從磁碟讀取到記憶體，或將修改過的頁面從記憶體寫入磁碟時，通常會發生這種情況。`BufferIO` 等待事件會防止多個程序在 I/O 操作進行時存取或修改相同的緩衝區，以確保一致性。此等待事件的頻繁出現可能表示資料庫工作負載中的磁碟瓶頸或過多的 I/O 活動。

在 TOAST 操作期間：
+ PostgreSQL 會為大型物件配置 OIDs，並透過掃描 TOAST 資料表的索引來確保其唯一性。
+ 大型 TOAST 索引可能需要存取多個頁面來驗證 OID 唯一性。這會導致磁碟 I/O 增加，特別是當緩衝集區無法快取所有必要的頁面時。

索引的大小會直接影響在這些操作期間需要存取的緩衝區頁面數目。即使索引未膨脹，其透薄大小也會增加緩衝區 I/O，尤其是在高並行或高流失環境中。如需詳細資訊，請參閱 [LWLock：BufferIO 等待事件疑難排解指南](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/apg-waits.lwlockbufferio.html)。

#### LWLock:OidGenLock
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.LWLockOidGenLock"></a>

`OidGenLock` 是當 PostgreSQL 工作階段正在等待配置新的物件識別符 (OID) 時發生的等待事件。此鎖定可確保循序且安全地產生 OIDs，一次只允許一個程序產生 OIDs。

在 TOAST 操作期間：
+ **TOAST 資料表中區塊的 OID 配置** – PostgreSQL 會將 OIDs 指派給 TOAST 資料表中的區塊。每個 OID 都必須是唯一的，以防止系統目錄中的衝突。
+ **高並行** – 由於對 OID 產生器的存取是循序的，因此當多個工作階段同時建立需要 OIDs物件時，`OidGenLock`可能會發生 的爭用。這會增加工作階段等待 OID 配置完成的可能性。
+ **相依於系統目錄存取** – 配置 OIDs 需要更新共用系統目錄資料表，例如 `pg_class`和 `pg_type`。如果這些資料表遇到繁重的活動 （由於頻繁的 DDL 操作），可能會增加 的鎖定爭用`OidGenLock`。
+ **高 OID 分配需求** – 具有大型資料記錄的 TOAST 繁重工作負載需要持續的 OID 分配，從而增加爭用。

增加 OID 爭用的其他因素：
+ **頻繁建立物件** – 經常建立和捨棄物件的工作負載，例如暫存資料表，在全域 OID 計數器上擴增爭用。
+ **全域計數器鎖定** – 全域 OID 計數器會循序存取，以確保唯一性，在高並行環境中建立單一爭用點。

## 搭配使用 RDS for PostgreSQL 支援的記錄機制
<a name="Appendix.PostgreSQL.CommonDBATasks.Auditing"></a>

您可以設定數個參數、擴充功能和其他可設定項目來記錄在 PostgreSQL 資料庫執行個體上發生的活動。這些索引標籤包括以下項目：
+ `log_statement` 參數可用來記錄 PostgreSQL 資料庫中的使用者活動。若要進一步了解 RDS for PostgreSQL 記錄和如何監控日誌，請參閱 [ RDS for PostgreSQL 資料庫日誌檔案](USER_LogAccess.Concepts.PostgreSQL.md)。
+ `rds.force_admin_logging_level` 參數可記錄 Amazon RDS 內部使用者 (rdsadmin) 在資料庫中對資料庫執行個體執行的動作。其會將輸出寫入 PostgreSQL 錯誤日誌。允許的值為：`disabled`、`debug5`、`debug4`、`debug3`、`debug2`、`debug1`、`info`、`notice`、`warning`、`error`、log、`fatal` 和 `panic`。預設值為 `disabled`。
+ `rds.force_autovacuum_logging_level` 參數可設定為在 PostgreSQL 錯誤日誌中擷取各種自動資料清理作業。如需詳細資訊，請參閱[記錄清理和自動資料清理活動](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.Logging.md)。
+ PostgreSQL Audit (pgAudit) 擴充功能可安裝並設定為擷取工作階段層級或物件層級的活動。如需詳細資訊，請參閱[使用 PgAudit 記錄資料庫活動](Appendix.PostgreSQL.CommonDBATasks.pgaudit.md)。
+ `log_fdw` 擴充功能可讓您使用 SQL 存取資料庫引擎日誌。如需詳細資訊，請參閱[使用 log\$1fdw 擴充功能存取使用 SQL 的資料庫日誌](CHAP_PostgreSQL.Extensions.log_fdw.md)。
+ `pg_stat_statements` 程式庫被指定為 RDS for PostgreSQL 第 10 版及更高版本中 `shared_preload_libraries` 參數的預設值。您可以使用這個程式庫來分析正在執行的查詢。請確定已在資料庫參數群組中設定 `pg_stat_statements`。如需使用此程式庫提供的資訊監控 RDS for PostgreSQL 資料庫執行個體的詳細資訊，請參閱 [RDS PostgreSQL 的 SQL 統計資料](USER_PerfInsights.UsingDashboard.AnalyzeDBLoad.AdditionalMetrics.PostgreSQL.md)。
+ `log_hostname` 參數會將每個用戶端連線的主機名稱擷取至日誌檔。對於 RDS for PostgreSQL 第 12 版及更新版本，此參數預設會設為 `off`。如果您將其開啟，請務必監控工作階段連線時間。開啟時，服務會使用網域名稱系統 (DNS) 反向查詢請求，來取得進行連線的用戶端主機名稱，並將其新增至 PostgreSQL 日誌。這會在工作階段連線期間產生明顯的影響。建議您開啟此參數，僅用於疑難排解目的。

一般來說，記錄是為了讓 DBA 監控情況、調校效能和排除故障。許多日誌都會自動上傳到 Amazon CloudWatch 或 Performance Insights。日誌會在這些地方進行排序和分組，以便為您的資料庫執行個體提供完整的指標。若要進一步了解 Amazon RDS 監控和指標，請參閱 [監控 Amazon RDS 執行個體中的指標](CHAP_Monitoring.md)。

# 使用 PostgreSQL 管理暫存檔案
<a name="PostgreSQL.ManagingTempFiles"></a>

在 PostgreSQL 中，複雜查詢可能會同時執行數個排序或雜湊操作，每個操作都使用執行個體記憶體來儲存結果，直到 [https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-WORK-MEM](https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-WORK-MEM) 參數中指定的值為止。當執行個體記憶體不足時，會建立暫存檔來儲存結果。這些檔案會寫入磁碟以完成查詢執行。稍後，這些檔案會在查詢完成後自動移除。在 RDS for PostgreSQL 中，這些檔案會儲存在資料磁碟區上的 Amazon EBS 中。如需詳細資訊，請參閱 [Amazon RDS 資料庫執行個體儲存體](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Storage.html)。您可以監控在 CloudWatch​ 中發佈的 `FreeStorageSpace`​ 指標，藉此確保資料庫執行個體有充足的可用儲存空間。如需詳細資訊，請參閱 [https://repost.aws/knowledge-center/storage-full-rds-cloudwatch-alarm](https://repost.aws/knowledge-center/storage-full-rds-cloudwatch-alarm)。

我們建議針對涉及多個並行查詢的工作負載使用 Amazon RDS Optimized Read 執行個體，以增加暫存檔案的使用量。這些執行個體會使用本機非揮發性記憶體快速 (NVMe) 為主的固態硬碟 (SSD) 區塊層級儲存體來放置暫存檔案。如需詳細資訊，請參閱 [使用 Amazon RDS Optimized Reads 改善 RDS for PostgreSQL 的查詢效能](USER_PostgreSQL.optimizedreads.md)。

您可以使用以下參數和函數來管理執行個體中的暫存檔案。
+ **[https://www.postgresql.org/docs/current/runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-DISK](https://www.postgresql.org/docs/current/runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-DISK)** – 此參數會取消任何超過 temp\$1file 大小的查詢 (以 KB 為單位)。此限制可防止任何查詢無休止地執行，並消耗含有暫存檔的磁碟空間。您可以使用 `log_temp_files` 參數的結果來估計值。最佳實務是檢查工作負載行為並根據估計值設定限制。以下範例顯示查詢超過限制時的取消方式。

  ```
  postgres=>select * from pgbench_accounts, pg_class, big_table;
  ```

  ```
  ERROR: temporary file size exceeds temp_file_limit (64kB)
  ```
+ **[https://www.postgresql.org/docs/current/runtime-config-logging.html#GUC-LOG-TEMP-FILES](https://www.postgresql.org/docs/current/runtime-config-logging.html#GUC-LOG-TEMP-FILES)** – 此參數會在移除工作階段的暫存檔案時，將訊息傳送至 postgresql.log。這個參數會在查詢順利完成後產生日誌。因此，它可能無助於疑難排解使用中、長時間執行的查詢。

  下列範例顯示，當查詢順利完成時，這些項目會在清理暫存檔時記錄在 postgresql.log 檔案中。

  ```
                      
  2023-02-06 23:48:35 UTC:205.251.233.182(12456):adminuser@postgres:[31236]:LOG:  temporary file: path "base/pgsql_tmp/pgsql_tmp31236.5", size 140353536
  2023-02-06 23:48:35 UTC:205.251.233.182(12456):adminuser@postgres:[31236]:STATEMENT:  select a.aid from pgbench_accounts a, pgbench_accounts b where a.bid=b.bid order by a.bid limit 10;
  2023-02-06 23:48:35 UTC:205.251.233.182(12456):adminuser@postgres:[31236]:LOG:  temporary file: path "base/pgsql_tmp/pgsql_tmp31236.4", size 180428800
  2023-02-06 23:48:35 UTC:205.251.233.182(12456):adminuser@postgres:[31236]:STATEMENT:  select a.aid from pgbench_accounts a, pgbench_accounts b where a.bid=b.bid order by a.bid limit 10;
  ```
+ **[https://www.postgresql.org/docs/current/functions-admin.html#FUNCTIONS-ADMIN-GENFILE](https://www.postgresql.org/docs/current/functions-admin.html#FUNCTIONS-ADMIN-GENFILE)** – 此功能可從 RDS for PostgreSQL 13 及以上版本使用，提供目前暫存檔案使用情況的可見性。完成的查詢不會出現在函數的結果中。在下列範例中，您可以檢視此函數的結果。

  ```
  postgres=>select * from pg_ls_tmpdir();
  ```

  ```
        name       |    size    |      modification
  -----------------+------------+------------------------
   pgsql_tmp8355.1 | 1072250880 | 2023-02-06 22:54:56+00
   pgsql_tmp8351.0 | 1072250880 | 2023-02-06 22:54:43+00
   pgsql_tmp8327.0 | 1072250880 | 2023-02-06 22:54:56+00
   pgsql_tmp8351.1 |  703168512 | 2023-02-06 22:54:56+00
   pgsql_tmp8355.0 | 1072250880 | 2023-02-06 22:54:00+00
   pgsql_tmp8328.1 |  835031040 | 2023-02-06 22:54:56+00
   pgsql_tmp8328.0 | 1072250880 | 2023-02-06 22:54:40+00
  (7 rows)
  ```

  ```
  postgres=>select query from pg_stat_activity where pid = 8355;
                  
  query
  ----------------------------------------------------------------------------------------
  select a.aid from pgbench_accounts a, pgbench_accounts b where a.bid=b.bid order by a.bid
  (1 row)
  ```

  檔案名稱包含產生暫存檔之工作階段的處理 ID (PID)。較進階的查詢 (例如下列範例) 會針對每個 PID 執行暫存檔案的總和。

  ```
  postgres=>select replace(left(name, strpos(name, '.')-1),'pgsql_tmp','') as pid, count(*), sum(size) from pg_ls_tmpdir() group by pid;
  ```

  ```
   pid  | count |   sum
  ------+-------------------
   8355 |     2 | 2144501760
   8351 |     2 | 2090770432
   8327 |     1 | 1072250880
   8328 |     2 | 2144501760
  (4 rows)
  ```
+ **`[ pg\$1stat\$1statements](https://www.postgresql.org/docs/current/pgstatstatements.html)`** – 如果您啟動 pg\$1stat\$1statements 參數，則可以檢視每次呼叫的平均暫存檔案使用量。您可以識別查詢的 query\$1id，並使用它來檢查暫存檔的使用情況，如以下範例所示。

  ```
  postgres=>select queryid from pg_stat_statements where query like 'select a.aid from pgbench%';
  ```

  ```
         queryid
  ----------------------
   -7170349228837045701
  (1 row)
  ```

  ```
  postgres=>select queryid, substr(query,1,25), calls, temp_blks_read/calls temp_blks_read_per_call, temp_blks_written/calls temp_blks_written_per_call from pg_stat_statements where queryid = -7170349228837045701;
  ```

  ```
         queryid        |          substr           | calls | temp_blks_read_per_call | temp_blks_written_per_call
  ----------------------+---------------------------+-------+-------------------------+----------------------------
   -7170349228837045701 | select a.aid from pgbench |    50 |                  239226 |                     388678
  (1 row)
  ```
+ **`[Performance Insights](https://aws.amazon.com/rds/performance-insights/)`** – 在績效詳情儀表板中，您可以透過開啟指標 **temp\$1bytes** 和 **temp\$1files** 來檢視暫存檔的使用情況。然後，您可以查看這兩個指標的平均值，並查看它們如何對應至查詢工作負載。績效詳情中的檢視不會明確顯示產生暫存檔的查詢。不過，當您將績效詳情與為 `pg_ls_tmpdir` 顯示的查詢結合使用時，您可以疑難排解、分析及判斷查詢工作負載中的變更。

  如需如何使用 Performance Insights 來分析指標和查詢的詳細資訊，請參閱 [使用績效詳情儀表板來分析指標](USER_PerfInsights.UsingDashboard.md)。

  如需使用 Performance Insights 檢視暫存檔案使用量的範例，請參閱 [使用 Performance Insights 來檢視暫存檔使用情況](PostgreSQL.ManagingTempFiles.Example.md)

# 使用 Performance Insights 來檢視暫存檔使用情況
<a name="PostgreSQL.ManagingTempFiles.Example"></a>

您可以使用 Performance Insights，透過開啟指標 **temp\$1bytes** 和 **temp\$1files** 來檢視暫存檔的使用情況。Performance Insights 中的檢視不會顯示產生暫存檔的特定查詢，但是，當您將 Performance Insights 與針對 `pg_ls_tmpdir` 顯示的查詢結合時，您可以疑難排解、分析和判斷查詢工作負載中的變更。

1. 在 [績效詳情] 儀表板中選擇**管理指標**。

1. 選擇**資料庫指標**，並選取 **temp\$1bytes** 和 **temp\$1files** 指標，如下方影像所示。  
![\[指標會顯示在圖形中。\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/images/rpg_mantempfiles_metrics.png)

1. 在**最高 SQL**索引標籤中，選擇**偏好設定**圖示。

1. 在**偏好設定**視窗中，開啟**最高 SQL**索引標籤中顯示的下列統計資料，然後選擇**繼續**。
   + Temp writes/sec
   + Temp reads/sec
   + Tmp blk write/call
   + Tmp blk read/call

1. 暫存檔在與針對 `pg_ls_tmpdir` 顯示的查詢組合時會被劃分，如以下範例所示。  
![\[顯示暫存檔使用情況的查詢。\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/images/rpg_mantempfiles_query.png)

當工作負載中最常用的查詢經常建立暫存檔案時，就會發生 `IO:BufFileRead` 和 `IO:BufFileWrite` 事件。您可以使用 Performance Insights，透過檢閱「資料庫負載」和「最高 SQL」區段中的「平均作用中工作階段」(AAS)，找出最常在 `IO:BufFileRead` 和 `IO:BufFileWrite` 上等待的查詢。

![\[圖中的 IO:BufFileRead 和 IO:BufFileWrite。\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/images/perfinsights_IOBufFile.png)


如需如何使用 Performance Insights 來分析各等待事件的最常用查詢和負載的詳細資訊，請參閱 [最高 SQL 索引標籤概觀](USER_PerfInsights.UsingDashboard.AnalyzeDBLoad.AdditionalMetrics.md#USER_PerfInsights.UsingDashboard.Components.AvgActiveSessions.TopLoadItemsTable.TopSQL)。您應找出並調整造成暫存檔案使用量及相關等待事件增加的查詢。如需這些等待事件和修補的詳細資訊，請參閱 [IO:BufFileRead 和 IO:BufFileWrite](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/wait-event.iobuffile.html)。

**注意**  
[https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-WORK-MEM](https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-WORK-MEM) 參數可控制排序操作何時用完記憶體，以及將結果寫入暫存檔。我們建議您不要將此參數的設定變更為高於預設值，因為它會允許每個資料庫工作階段耗用更多記憶體。此外，執行複雜聯結和排序的單一工作階段可以執行平行操作，其中每個操作都會耗用記憶體。  
最佳實務是，當您有具有多個聯結和排序的大型報表時，請使用 `SET work_mem` 命令在工作階段層級設定此參數。然後，變更僅套用於目前工作階段，不會全域變更該值。

## 使用 pgBadger 進行 PostgreSQL 的日誌分析
<a name="Appendix.PostgreSQL.CommonDBATasks.Badger"></a>

您可以使用 [pgbadger](http://dalibo.github.io/pgbadger/) 等日誌分析器來分析 PostgreSQL 日誌。pgBadger 文件會陳述 %l 模式 (工作階段或程序的日誌行) 應該是字首的一部分。不過，如果您將目前的 RDS `log_line_prefix` 當作參數提供給 pgBadger，它應該仍會產生報告。

例如，下列命令會使用 pgbadger 正確地格式化日期為 2014-02-04 的 Amazon RDS for PostgreSQL 日誌檔案。

```
./pgbadger -f stderr -p '%t:%r:%u@%d:[%p]:' postgresql.log.2014-02-04-00 
```

## 使用 PgSNAPPER 監控 PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Snapper"></a>

您可以使用 PgSNapper 協助定期收集與 Amazon RDS for PostgreSQL 效能相關的統計資訊和指標。如需詳細資訊，請參閱[使用 PGSnapper 監控 Amazon RDS for PostgreSQL 效能](https://aws.amazon.com/blogs/database/monitor-amazon-rds-for-postgresql-and-amazon-aurora-postgresql-performance-using-pgsnapper/)

# 在 RDS for PostgreSQL 中管理自訂轉換
<a name="PostgreSQL.CustomCasts"></a>

PostgreSQL **中的類型轉換**是將值從一個資料類型轉換為另一個資料類型的程序。PostgreSQL 提供許多常見轉換的內建轉換，但您也可以建立自訂轉換來定義特定類型轉換應如何運作。

轉換指定如何執行從一個資料類型到另一個資料類型的轉換。例如，將文字轉換為`'123'`整數 `123`，或將數值`45.67`轉換為文字 `'45.67'`。

如需 PostgreSQL 轉換概念和語法的完整資訊，請參閱 [PostgreSQL CREATE CAST 文件](https://www.postgresql.org/docs/current/sql-createcast.html)。

從 RDS for PostgreSQL 13.23、14.20、15.15、16.11、17.7 和 18.1 版開始，您可以使用 rds\$1casts 擴充功能為內建類型安裝額外的轉換，同時仍然能夠為自訂類型建立自己的轉換。

**Topics**
+ [安裝和使用 rds\$1casts 延伸模組](#PostgreSQL.CustomCasts.Installing)
+ [支援的轉換](#PostgreSQL.CustomCasts.Supported)
+ [建立或捨棄轉換](#PostgreSQL.CustomCasts.Creating)
+ [使用適當的內容策略建立自訂轉換](#PostgreSQL.CustomCasts.BestPractices)

## 安裝和使用 rds\$1casts 延伸模組
<a name="PostgreSQL.CustomCasts.Installing"></a>

若要建立`rds_casts`擴充功能，請將 RDS for 執行個體，`rds_superuser`並執行下列命令： PostgreSQL  

```
CREATE EXTENSION IF NOT EXISTS rds_casts;
```

## 支援的轉換
<a name="PostgreSQL.CustomCasts.Supported"></a>

在您要使用自訂轉換的每個資料庫中建立延伸。建立擴充功能後，請使用下列命令來檢視所有可用的轉換：

```
SELECT * FROM rds_casts.list_supported_casts();
```

此函數會列出可用的轉換組合 （來源類型、目標類型、強制內容和轉換函數）。例如，如果您想要`text`將 建立`numeric`為 `implicit` 轉換。您可以使用下列查詢來尋找轉換是否可供建立：

```
SELECT * FROM rds_casts.list_supported_casts()
WHERE source_type = 'text' AND target_type = 'numeric';
 id | source_type | target_type |          qualified_function          | coercion_context
----+-------------+-------------+--------------------------------------+------------------
 10 | text        | numeric     | rds_casts.rds_text_to_numeric_custom | implicit
 11 | text        | numeric     | rds_casts.rds_text_to_numeric_custom | assignment
 13 | text        | numeric     | rds_casts.rds_text_to_numeric_custom | explicit
 20 | text        | numeric     | rds_casts.rds_text_to_numeric_inout  | implicit
 21 | text        | numeric     | rds_casts.rds_text_to_numeric_inout  | assignment
 23 | text        | numeric     | rds_casts.rds_text_to_numeric_inout  | explicit
```

rds\$1casts 延伸提供每種轉換函數的兩種類型：
+ *\$1inout 函數* - 使用 PostgreSQL 的標準 I/O 轉換機制，其行為與使用 INOUT 方法建立的轉換完全相同
+ *\$1custom 函數* - 提供處理邊緣案例的增強型轉換邏輯，例如將空字串轉換為 NULL 值以避免轉換錯誤

這些`inout`函數會複寫 PostgreSQL 的原生轉換行為，而`custom`函數會透過處理標準 INOUT 轉換無法容納的案例來擴展此功能，例如將空字串轉換為整數。

## 建立或捨棄轉換
<a name="PostgreSQL.CustomCasts.Creating"></a>

您可以使用兩種方法建立和捨棄支援的轉換：

### 投射建立
<a name="PostgreSQL.CustomCasts.Creating.Methods"></a>

**方法 1：使用原生 CREATE CAST 命令**

```
CREATE CAST (text AS numeric)
WITH FUNCTION rds_casts.rds_text_to_numeric_custom
AS IMPLICIT;
```

**方法 2：使用 rds\$1casts.create\$1cast 函數**

```
SELECT rds_casts.create_cast(10);
```

`create_cast` 函數會從`list_supported_casts()`輸出取得 ID。此方法更簡單，並確保您使用正確的函數和內容組合。此 ID 保證在不同 Postgres 版本中保持不變。

若要確認已成功建立轉換，請查詢 pg\$1cast 系統目錄：

```
SELECT oid, castsource::regtype, casttarget::regtype, castfunc::regproc, castcontext, castmethod
FROM pg_cast
WHERE castsource = 'text'::regtype AND casttarget = 'numeric'::regtype;
  oid   | castsource | casttarget |               castfunc               | castcontext | castmethod
--------+------------+------------+--------------------------------------+-------------+------------
 356372 | text       | numeric    | rds_casts.rds_text_to_numeric_custom | i           | f
```

`castcontext` 資料欄顯示：`e`適用於 EXPLICIT、`a`適用於 ASSIGNMENT 或`i`適用於 IMPLICIT。

### 捨棄轉換
<a name="PostgreSQL.CustomCasts.Dropping"></a>

**方法 1：使用 DROP CAST 命令**

```
DROP CAST IF EXISTS (text AS numeric);
```

**方法 2：使用 rds\$1casts.drop\$1cast 函數**

```
SELECT rds_casts.drop_cast(10);
```

`drop_cast` 函數會採用與建立投射時相同的 ID。此方法可確保您捨棄使用對應 ID 建立的確切轉換。

## 使用適當的內容策略建立自訂轉換
<a name="PostgreSQL.CustomCasts.BestPractices"></a>

為整數類型建立多個轉換時，如果所有轉換都建立為 IMPLICIT，則可能會發生運算子模棱兩可錯誤。下列範例透過建立從文字到不同整數寬度的兩個隱含轉換來示範此問題：

```
-- Creating multiple IMPLICIT casts causes ambiguity
postgres=> CREATE CAST (text AS int4) WITH FUNCTION rds_casts.rds_text_to_int4_custom(text) AS IMPLICIT;
CREATE CAST
postgres=> CREATE CAST (text AS int8) WITH FUNCTION rds_casts.rds_text_to_int8_custom(text) AS IMPLICIT;
CREATE CAST

postgres=> CREATE TABLE test_cast(col int);
CREATE TABLE
postgres=> INSERT INTO test_cast VALUES ('123'::text);
INSERT 0 1
postgres=> SELECT * FROM test_cast WHERE col='123'::text;
ERROR:  operator is not unique: integer = text
LINE 1: SELECT * FROM test_cast WHERE col='123'::text;
                                         ^
HINT:  Could not choose a best candidate operator. You might need to add explicit type casts.
```

發生錯誤是因為 PostgreSQL 無法判斷在比較整數資料欄與文字值時要使用的隱含轉換。int4 和 int8 隱含轉換都是有效的候選項目，可建立模棱兩可。

若要避免此運算子模棱兩可的情況，請針對較小的整數寬度使用 ASSIGNMENT 內容，針對較大的整數寬度使用 IMPLICIT 內容：

```
-- Use ASSIGNMENT for smaller integer widths
CREATE CAST (text AS int2)
WITH FUNCTION rds_casts.rds_text_to_int2_custom(text)
AS ASSIGNMENT;

CREATE CAST (text AS int4)
WITH FUNCTION rds_casts.rds_text_to_int4_custom(text)
AS ASSIGNMENT;

-- Use IMPLICIT for larger integer widths
CREATE CAST (text AS int8)
WITH FUNCTION rds_casts.rds_text_to_int8_custom(text)
AS IMPLICIT;

postgres=> INSERT INTO test_cast VALUES ('123'::text);
INSERT 0 1
postgres=> SELECT * FROM test_cast WHERE col='123'::text;
 col
-----
 123
(1 row)
```

透過此策略，只有 int8 轉換是隱含的，因此 PostgreSQL 可以明確判斷要使用的轉換。

# RDS for PostgreSQL 中平行查詢的最佳實務
<a name="PostgreSQL.ParallelQueries"></a>

平行查詢執行是 PostgreSQL 的一項功能，可讓單一 SQL 查詢分割為由多個背景工作者程序同時處理的較小任務。PostgreSQL 可以跨多個 CPU 核心分配部分的查詢，例如掃描、聯結、彙總或排序，而不是完全在單一後端程序中執行查詢。*領導者程序*會協調此執行，並從*平行工作者*收集結果。

不過，對於大多數生產工作負載，特別是高並行 OLTP 系統，我們建議停用自動平行查詢執行。雖然平行處理可以加速分析或報告工作負載中大型資料集的查詢，但它帶來的重大風險通常超過忙碌生產環境中的優勢。

平行執行也會帶來大量的額外負荷。每個平行工作者都是完整的 PostgreSQL 後端程序，這需要程序偽造 （複製記憶體結構和初始化程序狀態） 和身分驗證 （從您的`max_connections`限制使用連線插槽）。每個工作者也會使用自己的記憶體，包括`work_mem`用於排序和雜湊操作，每個查詢有多個工作者，記憶體用量會快速增加 （例如，4 個工作者 × 64MB `work_mem` = 每個查詢 256MB)。因此，平行查詢可能會耗用比單一程序查詢更多的系統資源。如果未正確調校， 它們可能會導致 CPU 飽和 （多個工作者壓倒可用的處理容量）， 增加內容切換 （作業系統經常在許多工作者程序之間切換， 新增額外負荷並降低輸送量）、 或 連線耗盡 （因為每個平行工作者都會使用連線插槽， 具有 4 個工作者的單一查詢總共使用 5 個連線， 1 個領導者 \$1 4 個工作者， 可在高並行下快速耗盡連線集區， 防止新的用戶端連線並導致應用程式失敗）。在高並行工作負載中，這些問題特別嚴重，其中多個查詢可能會同時嘗試平行執行。

PostgreSQL 會根據成本估算決定是否使用平行處理。在某些情況下，規劃器可能會自動切換到平行計劃，即使實際上並不理想，它看起來更便宜。如果索引統計資料已過期，或者如果膨脹使循序掃描看起來比索引查詢更具吸引力，則可能會發生這種情況。由於這種行為，自動平行計畫有時可能會在查詢效能或系統穩定性中引入迴歸。

若要從 RDS for PostgreSQL 的平行查詢中獲得最大效益，請務必根據您的工作負載進行測試和調校、監控系統影響，以及停用自動平行計劃選擇，以有利於查詢層級控制。

## 組態參數
<a name="PostgreSQL.ParallelQueries.ConfigurationParameters"></a>

PostgreSQL 使用數個參數來控制平行查詢的行為和可用性。了解和調校這些對於實現可預測效能至關重要：


| 參數 | 描述 | 預設 | 
| --- | --- | --- | 
| max\$1parallel\$1workers | 可以執行的背景工作者程序總數上限 | GREATEST(\$1DBInstanceVCPU/2,8) | 
| max\$1parallel\$1workers\$1per\$1gather | 每個查詢計劃節點的工作者數量上限 （例如，每個 Gather) | 2 | 
| parallel\$1setup\$1cost | 新增啟動平行查詢基礎設施的規劃器成本 | 1000 | 
| parallel\$1tuple\$1cost | 在平行模式下處理的每元組成本 （影響規劃器決策） | 0.1 | 
| force\$1parallel\$1mode | 強制規劃器測試平行計劃 (off、on、regress) | off | 

### 重要考量事項
<a name="PostgreSQL.ParallelQueries.ConfigurationParameters.KeyConsiderations"></a>
+ `max_parallel_workers` 控制平行工作者的總集區。如果設定過低，某些查詢可能會回復到序列執行。
+ `max_parallel_workers_per_gather` 會影響單一查詢可以使用的工作者數量。較高的值會增加並行，但也會增加資源用量。
+ `parallel_setup_cost` 和 `parallel_tuple_cost`會影響規劃器的成本模型。降低這些值可能會讓平行計劃更容易被選擇。
+ `force_parallel_mode` 適用於測試，但除非必要，否則不應用於生產環境。

**注意**  
參數的預設值`max_parallel_workers`會根據執行個體大小使用公式 動態計算`GREATEST($DBInstanceVCPU/2, 8)`。這表示當您將 DB 執行個體擴展到具有更多 vCPUs較大運算大小時，可用的平行工作者數量上限會自動增加。因此，先前連續執行或具有有限平行處理的查詢可能會在擴展操作後突然利用更多平行工作者，這可能會導致連線用量、CPU 使用率和記憶體耗用量意外增加。請務必監控任何運算擴展事件之後的平行查詢行為`max_parallel_workers_per_gather`，並視需要調整以維持可預測的資源用量。

## 識別平行查詢用量
<a name="PostgreSQL.ParallelQueries.IdentifyUsage"></a>

查詢可能會根據資料分佈或統計資料轉換為平行計畫。例如：

```
SELECT count(*) FROM customers WHERE last_login < now() - interval '6 months';
```

此查詢可能會針對最近資料使用 索引，但切換到針對歷史資料的平行循序掃描。

您可以透過載入 `auto_explain`模組來記錄查詢執行計畫。若要進一步了解，請參閱 AWS 知識中心的[記錄查詢的執行計畫](https://aws.amazon.com/premiumsupport/knowledge-center/rds-postgresql-tune-query-performance/#)。



您可以監控 [CloudWatch Database Insights](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Database-Insights-Database-Instance-Dashboard.html) 的平行查詢相關等待事件。若要進一步了解平行查詢相關的等待事件，請執行 [IPC：平行等待事件](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/apg-ipc-parallel.html)

從 PostgreSQL 第 18 版，您可以使用 [https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW](https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW)和 中的新資料欄來監控平行工作者活動[https://www.postgresql.org/docs/current/pgstatstatements.html](https://www.postgresql.org/docs/current/pgstatstatements.html)：
+ `parallel_workers_to_launch`：計劃啟動的平行工作者數量
+ `parallel_workers_launched`：實際啟動的平行工作者數量

這些指標有助於識別計劃和實際平行處理之間的差異，這可能表示資源限制或組態問題。使用下列查詢來監控平行執行：

對於資料庫層級平行工作者指標：

```
SELECT datname, parallel_workers_to_launch, parallel_workers_launched
FROM pg_stat_database
WHERE datname = current_database();
```

對於查詢層級平行工作者指標

```
SELECT query, parallel_workers_to_launch, parallel_workers_launched
FROM pg_stat_statements
ORDER BY parallel_workers_launched;
```

## 如何控制平行處理
<a name="PostgreSQL.ParallelQueries.ControlParallelism"></a>

有多種方法可以控制查詢平行處理，每個都針對不同的案例和需求而設計。

若要全域停用自動平行處理，請[修改參數群組](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_WorkingWithParamGroups.Modifying.html)以設定：

```
max_parallel_workers_per_gather = 0;
```

對於持久性的使用者特定設定，ALTER ROLE 命令提供設定參數的方法，這些參數將套用至特定使用者未來的所有工作階段。

例如：

`ALTER ROLE username SET max_parallel_workers_per_gather = 4;` 確保每次此使用者連線到資料庫時，其工作階段都會在需要時使用此平行工作者設定。

您可以使用 SET 命令來達成工作階段層級控制，該命令會修改目前資料庫工作階段期間的參數。當您需要暫時調整設定，而不會影響其他使用者或未來的工作階段時，這特別有用。一旦設定，這些參數會保持有效，直到明確重設或工作階段結束為止。命令非常簡單：

```
SET max_parallel_workers_per_gather = 4;
-- Run your queries
RESET max_parallel_workers_per_gather;
```

對於更精細的控制，SET LOCAL 可讓您修改單一交易的參數。當您需要調整交易中特定查詢集的設定時，這很理想，之後設定會自動回復到其先前的值。此方法有助於防止對相同工作階段中的其他操作產生意外影響。

## 診斷平行查詢行為
<a name="PostgreSQL.ParallelQueries.Diagnosing"></a>

使用 `EXPLAIN (ANALYZE, VERBOSE)`確認查詢是否使用平行執行：
+ 尋找節點，例如 `Gather`、 `Gather Merge`或 `Parallel Seq Scan`。
+ 比較具有和沒有平行處理的計劃。

若要暫時停用平行處理以進行比較：

```
SET max_parallel_workers_per_gather = 0;
EXPLAIN ANALYZE <your_query>;
RESET max_parallel_workers_per_gather;
```

# 在 RDS for PostgreSQL 資料庫執行個體上搭配使用參數
<a name="Appendix.PostgreSQL.CommonDBATasks.Parameters"></a>

某些情況下，您可能會在沒有指定自訂參數群組的狀況下建立一個 RDS for PostgreSQL 資料庫執行個體。如果是這樣，系統會使用您所選擇 PostgreSQL 版本的預設參數群組來建立資料庫執行個體。例如，假設您使用 PostgreSQL 13.3 建立 RDS for PostgreSQL 資料庫執行個體。在這種情況下，系統會使用 PostgreSQL 第 13 版參數群組 (`default.postgres13`) 中的值來建立資料庫執行個體。

您也可以建立自己的自訂資料庫參數群組。如果要從預設值中修改 RDS for PostgreSQL 資料庫執行個體的任何設定，則需要執行此操作。若要了解作法，請參閱[Amazon RDS 的參數群組](USER_WorkingWithParamGroups.md)。

您可以使用多種不同的方式追蹤 RDS for PostgreSQL 資料庫執行個體上的設定。您可以使用 AWS 管理主控台、 AWS CLI或 Amazon RDS API。您也可以查詢執行個體 PostgreSQL `pg_settings` 資料表中的值，如下所示。

```
SELECT name, setting, boot_val, reset_val, unit
 FROM pg_settings
 ORDER BY name;
```

若要進一步了解此查詢傳回的值，請參閱 PostgreSQL 說明文件中的 [https://www.postgresql.org/docs/current/view-pg-settings.html](https://www.postgresql.org/docs/current/view-pg-settings.html)。

為 RDS for PostgreSQL 資料庫執行個體更改 `max_connections` 和 `shared_buffers` 的設定時請格外小心。例如，假設您修改 `max_connections` 或 `shared_buffers` 的設定並且使用的值對於實際工作負載而言過高。這種情況下，RDS for PostgreSQL 資料庫執行個體將無法啟動。如果發生這種情況，`postgres.log` 中會顯示錯誤，如下所示。

```
2018-09-18 21:13:15 UTC::@:[8097]:FATAL:  could not map anonymous shared memory: Cannot allocate memory
2018-09-18 21:13:15 UTC::@:[8097]:HINT:  This error usually means that PostgreSQL's request for a shared memory segment
exceeded available memory or swap space. To reduce the request size (currently 3514134274048 bytes), reduce 
PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.
```

但是，您無法更改預設 RDS for PostgreSQL 資料庫參數群組中包含的任何設定值。若要變更任何參數的設定，請首先建立自訂資料庫參數群組。然後變更該自訂資料群組中的設定，再將自訂參數群組套用於 RDS for PostgreSQL 資料庫執行個體。如需詳細資訊，請參閱 [Amazon RDS 的參數群組](USER_WorkingWithParamGroups.md)。

RDS for PostgreSQL 中的參數有兩種類型。
+ **靜態參數** – 靜態參數變更後需重新啟動 RDS for PostgreSQL 資料庫執行個體，新值才會生效。
+ **動態參數** – 動態參數的設定變更後不需要重新啟動。

**注意**  
如果 RDS for PostgreSQL 資料庫執行個體使用自己的自訂資料庫參數群組，您可以變更正在執行中的資料庫執行個體上的動態參數值。您可以使用 AWS 管理主控台、 AWS CLI或 Amazon RDS API 來執行此操作。

如果您擁有權限，也可以使用 `ALTER DATABASE`、`ALTER ROLE` 和 `SET` 命令來變更參數值。

## RDS for PostgreSQL DB 資料庫執行個體參數清單
<a name="Appendix.PostgreSQL.CommonDBATasks.Parameters.parameters-list"></a>

下表列出 RDS for PostgreSQL 資料庫執行個體中的一些 (但並非全部) 可用參數。若要檢視所有可用的參數，請使用 [describe-db-parameters](https://docs.aws.amazon.com/cli/latest/reference/rds/describe-db-parameters.html) AWS CLI 命令。例如，若要取得預設參數群組中 RDS for PostgreSQL 第 13 版可用的所有參數清單，請執行下列命令。

```
aws rds describe-db-parameters --db-parameter-group-name default.postgres13
```

您也可以使用主控台。從 Amazon RDS 功能表中選擇 **Parameter groups** (參數群組)，然後從 AWS 區域中可用的參數群組中選擇參數群組。


|  參數名稱  |  Apply\$1Type  |  描述  | 
| --- | --- | --- | 
|  `application_name`  | 動態 | 設定要在統計資訊和日誌中報告的應用程式名稱。 | 
|  `archive_command`  | 動態 | 設定將呼叫的 shell 命令來封存 WAL 檔案。 | 
|  `array_nulls`  | 動態 | 能夠在陣列中輸入 NULL 元素。 | 
|  `authentication_timeout`  | 動態 | 設定要完成用戶端驗證的最大允許時間。 | 
|  `autovacuum`  | 動態 | 啟動自動資料清理子程序。 | 
|  `autovacuum_analyze_scale_factor`  | 動態 | 在分析之前的 tuple 插入、更新或刪除數目 (成為 reltuple 的一小部分)。 | 
|  `autovacuum_analyze_threshold`  | 動態 | 在分析之前的 tuple 插入、更新或刪除數目下限。 | 
|  `autovacuum_freeze_max_age`  | 靜態 | 要自動資料清理資料表以防止交易 ID 包圍的存留期。 | 
|  `autovacuum_naptime`  | 動態 | 自動資料清理執行之間的休眠時間。 | 
|  `autovacuum_max_workers`  | 靜態 | 設定同時執行自動清空工作者程序的數目上限。 | 
|  `autovacuum_vacuum_cost_delay`  | 動態 | 自動資料清理的清理成本延遲 (以毫秒為單位)。 | 
|  `autovacuum_vacuum_cost_limit`  | 動態 | 自動資料清理在小憩前可用的清理成本金額。 | 
|  `autovacuum_vacuum_scale_factor`  | 動態 | 在清理之前的 tuple 更新或刪除數目 (成為 reltuple 的一小部分)。 | 
|  `autovacuum_vacuum_threshold`  | 動態 | 在清理之前的 tuple 更新或刪除數目下限。 | 
|  `backslash_quote`  | 動態 | 設定在字串常值中是否允許反斜線 (\$1)。 | 
|  `bgwriter_delay`  | 動態 | 回合之間的背景寫入器休眠時間。 | 
|  `bgwriter_lru_maxpages`  | 動態 | 每回合要清空之 LRU 頁面的背景寫入器數目上限。 | 
|  `bgwriter_lru_multiplier`  | 動態 | 每回合要釋放之平均緩衝區使用量的倍數。 | 
|  `bytea_output`  | 動態 | 設定位元組的輸出格式。 | 
|  `check_function_bodies`  | 動態 | 在 CREATE FUNCTION 期間檢查函數本文。 | 
|  `checkpoint_completion_target`  | 動態 | 在檢查點期間用於清空已變更緩衝區的時間 (成為檢查點間隔的一小部分)。 | 
|  `checkpoint_segments`  | 動態 | 設定日誌區段中自動預寫入日誌 WAL 檢查點之間的最大距離。 | 
|  `checkpoint_timeout`  | 動態 | 設定自動 WAL 檢查點之間的最長時間。 | 
|  `checkpoint_warning`  | 動態 | 啟用檢查點區段的填入頻率高於此值時的警告。 | 
|  `client_connection_check_interval`  | 動態 |  設定執行查詢時檢查是否中斷連線的時間間隔。 | 
|  `client_encoding`  | 動態 | 設定用戶端的字元集編碼。 | 
|  `client_min_messages`  | 動態 | 設定傳送給用戶端的訊息層級。 | 
|  `commit_delay`  | 動態 | 設定在交易認可與將 WAL 清空至磁碟之間的延遲 (以毫秒為單位)。 | 
|  `commit_siblings`  | 動態 | 設定在執行 commit\$1delay 之前同時開啟的交易數目下限。 | 
|  `constraint_exclusion`  | 動態 | 讓規劃器能夠使用限制條件來最佳化查詢。 | 
|  `cpu_index_tuple_cost`  | 動態 | 設定規劃器對於在索引掃描期間處理每個索引項目的成本估算。 | 
|  `cpu_operator_cost`  | 動態 | 設定規劃器對於處理每個運算子或函數呼叫的成本估算。 | 
|  `cpu_tuple_cost`  | 動態 | 設定規劃器對於處理每個 tuple (資料列) 的成本估算。 | 
|  `cursor_tuple_fraction`  | 動態 | 設定規劃器對於將擷取之游標的資料列部分估算。 | 
|  `datestyle`  | 動態 | 設定日期和時間值的顯示格式。 | 
|  `deadlock_timeout`  | 動態 | 設定在檢查死鎖前等待鎖定的時間。 | 
|  `debug_pretty_print`  | 動態 | 將剖析和計劃樹狀顯示縮排。 | 
|  `debug_print_parse`  | 動態 | 記錄每項查詢的剖析樹狀。 | 
|  `debug_print_plan`  | 動態 | 記錄每項查詢的執行計劃。 | 
|  `debug_print_rewritten`  | 動態 | 記錄每項查詢的重寫剖析樹狀。 | 
|  `default_statistics_target`  | 動態 | 設定預設統計資訊目標。 | 
|  `default_tablespace`  | 動態 | 設定要在其中建立資料表和索引的預設資料表空間。 | 
|  `default_transaction_deferrable`  | 動態 | 設定新交易的預設可延遲狀態。 | 
|  `default_transaction_isolation`  | 動態 | 設定每項新交易的交易隔離層級。 | 
|  `default_transaction_read_only`  | 動態 | 設定新交易的預設唯讀狀態。 | 
|  `default_with_oids`  | 動態 | 依預設建立內含物件 ID (OID) 的新資料表。 | 
|  `effective_cache_size`  | 動態 | 設定規劃器對於磁碟快取大小的假設。 | 
|  `effective_io_concurrency`  | 動態 | 磁碟子系統可以有效處理的同時要求數目。 | 
|  `enable_bitmapscan`  | 動態 | 讓規劃器能夠使用點陣圖掃描計劃。 | 
|  `enable_hashagg`  | 動態 | 讓規劃器能夠使用雜湊彙整計劃。 | 
|  `enable_hashjoin`  | 動態 | 讓規劃器能夠使用雜湊聯結計劃。 | 
|  `enable_indexscan`  | 動態 | 讓規劃器能夠使用索引掃描計劃。 | 
|  `enable_material`  | 動態 | 讓規劃器能夠使用實體化。 | 
|  `enable_mergejoin`  | 動態 | 讓規劃器能夠使用合併聯結計劃。 | 
|  `enable_nestloop`  | 動態 | 讓規劃器能夠使用巢狀迴圈聯結計劃。 | 
|  `enable_seqscan`  | 動態 | 讓規劃器能夠使用循序掃描計劃。 | 
|  `enable_sort`  | 動態 | 讓規劃器能夠使用明確排序步驟。 | 
|  `enable_tidscan`  | 動態 | 讓規劃器能夠使用 TID 掃描計劃。 | 
|  `escape_string_warning`  | 動態 | 一般字串常值中反斜線 (\$1) 逸出的相關警告。 | 
|  `extra_float_digits`  | 動態 | 設定針對浮點值顯示的位數。 | 
|  `from_collapse_limit`  | 動態 | 設定 FROM-list 大小，超過此大小就不會收合子查詢。 | 
|  `fsync`  | 動態 | 強制將更新同步至磁碟。 | 
|  `full_page_writes`  | 動態 | 在檢查點後第一次修改時，將完整頁面寫入至 WAL。 | 
|  `geqo`  | 動態 | 啟用基因查詢最佳化。 | 
|  `geqo_effort`  | 動態 | GEQO：作業是用於設定其他 GEQO 參數的預設值。 | 
|  `geqo_generations`  | 動態 | GEQO：演算法的反覆運算次數。 | 
|  `geqo_pool_size`  | 動態 | GEQO：人口中的個體數目。 | 
|  `geqo_seed`  | 動態 | GEQO：隨機路徑選取的種子。 | 
|  `geqo_selection_bias`  | 動態 | GEQO：人口中的選擇壓力。 | 
|  `geqo_threshold`  | 動態 | 設定 FROM 項目的閾值，超出此閾值時就會使用 GEQO。 | 
|  `gin_fuzzy_search_limit`  | 動態 | 設定 GIN 確切搜尋所允許的結果上限。 | 
|  `hot_standby_feedback`  | 動態 | 決定熱待命是否將意見回饋訊息傳送給主要或上游待命。 | 
|  `intervalstyle`  | 動態 | 設定間隔值的顯示格式。 | 
|  `join_collapse_limit`  | 動態 | 設定 FROM-list 大小，超過此大小就不會將 JOIN 結構扁平化。 | 
|  `lc_messages`  | 動態 | 設定用來顯示訊息的語言。 | 
|  `lc_monetary`  | 動態 | 設定用於格式化貨幣金額的地區設定。 | 
|  `lc_numeric`  | 動態 | 設定用於格式化數字的地區設定。 | 
|  `lc_time`  | 動態 | 設定用於格式化日期和時間值的地區設定。 | 
|  `log_autovacuum_min_duration`  | 動態 | 設定執行時間下限，超出此時間就會記錄自動資料清理動作。 | 
|  `log_checkpoints`  | 動態 | 記錄每個檢查點。 | 
|  `log_connections`  | 動態 | 記錄每個成功連線。 | 
|  `log_disconnections`  | 動態 | 記錄工作階段的結尾，包括持續時間。 | 
|  `log_duration`  | 動態 | 記錄每個已完成 SQL 陳述式的持續時間。 | 
|  `log_error_verbosity`  | 動態 | 設定已記錄訊息的詳細資訊。 | 
|  `log_executor_stats`  | 動態 | 將執行器效能統計資訊寫入至伺服器日誌。 | 
|  `log_filename`  | 動態 | 設定日誌檔案的檔案名稱樣式。 | 
|  `log_file_mode`  | 動態 | 設定日誌檔案的許可。預設值為 0644。 | 
|  `log_hostname`  | 動態 | 在連線日誌中記錄主機名稱。從 PostgreSQL 12 及更新版本開始，此參數預設為 'off'。開啟時，連線會使用 DNS 反向查詢來取得擷取至連線日誌的主機名稱。如果開啟此參數，您應該監控它對建立連線所需時間的影響。 | 
|  `log_line_prefix `  | 動態 | 控制每個日誌行前綴的資訊。 | 
|  `log_lock_waits`  | 動態 | 記錄長鎖定等待。 | 
|  `log_min_duration_statement`  | 動態 | 設定執行時間下限，超出此時間就會記錄陳述式。 | 
|  `log_min_error_statement`  | 動態 | 導致所有陳述式在這個層級或以上產生要記錄的錯誤。 | 
|  `log_min_messages`  | 動態 | 設定所記錄的訊息層級。 | 
|  `log_parser_stats`  | 動態 | 將剖析器效能統計資訊寫入至伺服器日誌。 | 
|  `log_planner_stats`  | 動態 | 將規劃器效能統計資訊寫入至伺服器日誌。 | 
|  `log_rotation_age`  | 動態 | 自動日誌檔案輪換將在 N 分鐘後發生。 | 
|  `log_rotation_size`  | 動態 | 自動日誌檔案輪換將在 N KB 後發生。 | 
|  `log_statement`  | 動態 | 設定已記錄的陳述式類型。 | 
|  `log_statement_stats`  | 動態 | 將累積效能統計資訊寫入至伺服器日誌。 | 
|  `log_temp_files`  | 動態 | 記錄大於此 KB 數的暫時檔案使用。 | 
|  `log_timezone`  | 動態 | 設定要在日誌訊息中使用的時區。 | 
|  `log_truncate_on_rotation`  | 動態 | 在日誌輪換期間截斷名稱相同的現有日誌檔案。 | 
|  `logging_collector`  | 靜態 | 開始子程序，將 stderr 輸出和/或 csvlog 擷取到日誌檔案中。 | 
|  `maintenance_work_mem`  | 動態 | 設定要用於維護作業的記憶體上限。 | 
|  `max_connections`  | 靜態 | 設定同時連線的數目上限。 | 
|  `max_files_per_process`  | 靜態 | 設定每個伺服器程序的同時開啟檔案數目上限。 | 
|  `max_locks_per_transaction`  | 靜態 | 設定每項交易的鎖定數目上限。 | 
|  `max_pred_locks_per_transaction`  | 靜態 | 設定每項交易的述詞鎖定數目上限。 | 
|  `max_prepared_transactions`  | 靜態 | 設定同時備妥交易的數目上限。 | 
|  `max_stack_depth`  | 動態 | 設定堆疊深度上限 (以 KB 為單位)。 | 
|  `max_standby_archive_delay`  | 動態 | 當熱待命伺服器正在處理已封存的 WAL 資料時，設定在取消查詢前的延遲上限。 | 
|  `max_standby_streaming_delay`  | 動態 | 當熱待命伺服器正在處理已串流的 WAL 資料時，設定在取消查詢前的延遲上限。 | 
| max\$1wal\$1size | 動態 | 設定觸發檢查點的 WAL 大小 (MB)。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Parameters.html) 在 Amazon RDS for PostgreSQL 資料庫執行個體上使用下列命令，以查看其現行值： <pre>SHOW max_wal_size;</pre>  | 
| min\$1wal\$1size | 動態 | 設定 WAL 縮減到最小的大小。Postgre SQL 9.6 版和更早的版本， min\$1wal\$1size 單位是 16 MB。Postgre SQL 10 版和更新版本， min\$1wal\$1size 單位是 1 MB。 | 
|  `quote_all_identifiers`  | 動態 | 在產生 SQL 片段時，將引號 (") 新增至所有識別符。 | 
|  `random_page_cost`  | 動態 | 設定規劃器對於非循序擷取磁碟頁面的成本估算。除非開啟查詢計劃管理 (QPM)，否則此參數並無任何值。開啟 QPM 時，此參數的預設值為 4。 | 
| rds.adaptive\$1autovacuum | 動態 | 當交易 ID 閥值超過時，隨時自動調整自動資料清理的參數。 | 
| rds.force\$1ssl | 動態 | 需要使用 SSL 連線。對於 RDS for PostgreSQL 第 15 版，預設值會設定為 1 (開啟)。所有其他 RDS for PostgreSQL 主要版本 14 及更舊版本都會將預設值設定為 0 (關閉)。 | 
|  `rds.local_volume_spill_enabled`  | 靜態 | 允許將邏輯溢出檔案寫入本機磁碟區。 | 
|  `rds.log_retention_period`  | 動態 | 設定日誌保留期，像是 Amazon RDS 超過 n 分鐘時刪除 PostgreSQL 日誌。 | 
| rds.rds\$1superuser\$1reserved\$1connections | 靜態 | 設定為 rds\$1superusers 保留的連線槽數。此參數僅適用於第 15 版和更舊版本。如需詳細資訊，請參閱 PostgreSQL 文件 [reserved\$1connections](https://www.postgresql.org/docs/current/runtime-config-connection.html#GUC-RESERVED-CONNECTIONS)。 | 
| `rds.replica_identity_full` | 動態 | 當您將此參數設定為 `on` 時，它會將所有資料庫資料表的複本身分設定覆寫為 `FULL`。這表示無論 `REPLICA IDENTITY FULL` 設定為何，所有資料欄值都會寫入預寫日誌 (WAL)。  由於額外的 WAL 記錄，開啟此參數可能會增加資料庫執行個體 IOPS。   | 
| rds.restrict\$1password\$1commands | 靜態 | 限制可以管理具有 rds\$1password 角色之使用者密碼的人員。將此參數設為 1 可啟用密碼限制。預設為 0。 | 
|  `search_path`  | 動態 | 針對不符合結構描述的名稱設定結構描述搜尋順序。 | 
|  `seq_page_cost`  | 動態 | 設定規劃器對於循序擷取磁碟頁面的成本估算。 | 
|  `session_replication_role`  | 動態 | 設定觸發器和重寫規則的工作階段行為。 | 
|  `shared_buffers`  | 靜態 | 設定伺服器所用的共享記憶體緩衝區數目。 | 
|  `shared_preload_libraries `  | 靜態 | 列出要預先載入至 RDS for PostgreSQL 資料庫執行個體的共用程式庫。支援的值包括 auto\$1explain、orafce、pgaudit、pglogical、pg\$1bigm、pg\$1cron、pg\$1hint\$1plan、pg\$1prewarm、pg\$1similarity、pg\$1stat\$1statements、pg\$1tle, pg\$1transport、plprofiler 及 plrust。 | 
|  `ssl`  | 動態 | 啟用 SSL 連線。 | 
|  `sql_inheritance`  | 動態 | 導致子資料表依預設包含在各種命令中。 | 
|  `ssl_renegotiation_limit`  | 動態 | 設定在重新商談加密金鑰前要傳送和接收的流量。 | 
|  `standard_conforming_strings`  | 動態 | 導致 ... 字串逐字地處理反斜線。 | 
|  `statement_timeout`  | 動態 | 設定任何陳述式允許的持續時間上限。 | 
|  `synchronize_seqscans`  | 動態 | 啟用已同步的循序掃描。 | 
|  `synchronous_commit`  | 動態 | 設定目前交易的同步層級。 | 
|  `tcp_keepalives_count`  | 動態 | TCP 保持連線重新傳輸的數量上限 | 
|  `tcp_keepalives_idle`  | 動態 | 發出 TCP 保持連線之間的時間。 | 
|  `tcp_keepalives_interval`  | 動態 | TCP 保持連線重新傳輸之間的時間。 | 
|  `temp_buffers`  | 動態 | 設定每個工作階段所用的暫時緩衝區數目上限。 | 
| temp\$1file\$1limit | 動態 | 設定暫時檔案可以增長的大小上限 (以 KB 為單位)。 | 
|  `temp_tablespaces`  | 動態 | 設定要用於暫存資料表和排序檔案的資料表空間。 | 
|  `timezone`  | 動態 | 設定可供顯示和解譯時間戳記的時區。 網際網路號碼分配局 (IANA) 每年會在 [https://www.iana.org/time-zones](https://www.iana.org/time-zones) 發布數次新時區。每次 RDS 發布 PostgreSQL 的新次要維護版本時，它都會在發布時隨附最新的時區資料。當您使用最新的 RDS for PostgreSQL 版本時，您會有來自 RDS 的最新時區資料。為確保您的資料庫執行個體擁有最新的時區資料，建議您升級至更高的資料庫引擎版本。您無法手動修改 PostgreSQL 資料庫執行個體中的時區表。RDS 不會修改或重設執行中資料庫執行個體的時區資料。只有在您執行資料庫引擎版本升級時，才會安裝新的時區資料。 | 
|  `track_activities`  | 動態 | 收集有關執行命令的資訊。 | 
|  `track_activity_query_size`  | 靜態 | 設定為 pg\$1stat\$1activity.current\$1query 保留的大小 (以位元組為單位)。 | 
|  `track_counts`  | 動態 | 收集資料庫活動的統計資訊。 | 
|  `track_functions`  | 動態 | 收集資料庫活動的功能層級統計資訊。 | 
|  `track_io_timing`  | 動態 | 收集資料庫輸入/輸出活動的計時統計資訊。 | 
|  `transaction_deferrable`  | 動態 | 指出是否延遲唯讀可序列化交易，直到可加以啟動為止 (沒有可能的序列化失敗)。 | 
|  `transaction_isolation`  | 動態 | 設定目前交易的隔離層級。 | 
|  `transaction_read_only`  | 動態 | 設定目前交易的唯讀狀態。 | 
|  `transform_null_equals`  | 動態 | 將 expr=NULL 視為 expr IS NULL。 | 
|  `update_process_title`  | 動態 | 更新程序標題以顯示作用中的 SQL 命令。 | 
|  `vacuum_cost_delay`  | 動態 | 清理成本延遲 (以毫秒為單位)。 | 
|  `vacuum_cost_limit`  | 動態 | 在小憩前可用的清理成本金額。 | 
|  `vacuum_cost_page_dirty`  | 動態 | 清理所變更之頁面的清理成本。 | 
|  `vacuum_cost_page_hit`  | 動態 | 在緩衝區快取中找到之頁面的清理成本。 | 
|  `vacuum_cost_page_miss`  | 動態 | 在緩衝區快取中找不到之頁面的清理成本。 | 
|  `vacuum_defer_cleanup_age`  | 動態 | 應延遲清理和熱清理 (如果有的話) 的交易數目。 | 
|  `vacuum_freeze_min_age`  | 動態 | 清理應凍結資料表列的存留期下限。 | 
|  `vacuum_freeze_table_age`  | 動態 | 清理應掃描整個資料表以凍結 tuple 的存留期。 | 
|  `wal_buffers`  | 靜態 | 為 WAL 設定共享記憶體中的磁碟分頁緩衝區數目。 | 
|  `wal_writer_delay`  | 動態 | WAL 清空之間的 WAL 寫入器休眠時間。 | 
|  `work_mem`  | 動態 | 設定要用於查詢工作空間的記憶體上限。 | 
|  `xmlbinary`  | 動態 | 設定有多少二進位值要在 XML 中編碼。 | 
|  `xmloption`  | 動態 | 設定要將明確剖析和序列化作業中的 XML 資料視為文件或內容片段。 | 

Amazon RDS 會對所有參數使用預設 PostgreSQL 單位。下表顯示每個參數的 PostgreSQL 預設單位。


|  參數名稱  |  單位  | 
| --- | --- | 
| `archive_timeout` | s | 
| `authentication_timeout` | s | 
| `autovacuum_naptime` | s | 
| `autovacuum_vacuum_cost_delay` | ms | 
| `bgwriter_delay` | ms | 
| `checkpoint_timeout` | s | 
| `checkpoint_warning` | s | 
| `deadlock_timeout` | ms | 
| `effective_cache_size` | 8 KB | 
| `lock_timeout` | ms | 
| `log_autovacuum_min_duration` | ms | 
| `log_min_duration_statement` | ms | 
| `log_rotation_age` | 分鐘 | 
| `log_rotation_size` | KB | 
| `log_temp_files` | KB | 
| `maintenance_work_mem` | KB | 
| `max_stack_depth` | KB | 
| `max_standby_archive_delay` | ms | 
| `max_standby_streaming_delay` | ms | 
| `post_auth_delay` | s | 
| `pre_auth_delay` | s | 
| `segment_size` | 8 KB | 
| `shared_buffers` | 8 KB | 
| `statement_timeout` | ms | 
| `ssl_renegotiation_limit` | KB | 
| `tcp_keepalives_idle` | s | 
| `tcp_keepalives_interval` | s | 
| `temp_file_limit` | KB | 
| `work_mem` | KB | 
| `temp_buffers` | 8 KB | 
| `vacuum_cost_delay` | ms | 
| `wal_buffers` | 8 KB | 
| `wal_receiver_timeout` | ms | 
| `wal_segment_size` | B | 
| `wal_sender_timeout` | ms | 
| `wal_writer_delay` | ms | 
| `wal_receiver_status_interval` | s | 

# 調校 RDS for PostgreSQL 的等待事件
<a name="PostgreSQL.Tuning"></a>

等待事件是 RDS for PostgreSQL 的重要調校工具。如果您了解工作階段為何等待資源及其運作情形，就更能夠減少瓶頸。您可以使用本節的資訊來尋找可能的原因和更正動作。本節也討論基本 PostgreSQL 調校概念。

本節中的等待事件專屬於 RDS for PostgreSQL。

**Topics**
+ [RDS for PostgreSQL 調校的基本概念](PostgreSQL.Tuning.concepts.md)
+ [RDS for PostgreSQL 等待事件](PostgreSQL.Tuning.concepts.summary.md)
+ [Client:ClientRead](wait-event.clientread.md)
+ [Client:ClientWrite](wait-event.clientwrite.md)
+ [CPU](wait-event.cpu.md)
+ [IO:BufFileRead 和 IO:BufFileWrite](wait-event.iobuffile.md)
+ [IO:DataFileRead](wait-event.iodatafileread.md)
+ [IO:WALWrite](wait-event.iowalwrite.md)
+ [IPC:parallel 等待事件](rpg-ipc-parallel.md)
+ [IPC:ProcArrayGroupUpdate](apg-rpg-ipcprocarraygroup.md)
+ [Lock:advisory](wait-event.lockadvisory.md)
+ [Lock:extend](wait-event.lockextend.md)
+ [Lock:Relation](wait-event.lockrelation.md)
+ [Lock:transactionid](wait-event.locktransactionid.md)
+ [Lock:tuple](wait-event.locktuple.md)
+ [LWLock:BufferMapping (LWLock:buffer\$1mapping)](wait-event.lwl-buffer-mapping.md)
+ [LWLock:BufferIO (IPC:BufferIO)](wait-event.lwlockbufferio.md)
+ [LWLock:buffer\$1content (BufferContent)](wait-event.lwlockbuffercontent.md)
+ [LWLock:lock\$1manager (LWLock:lockmanager)](wait-event.lw-lock-manager.md)
+ [LWLock:pg\$1stat\$1statements](apg-rpg-lwlockpgstat.md)
+ [LWLock：SubtransSLRU (LWLock：SubtransControlLock)](wait-event.lwlocksubtransslru.md)
+ [Timeout:PgSleep](wait-event.timeoutpgsleep.md)
+ [Timeout:VacuumDelay](wait-event.timeoutvacuumdelay.md)

# RDS for PostgreSQL 調校的基本概念
<a name="PostgreSQL.Tuning.concepts"></a>

調校 RDS for PostgreSQL 資料庫之前，請務必先瞭解什麼是等待事件及其發生原因。也請檢閱 RDS for PostgreSQL 的基本記憶體和磁碟架構。如需實用的架構圖，請參閱 [PostgreSQL](https://en.wikibooks.org/wiki/PostgreSQL/Architecture) 維基教科書。

**Topics**
+ [RDS for PostgreSQL 等待事件](PostgreSQL.Tuning.concepts.waits.md)
+ [RDS for PostgreSQL 記憶體](PostgreSQL.Tuning.concepts.memory.md)
+ [RDS for PostgreSQL 程序](PostgreSQL.Tuning.concepts.processes.md)

# RDS for PostgreSQL 等待事件
<a name="PostgreSQL.Tuning.concepts.waits"></a>

*等待事件*表示工作階段正在等待資源。例如，當 RDS for PostgreSQL 等待從用戶端接收資料時會發生等待事件 `Client:ClientRead`。工作階段通常會等待如下資源。
+ 透過單一執行緒存取緩衝區，例如，當工作階段嘗試修改緩衝區時
+ 另一個工作階段目前鎖定的資料列
+ 資料檔讀取
+ 日誌檔寫入

例如，為了滿足查詢，工作階段可能執行完整的資料表掃描。如果資料不在記憶體中，工作階段會等待磁碟輸入/輸出完成。將緩衝區讀入記憶體後，工作階段可能需要等待，因為其他工作階段正在存取這些緩衝區。資料庫使用預先定義的等待事件來記錄等待。這些事件分組為多個類別。

單一等待事件本身不表示效能問題。例如，如果請求的資料不在記憶體中，則需要從磁碟讀取資料。如果一個工作階段鎖定資料列來更新，則另一個工作階段要等待此資料列解除鎖定才能更新。遞交需要等待寫入日誌檔完成。等待是資料庫正常運作所不可或缺。

另一方面，大量等待事件通常顯示效能問題。在這種情況下，您可以使用等待事件資料來判斷工作階段將時間花在何處。例如，如果報告通常執行幾分鐘，但現在執行數小時，您可以識別佔總等待時間最多的等待事件。如果您可以查出最常等待事件的原因，通常就能做些改變來改善效能。例如，如果工作階段等待的資料列被另一個工作階段鎖定，您可以結束該鎖定工作階段。

# RDS for PostgreSQL 記憶體
<a name="PostgreSQL.Tuning.concepts.memory"></a>

RDS for PostgreSQL 記憶體分成共用和本機。

**Topics**
+ [RDS for PostgreSQL 中的共用記憶體](#PostgreSQL.Tuning.concepts.shared)
+ [RDS for PostgreSQL 中的本機記憶體](#PostgreSQL.Tuning.concepts.local)

## RDS for PostgreSQL 中的共用記憶體
<a name="PostgreSQL.Tuning.concepts.shared"></a>

RDS for PostgreSQL 在執行個體啟動時配置共用記憶體。共用記憶體分成多個子區域。以下幾節將說明最重要的部分。

**Topics**
+ [共用緩衝區](#PostgreSQL.Tuning.concepts.buffer-pool)
+ [預寫日誌 (WAL) 緩衝區](#PostgreSQL.Tuning.concepts.WAL)

### 共用緩衝區
<a name="PostgreSQL.Tuning.concepts.buffer-pool"></a>

*共用緩衝集區*是一種 RDS for PostgreSQL 記憶體區域，其中保留應用程式連線正在使用或已使用的所有分頁。*分頁*是記憶體形式的磁碟區塊。共用緩衝集區快取從磁碟讀取的資料區塊。集區可減少從磁碟重新讀取資料的次數，讓資料庫運作更有效率。

每個資料表和索引儲存為一連串固定大小的分頁。每個區塊包含多個元組，對應於資料列。元組可以存放在任何分頁中。

共用緩衝集區的記憶體有限。如果新請求需要的分頁不在記憶體中，且已沒有更多記憶體，RDS for PostgreSQL 會移出較不常用的分頁來容納請求。移出政策以時鐘掃描演算法實作。

`shared_buffers` 參數決定伺服器專用於快取資料的記憶體數量。預設值會根據資料庫執行個體的可用記憶體設定為 `{DBInstanceClassMemory/32768}` 位元組。

### 預寫日誌 (WAL) 緩衝區
<a name="PostgreSQL.Tuning.concepts.WAL"></a>

*預寫日誌 (WAL) 緩衝區*保留交易資料，供 RDS for PostgreSQL 稍後寫入持久性儲存。RDS for PostgreSQL 可以透過 WAL 機制達成下列目標：
+ 在故障後復原資料
+ 避免頻繁寫入磁碟以減少磁碟輸入/輸出

當用戶端變更資料時，RDS for PostgreSQL 會將變更寫入 WAL 緩衝區。當用戶端發出 `COMMIT` 時，WAL 寫入器程序會將交易資料寫入 WAL 檔案。

`wal_level` 參數會決定有多少資訊會寫入 WAL，可能的值包括 `minimal`、`replica` 和 `logical`。

## RDS for PostgreSQL 中的本機記憶體
<a name="PostgreSQL.Tuning.concepts.local"></a>

每個後端程序會配置本機記憶體來處理查詢。

**Topics**
+ [工作記憶體區域](#PostgreSQL.Tuning.concepts.local.work_mem)
+ [維護工作記憶體區域](#PostgreSQL.Tuning.concepts.local.maintenance_work_mem)
+ [暫時緩衝區域](#PostgreSQL.Tuning.concepts.temp)

### 工作記憶體區域
<a name="PostgreSQL.Tuning.concepts.local.work_mem"></a>

*工作記憶體區域*為執行排序和雜湊的查詢保留暫存資料。例如，含有 `ORDER BY` 子句的查詢執行排序。查詢在雜湊聯結和彙總中使用雜湊表。

`work_mem` 參數會指定在寫入暫存磁碟檔案之前，供內部排序操作和雜湊表使用的記憶體數量 (以 MB 為單位)。預設值為 4 MB。多個工作階段可以同時執行，每個工作階段可以平行執行維護操作。因此，使用的總工作記憶體可能是 `work_mem` 設定的倍數。

### 維護工作記憶體區域
<a name="PostgreSQL.Tuning.concepts.local.maintenance_work_mem"></a>

*維護工作記憶體區域*快取維護操作的資料。這些操作包括清理、建立索引和新增外部索引鍵。

`maintenance_work_mem` 參數會指定供維護操作使用的記憶體數量上限 (以 MB 為單位)。預設值為 64 MB。一個資料庫工作階段一次只能執行一個維護操作。

### 暫時緩衝區域
<a name="PostgreSQL.Tuning.concepts.temp"></a>

*暫時緩衝區域*快取每個資料庫工作階段的暫存資料表。

每個工作階段視需要配置暫存緩衝區，以您指定的限制為上限。工作階段結束時，伺服器會清除緩衝區。

`temp_buffers` 參數會設定每個工作階段使用的暫存緩衝區數目上限 (以 MB 為單位)。預設值為 8 MB。在工作階段內第一次使用暫存資料表之前，您可以變更 `temp_buffers` 值。

# RDS for PostgreSQL 程序
<a name="PostgreSQL.Tuning.concepts.processes"></a>

RDS for PostgreSQL 使用多個程序。

**Topics**
+ [郵件管理員程序](#PostgreSQL.Tuning.concepts.postmaster)
+ [後端程序](#PostgreSQL.Tuning.concepts.backend)
+ [背景程序](#PostgreSQL.Tuning.concepts.vacuum)

## 郵件管理員程序
<a name="PostgreSQL.Tuning.concepts.postmaster"></a>

*郵件管理員程序*是您啟動 RDS for PostgreSQL 時啟動的第一個程序。郵件管理員程序有下列主要責任：
+ 分叉和監控背景程序
+ 接收來自用戶端程序的身分驗證請求，並在驗證請求之後才允許資料庫處理請求

## 後端程序
<a name="PostgreSQL.Tuning.concepts.backend"></a>

如果郵件管理員驗證用戶端請求，郵件管理員會分叉新的後端程序，也稱為 postgres 程序。一個用戶端程序只連線到一個後端程序。用戶端程序和後端程序直接通訊，無須郵件管理員程序介入。

## 背景程序
<a name="PostgreSQL.Tuning.concepts.vacuum"></a>

郵件管理員程序分叉幾個程序來執行不同的後端任務。一些較重要的程序包括：
+ WAL 寫入器

  RDS for PostgreSQL 將 WAL (預寫日誌) 緩衝區中的資料寫入日誌檔。預寫日誌的原則是直到資料庫將描述變更的日誌記錄寫入磁碟之後，資料庫才能將這些變更寫入資料檔。WAL 機制可減少磁碟輸入/輸出，並允許 RDS for PostgreSQL 在故障後使用日誌來復原資料庫。
+ 背景寫入器

  這個程序定期將已變更 (已修改) 分頁從記憶體緩衝區寫入資料檔。當後端程序在記憶體中修改分頁時，此分頁會變成已變更。
+ 自動資料清理常駐程式

  此常駐程式由下列組成：
  + 自動資料清理啟動器
  + 自動資料清理工作者程序

  自動資料清理啟用時會檢查已插入、更新或刪除大量元組的資料表。此常駐程式有下列責任：
  + 復原或重複使用已更新或刪除的資料列所佔用的磁碟空間
  + 更新規劃員使用的統計數字
  + 防止因交易 ID 環繞而遺失舊資料

  自動資料清理功能可自動執行 `VACUUM` 和 `ANALYZE` 命令。`VACUUM` 有以下變體：標準和完整。標準清理與其他資料庫操作平行執行。`VACUUM FULL` 需要獨佔鎖定其處理的資料表。因此，無法與存取同一個資料表的操作平行執行。`VACUUM` 會建立大量輸入/輸出流量，可能導致其他作用中工作階段的效能不佳。

# RDS for PostgreSQL 等待事件
<a name="PostgreSQL.Tuning.concepts.summary"></a>

下表列出 RDS for PostgreSQL 中最常表示有效能問題的等待事件，並概述最常見的原因和更正動作。


| 等待事件 | 定義 | 
| --- | --- | 
|  [Client:ClientRead](wait-event.clientread.md)  |  此事件表示 RDS for PostgreSQL 正在等待從用戶端接收資料。  | 
|  [Client:ClientWrite](wait-event.clientwrite.md)  |  此事件表示 RDS for PostgreSQL 正在等待將資料寫入用戶端。  | 
|  [CPU](wait-event.cpu.md)  | 此事件表示執行緒活躍於 CPU 中或正在等待 CPU。 | 
|  [IO:BufFileRead 和 IO:BufFileWrite](wait-event.iobuffile.md)  |  這些事件表示 RDS for PostgreSQL 建立暫存檔。  | 
|  [IO:DataFileRead](wait-event.iodatafileread.md)  |  此事件表示連線等待後端程序從儲存讀取必要分頁，因為共用記憶體中沒有此分頁。  | 
| [IO:WALWrite](wait-event.iowalwrite.md)  | 此事件表示 RDS for PostgreSQL 正在等待預寫日誌 (WAL) 緩衝區寫入至 WAL 檔案。  | 
|  [Lock:advisory](wait-event.lockadvisory.md)  |  此事件表示 PostgreSQL 應用程式使用鎖定在多個工作階段之間協調活動。  | 
|  [Lock:extend](wait-event.lockextend.md) |  此事件表示後端程序正在等待鎖定關聯來延伸，但另一個程序也基於相同目的而鎖定該關係。  | 
|  [Lock:Relation](wait-event.lockrelation.md)  |  此事件表示查詢正等待在目前由另一個交易鎖定的資料表或檢視表上取得鎖定。  | 
|  [Lock:transactionid](wait-event.locktransactionid.md)  | 此事件表示交易正在等待資料列層級鎖定。 | 
|  [Lock:tuple](wait-event.locktuple.md)  |  此事件表示後端程序正等待在元組上取得鎖定。  | 
|  [LWLock:BufferMapping (LWLock:buffer\$1mapping)](wait-event.lwl-buffer-mapping.md)  |  此事件表示工作階段正在等待將資料區塊與共用緩衝集區中的緩衝區建立關聯。  | 
|  [LWLock:BufferIO (IPC:BufferIO)](wait-event.lwlockbufferio.md)  |  此事件表示 RDS for PostgreSQL 與其他程序同時嘗試存取分頁，正在等待其他程序完成輸入/輸出 (I/O) 操作。  | 
|  [LWLock:buffer\$1content (BufferContent)](wait-event.lwlockbuffercontent.md)  |  此事件表示工作階段正等待在記憶體中讀取或寫入資料分頁，但另一個工作階段已鎖定該分頁來寫入。  | 
|  [LWLock:lock\$1manager (LWLock:lockmanager)](wait-event.lw-lock-manager.md)  | 此事件表示因為無法執行快速路徑鎖定，RDS for PostgreSQL 引擎維護共用鎖定的記憶體區域來配置、檢查和解除配置鎖定。 | 
|  [LWLock：SubtransSLRU (LWLock：SubtransControlLock)](wait-event.lwlocksubtransslru.md)  |  當程序正在等待存取簡單最近最少使用 (SLRU) 快取進行子交易時，就會發生此事件。  | 
|  [Timeout:PgSleep](wait-event.timeoutpgsleep.md)  |  此事件表示伺服器程序已呼叫 `pg_sleep` 函數，正在等待睡眠逾時到期。  | 
|  [Timeout:VacuumDelay](wait-event.timeoutvacuumdelay.md)  | 此事件表示清空程序正在休眠，因為已達到預估的成本限制。 | 

# Client:ClientRead
<a name="wait-event.clientread"></a>

`Client:ClientRead` 事件表示 RDS for PostgreSQL 正在等待從用戶端接收資料。

**Topics**
+ [支援的引擎版本](#wait-event.clientread.context.supported)
+ [Context](#wait-event.clientread.context)
+ [等待變多的可能原因](#wait-event.clientread.causes)
+ [動作](#wait-event.clientread.actions)

## 支援的引擎版本
<a name="wait-event.clientread.context.supported"></a>

RDS for PostgreSQL 第 10 版及更高版本支援此等待事件資訊。

## Context
<a name="wait-event.clientread.context"></a>

RDS for PostgreSQL 資料庫執行個體正在等待從用戶端接收資料。RDS for PostgreSQL 資料庫執行個體必須先從用戶端接收資料，才能將更多資料傳送至用戶端。執行個體從用戶端接收資料之前等待的時間是 `Client:ClientRead` 事件。

## 等待變多的可能原因
<a name="wait-event.clientread.causes"></a>

`Client:ClientRead` 事件出現在最常等待名單中的常見原因包括：

**網路延遲較久**  
RDS for PostgreSQL 資料庫執行個體與用戶端之間的網路延遲可能變長。網路延遲較久會導致資料庫執行個體需要更多時間從用戶端接收資料。

**用戶端的負載增加**  
用戶端可能面臨 CPU 壓力或網路飽和。用戶端的負載增加可能延遲將資料從用戶端傳輸至 RDS for PostgreSQL 資料庫執行個體。

**網路往返太頻繁**  
如果 RDS for PostgreSQL 資料庫執行個體與用戶端之間網路往返太頻繁，可能會延遲將資料從用戶端傳輸至 RDS for PostgreSQL 資料庫執行個體。

**複製操作龐大**  
在複製操作期間，資料從用戶端的檔案系統傳輸至 RDS for PostgreSQL 資料庫執行個體。如果將大量資料傳送至資料庫執行個體，可能會延遲將資料從用戶端傳輸至資料庫執行個體。

**閒置用戶端連線**  
當用戶端連線至 `idle in transaction` 狀態的 RDS for PostgreSQL 資料庫執行個體時，資料庫執行個體可能會等待用戶端傳送更多資料或發出命令。處於此狀態的連線可能導致 `Client:ClientRead` 事件增加。

**連線集區使用的 PgBuncer**  
PgBuncer 有一個低階網路組態設定稱為 `pkt_buf`，預設為 4,096。如果工作負載透過 PgBuncer 傳送大於 4,096 個位元組的查詢封包，建議將 `pkt_buf` 設定增加為 8,192。如果新的設定未能減少 `Client:ClientRead` 事件，建議將 `pkt_buf` 設定增加為更大的值，例如 16,384 或 32,768。如果查詢文字很大，則較大的設定可能特別有用。

## 動作
<a name="wait-event.clientread.actions"></a>

根據等待事件的原因，我們會建議不同的動作。

**Topics**
+ [將用戶端放在與執行個體相同的可用區域和 VPC 子網路中](#wait-event.clientread.actions.az-vpc-subnet)
+ [擴展用戶端](#wait-event.clientread.actions.scale-client)
+ [使用最新一代的執行個體](#wait-event.clientread.actions.db-instance-class)
+ [增加網路頻寬](#wait-event.clientread.actions.increase-network-bandwidth)
+ [監控網路效能的最大值](#wait-event.clientread.actions.monitor-network-performance)
+ [監控處於 "idle in transaction" 狀態的交易](#wait-event.clientread.actions.check-idle-in-transaction)

### 將用戶端放在與執行個體相同的可用區域和 VPC 子網路中
<a name="wait-event.clientread.actions.az-vpc-subnet"></a>

若要縮短網路延遲並增加網路輸送量，請將用戶端放在與 RDS for PostgreSQL 資料庫執行個體相同的可用區域和虛擬私有雲端 (VPC) 子網路中。確保用戶端的地理位置盡可能靠近資料庫執行個體。

### 擴展用戶端
<a name="wait-event.clientread.actions.scale-client"></a>

使用 Amazon CloudWatch 或其他主機指標，判斷用戶端目前是否受限於 CPU、網路頻寬，或同時受限於這兩者。如果用戶端受到限制，請相應地擴展用戶端。

### 使用最新一代的執行個體
<a name="wait-event.clientread.actions.db-instance-class"></a>

在某些情況下，您使用的資料庫執行個體類別可能不支援 Jumbo Frame。如果您在 Amazon EC2 上執行應用程式，請考慮為用戶端使用最新一代的執行個體。此外，在用戶端作業系統上設定最大傳輸單位 (MTU)。此技術可以減少網路往返次數並增加網路輸送量。如需詳細資訊，請參閱《Amazon EC2 使用者指南》**中的 [Jumbo Frame (9001 MTU)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/network_mtu.html#jumbo_frame_instances)。

如需資料庫執行個體類別的相關資訊，請參閱 [ 資料庫執行個體類別](Concepts.DBInstanceClass.md)。若要決定等同於 Amazon EC2 執行個體類型的資料庫執行個體類別，請在 Amazon EC2 執行個體類型名稱前面加上 `db.`。例如，`r5.8xlarge` Amazon EC2 執行個體等同於 `db.r5.8xlarge` 資料庫執行個體類別。

### 增加網路頻寬
<a name="wait-event.clientread.actions.increase-network-bandwidth"></a>

使用 `NetworkReceiveThroughput` 和 `NetworkTransmitThroughput` Amazon CloudWatch 指標來監控資料庫執行個體上的傳入和傳出網路流量。這些指標可協助您判斷網路頻寬是否足以應付工作負載。

如果網路頻寬不夠，請增加頻寬。如果 AWS 用戶端或資料庫執行個體達到網路頻寬限制，增加頻寬的唯一方法是增加資料庫執行個體大小。如需詳細資訊，請參閱[資料庫執行個體類別的類型](Concepts.DBInstanceClass.Types.md)。

如需 CloudWatch 指標的詳細資訊，請參閱[Amazon RDS 的 Amazon CloudWatch 指標](rds-metrics.md)。

### 監控網路效能的最大值
<a name="wait-event.clientread.actions.monitor-network-performance"></a>

如果您使用 Amazon EC2 用戶端，Amazon EC2 提供網路效能指標的最大值，包括傳入和傳出網路總頻寬。也提供連線追蹤來確保如預期傳回封包，還有網域名稱系統 (DNS) 等服務的連結本機服務存取。若要監控這些最大值，請使用目前的增強型網路驅動程式，以監控用戶端的網路效能。

如需詳細資訊，請參閱《Amazon EC2 使用者指南》**中的[監控 Amazon EC2 執行個體的網路效能](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-network-performance-ena.html)和《Amazon EC2使用者指南》**中的[監控 Amazon EC2 執行個體的網路效能](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/monitoring-network-performance-ena.html)。

### 監控處於 "idle in transaction" 狀態的交易
<a name="wait-event.clientread.actions.check-idle-in-transaction"></a>

檢查 `idle in transaction` 連線是否變多。作法是監控 `pg_stat_activity` 資料表的 `state` 資料欄。您可以執行類似下列的查詢來識別連線來源。

```
select client_addr, state, count(1) from pg_stat_activity 
where state like 'idle in transaction%' 
group by 1,2 
order by 3 desc
```

# Client:ClientWrite
<a name="wait-event.clientwrite"></a>

`Client:ClientWrite` 事件表示 RDS for PostgreSQL 正在等待將資料寫入用戶端。

**Topics**
+ [支援的引擎版本](#wait-event.clientwrite.context.supported)
+ [Context](#wait-event.clientwrite.context)
+ [等待變多的可能原因](#wait-event.clientwrite.causes)
+ [動作](#wait-event.clientwrite.actions)

## 支援的引擎版本
<a name="wait-event.clientwrite.context.supported"></a>

RDS for PostgreSQL 第 10 版及更高版本支援此等待事件資訊。

## Context
<a name="wait-event.clientwrite.context"></a>

用戶端程序必須先讀取從 RDS for PostgreSQL 資料庫叢集收到的所有資料，叢集才能傳送更多資料。叢集將更多資料傳送至用戶端之前等待的時間是 `Client:ClientWrite` 事件。

RDS for PostgreSQL 資料庫執行個體與用戶端之間的網路輸送量減少可能造成此事件。用戶端的 CPU 壓力和網路飽和也可能造成此事件。*CPU 壓力*表示 CPU 耗盡，但有任務正在等待 CPU 時間。*網路飽和*表示資料庫與用戶端之間的網路傳送太多資料，應付不來。

## 等待變多的可能原因
<a name="wait-event.clientwrite.causes"></a>

`Client:ClientWrite` 事件出現在最常等待名單中的常見原因包括：

**網路延遲較久**  
RDS for PostgreSQL 資料庫執行個體與用戶端之間的網路延遲可能變長。網路延遲較久會導致用戶端需要更多時間來接收資料。

**用戶端的負載增加**  
用戶端可能面臨 CPU 壓力或網路飽和。用戶端的負載增加會延遲從 RDS for PostgreSQL 資料庫執行個體接收資料。

**傳送大量資料給用戶端**  
RDS for PostgreSQL 資料庫執行個體可能將大量資料傳送至用戶端。用戶端可能來不及接收叢集傳送的資料。例如，複製大型資料表這種活動可能導致 `Client:ClientWrite` 事件增加。

## 動作
<a name="wait-event.clientwrite.actions"></a>

根據等待事件的原因，我們會建議不同的動作。

**Topics**
+ [將用戶端放在與叢集相同的可用區域和 VPC 子網路中](#wait-event.clientwrite.actions.az-vpc-subnet)
+ [使用最新一代的執行個體](#wait-event.clientwrite.actions.db-instance-class)
+ [減少傳送至用戶端的資料量](#wait-event.clientwrite.actions.reduce-data)
+ [擴展用戶端](#wait-event.clientwrite.actions.scale-client)

### 將用戶端放在與叢集相同的可用區域和 VPC 子網路中
<a name="wait-event.clientwrite.actions.az-vpc-subnet"></a>

若要縮短網路延遲並增加網路輸送量，請將用戶端放在與 RDS for PostgreSQL 資料庫執行個體相同的可用區域和虛擬私有雲端 (VPC) 子網路中。

### 使用最新一代的執行個體
<a name="wait-event.clientwrite.actions.db-instance-class"></a>

在某些情況下，您使用的資料庫執行個體類別可能不支援 Jumbo Frame。如果您在 Amazon EC2 上執行應用程式，請考慮為用戶端使用最新一代的執行個體。此外，在用戶端作業系統上設定最大傳輸單位 (MTU)。此技術可以減少網路往返次數並增加網路輸送量。如需詳細資訊，請參閱《Amazon EC2 使用者指南》**中的 [Jumbo Frame (9001 MTU)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/network_mtu.html#jumbo_frame_instances)。

如需資料庫執行個體類別的相關資訊，請參閱 [ 資料庫執行個體類別](Concepts.DBInstanceClass.md)。若要決定等同於 Amazon EC2 執行個體類型的資料庫執行個體類別，請在 Amazon EC2 執行個體類型名稱前面加上 `db.`。例如，`r5.8xlarge` Amazon EC2 執行個體等同於 `db.r5.8xlarge` 資料庫執行個體類別。

### 減少傳送至用戶端的資料量
<a name="wait-event.clientwrite.actions.reduce-data"></a>

可能的話，請調整應用程式，以減少 RDS for PostgreSQL 資料庫執行個體傳送至用戶端的資料量。這樣調整可以減輕用戶端的 CPU 和網路爭用情形。

### 擴展用戶端
<a name="wait-event.clientwrite.actions.scale-client"></a>

使用 Amazon CloudWatch 或其他主機指標，判斷用戶端目前是否受限於 CPU、網路頻寬，或同時受限於這兩者。如果用戶端受到限制，請相應地擴展用戶端。

# CPU
<a name="wait-event.cpu"></a>

此事件表示執行緒活躍於 CPU 中或正在等待 CPU。

**Topics**
+ [支援的引擎版本](#wait-event.cpu.context.supported)
+ [Context](#wait-event.cpu.context)
+ [等待變多的可能原因](#wait-event.cpu.causes)
+ [動作](#wait-event.cpu.actions)

## 支援的引擎版本
<a name="wait-event.cpu.context.supported"></a>

此等待事件資訊與所有 RDS for PostgreSQL 版本有關。

## Context
<a name="wait-event.cpu.context"></a>

*中央處理單元 (CPU)* 是執行指令的電腦元件。例如，CPU 指令執行算術運算，並在記憶體中交換資料。如果查詢增加更多指令來透過資料庫引擎執行，則查詢會執行更久。*CPU 排程*將 CPU 時間撥給程序。排程由作業系統的核心協調。

**Topics**
+ [如何得知發生這種等待](#wait-event.cpu.when-it-occurs)
+ [DBLoadCPU 指標](#wait-event.cpu.context.dbloadcpu)
+ [os.cpuUtilization 指標](#wait-event.cpu.context.osmetrics)
+ [CPU 排程的可能原因](#wait-event.cpu.context.scheduling)

### 如何得知發生這種等待
<a name="wait-event.cpu.when-it-occurs"></a>

此 `CPU` 等待事件表示後端程序活躍於 CPU 中或正在等待 CPU。當查詢顯示下列資訊時，就表示發生此事件：
+ `pg_stat_activity.state` 欄具有值 `active`。
+ `pg_stat_activity` 中的 `wait_event_type` 和 `wait_event` 欄皆為 `null`。

若要查看正在使用或等待 CPU 的後端程序，請執行下列查詢。

```
SELECT * 
FROM   pg_stat_activity
WHERE  state = 'active'
AND    wait_event_type IS NULL
AND    wait_event IS NULL;
```

### DBLoadCPU 指標
<a name="wait-event.cpu.context.dbloadcpu"></a>

CPU 的績效詳情指標為 `DBLoadCPU`。`DBLoadCPU` 的值與 Amazon CloudWatch 指標 `CPUUtilization` 的值可能不同。後者是從 HyperVisor 為資料庫執行個體收集的指標。

### os.cpuUtilization 指標
<a name="wait-event.cpu.context.osmetrics"></a>

績效詳情作業系統指標提供 CPU 使用率的詳細資訊。例如，您可以顯示下列指標：
+ `os.cpuUtilization.nice.avg`
+ `os.cpuUtilization.total.avg`
+ `os.cpuUtilization.wait.avg`
+ `os.cpuUtilization.idle.avg`

績效詳情以 `os.cpuUtilization.nice.avg` 報告資料庫引擎的 CPU 使用率。

### CPU 排程的可能原因
<a name="wait-event.cpu.context.scheduling"></a>

 作業系統核心會處理 CPU 的排程。CPU *作用中*時，程序可能需要等待排程。CPU 在執行運算時處於作用中狀態。當它具有未執行的閒置執行緒 (亦即，等待記憶體 I/O 的執行緒) 時，也是處於作用中狀態。此類型的 I/O 主導典型資料庫工作負載。

滿足下列條件時，程序可能等待排定使用 CPU：
+ CloudWatch `CPUUtilization` 指標接近 100%。
+ 平均負載大於 vCPU 數目，表示負載過重。您可以在績效詳情的作業系統指標區段中找到 `loadAverageMinute` 指標。

## 等待變多的可能原因
<a name="wait-event.cpu.causes"></a>

CPU 等待事件比平時更常發生時，可能表示有效能問題，典型原因包括下列各項。

**Topics**
+ [突然激增的可能原因](#wait-event.cpu.causes.spikes)
+ [長期頻繁的可能原因](#wait-event.cpu.causes.long-term)
+ [罕見情況](#wait-event.cpu.causes.corner-cases)

### 突然激增的可能原因
<a name="wait-event.cpu.causes.spikes"></a>

突然激增最可能的原因如下：
+ 應用程式對資料庫同時開啟太多連線。這種情況稱為「連線風暴」。
+ 應用程式工作負載出現下列任何變化：
  + 新查詢
  + 資料集變大
  + 維護或建立索引
  + 新函數
  + 新運算子
  + 平行執行查詢增加
+ 查詢執行計劃已變更。在某些情況下，變更可能造成緩衝區增加。例如，查詢原本使用索引，但現在使用循序掃描。在此情況下，查詢需要更多 CPU 才能完成相同的目標。

### 長期頻繁的可能原因
<a name="wait-event.cpu.causes.long-term"></a>

事件長期復發最可能的原因：
+ CPU 上同時執行太多後端程序。這些程序可能是平行工作者。
+ 查詢表現欠佳，因為需要大量緩衝區。

### 罕見情況
<a name="wait-event.cpu.causes.corner-cases"></a>

如果可能原因都不是真正原因，可能表示發生下列情況：
+ CPU 正在換入換出程序。
+ 如果*大型頁面*功能已關閉，則 CPU 可能正在管理頁面表格項目。除了微型、小型和中型資料庫執行個體類之外，所有資料庫執行個體類都預設開啟此記憶體管理功能。如需詳細資訊，請參閱[RDS for PostgreSQL 的巨型分頁](PostgreSQL.Concepts.General.FeatureSupport.HugePages.md)。

## 動作
<a name="wait-event.cpu.actions"></a>

如果 `CPU` 等待事件在資料庫活動中佔多數，則不見得表示有效能問題。效能降低時才需要回應此事件。

**Topics**
+ [調查資料庫是否造成 CPU 使用率上升](#wait-event.cpu.actions.db-CPU)
+ [判斷連線數目是否增加](#wait-event.cpu.actions.connections)
+ [回應工作負載變更](#wait-event.cpu.actions.workload)

### 調查資料庫是否造成 CPU 使用率上升
<a name="wait-event.cpu.actions.db-CPU"></a>

在績效詳情中檢查 `os.cpuUtilization.nice.avg` 指標。如果此值遠低於 CPU 使用率，表示佔用 CPU 以非資料庫的程序為主。

### 判斷連線數目是否增加
<a name="wait-event.cpu.actions.connections"></a>

在 Amazon CloudWatch 中檢查 `DatabaseConnections` 指標。您的動作取決於在 CPU 等待事件變多期間，連線數目是增加還是減少。

#### 連線增加
<a name="wait-event.cpu.actions.connections.increased"></a>

如果連線數目上升，請將耗用 CPU 的後端程序數目與 vCPU 數目做比較。可能的情況如下：
+ 耗用 CPU 的後端程序數目小於 vCPU 數目。

  在此情況下，連線數目不是問題。但您仍然可以嘗試降低 CPU 使用率。
+ 耗用 CPU 的後端程序數目大於 vCPU 數目。

  在此情況下，請考慮下列選項：
  + 將連線至資料庫的後端程序數目減少。例如，實作連線集區解決方案，例如 RDS Proxy。如需詳細資訊，請參閱 [Amazon RDS Proxy ](rds-proxy.md)。
  + 加大執行個體以取得更多 vCPU。
  + 如適用，請將一些唯讀工作負載重新導向至讀取器節點

#### 連線未增加
<a name="wait-event.cpu.actions.connections.decreased"></a>

在績效詳情中檢查 `blks_hit` 指標。尋找 `blks_hit` 增加與 CPU 使用率之間的關聯性。可能的情況如下：
+ CPU 使用率與 `blks_hit` 有關。

  在此情況下，請找出與 CPU 使用率最有關的 SQL 陳述式，並尋找計劃變更。您可以使用下列任一技巧：
  + 手動解釋計劃，並與預期的執行計劃做比較。
  + 查明每秒區塊命中數和每秒本機區塊命中數是否增加。在績效詳情儀表板的 **Top SQL** (常用 SQL) 區段中，選擇 **Preferences** (偏好設定)。
+ CPU 使用率與 `blks_hit` 無關。

  在此情況下，請判斷是否發生下列任何情形：
  + 應用程式與資料庫之間快速連線和斷線。

    請開啟 `log_connections` 和 `log_disconnections`，然後分析 PostgreSQL 日誌，以診斷此行為。考慮使用 `pgbadger` 日誌分析器。如需詳細資訊，請參閱 [https://github.com/darold/pgbadger](https://github.com/darold/pgbadger)。
  + 作業系統超載。

    在此情況下，績效詳情會指出後端程序耗用 CPU 比平常更久。在績效詳情 `os.cpuUtilization` 指標或 CloudWatch `CPUUtilization` 指標中查證。如果作業系統超載，請檢查增強型監控指標以進一步診斷。具體來說，請檢查程序清單及每個程序耗用的 CPU 百分比。
  + 常用 SQL 陳述式耗用太多 CPU。

    檢查與 CPU 使用率有關的陳述式，了解是否可以少用 CPU。執行 `EXPLAIN` 命令，專注於影響最大的計劃節點上。考慮使用 PostgreSQL execution plan visualizer。若要試用此工具，請參閱 [http://explain.dalibo.com/](http://explain.dalibo.com/)。

### 回應工作負載變更
<a name="wait-event.cpu.actions.workload"></a>

如果工作負載已變更，請尋找下列類型的變更：

新查詢  
檢查是否需要新的查詢。如果是，請確定其執行計劃和每秒執行次數合理。

資料集變大  
決定是否應該分割 (如果尚未分割)。此策略可以減少查詢需要擷取的分頁數。

維護或建立索引  
檢查是否需要排定維護。最佳實務是將維護活動排定在尖峰活動之外。

新函數  
檢查這些函數在測試期間是否正常執行。具體來說，請檢查每秒執行次數是否合理。

新運算子  
檢查在測試期間是否正常執行。

平行執行查詢增加  
判斷是否發生下列任何情況：  
+ 涉及的關聯或索引突然變大，明顯不同於 `min_parallel_table_scan_size` 或 `min_parallel_index_scan_size`。
+ 最近變更 `parallel_setup_cost` 或 `parallel_tuple_cost`。
+ 最近變更 `max_parallel_workers` 或 `max_parallel_workers_per_gather`。

# IO:BufFileRead 和 IO:BufFileWrite
<a name="wait-event.iobuffile"></a>

`IO:BufFileRead` 和 `IO:BufFileWrite` 事件表示 RDS for PostgreSQL 建立暫存檔。如果操作需要的記憶體超過工作記憶體參數目前的定義，則會將暫存資料寫入永久性儲存。此操作有時稱為*溢出到磁碟*。如需暫存檔案及其使用情況的詳細資訊，請參閱 [使用 PostgreSQL 管理暫存檔案](PostgreSQL.ManagingTempFiles.md)。

**Topics**
+ [支援的引擎版本](#wait-event.iobuffile.context.supported)
+ [Context](#wait-event.iobuffile.context)
+ [等待變多的可能原因](#wait-event.iobuffile.causes)
+ [動作](#wait-event.iobuffile.actions)

## 支援的引擎版本
<a name="wait-event.iobuffile.context.supported"></a>

所有 RDS for PostgreSQL 版本都支援此等待事件資訊。

## Context
<a name="wait-event.iobuffile.context"></a>

`IO:BufFileRead` 和 `IO:BufFileWrite` 與工作記憶體區域和維護工作記憶體區域有關。如需這些本機記憶體區域的詳細資訊，請參閱 PostgreSQL 文件中的[資源耗用](https://www.postgresql.org/docs/current/runtime-config-resource.html)。

`work_mem` 的預設值為 4 MB。如果一個工作階段平行執行操作，則負責平行處理的每個工作者會使用 4 MB 的記憶體。因此，請小心設定 `work_mem`。如果將此值設得太大，則執行許多工作階段的資料庫可能會耗用太多記憶體。如果將此值設得太低，RDS for PostgreSQL 會在本機儲存體中建立暫存檔。這些暫存檔的磁碟輸入/輸出可能造成效能降低。

如果您看到下列事件序列，表示資料庫可能正在產生暫存檔：

1. 可用性突然遽降

1. 可用空間迅速復原

您也可能看到「鏈鋸」模式。此模式可能表示資料庫不斷建立小檔案。

## 等待變多的可能原因
<a name="wait-event.iobuffile.causes"></a>

一般而言，這些等待事件起因於操作耗用超過 `work_mem` 或 `maintenance_work_mem`參數所配置的記憶體。為了補償，操作寫入暫存檔。`IO:BufFileRead` 和 `IO:BufFileWrite` 事件的常見原因包括：

**查詢需要比工作記憶體區域中更多的記憶體**  
具有下列特性的查詢使用工作記憶體區域：  
+ 雜湊聯結。
+ `ORDER BY` 子句
+ `GROUP BY` 子句
+ `DISTINCT`
+ 範圍函數
+ `CREATE TABLE AS SELECT`
+ 具體化檢視表重新整理

**陳述式需要比維護工作記憶體區域中更多的記憶體**  
下列陳述式使用維護工作記憶體區域：  
+ `CREATE INDEX`
+ `CLUSTER`

## 動作
<a name="wait-event.iobuffile.actions"></a>

根據等待事件的原因，我們會建議不同的動作。

**Topics**
+ [識別問題](#wait-event.iobuffile.actions.problem)
+ [檢查聯結查詢](#wait-event.iobuffile.actions.joins)
+ [檢查 ORDER BY 和 GROUP BY 查詢](#wait-event.iobuffile.actions.order-by)
+ [避免使用 DISTINCT 操作](#wait-event.iobuffile.actions.distinct)
+ [考慮使用視窗函數代替 GROUP BY 函數](#wait-event.iobuffile.actions.window)
+ [調查具體化檢視表和 CTAS 陳述式](#wait-event.iobuffile.actions.mv-refresh)
+ [重建索引時使用 pg\$1repack](#wait-event.iobuffile.actions.pg_repack)
+ [叢集化資料表時提高 maintenance\$1work\$1mem](#wait-event.iobuffile.actions.cluster)
+ [調整記憶體以防止 IO:BufFileRead 和 IO:BufFileWrite](#wait-event.iobuffile.actions.tuning-memory)

### 識別問題
<a name="wait-event.iobuffile.actions.problem"></a>

您可以直接在績效詳情中檢視暫存檔案用量。如需詳細資訊，請參閱[使用 Performance Insights 來檢視暫存檔使用情況](PostgreSQL.ManagingTempFiles.Example.md)。停用績效詳情時，您可能會注意到 `IO:BufFileRead`和 `IO:BufFileWrite`操作增加。

若要識別問題的來源，您可以設定 `log_temp_files` 參數來記錄所有產生超過指定閾值 KB 暫存檔的查詢。根據預設，`log_temp_files` 會設為 `-1`，這會關閉此記錄功能。如果您將此參數設為 `0`，RDS for PostgreSQL 會記錄所有暫存檔。如果您將其設為 `1024`，RDS for PostgreSQL 會記錄所有產生大於 1 MB 暫存檔的查詢。如需 `log_temp_files` 的詳細資訊，請參閱 PostgreSQL 文件中的[錯誤報告和日誌記錄](https://www.postgresql.org/docs/current/runtime-config-logging.html)。

### 檢查聯結查詢
<a name="wait-event.iobuffile.actions.joins"></a>

您的查詢很可能使用聯結。例如，下列查詢會聯結四個資料表。

```
SELECT * 
       FROM "order" 
 INNER JOIN order_item 
       ON (order.id = order_item.order_id)
 INNER JOIN customer 
       ON (customer.id = order.customer_id)
 INNER JOIN customer_address 
       ON (customer_address.customer_id = customer.id AND 
           order.customer_address_id = customer_address.id)
 WHERE customer.id = 1234567890;
```

暫存檔使用量激增的可能原因在於查詢本身有問題。例如，不標準的子句可能無法正確篩選聯結。請看下列範例中的第二個內部聯結。

```
SELECT * 
       FROM "order"
 INNER JOIN order_item 
       ON (order.id = order_item.order_id)
 INNER JOIN customer 
       ON (customer.id = customer.id)
 INNER JOIN customer_address 
       ON (customer_address.customer_id = customer.id AND 
           order.customer_address_id = customer_address.id)
 WHERE customer.id = 1234567890;
```

上述查詢誤將 `customer.id` 聯結至 `customer.id`，導致在每個客戶與每筆訂單之間產生笛卡爾乘積。這種意外聯結會產生大型暫存檔。根據資料表的大小，笛卡爾查詢甚至可能導致填滿儲存。有下列情況時，表示應用程式可能有笛卡爾聯結：
+ 您看到儲存可用性大幅遽降，接著迅速復原。
+ 未建立索引。
+ 未發出 `CREATE TABLE FROM SELECT` 陳述式。
+ 未重新整理具體化檢視表。

若要檢查是否以適當索引鍵聯結資料表，請檢驗查詢和物件關聯式映射指令。切記，不一定會呼叫應用程式的某些查詢，有些查詢是動態產生。

### 檢查 ORDER BY 和 GROUP BY 查詢
<a name="wait-event.iobuffile.actions.order-by"></a>

在某些情況下，`ORDER BY` 子句可能導致產生過多暫存檔。請考量下列準則：
+ 只將需要排序的資料欄放入 `ORDER BY` 子句中。如果查詢傳回數千個資料列，並在 `ORDER BY` 子句中指定許多資料欄，此準則尤其重要。
+ 當 `ORDER BY` 子句比對的資料欄有相同遞增或遞減順序時，請考慮建立索引以加速執行。最好是局部索引，因為較小。讀取和周遊較小的索引比較快。
+ 如果您為可接受空值的資料欄建立索引，請決定要將空值存放在索引結尾還是開頭。

  可能的話，請篩選結果集，以減少需要排序的資料列數。如果您使用 `WITH` 子句陳述式或子查詢，請記住，內部查詢會產生結果集並傳給外部查詢。查詢篩選掉越多資料列，查詢就越不需要排序。
+ 如果不需要取得完整結果集，請使用 `LIMIT` 子句。例如，如果您只想要前五個資料列，則在查詢中使用 `LIMIT` 子句就不會一直產生結果。如此，查詢只需要較少的記憶體和暫存檔。

使用 `GROUP BY` 子句的查詢可能也需要暫存檔。`GROUP BY` 查詢使用如下函數來彙總值：
+ `COUNT`
+ `AVG`
+ `MIN`
+ `MAX`
+ `SUM`
+ `STDDEV`

若要調校 `GROUP BY` 查詢，請遵循 `ORDER BY` 查詢的建議。

### 避免使用 DISTINCT 操作
<a name="wait-event.iobuffile.actions.distinct"></a>

可能的話，請避免使用 `DISTINCT` 操作來移除重複的資料列。查詢傳回不必要和重複的資料列越多，`DISTINCT` 操作的成本越高。可能的話，請在 `WHERE` 子句中增加篩選條件，即使不同的資料表使用相同的篩選器也無妨。篩選查詢並正確聯結可改善效能和減少使用資源。還可防止不正確的報告和結果。

如果需要對同一個資料表的多個資料列使用 `DISTINCT`，請考慮建立複合索引。將多個資料列組合成一個索引，可縮短相異資料列的評估時間。此外，如果您使用 RDS for PostgreSQL 第 10 版或更新版本，則可以使用 `CREATE STATISTICS` 命令，將多個資料欄之間的統計數字相互關聯。

### 考慮使用視窗函數代替 GROUP BY 函數
<a name="wait-event.iobuffile.actions.window"></a>

使用 `GROUP BY` 時，您變更結果集，然後擷取彙總結果。使用視窗函數時，您彙總資料而不變更結果集。視窗函數使用 `OVER` 子句來跨查詢所定義的集執行計算，使資料列彼此相互關聯。您在視窗函數中可以使用所有 `GROUP BY` 函數，但也可使用如下函數：
+ `RANK`
+ `ARRAY_AGG`
+ `ROW_NUMBER`
+ `LAG`
+ `LEAD`

若要盡量減少視窗函數產生的暫存檔，當需要兩個相異彙總時，請移除相同結果集的重複部分。請看下列查詢。

```
SELECT sum(salary) OVER (PARTITION BY dept ORDER BY salary DESC) as sum_salary
     , avg(salary) OVER (PARTITION BY dept ORDER BY salary ASC) as avg_salary
  FROM empsalary;
```

您可以使用 `WINDOW` 子句重寫查詢，如下所示。

```
SELECT sum(salary) OVER w as sum_salary
         , avg(salary) OVER w as_avg_salary
    FROM empsalary
  WINDOW w AS (PARTITION BY dept ORDER BY salary DESC);
```

根據預設，RDS for PostgreSQL 執行規劃工具會合併相似的節點，以免重複操作。不過，使用視窗區塊的明確宣告可以更輕鬆維護查詢。防止重複也可以改善效能。

### 調查具體化檢視表和 CTAS 陳述式
<a name="wait-event.iobuffile.actions.mv-refresh"></a>

具體化檢視表重新整理時會執行查詢。此查詢可以包含 `GROUP BY`、`ORDER BY` 或 `DISTINCT` 等操作。在重新整理期間，您可能看到大量暫存檔及等待事件 `IO:BufFileWrite` 和 `IO:BufFileRead`。同樣地，當您根據 `SELECT` 陳述式建立資料表時，`CREATE TABLE` 陳述式會執行查詢。若要減少所需的暫存檔，請最佳化查詢。

### 重建索引時使用 pg\$1repack
<a name="wait-event.iobuffile.actions.pg_repack"></a>

當您建立索引時，引擎會排序結果集。隨著資料表變大，以及索引資料欄的值變得更多樣化，暫存檔需要更多空間。在大多數情況下，除非修改維護工作記憶體區域，否則無法阻止為大型資料表建立暫存檔。如需 `maintenance_work_mem` 的詳細資訊，請參閱 PostgreSQL 文件中的 [https://www.postgresql.org/docs/current/runtime-config-resource.html](https://www.postgresql.org/docs/current/runtime-config-resource.html)。

重新建立大型索引時，可能的解決方法是使用 pg\$1repack 延伸模組。如需詳細資訊，請參閱 pg\$1repack 文件中的[以最少鎖定重組 PostgreSQL 資料庫中的資料表](https://reorg.github.io/pg_repack/)。如需在 RDS for PostgreSQL 資料庫執行個體中設定延伸模組的相關資訊，請參閱 [使用 pg\$1repack 擴充功能減少資料表和索引膨脹](Appendix.PostgreSQL.CommonDBATasks.pg_repack.md)。

### 叢集化資料表時提高 maintenance\$1work\$1mem
<a name="wait-event.iobuffile.actions.cluster"></a>

`CLUSTER` 命令根據 *index\$1name* 指定的現有索引，以叢集化 *table\$1name* 指定的資料表。RDS for PostgreSQL 實際上會重新建立資料表，以符合特定索引的順序。

在磁帶儲存盛行的年代，因為儲存輸送量有限，叢集很普遍。如今 SSD 型儲存很普遍，較不流行叢集。不過，如果將資料表叢集化，還是可稍微提高效能，視資料表大小、索引、查詢等而定。

如果您執行 `CLUSTER` 命令，然後看到等待事件 `IO:BufFileWrite` 和 `IO:BufFileRead`,請調校 `maintenance_work_mem`。請將記憶體調到很大。較大的值表示引擎可以使用更多記憶體執行叢集操作。

### 調整記憶體以防止 IO:BufFileRead 和 IO:BufFileWrite
<a name="wait-event.iobuffile.actions.tuning-memory"></a>

在某些情況下，您需要調整記憶體。您的目標是使用適當的參數來平衡下列消用區域的記憶體，如下所示。
+ `work_mem` 值。
+ 折除 `shared_buffers` 值之後剩餘的記憶體
+ 已開啟和使用中的連線數上限，受限於 `max_connections`

如需如何調整記憶體的詳細資訊，請參閱 PostgreSQL 文件中的[資源耗用](https://www.postgresql.org/docs/current/runtime-config-resource.html)。

#### 增加工作記憶體區域的大小
<a name="wait-event.iobuffile.actions.tuning-memory.work-mem"></a>

在某些情況下，您只能選擇增加工作階段所使用的記憶體。如果查詢撰寫無誤，且使用正確的索引鍵來聯結，請考慮提高 `work_mem` 值。

若要了解查詢產生多少暫存檔，請將 `log_temp_files` 設定為 `0`。如果將 `work_mem` 值提高到日誌中指出的最大值，就可以防止查詢產生暫存檔。然而，`work_mem` 會針對每個連線或平行工作者，設定每個計劃節點的最大值。如果資料庫有 5,000 個連線，且每個連線各使用 256 MiB 的記憶體，則引擎需要 1.2 TiB 的 RAM。因此，執行個體可能記憶體不足。

#### 為共用緩衝集區保留足夠記憶體
<a name="wait-event.iobuffile.actions.tuning-memory.shared-pool"></a>

資料庫不只使用工作記憶體區域，還使用共用緩衝集區之類的記憶體區域。提高 `work_mem` 之前，請考慮這些額外記憶體區域的需求。

例如，假設您的 RDS for PostgreSQL 執行個體類別為 db.r5.2xlarge。此類別有 64 GiB 的記憶體。預設會保留 25% 的記憶體給共用緩衝集區。減去配置給共用記憶體區域的數量後，剩下 16,384 MB。請勿將剩餘的記憶體全部配置給工作記憶體區域，因為作業系統和引擎也需要記憶體。

可配置給 `work_mem` 的記憶體取決於執行個體類別。使用越大的執行個體類別，可用的記憶體越多。不過，在上述範例中，最多只能使用 16 GiB。否則，當記憶體不足時，就無法使用執行個體。為了讓執行個體從無法使用狀態中復原，RDS for PostgreSQL 自動化服務會自動重新啟動。

#### 管理連線數目
<a name="wait-event.iobuffile.actions.tuning-memory.connections"></a>

假設您的資料庫執行個體有 5,000 個同時連線。每個連線至少使用 4 MiB 的 `work_mem`。連線耗用大量記憶體可能導致效能降低。因應之道如下：
+ 提升為更大的執行個體類別。
+ 使用連線代理或集區來減少同時的資料庫連線數。

關於代理，根據您的應用程式而定，請考慮 Amazon RDS Proxy、pgBuncer 或連線集區。此解決方案可減輕 CPU 負載。面臨所有連線都需要工作記憶體區域時，也能降低風險。在只有少數資料庫連線時，您可以提高 `work_mem` 的值。如此就能減少 `IO:BufFileRead` 和 `IO:BufFileWrite` 等待事件。等待工作記憶體區域的查詢也會大幅加速。

# IO:DataFileRead
<a name="wait-event.iodatafileread"></a>

`IO:DataFileRead` 事件表示因為所需的分頁不在共用記憶體中，連線等待後端程序從儲存讀取該分頁。

**Topics**
+ [支援的引擎版本](#wait-event.iodatafileread.context.supported)
+ [Context](#wait-event.iodatafileread.context)
+ [等待時間增加的可能原因](#wait-event.iodatafileread.causes)
+ [動作](#wait-event.iodatafileread.actions)

## 支援的引擎版本
<a name="wait-event.iodatafileread.context.supported"></a>

所有 RDS for PostgreSQL 版本都支援此等待事件資訊。

## Context
<a name="wait-event.iodatafileread.context"></a>

所有查詢和資料操作 (DML) 作業會存取緩衝集區中的分頁。引起讀取的陳述式包括 `SELECT`、`UPDATE` 及 `DELETE`。例如，`UPDATE` 可以從資料表或索引讀取分頁。如果所請求或更新的頁面不在共用緩衝集區中，則此讀取可能引起 `IO:DataFileRead` 事件。

共用緩衝集區有限，可能填滿。在此情況下，請求的分頁不在記憶體中，迫使資料庫從磁碟讀取區塊。如果 `IO:DataFileRead` 事件經常發生，可能表示共用緩衝集區太小，不足以應付工作負載。這是嚴重問題，因為 `SELECT` 查詢讀取大量資料列，塞不進緩衝集區。如需緩衝集區的詳細資訊，請參閱 PostgreSQL 文件中的[資源耗用](https://www.postgresql.org/docs/current/runtime-config-resource.html)。

## 等待時間增加的可能原因
<a name="wait-event.iodatafileread.causes"></a>

`IO:DataFileRead` 的常見原因包括：

**連線尖峰**  
您可能發現多個連線產生一樣多的 IO:DataFileRead 等待事件。在此情況下，`IO:DataFileRead` 事件可能出現尖峰 (突然大幅增加)。

**SELECT 和 DML 陳述式執行循序掃描**  
您的應用程式可能執行新的操作。或者，現有的操作可能因為新的執行計劃而變更。在這種情況下，請尋找 `seq_scan` 值較大的資料表 (特別是大型資料表)。查詢 `pg_stat_user_tables` 來尋找。若要追蹤哪些查詢產生較多讀取操作，請使用延伸 `pg_stat_statements`。

**大型資料集的 CTAS 和 CREATE INDEX**  
*CTAS* 代表 `CREATE TABLE AS SELECT` 陳述式。如果您以大型資料集為來源執行 CTAS，或在大型資料表上建立索引，可能會發生 `IO:DataFileRead` 事件。建立索引時，資料庫可能需要使用循序掃描來讀取整個物件。當分頁不在記憶體中時，CTAS 會產生 `IO:DataFile` 讀取。

**多個清理工作者同時執行**  
清理工作者是手動或自動觸發。建議採取積極清理策略。不過，當資料表更新或刪除許多資料列時，`IO:DataFileRead` 等待會變多。回收空間後，花在 `IO:DataFileRead` 的清理時間就會減少。

**擷取大量資料**  
當應用程式擷取大量資料時，`ANALYZE` 操作可能更頻繁發生。`ANALYZE` 程序可以由自動資料清理啟動器觸發，或手動叫用。  
`ANALYZE` 操作讀取資料表的子集。將 30 乘以 `default_statistics_target` 值，即可算出必須掃描的分頁數。如需詳細資訊，請參閱 [PostgreSQL 文件](https://www.postgresql.org/docs/current/runtime-config-query.html#GUC-DEFAULT-STATISTICS-TARGET)。`default_statistics_target` 參數接受 1 到 10,000 之間的值，預設值為 100。

**資源耗盡**  
如果耗用執行個體網路頻寬或 CPU，`IO:DataFileRead` 事件可能更頻繁發生。

## 動作
<a name="wait-event.iodatafileread.actions"></a>

根據等待事件的原因，我們會建議不同的動作。

**Topics**
+ [對產生等待的查詢檢查述詞篩選條件](#wait-event.iodatafileread.actions.filters)
+ [將維護操作的影響降至最低](#wait-event.iodatafileread.actions.maintenance)
+ [因應大量連線](#wait-event.iodatafileread.actions.connections)

### 對產生等待的查詢檢查述詞篩選條件
<a name="wait-event.iodatafileread.actions.filters"></a>

假設您發現特定的查詢正在產生 `IO:DataFileRead` 等待事件。請利用下列技巧來識別：
+ 績效詳情
+ 目錄檢視表，例如延伸 `pg_stat_statements` 提供的檢視表
+ 目錄檢視表 `pg_stat_all_tables` (如果定期指出實體讀取變多)
+ `pg_statio_all_tables` 檢視表 (如果指出 `_read` 計數器上升)

建議您判斷這些查詢的述詞中 (`WHERE` 子句) 使用哪些篩選條件。請遵守下列準則：
+ 執行 `EXPLAIN` 命令。在輸出中，識別使用的掃描類型。循序掃描並不一定代表有問題。使用循序掃描的查詢，當然比使用篩選條件的查詢產生更多 `IO:DataFileRead` 事件。

  查明列在 `WHERE` 子句中的資料欄是否已編成索引。如果不是，請考慮為此資料欄建立索引。這種方法可避免循序掃描，並減少 `IO:DataFileRead` 事件。如果查詢有嚴格的篩選條件，但仍產生循序掃描，請評估使用的索引是否適當。
+ 查明查詢是否存取非常大的資料表。在某些情況下，將資料表分割可以改善效能，讓查詢只讀取必要的分割區。
+ 檢查聯結操作中的基數 (總資料列數)。請注意您在 `WHERE` 子句的過濾條件中傳入的值有多嚴格。可能的話，請調整查詢，以減少在計劃的每個步驟中傳入的資料列數目。

### 將維護操作的影響降至最低
<a name="wait-event.iodatafileread.actions.maintenance"></a>

維護操作很重要，例如 `VACUUM` 和 `ANALYZE`。建議不要因為發現這些維護操作相關的 `IO:DataFileRead` 等待事件而關閉維護。下列方法可以將這些操作的影響降至最低：
+ 在離峰時段手動執行維護操作。這項技巧可防止資料庫達到自動化操作的閾值。
+ 如果資料表非常大，請考慮分割資料表。這項技巧可減少維護操作的額外負荷。資料庫只會存取需要維護的分割區。
+ 擷取大量資料時，請考慮停用自動分析功能。

下列公式成立時會自動對資料表觸發自動資料清理功能。

```
pg_stat_user_tables.n_dead_tup > (pg_class.reltuples x autovacuum_vacuum_scale_factor) + autovacuum_vacuum_threshold
```

檢視表 `pg_stat_user_tables` 和目錄 `pg_class` 有多個資料列。一個資料列可以對應於資料表中的一個資料列。這個公式假設 `reltuples` 專用於特定資料表。通常是為整個執行個體來整體設定參數 `autovacuum_vacuum_scale_factor` (預設為 0.20) 和 `autovacuum_vacuum_threshold` (預設為 50 個元組)。但您可以針對特定資料表設定不同的值。

**Topics**
+ [尋找不必要耗用空間的資料表](#wait-event.iodatafileread.actions.maintenance.tables)
+ [尋找不必要耗用空間的索引](#wait-event.iodatafileread.actions.maintenance.indexes)
+ [尋找適合自動資料清理的資料表](#wait-event.iodatafileread.actions.maintenance.autovacuumed)

#### 尋找不必要耗用空間的資料表
<a name="wait-event.iodatafileread.actions.maintenance.tables"></a>

若要尋找不必要耗用空間的資料表，您可以使用 PostgreSQL `pgstattuple` 延伸模組中的函數。根據預設，所有 RDS for PostgreSQL 資料庫執行個體都可以使用此延伸模組 (模組)，並可以使用下列命令在執行個體上具體化。

```
CREATE EXTENSION pgstattuple;
```

如需此延伸模組的詳細資訊，請參閱 PostgreSQL 文件中的 [pgstattuple](https://www.postgresql.org/docs/current/pgstattuple.html)。

您可以在應用程式中檢查資料表和索引膨脹。如需詳細資訊，請參閱[診斷資料表和索引膨脹](https://docs.aws.amazon.com//AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.diag-table-ind-bloat.html)。

#### 尋找不必要耗用空間的索引
<a name="wait-event.iodatafileread.actions.maintenance.indexes"></a>

若要尋找膨脹的索引，並預估您對其具有讀取權限之資料表上不必要的空間耗用量，您可以執行下列查詢。

```
-- WARNING: rows with is_na = 't' are known to have bad statistics ("name" type is not supported).
-- This query is compatible with PostgreSQL 8.2 and later.

SELECT current_database(), nspname AS schemaname, tblname, idxname, bs*(relpages)::bigint AS real_size,
  bs*(relpages-est_pages)::bigint AS extra_size,
  100 * (relpages-est_pages)::float / relpages AS extra_ratio,
  fillfactor, bs*(relpages-est_pages_ff) AS bloat_size,
  100 * (relpages-est_pages_ff)::float / relpages AS bloat_ratio,
  is_na
  -- , 100-(sub.pst).avg_leaf_density, est_pages, index_tuple_hdr_bm, 
  -- maxalign, pagehdr, nulldatawidth, nulldatahdrwidth, sub.reltuples, sub.relpages 
  -- (DEBUG INFO)
FROM (
  SELECT coalesce(1 +
       ceil(reltuples/floor((bs-pageopqdata-pagehdr)/(4+nulldatahdrwidth)::float)), 0 
       -- ItemIdData size + computed avg size of a tuple (nulldatahdrwidth)
    ) AS est_pages,
    coalesce(1 +
       ceil(reltuples/floor((bs-pageopqdata-pagehdr)*fillfactor/(100*(4+nulldatahdrwidth)::float))), 0
    ) AS est_pages_ff,
    bs, nspname, table_oid, tblname, idxname, relpages, fillfactor, is_na
    -- , stattuple.pgstatindex(quote_ident(nspname)||'.'||quote_ident(idxname)) AS pst, 
    -- index_tuple_hdr_bm, maxalign, pagehdr, nulldatawidth, nulldatahdrwidth, reltuples 
    -- (DEBUG INFO)
  FROM (
    SELECT maxalign, bs, nspname, tblname, idxname, reltuples, relpages, relam, table_oid, fillfactor,
      ( index_tuple_hdr_bm +
          maxalign - CASE -- Add padding to the index tuple header to align on MAXALIGN
            WHEN index_tuple_hdr_bm%maxalign = 0 THEN maxalign
            ELSE index_tuple_hdr_bm%maxalign
          END
        + nulldatawidth + maxalign - CASE -- Add padding to the data to align on MAXALIGN
            WHEN nulldatawidth = 0 THEN 0
            WHEN nulldatawidth::integer%maxalign = 0 THEN maxalign
            ELSE nulldatawidth::integer%maxalign
          END
      )::numeric AS nulldatahdrwidth, pagehdr, pageopqdata, is_na
      -- , index_tuple_hdr_bm, nulldatawidth -- (DEBUG INFO)
    FROM (
      SELECT
        i.nspname, i.tblname, i.idxname, i.reltuples, i.relpages, i.relam, a.attrelid AS table_oid,
        current_setting('block_size')::numeric AS bs, fillfactor,
        CASE -- MAXALIGN: 4 on 32bits, 8 on 64bits (and mingw32 ?)
          WHEN version() ~ 'mingw32' OR version() ~ '64-bit|x86_64|ppc64|ia64|amd64' THEN 8
          ELSE 4
        END AS maxalign,
        /* per page header, fixed size: 20 for 7.X, 24 for others */
        24 AS pagehdr,
        /* per page btree opaque data */
        16 AS pageopqdata,
        /* per tuple header: add IndexAttributeBitMapData if some cols are null-able */
        CASE WHEN max(coalesce(s.null_frac,0)) = 0
          THEN 2 -- IndexTupleData size
          ELSE 2 + (( 32 + 8 - 1 ) / 8) 
          -- IndexTupleData size + IndexAttributeBitMapData size ( max num filed per index + 8 - 1 /8)
        END AS index_tuple_hdr_bm,
        /* data len: we remove null values save space using it fractionnal part from stats */
        sum( (1-coalesce(s.null_frac, 0)) * coalesce(s.avg_width, 1024)) AS nulldatawidth,
        max( CASE WHEN a.atttypid = 'pg_catalog.name'::regtype THEN 1 ELSE 0 END ) > 0 AS is_na
      FROM pg_attribute AS a
        JOIN (
          SELECT nspname, tbl.relname AS tblname, idx.relname AS idxname, 
            idx.reltuples, idx.relpages, idx.relam,
            indrelid, indexrelid, indkey::smallint[] AS attnum,
            coalesce(substring(
              array_to_string(idx.reloptions, ' ')
               from 'fillfactor=([0-9]+)')::smallint, 90) AS fillfactor
          FROM pg_index
            JOIN pg_class idx ON idx.oid=pg_index.indexrelid
            JOIN pg_class tbl ON tbl.oid=pg_index.indrelid
            JOIN pg_namespace ON pg_namespace.oid = idx.relnamespace
          WHERE pg_index.indisvalid AND tbl.relkind = 'r' AND idx.relpages > 0
        ) AS i ON a.attrelid = i.indexrelid
        JOIN pg_stats AS s ON s.schemaname = i.nspname
          AND ((s.tablename = i.tblname AND s.attname = pg_catalog.pg_get_indexdef(a.attrelid, a.attnum, TRUE)) 
          -- stats from tbl
          OR  (s.tablename = i.idxname AND s.attname = a.attname))
          -- stats from functional cols
        JOIN pg_type AS t ON a.atttypid = t.oid
      WHERE a.attnum > 0
      GROUP BY 1, 2, 3, 4, 5, 6, 7, 8, 9
    ) AS s1
  ) AS s2
    JOIN pg_am am ON s2.relam = am.oid WHERE am.amname = 'btree'
) AS sub
-- WHERE NOT is_na
ORDER BY 2,3,4;
```

#### 尋找適合自動資料清理的資料表
<a name="wait-event.iodatafileread.actions.maintenance.autovacuumed"></a>

若要尋找適合自動資料清理的資料表，請執行下列查詢。

```
--This query shows tables that need vacuuming and are eligible candidates.
--The following query lists all tables that are due to be processed by autovacuum. 
-- During normal operation, this query should return very little.
WITH  vbt AS (SELECT setting AS autovacuum_vacuum_threshold 
              FROM pg_settings WHERE name = 'autovacuum_vacuum_threshold')
    , vsf AS (SELECT setting AS autovacuum_vacuum_scale_factor 
              FROM pg_settings WHERE name = 'autovacuum_vacuum_scale_factor')
    , fma AS (SELECT setting AS autovacuum_freeze_max_age 
              FROM pg_settings WHERE name = 'autovacuum_freeze_max_age')
    , sto AS (SELECT opt_oid, split_part(setting, '=', 1) as param, 
                split_part(setting, '=', 2) as value 
              FROM (SELECT oid opt_oid, unnest(reloptions) setting FROM pg_class) opt)
SELECT
    '"'||ns.nspname||'"."'||c.relname||'"' as relation
    , pg_size_pretty(pg_table_size(c.oid)) as table_size
    , age(relfrozenxid) as xid_age
    , coalesce(cfma.value::float, autovacuum_freeze_max_age::float) autovacuum_freeze_max_age
    , (coalesce(cvbt.value::float, autovacuum_vacuum_threshold::float) + 
         coalesce(cvsf.value::float,autovacuum_vacuum_scale_factor::float) * c.reltuples) 
         as autovacuum_vacuum_tuples
    , n_dead_tup as dead_tuples
FROM pg_class c 
JOIN pg_namespace ns ON ns.oid = c.relnamespace
JOIN pg_stat_all_tables stat ON stat.relid = c.oid
JOIN vbt on (1=1) 
JOIN vsf ON (1=1) 
JOIN fma on (1=1)
LEFT JOIN sto cvbt ON cvbt.param = 'autovacuum_vacuum_threshold' AND c.oid = cvbt.opt_oid
LEFT JOIN sto cvsf ON cvsf.param = 'autovacuum_vacuum_scale_factor' AND c.oid = cvsf.opt_oid
LEFT JOIN sto cfma ON cfma.param = 'autovacuum_freeze_max_age' AND c.oid = cfma.opt_oid
WHERE c.relkind = 'r' 
AND nspname <> 'pg_catalog'
AND (
    age(relfrozenxid) >= coalesce(cfma.value::float, autovacuum_freeze_max_age::float)
    or
    coalesce(cvbt.value::float, autovacuum_vacuum_threshold::float) + 
      coalesce(cvsf.value::float,autovacuum_vacuum_scale_factor::float) * c.reltuples <= n_dead_tup
    -- or 1 = 1
)
ORDER BY age(relfrozenxid) DESC;
```

### 因應大量連線
<a name="wait-event.iodatafileread.actions.connections"></a>

監控 Amazon CloudWatch 時，您可能發現 `DatabaseConnections` 指標激增。此增加表示資料庫的連線數增加。建議採取下列作法：
+ 限制應用程式可以對每個執行個體開啟的連線數。如果應用程式有內嵌連線集區功能，請設定合理的連線數目。請以執行個體中的 vCPU 可有效平行處理的數目為準。

  如果應用程式不使用連線集區功能，請考慮使用 Amazon RDS Proxy 或替代方案。這種作法可讓應用程式對負載平衡器開啟多個連線。因此，平衡器就能對資料庫開啟較少的連線。由於平行執行的連線較少，資料庫執行個體在核心中就能減少切換環境。查詢應該會進行得更快，使得等待事件變少。如需詳細資訊，請參閱[Amazon RDS Proxy ](rds-proxy.md)。
+ 盡可能利用 RDS for PostgreSQL 的僅供讀取複本。當您的應用程式執行唯讀操作時，請將這些請求傳送至僅供讀取複本。這項技巧可減少主要 (寫入器) 節點的 I/O 壓力。
+ 考慮擴充資料庫執行個體的規模。容量較大的執行個體類別提供更多記憶體，讓 RDS for PostgreSQL 有較大的共用緩衝集區可保留分頁。越大也讓資料庫執行個體有越多 vCPU 來處理連線。當寫入操作產生 `IO:DataFileRead` 等待事件時，較多 vCPU 會特別有用。

# IO:WALWrite
<a name="wait-event.iowalwrite"></a>



**Topics**
+ [支援的引擎版本](#wait-event.iowalwrite.context.supported)
+ [Context](#wait-event.iowalwrite.context)
+ [等待時間增加的可能原因](#wait-event.iowalwrite.causes)
+ [動作](#wait-event.iowalwrite.actions)

## 支援的引擎版本
<a name="wait-event.iowalwrite.context.supported"></a>

所有 RDS for PostgreSQL 第 10 版和更新版本都支援此等待事件資訊。

## Context
<a name="wait-event.iowalwrite.context"></a>

資料庫中產生預寫日誌資料的資料庫中的活動會先填滿 WAL 緩衝區，然後以非同步方式寫入至磁碟。等待事件 `IO:WALWrite` 是在 SQL 工作階段正在等待 WAL 資料，以完成寫入至磁碟時產生的，以便它可以釋出交易的 COMMIT 呼叫。

## 等待時間增加的可能原因
<a name="wait-event.iowalwrite.causes"></a>

如果此等待事件經常發生，您應該檢閱工作負載，以及工作負載執行的更新類型及其頻率。尤其，尋找下列類型的活動。

**繁重的 DML 活動**  
變更資料庫資料表中的資料不會立即發生。插入至一個資料表可能需要等待另一個用戶端的相同資料表插入或更新。用於變更資料值的資料處理語言 (DML) 陳述式 (INSERT、UPDATE、DELETE、COMMIT、ROLLBACK TRANSACTION) 可能會產生爭用，因而造成預寫日誌檔等待緩衝區排清。此情況是在下列指出繁重 DML 活動的 Amazon RDS Performance Insights 指標中擷取的。  
+  `tup_inserted`
+ `tup_updated`
+ `tup_deleted`
+ `xact_rollback`
+ `xact_commit`
如需這些指標的詳細資訊，請參閱 [Amazon RDS for PostgreSQL 的績效詳情計數器](USER_PerfInsights_Counters.md#USER_PerfInsights_Counters.PostgreSQL)。

**頻繁的檢查點活動**  
頻繁的檢查點會導致 WAL 檔案增加。在 RDS for PostgreSQL 中，整頁寫入一律「開啟」。整頁寫入有助於防範資料遺失。不過，當檢查點發生過於頻繁時，系統可能會遭受整體效能問題。在 DML 活動繁重的系統上尤其如此。在某些情況下，您可能會在 `postgresql.log` 發現錯誤訊息，說明「檢查點發生過於頻繁」。  
建議您在調整檢查點時，仔細平衡效能與異常關機時需要復原的預期時間。

## 動作
<a name="wait-event.iowalwrite.actions"></a>

建議採取下列動作來減少此等待事件的數目。

**Topics**
+ [減少遞交次數](#wait-event.iowalwrite.actions.problem)
+ [監控檢查點](#wait-event.iowalwrite.actions.monitor)
+ [擴增 IO](#wait-event.iowalwrite.actions.scale-io)
+ [專用日誌磁碟區 (DLV)](#wait-event.iowalwrite.actions.dlv)

### 減少遞交次數
<a name="wait-event.iowalwrite.actions.problem"></a>

若要減少遞交次數，您可以將陳述式合併成交易區塊。使用 Amazon RDS Performance Insights 來檢查正在執行的查詢類型。您也可以將大型維護操作移至離峰時段。例如，建立索引或在非生產時段使用 `pg_repack` 操作。

### 監控檢查點
<a name="wait-event.iowalwrite.actions.monitor"></a>

有兩個您可以監控的參數，以查看 RDS for PostgreSQL 資料庫執行個體寫入至 WAL 檔案以取得檢查點的頻率。
+ `log_checkpoints` – 此參數預設為「開啟」。它會導致訊息傳送至每個檢查點的 PostgreSQL 日誌。這些日誌訊息包含寫入的緩衝區數目、寫入它們所花費的時間，以及針對指定檢查點新增，刪除或回收的 WAL 檔案數目。

  如需此參數的詳細資訊，請參閱 PostgreSQL 文件中的[錯誤報告和記錄](https://www.postgresql.org/docs/current/runtime-config-logging.html#GUC-LOG-CHECKPOINTS)。
+ `checkpoint_warning` – 此參數設定檢查點頻率的閾值 (以秒為單位)，若超過此值，就會產生警告。根據預設，此參數不會在 RDS for PostgreSQL 中設定。您可以設定此參數的值，在 RDS for PostgreSQL 資料庫執行個體中的資料庫變更以 WAL 檔案未調整為可處理大小的速率寫入時收到警告。例如，假設您將此參數設為 30。如果您的 RDS for PostgreSQL 執行個體需要寫入變更的頻率超過每 30 秒一次，則「檢查點發生過於頻繁」的警告會傳送至 PostgreSQL 日誌。這可能指出您的 `max_wal_size` 值應該增加。

  如需的詳細資訊，請參閱 PostgreSQL 文件中的[預寫日誌](https://www.postgresql.org/docs/current/runtime-config-wal.html#RUNTIME-CONFIG-WAL-CHECKPOINTS)。

### 擴增 IO
<a name="wait-event.iowalwrite.actions.scale-io"></a>

此類型的輸入/輸出 (IO) 等待事件可透過擴展每秒讀寫次數 (IOPS) 來修補，以提供更快的 IO。擴展 IO 優於擴展 CPU，因為擴展 CPU 可能會導致更多的 IO 爭用，因為增加的 CPU 可以處理更多的工作，從而使 IO 瓶頸更糟。一般而言，在執行擴展操作之前，建議您考慮調整工作負載。

### 專用日誌磁碟區 (DLV)
<a name="wait-event.iowalwrite.actions.dlv"></a>

您可以使用 Amazon RDS 主控台、AWS CLI 或 Amazon RDS API，將專用日誌磁碟區 (DLV) 用於使用佈建 IOPS (PIOPS) 儲存體的資料庫執行個體。DLV 會將 PostgreSQL 資料庫交易日誌移至與包含資料庫資料表的磁碟區不同的儲存磁碟區。如需詳細資訊，請參閱 [專用日誌磁碟區 (DLV)](CHAP_Storage.md#CHAP_Storage.dlv)。

# IPC:parallel 等待事件
<a name="rpg-ipc-parallel"></a>

下列 `IPC:parallel wait events` 指出工作階段正在等待與平行查詢執行操作相關的程序間通訊。
+ `IPC:BgWorkerStartup` - 程序正在等待平行工作者程序完成其啟動序列。初始化工作者以進行平行查詢執行時會發生這種情況。
+ `IPC:BgWorkerShutdown` - 程序正在等待平行工作者程序完成其關閉順序。這會在平行查詢執行的清除階段期間發生。
+ `IPC:ExecuteGather` - 程序正在等待在查詢執行期間從平行工作者程序接收資料。當領導程序需要從工作者收集結果時，就會發生這種情況。
+ `IPC:ParallelFinish` - 程序正在等待平行工作者完成其執行並報告其最終結果。這會在平行查詢執行的完成階段發生。

**Topics**
+ [支援的引擎版本](#rpg-ipc-parallel-context-supported)
+ [Context](#rpg-ipc-parallel-context)
+ [等待時間增加的可能原因](#rpg-ipc-parallel-causes)
+ [動作](#rpg-ipc-parallel-actions)

## 支援的引擎版本
<a name="rpg-ipc-parallel-context-supported"></a>

所有版本的 Aurora PostgreSQL 都支援此等待事件資訊。

## Context
<a name="rpg-ipc-parallel-context"></a>

PostgreSQL 中的平行查詢執行涉及多個程序共同處理單一查詢。當查詢判斷為適合平行處理時，領導程序會根據 `max_parallel_workers_per_gather` 參數設定，與一或多個平行工作者程序協調。領導程序會將工作分割給工作者，每個工作者都會獨立處理其部分的資料，並將結果收集回領導程序。

**注意**  
每個平行工作者會以單獨的程序運作，具有與完整使用者工作階段類似的資源需求。這表示與非平行查詢相比，具有 4 個工作者的平行查詢最多可耗用 5 倍的資源 (CPU、記憶體、I/O 頻寬)，因為領導程序和每個工作者程序都會維持自己的資源配置。針對執行個體，例如 `work_mem` 等設定會個別套用到每個工作者，可能會將所有程序之間的總記憶體用量相乘。

平行查詢架構包含三個主要元件：
+ 領導程序：啟動平行操作、分割工作負載並與工作者程序協調的主要程序。
+ 工作者程序：平行執行部分查詢的背景程序。
+ 收集/收集合併：將多個工作者程序的結果合併回領導者的操作

在平行執行期間，程序需要透過程序間通訊 (IPC) 機制彼此通訊。這些 IPC 等待事件會在不同的階段發生：
+ 工作者啟動：正在初始化平行工作者時
+ 資料交換：工作者處理資料並將結果傳送給領導時
+ 工作者關閉：平行執行完成且工作者終止時
+ 同步點：當程序需要協調或等待其他程序完成其任務時

了解這些等待事件對於診斷與平行查詢執行相關的效能問題至關重要，尤其是在可能同時執行多個平行查詢的高度並行環境中。

## 等待時間增加的可能原因
<a name="rpg-ipc-parallel-causes"></a>

有幾個因素可能會導致平行相關的 IPC 等待事件增加：

**平行查詢的高度並行**  
當許多平行查詢同時執行時，可能會導致資源爭用並增加 IPC 操作的等待時間。這在具有高交易量或分析工作負載的系統中特別常見。

**次佳的平行查詢計劃**  
如果查詢規劃器選擇效率不佳的平行計劃，可能會導致工作者之間不必要的平行化或工作分配不佳。這可能會導致 IPC 等待增加，尤其是 `IPC:ExecuteGather` 和 `IPC:ParallelFinish` 事件。這些規劃問題通常來自過時的統計資料和資料表/索引膨脹。

**頻繁啟動和關閉平行工作者**  
頻繁啟動和終止平行工作者的短期查詢可能會導致 `IPC:BgWorkerStartup` 和 `IPC:BgWorkerShutdown` 事件增加。這通常在具有許多小型、可平行化查詢的 OLTP 工作負載中出現。

**資源限制**  
有限的 CPU、記憶體或 I/O 容量可能會導致平行執行的瓶頸，進而增加所有 IPC 事件的等待時間。例如，如果 CPU 飽和，工作者程序可能需要更長的時間才能啟動或處理其工作部分。

**複雜的查詢結構**  
具有多層平行處理的查詢 (例如，平行聯結後接平行彙總) 可能會導致更複雜的 IPC 模式，並可能增加等待時間，尤其是 `IPC:ExecuteGather` 事件。

**大型結果集**  
產生大型結果集的查詢可能會導致 `IPC:ExecuteGather` 等待時間增加，因為領導程序會花費更多時間收集和處理工作者程序的結果。

了解這些因素有助於診斷和解決與 Aurora PostgreSQL 中平行查詢執行相關的效能問題。

## 動作
<a name="rpg-ipc-parallel-actions"></a>

當您看到與平行查詢相關的等待時，這通常表示後端程序正在協調或等待平行工作者程序。這些等待在平行計劃執行期間很常見。您可以透過監控平行工作者用量、檢閱參數設定，以及調校查詢執行和資源配置，來調查和減輕這些等待的影響。

**Topics**
+ [分析低效率平行處理的查詢計劃](#rpg-ipc-parallel-analyze-plans)
+ [監控平行查詢用量](#rpg-ipc-parallel-monitor)
+ [檢閱和調整平行查詢設定](#rpg-ipc-parallel-adjust-settings)
+ [最佳化資源配置](#rpg-ipc-parallel-optimize-resources)
+ [調查連線管理](#rpg-ipc-parallel-connection-management)
+ [檢閱和最佳化維護操作](#rpg-ipc-parallel-maintenance)

### 分析低效率平行處理的查詢計劃
<a name="rpg-ipc-parallel-analyze-plans"></a>

平行查詢執行通常會導致系統不穩定、CPU 峰值和無法預測的查詢效能差異。徹底分析平行處理是否實際改善您的特定工作負載至關重要。使用 EXPLAIN ANALYZE 檢閱平行查詢執行計劃。

暫時停用工作階段層級的平行處理，以比較計劃效率：

```
SET max_parallel_workers_per_gather = 0;
EXPLAIN ANALYZE <your_query>;
```

重新啟用平行處理並比較：

```
RESET max_parallel_workers_per_gather;
EXPLAIN ANALYZE <your_query>;
```

如果停用平行處理可產生更好或更一致的結果，請考慮使用 SET 命令在工作階段層級針對特定查詢停用。為了獲得更廣泛的影響，您可能想要藉由調整資料庫參數群組中的相關參數，在執行個體層級停用平行處理。如需詳細資訊，請參閱[修改 Amazon RDS 中的資料庫參數群組中的參數](USER_WorkingWithParamGroups.Modifying.md)。

### 監控平行查詢用量
<a name="rpg-ipc-parallel-monitor"></a>

使用下列查詢來取得平行查詢活動和容量的可見性：

檢查作用中的平行工作者程序：

```
SELECT
    COUNT(*)
FROM
    pg_stat_activity
WHERE
    backend_type = 'parallel worker';
```

此查詢會顯示作用中平行工作者程序的數量。高值可能表示您的 `max\$1parallel\$1workers` 已設定為高值，建議您考慮將其減少。

檢查並行平行查詢：

```
SELECT
    COUNT(DISTINCT leader_pid)
FROM
    pg_stat_activity
WHERE
    leader_pid IS NOT NULL;
```

此查詢會傳回已啟動平行查詢的不同領導程序數目。此處的高數字表示多個工作階段同時執行平行查詢，這可能會增加對 CPU 和記憶體的需求。

### 檢閱和調整平行查詢設定
<a name="rpg-ipc-parallel-adjust-settings"></a>

檢閱下列參數，以確保它們與您的工作負載一致：
+ `max_parallel_workers`：所有工作階段的平行工作者總數。
+ `max_parallel_workers_per_gather`：每個查詢的工作者上限。

對於 OLAP 工作負載，增加這些值可以改善效能。對於 OLTP 工作負載，通常偏好較低的值。

```
SHOW max_parallel_workers;
SHOW max_parallel_workers_per_gather;
```

### 最佳化資源配置
<a name="rpg-ipc-parallel-optimize-resources"></a>

監控 CPU 使用率，如果持續很高，且您的應用程式受益於平行查詢，請考慮調整 vCPU 數量。確保有足夠記憶體可供平行操作使用。
+ 使用 Performance Insights 指標來判斷系統是否受限於 CPU。
+ 每個平行工作者都會使用自己的 `work_mem`。確保總記憶體用量在執行個體限制內。

平行查詢可能會耗用比非平行查詢更多的資源，因為每個工作者程序都是完全獨立的程序，對系統的影響與額外的使用者工作階段大致相同。選擇此設定的值時，以及設定控制資源使用率的其他設定時，應考慮這一點，例如 `work_mem`。如需詳細資訊，請參閱 [PostgreSQL 文件](https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-WORK-MEM)。`work_mem` 等資源限制會個別套用至每個工作者，這表示所有程序的總使用率可能遠高於任何單一程序。

如果您的工作負載高度平行化，請考慮增加 vCPU 或調校記憶體參數。

### 調查連線管理
<a name="rpg-ipc-parallel-connection-management"></a>

如果連線耗盡，請檢閱應用程式連線集區策略。如果尚未使用，請考慮在應用程式層級實作連線集區。

### 檢閱和最佳化維護操作
<a name="rpg-ipc-parallel-maintenance"></a>

協調索引建立和其他維護任務，以防止資源爭用。請考慮在離峰時間排程這些操作。避免在高使用者查詢負載期間排程大量維護 (例如平行索引建置)。這些操作可能會耗用平行工作者，並影響定期查詢的效能。

# IPC:ProcArrayGroupUpdate
<a name="apg-rpg-ipcprocarraygroup"></a>

當工作階段正在等待群組領導者在該操作結束時更新交易狀態時，就會`IPC:ProcArrayGroupUpdate`發生事件。雖然 PostgreSQL 通常會將 IPC 類型等待事件與平行查詢操作建立關聯，但此特定等待事件並非平行查詢特有的。

**Topics**
+ [支援的引擎版本](#apg-rpg-ipcprocarraygroup.supported)
+ [Context](#apg-rpg-ipcprocarraygroup.context)
+ [等待時間增加的可能原因](#apg-rpg-ipcprocarraygroup.causes)
+ [動作](#apg-rpg-ipcprocarraygroup.actions)

## 支援的引擎版本
<a name="apg-rpg-ipcprocarraygroup.supported"></a>

所有 RDS for PostgreSQL 的版本都支援此等待事件資訊。

## Context
<a name="apg-rpg-ipcprocarraygroup.context"></a>

**了解程序陣列** – 程序 (proc) 陣列是 PostgreSQL 中的共用記憶體結構。它保留所有執行中程序的相關資訊，包括交易詳細資訊。在交易完成期間 (`COMMIT` 或 `ROLLBACK`)，需要更新 ProcArray，以反映變更並從陣列清除 transactionID。嘗試完成其交易的工作階段必須在 ProcArray 上取得專屬鎖定。這可防止其他程序取得共用或獨佔鎖定。

**群組更新機制** – 執行 COMMIT 或 ROLLBACK 時，如果後端程序無法在獨佔模式中取得 ProcArrayLock，則會更新稱為 ProcArrayGroupMember 的特殊欄位。這會將交易新增至要結束的工作階段清單。此後端程序接著會進入休眠，而其休眠時間會檢測為 ProcArrayGroupUpdate 等待事件。ProcArray with procArrayGroupMember 中的第一個程序稱為領導程序，會以獨佔模式取得 ProcArrayLock。然後，它會清除等待群組 transactionID 清除的程序清單。完成後，領導者會釋出 ProcArrayLock，然後喚醒此清單中的所有程序，通知他們交易已完成。

## 等待時間增加的可能原因
<a name="apg-rpg-ipcprocarraygroup.causes"></a>

執行的程序越多，領導者在排他模式下保留至 procArrayLock 的時間就越長。因此，群組更新案例中的寫入交易越多，導致等待`ProcArrayGroupUpdate`事件的程序可能堆積。在 Database Insights 的最高 SQL 檢視中，您會看到 COMMIT 是具有大部分此等待事件的陳述式。這是預期的，但需要對正在執行的特定寫入 SQL 進行更深入的調查，以決定要採取何種適當動作。

## 動作
<a name="apg-rpg-ipcprocarraygroup.actions"></a>

根據等待事件的原因，我們會建議不同的動作。使用 Amazon RDS Performance Insights 或查詢 PostgreSQL 系統檢視 來識別`IPC:ProcArrayGroupUpdate`事件`pg_stat_activity`。

**Topics**
+ [監控交易遞交和轉返操作](#apg-rpg-ipcprocarraygroup.actions.monitor)
+ [減少並行](#apg-rpg-ipcprocarraygroup.actions.concurrency)
+ [實作連線集區](#apg-rpg-ipcprocarraygroup.actions.pooling)
+ [使用更快的儲存](#apg-rpg-ipcprocarraygroup.actions.storage)

### 監控交易遞交和轉返操作
<a name="apg-rpg-ipcprocarraygroup.actions.monitor"></a>

**監控遞交和轉返** – 遞交和轉返的數量增加可能會導致 ProcArray 的壓力增加。例如，如果 SQL 陳述式因為增加的重複金鑰違規而開始失敗，您可能會看到回復增加，這可能會增加 ProcArray 爭用和資料表膨脹。

Amazon RDS Database Insights 提供 PostgreSQL 指標`xact_rollback`，`xact_commit`並報告每秒遞交和轉返的數量。

### 減少並行
<a name="apg-rpg-ipcprocarraygroup.actions.concurrency"></a>

**批次交易** – 盡可能在單一交易中批次操作，以減少遞交/轉返操作。

**限制並行** – 減少並行作用中交易的數量，以減輕 ProcArray 上的鎖定爭用。雖然它需要一些測試，但減少並行連線的總數可以減少爭用和維護輸送量。

### 實作連線集區
<a name="apg-rpg-ipcprocarraygroup.actions.pooling"></a>

**連線集區解決方案** – 使用連線集區有效率地管理資料庫連線，減少後端總數，進而減少 ProcArray 上的工作負載。雖然它需要一些測試，但減少並行連線的總數可以減少爭用和維護輸送量。

**減少連線風暴** – 同樣地，經常建立和終止連線的模式會對 ProcArray 造成額外的壓力。透過減少此模式，可減少整體爭用。

### 使用更快的儲存
<a name="apg-rpg-ipcprocarraygroup.actions.storage"></a>

**專用日誌磁碟區** – 如果`IPC:ProcArrayGroupUpdate`等待事件伴隨高`IO:WALWrite`等待事件，設定專用日誌磁碟區可減少寫入 WAL 的瓶頸。反之，這可改善遞交的效能。

如需詳細資訊，請參閱[專用日誌磁碟區](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_PIOPS.dlv.html)。

# Lock:advisory
<a name="wait-event.lockadvisory"></a>

`Lock:advisory` 事件表示 PostgreSQL 應用程式使用鎖定來協調多個工作階段的活動。

**Topics**
+ [相關的引擎版本](#wait-event.lockadvisory.context.supported)
+ [Context](#wait-event.lockadvisory.context)
+ [原因](#wait-event.lockadvisory.causes)
+ [動作](#wait-event.lockadvisory.actions)

## 相關的引擎版本
<a name="wait-event.lockadvisory.context.supported"></a>

此等待事件資訊與 RDS for PostgreSQL 9.6 版及更新版本有關。

## Context
<a name="wait-event.lockadvisory.context"></a>

PostgreSQL 諮詢鎖定是應用程式層級的合作式鎖定，由使用者的應用程式碼明確鎖定和解除鎖定。應用程式可以使用 PostgreSQL 諮詢鎖定來協調多個工作階段的活動。不同於物件層級或資料列層級的一般鎖定，應用程式完全控制鎖定的生命週期。如需詳細資訊，請參閱 PostgreSQL 文件中的[諮詢鎖定](https://www.postgresql.org/docs/12/explicit-locking.html#ADVISORY-LOCKS)。

諮詢鎖定可以在交易結束之前釋放，或由工作階段跨交易保留。但系統強制的隱含鎖定不是如此，例如 `CREATE INDEX` 陳述式在資料表上取得的存取獨佔鎖定。

如需用來取得 (鎖定) 和釋放 (解除鎖定) 諮詢鎖定的函數描述，請參閱 PostgreSQL 說明文件中的[諮詢鎖定函數](https://www.postgresql.org/docs/current/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS)。

諮詢鎖定是在一般 PostgreSQL 鎖定系統上實作，在 `pg_locks` 系統檢視表中可見。

## 原因
<a name="wait-event.lockadvisory.causes"></a>

明確使用此鎖定類型的應用程式可完全控制鎖定。如果查詢為每個資料列都取得諮詢鎖定，可能會造成鎖定激增或長期累積。

當查詢取得的鎖定比查詢傳回的資料列更多時，就會出現這些現象。應用程式最終必須釋放每個鎖定，但如果是在未傳回的資料列上取得鎖定，則應用程式無法找齊全部的鎖定。

下列範例來自 PostgreSQL 文件中的[諮詢鎖定](https://www.postgresql.org/docs/12/explicit-locking.html#ADVISORY-LOCKS)。

```
SELECT pg_advisory_lock(id) FROM foo WHERE id > 12345 LIMIT 100;
```

在此範例中，只有在內部選取資料列並鎖定其 ID 值之後，`LIMIT` 子句才能停止查詢的輸出。突然發生這種情況表示資料量不斷增加，導致規劃工具選擇另一個未經過開發期間測試的執行計劃。在此情況下，發生累積起因於應用程式對每個已鎖定的 ID 值,明確呼叫 `pg_advisory_unlock`。但是，在此情況下，找不到在未傳回的資料列上取得的鎖定集。因為是在工作階段層級取得鎖定，交易結束時不會自動釋放鎖定。

鎖定嘗試受阻次數激增的另一個可能原因是意外衝突。在這些衝突中，應用程式的無關聯部分不慎共用相同的鎖定 ID 空間。

## 動作
<a name="wait-event.lockadvisory.actions"></a>

檢閱諮詢鎖定的應用程式用量，並詳述在應用程式流程中何處和何時取得和釋放每一種諮詢鎖定。

查明究竟是工作階段取得太多鎖定，還是長時間執行的工作階段未及早釋放鎖定，導致鎖定逐漸堆積。您可以使用 `pg_terminate_backend(pid)` 結束工作階段，以免工作階段層級鎖定逐漸堆積。

等待諮詢鎖定的用戶端以 `wait_event_type=Lock` 和 `wait_event=advisory` 出現在 `pg_stat_activity` 中。您可以在 `pg_locks` 系統檢視表中查詢相同的 `pid`，尋找 `locktype=advisory` 和 `granted=f`，以取得特定的鎖定值。

然後，您可以在 `pg_locks` 中查詢 `granted=t` 的同一個諮詢鎖定，以識別引起封鎖的工作階段，如下列範例所示。

```
SELECT blocked_locks.pid AS blocked_pid,
         blocking_locks.pid AS blocking_pid,
         blocked_activity.usename AS blocked_user,
         blocking_activity.usename AS blocking_user,
         now() - blocked_activity.xact_start AS blocked_transaction_duration,
         now() - blocking_activity.xact_start AS blocking_transaction_duration,
         concat(blocked_activity.wait_event_type,':',blocked_activity.wait_event) AS blocked_wait_event,
         concat(blocking_activity.wait_event_type,':',blocking_activity.wait_event) AS blocking_wait_event,
         blocked_activity.state AS blocked_state,
         blocking_activity.state AS blocking_state,
         blocked_locks.locktype AS blocked_locktype,
         blocking_locks.locktype AS blocking_locktype,
         blocked_activity.query AS blocked_statement,
         blocking_activity.query AS blocking_statement
    FROM pg_catalog.pg_locks blocked_locks
    JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
    JOIN pg_catalog.pg_locks blocking_locks
        ON blocking_locks.locktype = blocked_locks.locktype
        AND blocking_locks.DATABASE IS NOT DISTINCT FROM blocked_locks.DATABASE
        AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
        AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page
        AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple
        AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid
        AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid
        AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid
        AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid
        AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid
        AND blocking_locks.pid != blocked_locks.pid
    JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
    WHERE NOT blocked_locks.GRANTED;
```

所有諮詢鎖定 API 函數都有兩組引數，可能是一個 `bigint` 引數或兩個 `integer` 引數：
+ 如果 API 函數有一個 `bigint` 引數，則前段 32 位元在 `pg_locks.classid` 中，後段 32 位元在 `pg_locks.objid` 中。
+ 如果 API 函數有兩個 `integer` 引數，則第一個引數為 `pg_locks.classid`，第二個引數為 `pg_locks.objid`。

`pg_locks.objsubid` 值表示使用何種 API 形式：`1` 表示一個 `bigint` 引數；`2` 表示二個 `integer` 引數。

# Lock:extend
<a name="wait-event.lockextend"></a>

`Lock:extend` 事件表示後端程序正在等待鎖定關聯來延伸，但另一個程序也基於相同目的而鎖定該關聯。

**Topics**
+ [支援的引擎版本](#wait-event.lockextend.context.supported)
+ [Context](#wait-event.lockextend.context)
+ [等待變多的可能原因](#wait-event.lockextend.causes)
+ [動作](#wait-event.lockextend.actions)

## 支援的引擎版本
<a name="wait-event.lockextend.context.supported"></a>

所有 RDS for PostgreSQL 版本都支援此等待事件資訊。

## Context
<a name="wait-event.lockextend.context"></a>

`Lock:extend` 事件表示後端程序正在等待延伸關聯，但另一個後端程序已鎖定該關聯而正在延伸。因為一次只有一個程序可以延伸關聯，所以系統產生 `Lock:extend` 等待事件。`INSERT`、`COPY` 及`UPDATE` 操作可能產生此事件。

## 等待變多的可能原因
<a name="wait-event.lockextend.causes"></a>

`Lock:extend` 事件比平時更常出現時，可能表示有效能問題，典型原因包括：

**突增並行插入或更新同一個資料表 **  
以查詢來插入或更新同一個資料表的並行工作階段可能變多。

**網路頻寬不足**  
資料庫執行個體上的網路頻寬可能不足以滿足目前工作負載的儲存通訊需求。這可能會引起儲存延遲，導致 `Lock:extend` 事件增加。

## 動作
<a name="wait-event.lockextend.actions"></a>

根據等待事件的原因，我們會建議不同的動作。

**Topics**
+ [減少並行插入和更新同一個關聯](#wait-event.lockextend.actions.action1)
+ [增加網路頻寬](#wait-event.lockextend.actions.increase-network-bandwidth)

### 減少並行插入和更新同一個關聯
<a name="wait-event.lockextend.actions.action1"></a>

首先，判斷 `tup_inserted` 和 `tup_updated` 指標是否增加，以及此等待事件是否也隨之增加。如果是，請檢查哪些關聯激烈爭用插入和更新操作。若要查明，請在 `pg_stat_all_tables` 檢視表中查詢 `n_tup_ins` 和 `n_tup_upd` 欄位的值。如需 `pg_stat_all_tables` 檢視表的相關資訊，請參閱 PostgreSQL 文件中的 [pg\$1stat\$1all\$1tables](https://www.postgresql.org/docs/13/monitoring-stats.html#MONITORING-PG-STAT-ALL-TABLES-VIEW)。

關於引起封鎖的查詢和被封鎖的查詢，如需詳細資訊，請查詢 `pg_stat_activity`，如下列範例所示：

```
SELECT
    blocked.pid,
    blocked.usename,
    blocked.query,
    blocking.pid AS blocking_id,
    blocking.query AS blocking_query,
    blocking.wait_event AS blocking_wait_event,
    blocking.wait_event_type AS blocking_wait_event_type
FROM pg_stat_activity AS blocked
JOIN pg_stat_activity AS blocking ON blocking.pid = ANY(pg_blocking_pids(blocked.pid))
where
blocked.wait_event = 'extend'
and blocked.wait_event_type = 'Lock';
 
   pid  | usename  |            query             | blocking_id |                         blocking_query                           | blocking_wait_event | blocking_wait_event_type
  ------+----------+------------------------------+-------------+------------------------------------------------------------------+---------------------+--------------------------
   7143 |  myuser  | insert into tab1 values (1); |        4600 | INSERT INTO tab1 (a) SELECT s FROM generate_series(1,1000000) s; | DataFileExtend      | IO
```

在找出導致 `Lock:extend` 事件增加的關聯之後，請使用下列技巧來減少爭用：
+ 查明您是否可以使用分割來減少爭用同一個資料表。將插入或更新的元組分成不同分割區可以減少爭用。如需分割的相關資訊，請參閱[使用 pg\$1partman 擴充功能來管理 PostgreSQL 分割區](PostgreSQL_Partitions.md)。
+ 如果等待事件主要是由於更新活動，請考慮降低關聯的 fillfactor 值。這樣可以減少在更新期間請求新區塊。fillfactor 是資料表的儲存參數，決定可供壓縮資料表分頁的最大空間。以分頁總空間的百分比表示。如需 fillfactor 參數的詳細資訊，請參閱 PostgreSQL 文件中的 [CREATE TABLE](https://www.postgresql.org/docs/13/sql-createtable.html)。
**重要**  
如果您變更 fillfactor，強烈建議您測試系統，因為變更此值可能對效能造成負面影響，視工作負載而定。

### 增加網路頻寬
<a name="wait-event.lockextend.actions.increase-network-bandwidth"></a>

若要檢查寫入延遲是否變長，請在 CloudWatch 中檢查 `WriteLatency` 指標。如果是，請使用 `WriteThroughput` 和 `ReadThroughput` Amazon CloudWatch 指標來監控資料庫執行個體上的儲存體相關流量。這些指標可協助您判斷網路頻寬是否足以應付工作負載的儲存活動。

如果網路頻寬不夠，請增加頻寬。如果資料庫執行個體快達到網路頻寬限制，則增加頻寬的唯一辦法就是加大資料庫執行個體。

如需 CloudWatch 指標的詳細資訊，請參閱[Amazon RDS 的 Amazon CloudWatch 執行個體層級指標](rds-metrics.md#rds-cw-metrics-instance)。關於每個資料庫執行個體類別的網路效能，如需相關資訊，請參閱 [Amazon RDS 的 Amazon CloudWatch 執行個體層級指標](rds-metrics.md#rds-cw-metrics-instance)。

# Lock:Relation
<a name="wait-event.lockrelation"></a>

`Lock:Relation` 事件表示查詢正在等待取得鎖定的資料表或檢視表 (關聯)，目前由另一個交易鎖定。

**Topics**
+ [支援的引擎版本](#wait-event.lockrelation.context.supported)
+ [Context](#wait-event.lockrelation.context)
+ [等待時間增加的可能原因](#wait-event.lockrelation.causes)
+ [動作](#wait-event.lockrelation.actions)

## 支援的引擎版本
<a name="wait-event.lockrelation.context.supported"></a>

所有 RDS for PostgreSQL 版本都支援此等待事件資訊。

## Context
<a name="wait-event.lockrelation.context"></a>

大多數 PostgreSQL 命令隱含地使用鎖定來控制並行存取資料表中的資料。您也可以在應用程式碼中使用 `LOCK` 命令，以明確使用這些鎖定。許多鎖定模式彼此不相容，在嘗試存取同一個物件時，可能封鎖交易。發生這種情況時，RDS for PostgreSQL 會產生 `Lock:Relation` 事件。以下是一些常見例子：
+ 獨佔鎖定 (例如 `ACCESS EXCLUSIVE`) 會封鎖所有並行存取。資料定義語言 (DDL) 操作 (例如 `DROP TABLE`、`TRUNCATE`、`VACUUM FULL` 及 `CLUSTER`) 隱含地取得 `ACCESS EXCLUSIVE` 鎖定。對於未明確指定模式的 `LOCK TABLE` 陳述式，`ACCESS EXCLUSIVE` 也是預設鎖定模式。
+ 在資料表上使用 `CREATE INDEX (without CONCURRENT)` 時，與取得 `ROW EXCLUSIVE` 鎖定的資料處理語言 (DML) 陳述式 `UPDATE`、`DELETE` 及 `INSERT` 會發生衝突。

如需表格層級鎖定和衝突鎖定模式的詳細資訊，請參閱 PostgreSQL 文件中的[明確鎖定](https://www.postgresql.org/docs/13/explicit-locking.html)。

引起封鎖的查詢和交易通常透過下列其中一種方法解除封鎖：
+ 引起封鎖的查詢 — 由應用程式取消查詢，或由使用者結束程序。透過工作階段的陳述式逾時或死鎖偵測機制，引擎也可以強制結束查詢。
+ 引起封鎖的交易 — 交易執行 `ROLLBACK` 或 `COMMIT` 陳述式來停止封鎖。當工作階段由用戶端或因為網路問題而中斷連線時，或工作階段結束時，也會自動復原。資料庫引擎關閉、系統記憶體不足等原因會結束工作階段。

## 等待時間增加的可能原因
<a name="wait-event.lockrelation.causes"></a>

當 `Lock:Relation` 事件發生頻率高於正常情況時，則可能表示效能問題。典型原因包括：

**資料表鎖定發生衝突的並行工作階段變多**  
以查詢來鎖定同一個資料表但鎖定模式衝突的並行工作階段可能變多。

**維護操作**  
運作狀態維護操作 (例如 `VACUUM` 和 `ANALYZE`) 可能大幅增加衝突鎖定的數量。`VACUUM FULL` 取得 `ACCESS EXCLUSIVE` 鎖定，`ANALYSE` 取得 `SHARE UPDATE EXCLUSIVE` 鎖定。這兩種鎖定都可能引起 `Lock:Relation` 等待事件。應用程式資料維護操作 (例如重新整理具體化檢視表) 也會使鎖定的查詢和交易增加。

**鎖定讀取器執行個體**  
寫入器和讀取器保有的關係鎖之間可能存在衝突。目前，只有 `ACCESS EXCLUSIVE` 關係鎖被複製到讀取器執行個體。但是，`ACCESS EXCLUSIVE` 關係鎖將與讀取器所持有的任何 `ACCESS SHARE` 關係鎖發生衝突。這可能會造成讀取器上的鎖定關係等待事件增加。

## 動作
<a name="wait-event.lockrelation.actions"></a>

根據等待事件的原因，我們會建議不同的動作。

**Topics**
+ [減少封鎖 SQL 陳述式的影響](#wait-event.lockrelation.actions.reduce-blocks)
+ [將維護操作的影響降至最低](#wait-event.lockrelation.actions.maintenance)

### 減少封鎖 SQL 陳述式的影響
<a name="wait-event.lockrelation.actions.reduce-blocks"></a>

若要減少封鎖 SQL 陳述式的影響，請盡可能修改應用程式碼。以下是減少封鎖的兩種常用技巧：
+ 使用 `NOWAIT` 選項 — 某些 SQL 命令支援此選項，例如 `SELECT` 和 `LOCK` 陳述式。如果無法立即獲得鎖定，`NOWAIT` 指令會取消提出鎖定請求的查詢。這項技巧有助於避免引起封鎖的工作階段背後堆積被封鎖的工作階段。

  例如：假設交易 A 等待的鎖定由交易 B 持有。現在，如果 B 請求鎖定的資料表由交易 C 鎖定，則可能封鎖交易 A，直到交易 C 完成為止。但是，如果交易 B 請求鎖定 C 時使用 `NOWAIT`，則會很快失敗，以確保交易 A 不必無限期等待。
+ 使用 `SET lock_timeout` - 設定 `lock_timeout` 值來限制 SQL 陳述式在關聯上取得鎖定所等待的時間。如果在指定的逾時內未獲得鎖定，則會取消提出鎖定請求的交易。請在工作階段層級設定此值。

### 將維護操作的影響降至最低
<a name="wait-event.lockrelation.actions.maintenance"></a>

維護操作很重要，例如 `VACUUM` 和 `ANALYZE`。建議不要因為發現這些維護操作相關的 `Lock:Relation` 等待事件而關閉維護。下列方法可以將這些操作的影響降至最低：
+ 在離峰時段手動執行維護操作。
+ 若要減少 `Lock:Relation` 等待，請執行任何所需的自動資料清理調校。如需調整自動清理的相關資訊，請參閱《Amazon RDS 使用者指南》**中的[在 Amazon RDS 上使用 PostgreSQL 自動資料清理](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.html)。

# Lock:transactionid
<a name="wait-event.locktransactionid"></a>

`Lock:transactionid` 事件表示交易正在等待資料列層級鎖定。

**Topics**
+ [支援的引擎版本](#wait-event.locktransactionid.context.supported)
+ [Context](#wait-event.locktransactionid.context)
+ [等待變多的可能原因](#wait-event.locktransactionid.causes)
+ [動作](#wait-event.locktransactionid.actions)

## 支援的引擎版本
<a name="wait-event.locktransactionid.context.supported"></a>

所有 RDS for PostgreSQL 版本都支援此等待事件資訊。

## Context
<a name="wait-event.locktransactionid.context"></a>

`Lock:transactionid` 事件表示交易嘗試取得的資料列層級鎖定已授予同一時間執行的另一個交易。因為此鎖定，已封鎖出現 `Lock:transactionid` 等待事件的工作階段。當引起封鎖的交易在 `COMMIT` 或 `ROLLBACK` 陳述式中結束時，被封鎖的交易就可以繼續進行。

RDS for PostgreSQL 的多版本並行控制語意保證讀取器不會封鎖寫入器，而寫入器也不會封鎖讀取器。引起封鎖和被封鎖的交易必須發出下列類型的衝突陳述式，才會發生資料列層級衝突：
+ `UPDATE`
+ `SELECT … FOR UPDATE`
+ `SELECT … FOR KEY SHARE`

`SELECT … FOR KEY SHARE` 陳述式是特殊情況。資料庫使用 `FOR KEY SHARE` 子句來最佳化參考完整性的效能。如果資料列上有資料列層級鎖定，則會封鎖其他資料表上參考此資料列的 `INSERT`、`UPDATE` 及 `DELETE` 命令。

## 等待變多的可能原因
<a name="wait-event.locktransactionid.causes"></a>

此事件比平時更常出現時，通常是因為 `UPDATE`、`SELECT … FOR UPDATE` 或`SELECT … FOR KEY SHARE` 陳述式兼具下列情況。

**Topics**
+ [高度並行](#wait-event.locktransactionid.concurrency)
+ [交易閒置](#wait-event.locktransactionid.idle)
+ [長時間執行的交易](#wait-event.locktransactionid.long-running)

### 高度並行
<a name="wait-event.locktransactionid.concurrency"></a>

RDS for PostgreSQL 可以使用精細的資料列層級鎖定語意。有下列情況時，較可能發生資料列層級衝突：
+ 高度並行工作負載爭用相同的資料列。
+ 並行增加。

### 交易閒置
<a name="wait-event.locktransactionid.idle"></a>

有時候 `pg_stat_activity.state` 資料欄會顯示 `idle in transaction` 值。已啟動交易但尚未發出 `COMMIT` 或 `ROLLBACK` 的工作階段會出現此值。如果 `pg_stat_activity.state` 值不是 `active`，`pg_stat_activity` 中會顯示最近要完成執行的查詢。因為開啟的交易持有鎖定，引起封鎖的工作階段目前未處理查詢。

如果閒置交易已獲得資料列層級鎖定，可能會阻止其他工作階段取得鎖定。這種情況導致頻繁發生等待事件 `Lock:transactionid`。若要診斷問題，請檢查 `pg_stat_activity` 和 `pg_locks` 的輸出。

### 長時間執行的交易
<a name="wait-event.locktransactionid.long-running"></a>

長時間執行的交易會長時間持有鎖定。這些長期持有的鎖定可能阻止其他交易執行。

## 動作
<a name="wait-event.locktransactionid.actions"></a>

資料列鎖定會造成 `UPDATE`、`SELECT … FOR UPDATE` 或 `SELECT … FOR KEY SHARE` 陳述式之間發生衝突。嘗試解決之前，請查明這些陳述式是否在同一個資料列上執行。使用此資訊來選擇以下各節描述的策略。

**Topics**
+ [因應高度並行](#wait-event.locktransactionid.actions.problem)
+ [因應閒置的交易](#wait-event.locktransactionid.actions.find-blocker)
+ [因應長時間執行的交易](#wait-event.locktransactionid.actions.concurrency)

### 因應高度並行
<a name="wait-event.locktransactionid.actions.problem"></a>

如果問題在於並行，請嘗試下列其中一項技巧：
+ 降低應用程式中的並行。例如，減少作用中工作階段的數目。
+ 實作連線集區。若要了解如何使用 RDS Proxy 來建立連線集區，請參閱 [Amazon RDS Proxy ](rds-proxy.md)。
+ 將應用程式或資料模型設計成避免爭用 `UPDATE` 和 `SELECT … FOR UPDATE` 陳述式。您也可以減少 `SELECT … FOR KEY SHARE` 陳述式存取的外部索引鍵數目。

### 因應閒置的交易
<a name="wait-event.locktransactionid.actions.find-blocker"></a>

如果 `pg_stat_activity.state` 顯示 `idle in transaction`，請使用下列策略：
+ 盡可能開啟自動遞交。這種方法可以防止交易在等待 `COMMIT` 或 `ROLLBACK` 時封鎖其他交易。
+ 搜尋缺少 `COMMIT`、`ROLLBACK` 或 `END` 的程式碼路徑。
+ 確保應用程式中的異常處理邏輯一定有路徑通往有效 `end of transaction`。
+ 確保應用程式以 `COMMIT` 或 `ROLLBACK` 結束交易後處理查詢結果。

### 因應長時間執行的交易
<a name="wait-event.locktransactionid.actions.concurrency"></a>

如果長時間執行的交易導致頻繁出現 `Lock:transactionid`，請嘗試下列策略：
+ 避免長時間執行的交易使用資料列鎖定。
+ 盡可能實作自動遞交來限制查詢的長度。

# Lock:tuple
<a name="wait-event.locktuple"></a>

`Lock:tuple` 事件表示後端程序正等待在元組上取得鎖定。

**Topics**
+ [支援的引擎版本](#wait-event.locktuple.context.supported)
+ [Context](#wait-event.locktuple.context)
+ [等待變多的可能原因](#wait-event.locktuple.causes)
+ [動作](#wait-event.locktuple.actions)

## 支援的引擎版本
<a name="wait-event.locktuple.context.supported"></a>

所有 RDS for PostgreSQL 版本都支援此等待事件資訊。

## Context
<a name="wait-event.locktuple.context"></a>

`Lock:tuple` 事件表示後端正等待在元組上取得鎖定，但另一個後端在同一個元組上持有衝突鎖定。下表說明工作階段產生 `Lock:tuple` 事件的情節。


|  時間  |  工作階段 1  |  工作階段 2  |  工作階段 3  | 
| --- | --- | --- | --- | 
|  t1  |  開始交易。  |    |    | 
|  t2  |  更新資料列 1。  |    |    | 
|  t3  |    |  更新資料列 1。工作階段在元組上取得獨佔鎖定，然後等待工作階段 1 遞交或復原來釋放鎖定。  |    | 
|  t4  |    |    |  更新資料列 1。工作階段等待工作階段 2 釋放元組上的獨佔鎖定。  | 

或者，您可以使用基準化分析工具 `pgbench` 來模擬此等待事件。使用自訂 SQL 檔案，將大量並行工作階段設定成在資料表中更新相同資料列。

若要進一步了解衝突鎖定模式，請參閱 PostgreSQL 文件中的[明確鎖定](https://www.postgresql.org/docs/current/explicit-locking.html)。若要進一步了解 `pgbench`，請參閱 PostgreSQL 文件中的 [pgbench](https://www.postgresql.org/docs/current/pgbench.html)。

## 等待變多的可能原因
<a name="wait-event.locktuple.causes"></a>

此事件比平時更常出現時，可能表示有效能問題，典型原因包括：
+ 大量並行工作階段執行 `UPDATE` 或 `DELETE` 陳述式，嘗試取得同一個元組的衝突鎖定。
+ 高度並行工作階段使用 `FOR UPDATE` 或 `FOR NO KEY UPDATE` 鎖定模式來執行 `SELECT` 陳述式。
+ 各種因素迫使應用程式或連線集區開啟更多工作階段來執行相同的操作。由於新的工作階段嘗試修改相同的資料行，資料庫負載會激增，並出現 `Lock:tuple`。

如需詳細資訊，請參閱 PostgreSQL 文件中的[資料列層級鎖定](https://www.postgresql.org/docs/current/explicit-locking.html#LOCKING-ROWS)。

## 動作
<a name="wait-event.locktuple.actions"></a>

根據等待事件的原因，我們會建議不同的動作。

**Topics**
+ [調查應用程式邏輯](#wait-event.locktuple.actions.problem)
+ [尋找引起封鎖的工作階段](#wait-event.locktuple.actions.find-blocker)
+ [減少高度並行](#wait-event.locktuple.actions.concurrency)
+ [瓶頸疑難排解](#wait-event.locktuple.actions.bottlenecks)

### 調查應用程式邏輯
<a name="wait-event.locktuple.actions.problem"></a>

查明引起封鎖的工作階段是否長時間處於 `idle in transaction` 狀態。如果是，請考慮結束引起封鎖的工作階段，當作短期的解決辦法。您也可以使用 `pg_terminate_backend` 函數。如需此函數的詳細資訊，請參閱 PostgreSQL 文件中的[伺服器訊號函數](https://www.postgresql.org/docs/13/functions-admin.html#FUNCTIONS-ADMIN-SIGNAL)。

如需長期解決方案，請執行下列動作：
+ 調整應用程式邏輯。
+ 使用 `idle_in_transaction_session_timeout` 參數。任何工作階段中，如果開啟的交易已閒置超過一段指定的時間，此參數會結束工作階段。如需詳細資訊，請參閱 PostgreSQL 文件中的[用戶端連線預設值](https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-IDLE-IN-TRANSACTION-SESSION-TIMEOUT)。
+ 盡可能使用自動遞交。如需詳細資訊，請參閱 PostgreSQL 文件中的 [SET AUTOCOMMIT](https://www.postgresql.org/docs/current/ecpg-sql-set-autocommit.html)。

### 尋找引起封鎖的工作階段
<a name="wait-event.locktuple.actions.find-blocker"></a>

`Lock:tuple` 等待事件發生時，請查明哪些鎖定彼此相依，以找出引起封鎖和被封鎖的工作階段。如需詳細資訊，請參閱 PostgreSQL Wiki 中的[鎖定相依性資訊](https://wiki.postgresql.org/wiki/Lock_dependency_information)。

下列範例查詢所有工作階段，篩選 `tuple` 並依據 `wait_time` 排序。

```
SELECT blocked_locks.pid AS blocked_pid,
         blocking_locks.pid AS blocking_pid,
         blocked_activity.usename AS blocked_user,
         blocking_activity.usename AS blocking_user,
         now() - blocked_activity.xact_start AS blocked_transaction_duration,
         now() - blocking_activity.xact_start AS blocking_transaction_duration,
         concat(blocked_activity.wait_event_type,':',blocked_activity.wait_event) AS blocked_wait_event,
         concat(blocking_activity.wait_event_type,':',blocking_activity.wait_event) AS blocking_wait_event,
         blocked_activity.state AS blocked_state,
         blocking_activity.state AS blocking_state,
         blocked_locks.locktype AS blocked_locktype,
         blocking_locks.locktype AS blocking_locktype,
         blocked_activity.query AS blocked_statement,
         blocking_activity.query AS blocking_statement
    FROM pg_catalog.pg_locks blocked_locks
    JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
    JOIN pg_catalog.pg_locks blocking_locks
        ON blocking_locks.locktype = blocked_locks.locktype
        AND blocking_locks.DATABASE IS NOT DISTINCT FROM blocked_locks.DATABASE
        AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
        AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page
        AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple
        AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid
        AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid
        AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid
        AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid
        AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid
        AND blocking_locks.pid != blocked_locks.pid
    JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
    WHERE NOT blocked_locks.GRANTED;
```

### 減少高度並行
<a name="wait-event.locktuple.actions.concurrency"></a>

`Lock:tuple` 事件可能持續發生，尤其在忙碌的工作負載時段。在此情況下，對於非常忙碌的資料列，請考慮減少高度並行。通常只有少數資料列控制佇列或布林邏輯，使得這些資料列非常忙碌。

您可以根據商業需求、應用程式邏輯和工作負載類型，使用不同方法來減少並行。例如，您可以執行下列動作：
+ 重新設計資料表和資料邏輯來減少高度並行。
+ 變更應用程式邏輯來減少資料列層級的高度並行。
+ 善用並重新設計含有資料列層級鎖定的查詢。
+ 對重試操作使用 `NOWAIT` 子句。
+ 考慮使用樂觀和混合鎖定邏輯並行控制。
+ 考慮變更資料庫隔離層級。

### 瓶頸疑難排解
<a name="wait-event.locktuple.actions.bottlenecks"></a>

`Lock:tuple` 可能發生瓶頸，例如 CPU 不足或 Amazon EBS 頻寬耗盡。若要減少瓶頸，請考慮下列方法：
+ 擴充執行個體類別類型的規模。
+ 將消耗大量資源的查詢最佳化。
+ 變更應用程式邏輯。
+ 封存不常存取的資料。

# LWLock:BufferMapping (LWLock:buffer\$1mapping)
<a name="wait-event.lwl-buffer-mapping"></a>

此事件表示工作階段正在等待將資料區塊與共用緩衝集區中的緩衝區建立關聯。

**注意**  
對於 RDS for PostgreSQL 第 13 版及更新版本，此事件命名為 `LWLock:BufferMapping`。對於 RDS for PostgreSQL 第 12 版及更舊版本，此事件命名為 `LWLock:buffer_mapping`。

**Topics**
+ [支援的引擎版本](#wait-event.lwl-buffer-mapping.context.supported)
+ [Context](#wait-event.lwl-buffer-mapping.context)
+ [原因](#wait-event.lwl-buffer-mapping.causes)
+ [動作](#wait-event.lwl-buffer-mapping.actions)

## 支援的引擎版本
<a name="wait-event.lwl-buffer-mapping.context.supported"></a>

此等待事件資訊與 RDS for PostgreSQL 9.6 版及更新版本有關。

## Context
<a name="wait-event.lwl-buffer-mapping.context"></a>

*共用緩衝集區*是一種 PostgreSQL 記憶體區域，其中保留程序正在使用或已使用的所有分頁。程序需要分頁時會將分頁讀入共用緩衝集區。`shared_buffers` 參數設定共用緩衝區大小，並保留記憶體區域來存放資料表和索引分頁。如果您變更此參數，請務必重新啟動資料庫。

下列情況會發生 `LWLock:buffer_mapping` 等待事件：
+ 程序在緩衝區資料表中搜尋分頁，並取得共用緩衝區映射鎖定。
+ 程序將分頁載入緩衝集區，並取得獨佔緩衝區映射鎖定。
+ 程序從集區移除頁面，並取得獨佔緩衝區映射鎖定。

## 原因
<a name="wait-event.lwl-buffer-mapping.causes"></a>

此事件比平時更常出現時，可能表示有效能問題，資料庫正在共用緩衝集區中頁進頁出。典型原因包括：
+ 大型查詢
+ 膨脹的索引和資料表
+ 完整資料表掃描
+ 小於工作集的共用集區大小

## 動作
<a name="wait-event.lwl-buffer-mapping.actions"></a>

根據等待事件的原因，我們會建議不同的動作。

**Topics**
+ [監控緩衝區相關指標](#wait-event.lwl-buffer-mapping.actions.monitor-metrics)
+ [評估索引策略](#wait-event.lwl-buffer-mapping.actions.indexes)
+ [減少必須快速配置的緩衝區數目](#wait-event.lwl-buffer-mapping.actions.buffers)

### 監控緩衝區相關指標
<a name="wait-event.lwl-buffer-mapping.actions.monitor-metrics"></a>

`LWLock:buffer_mapping` 等待激增時，請調查緩衝區命中率。您可以使用這些指標，以更加了解緩衝區快取中的情況。檢查下列指標：

`blks_hit`  
此績效詳情計數器指標指出從共用緩衝集區擷取的區塊數目。在 `LWLock:buffer_mapping` 等待事件出現之後，您可能發現 `blks_hit` 激增。

`blks_read`  
此績效詳情計數器指標指出需要將輸入/輸出讀入共用緩衝集區的區塊數目。在 `LWLock:buffer_mapping` 等待事件發生之前，您可能發現 `blks_read` 激增。

### 評估索引策略
<a name="wait-event.lwl-buffer-mapping.actions.indexes"></a>

若要確認索引策略不會降低效能，請檢查下列各項：

索引膨脹  
請確定索引和資料表膨脹不會導致將不必要的分頁讀入共用緩衝區。如果資料表包含未使用的資料列，請考慮封存資料並從資料表中移除資料列。然後，您可以對已調整大小的資料表重建索引。

常用查詢的索引  
若要判斷您是否有最佳索引，請在績效詳情中監控資料庫引擎指標。`tup_returned` 指標顯示讀取的資料列數。`tup_fetched` 指標顯示傳回給用戶端的資料列數。如果 `tup_returned` 明顯大於 `tup_fetched`，表示資料可能未正確編製索引。此外，資料表統計數字可能不是最新。

### 減少必須快速配置的緩衝區數目
<a name="wait-event.lwl-buffer-mapping.actions.buffers"></a>

若要減少 `LWLock:buffer_mapping` 等待事件，請嘗試減少必須快速配置的緩衝區數目。有一種策略是執行較小的批次操作。您可以分割資料表來獲得較小的批次。

# LWLock:BufferIO (IPC:BufferIO)
<a name="wait-event.lwlockbufferio"></a>

`LWLock:BufferIO` 事件表示 RDS for PostgreSQL 與其他程序同時嘗試存取分頁，正在等待其他程序完成輸入/輸出 (I/O) 操作。目的是為了將該分頁讀入共用緩衝區。

**Topics**
+ [相關的引擎版本](#wait-event.lwlockbufferio.context.supported)
+ [Context](#wait-event.lwlockbufferio.context)
+ [原因](#wait-event.lwlockbufferio.causes)
+ [動作](#wait-event.lwlockbufferio.actions)

## 相關的引擎版本
<a name="wait-event.lwlockbufferio.context.supported"></a>

此等待事件資訊與所有 RDS for PostgreSQL 版本有關。對於適用於 PostgreSQL 12 的 RDS 和更早版本，此等待事件被命名為 lwlock:buffer\$1io，而在 RDS 中為 PostgreSQL 13 版本，它被命名為 lwlock:bufferio。從 RDS for PostgreSQL 14 版開始，此等待事件從 `LWLock`移動至 `IPC`等待事件類型 (IPC:BufferIO)。

## Context
<a name="wait-event.lwlockbufferio.context"></a>

每次必須在共用緩衝集區外擷取區塊 (或分頁) 時，每個共用緩衝區都有與 `LWLock:BufferIO` 等待事件相關聯的輸入/輸出鎖定。

此鎖定用於處理全都需要存取同一個區塊的多個工作階段。必須從 `shared_buffers` 參數定義的共用緩衝集區外讀取此區塊。

在共用緩衝集區內讀取分頁後，就會立刻釋放 `LWLock:BufferIO` 鎖定。

**注意**  
`LWLock:BufferIO` 等待事件在 [IO:DataFileRead](wait-event.iodatafileread.md) 等待事件之前發生。從儲存讀取資料時會發生 `IO:DataFileRead` 等待事件。

如需輕量級鎖定的詳細資訊，請參閱[鎖定概觀](https://github.com/postgres/postgres/blob/65dc30ced64cd17f3800ff1b73ab1d358e92efd8/src/backend/storage/lmgr/README#L20)。

## 原因
<a name="wait-event.lwlockbufferio.causes"></a>

`LWLock:BufferIO` 事件出現在最常等待名單中的常見原因包括：
+ 多個後端或連線嘗試存取同一個分頁，而此分頁也擱置輸入/輸出操作
+ 共用緩衝集區 (由 `shared_buffers` 參數定義) 的大小與目前工作負載所需緩衝區數目之間的比率
+ 共用緩衝集區的大小與其他操作移出的分頁數目不太相稱
+ 大型或膨脹的索引迫使引擎將過多分頁讀入共用緩衝集區
+ 缺少索引迫使資料庫引擎從資料表讀取過多分頁
+ 檢查點太頻繁出現或需要清除太多已修改的分頁
+ 嘗試對同一分頁執行操作的資料庫連線突然激增

## 動作
<a name="wait-event.lwlockbufferio.actions"></a>

我們根據等待事件的原因，建議不同的動作：
+ 如果您發現與 `BufferCacheHitRatio` 指標一致的 `LWLock:BufferIO` 下降，請根據工作負載尖峰時段來調校 `max_wal_size` 和 `checkpoint_timeout`。然後查明哪個查詢造成此狀況。
+ 驗證是否有未使用的索引，然後移除。
+ 使用分割的資料表 (也有分割的索引)。這樣做有助於盡量避免索引重新排序，並減少其影響。
+ 避免不必要地編製資料欄的索引。
+ 使用連線集區來防止資料庫連線突然激增。
+ 在最佳實務上限制資料庫的連線數目上限。

# LWLock:buffer\$1content (BufferContent)
<a name="wait-event.lwlockbuffercontent"></a>

`LWLock:buffer_content` 事件表示工作階段正等待在記憶體中讀取或寫入資料分頁，但另一個工作階段已鎖定該分頁來寫入。在 RDS for PostgreSQL 13 及更新版本中，此等待事件稱為 `BufferContent`。

**Topics**
+ [支援的引擎版本](#wait-event.lwlockbuffercontent.context.supported)
+ [Context](#wait-event.lwlockbuffercontent.context)
+ [等待變多的可能原因](#wait-event.lwlockbuffercontent.causes)
+ [動作](#wait-event.lwlockbuffercontent.actions)

## 支援的引擎版本
<a name="wait-event.lwlockbuffercontent.context.supported"></a>

所有 RDS for PostgreSQL 版本都支援此等待事件資訊。

## Context
<a name="wait-event.lwlockbuffercontent.context"></a>

為了讀取或操作資料，PostgreSQL 透過共用記憶體緩衝區來存取資料。為了讀取緩衝區，程序以共用模式在緩衝區內容上取得輕量級鎖定 (LWLock)。為了寫入緩衝區，程序以獨佔模式取得該鎖定。共用鎖定允許其他程序同時在該內容上取得共用鎖定。獨佔鎖定阻止其他程序在該內容上得得任何類型的鎖定。

`LWLock:buffer_content` (`BufferContent`) 事件表示多個程序正嘗試在特定緩衝區的內容上取得鎖定。

## 等待變多的可能原因
<a name="wait-event.lwlockbuffercontent.causes"></a>

`LWLock:buffer_content` (`BufferContent`) 事件比平時更常出現時，可能表示有效能問題，典型原因包括：

**更常並行更新相同資料**  
以查詢來更新相同緩衝區內容的並行工作階段可能變多。在有大量索引的資料表上，這種爭用可能更明顯。

**工作負載資料不在記憶體中**  
當作用中工作負載處理的資料不在記憶體中時，這些等待事件可能增加。這是因為程序在執行磁碟輸入/輸出操作時持有鎖定更久。

**過度使用外部索引鍵限制**  
外部索引鍵限制會延長程序持有緩衝區內容鎖定的時間。這是因為讀取操作在更新參考的索引鍵時，在該索引鍵上需要共用緩衝區內容鎖定。

## 動作
<a name="wait-event.lwlockbuffercontent.actions"></a>

根據等待事件的原因，我們會建議不同的動作。您可以使用 Amazon RDS 績效詳情或查詢 `LWLock:buffer_content` 檢視表來識別 `BufferContent` (`pg_stat_activity`) 事件。

**Topics**
+ [改善記憶體內效率](#wait-event.lwlockbuffercontent.actions.in-memory)
+ [減少使用外部索引鍵限制](#wait-event.lwlockbuffercontent.actions.foreignkey)
+ [移除未使用的索引](#wait-event.lwlockbuffercontent.actions.indexes)
+ [使用序列時增加快取大小](#wait-event.lwlockbuffercontent.actions.sequences)

### 改善記憶體內效率
<a name="wait-event.lwlockbuffercontent.actions.in-memory"></a>

若要讓作用中工作負載資料更有機會留在記憶體中，請分割資料表或擴充執行個體類別的規模。如需資料庫執行個體類別的相關資訊，請參閱 [ 資料庫執行個體類別](Concepts.DBInstanceClass.md)。

### 減少使用外部索引鍵限制
<a name="wait-event.lwlockbuffercontent.actions.foreignkey"></a>

調查遇到大量 `LWLock:buffer_content` (`BufferContent`）等待事件的工作負載如何使用外部引索鍵限制。刪除不必要的外部索引鍵限制。

### 移除未使用的索引
<a name="wait-event.lwlockbuffercontent.actions.indexes"></a>

對於遇到大量 `LWLock:buffer_content` (`BufferContent`) 等待事件的工作負載，請識別未使用的索引並移除。

### 使用序列時增加快取大小
<a name="wait-event.lwlockbuffercontent.actions.sequences"></a>

如果您的資料表使用序列，請增加快取大小，以移除序列頁面和索引頁面上的爭用。每個序列都是共用記憶體中的單一頁面。預先定義的快取根據每個連線。當許多並行工作階段取得序列值時，此快取可能不足以處理工作負載。

# LWLock:lock\$1manager (LWLock:lockmanager)
<a name="wait-event.lw-lock-manager"></a>

此事件表示因為無法執行快速路徑鎖定，RDS for PostgreSQL 引擎維護共用鎖定的記憶體區域來配置、檢查和解除配置鎖定。

**Topics**
+ [支援的引擎版本](#wait-event.lw-lock-manager.context.supported)
+ [Context](#wait-event.lw-lock-manager.context)
+ [等待變多的可能原因](#wait-event.lw-lock-manager.causes)
+ [動作](#wait-event.lw-lock-manager.actions)

## 支援的引擎版本
<a name="wait-event.lw-lock-manager.context.supported"></a>

此等待事件資訊與 RDS for PostgreSQL 9.6 版及更新版本有關。對於比第 13 版舊的 RDS for PostgreSQL 版本，此等待事件的名稱為 `LWLock:lock_manager`。對於 RDS for PostgreSQL 第 13 版及更新版本，此等待事件的名稱為 `LWLock:lockmanager`。

## Context
<a name="wait-event.lw-lock-manager.context"></a>

當您發出 SQL 陳述式時，RDS for PostgreSQL 會記錄鎖定，在並行操作期間保護資料庫的結構、資料和完整性。引擎可以使用快速路徑鎖定或不快速的路徑鎖定來達成此目標。不快速的路徑鎖定比快速路徑鎖定花更多成本，還會產生更多額外負荷。

### 快速路徑鎖定
<a name="wait-event.lw-lock-manager.context.fast-path"></a>

如果鎖定經常取得和釋放但很少衝突，為了減少額外負荷，後端程序可以使用快速路徑鎖定。資料庫使用此機制來處理符合下列條件的鎖定：
+ 使用 DEFAULT 鎖定方法。
+ 代表鎖定資料庫關聯，而不是共用關聯。
+ 弱鎖定，不太可能衝突。
+ 引擎可以快速確認不可能有衝突鎖定。

有下列任一情況時，引擎無法使用快速路徑鎖定：
+ 鎖定不符合上述條件。
+ 已無插槽可供後端程序使用。

若要調整您的查詢以進行快速路徑鎖定，您可以使用下列查詢。

```
SELECT count(*), pid, mode, fastpath
  FROM pg_locks
 WHERE fastpath IS NOT NULL
 GROUP BY 4,3,2
 ORDER BY pid, mode;
 count | pid  |      mode       | fastpath
-------+------+-----------------+----------
16 | 9185 | AccessShareLock | t
336 | 9185 | AccessShareLock | f
1 | 9185 | ExclusiveLock   | t
```

下列查詢只顯示整個資料庫的總計。

```
SELECT count(*), mode, fastpath
  FROM pg_locks
 WHERE fastpath IS NOT NULL
 GROUP BY 3,2
 ORDER BY mode,1;
count |      mode       | fastpath
-------+-----------------+----------
16 | AccessShareLock | t
337 | AccessShareLock | f
1 | ExclusiveLock   | t
(3 rows)
```

如需快速路徑鎖定的詳細資訊，請參閱 PostgreSQL 鎖定管理員 README 中的[快速路徑](https://github.com/postgres/postgres/blob/master/src/backend/storage/lmgr/README#L70-L76)和 PostgreSQL 文件中的 [pg-locks](https://www.postgresql.org/docs/9.3/view-pg-locks.html#AEN98195)。

### 鎖定管理員的擴展問題範例
<a name="wait-event.lw-lock-manager.context.lock-manager"></a>

在此範例中，名為 `purchases` 的資料表存放五年的資料，並按日分割。每個分割區都有兩個索引。發生下列事件序列：

1. 您查詢很多天的資料，使得資料庫需要讀取許多分割區。

1. 資料庫為每個分割區建立鎖定項目。如果分割區索引出現在最佳化工具存取路徑中，則資料庫也為這種索引建立鎖定項目。

1. 對同一個後端程序所請求的鎖定項目數大於 16 時，即 `FP_LOCK_SLOTS_PER_BACKEND` 的值，鎖定管理員會使用不快速的路徑鎖定方法。

現代化應用程式可能有數百個工作階段。如果並行工作階段查詢父項，但沒有適當的分割區剔除，則資料庫可能會建立數百甚至數千個不快速的路徑鎖定。當此並行高於 vCPU 數目時，通常會出現 `LWLock:lock_manager` 等待事件。

**注意**  
`LWLock:lock_manager` 等待事件與資料庫結構描述中的分割區或索引數目無關。但與資料庫必須控制的不快速路徑鎖定數目有關。

## 等待變多的可能原因
<a name="wait-event.lw-lock-manager.causes"></a>

`LWLock:lock_manager` 等待事件比平常更常發生時，可能表示有效能問題，突然激增最可能的原因如下：
+ 並行作用中工作階段正在執行的查詢未使用快速路徑鎖定。這些工作階段也超過 vCPU 上限。
+ 大量並行作用中工作階段正在存取高度分割的資料表。每個分割區有多個索引。
+ 資料庫遇到連線風暴。根據預設，當資料庫變慢時，某些應用程式和連線集區軟體會建立更多連線。這種做法使問題變得更糟。請調校連線集區軟體，以免發生連線風暴。
+ 大量工作階段查詢父資料表但未剔除分割區。
+ 資料定義語言 (DDL)、資料處理語言 (DML) 或維護命令獨佔鎖定忙碌關聯，或是經常存取或修改的元組。

## 動作
<a name="wait-event.lw-lock-manager.actions"></a>

發生 `CPU` 等待事件不見得表示有效能問題。只有在效能下降且此等待事件主宰資料庫負載時，才需要因應此事件。

**Topics**
+ [使用分割區剔除](#wait-event.lw-lock-manager.actions.pruning)
+ [移除不必要的索引](#wait-event.lw-lock-manager.actions.indexes)
+ [調校查詢以使用快速路徑鎖定](#wait-event.lw-lock-manager.actions.tuning)
+ [調校其他等待事件](#wait-event.lw-lock-manager.actions.other-waits)
+ [降低硬體瓶頸](#wait-event.lw-lock-manager.actions.hw-bottlenecks)
+ [使用連線集區](#wait-event.lw-lock-manager.actions.pooler)
+ [升級 RDS for PostgreSQL 版本](#wait-event.lw-lock-manager.actions.pg-version)

### 使用分割區剔除
<a name="wait-event.lw-lock-manager.actions.pruning"></a>

*剔除分割區*是一種宣告式分割資料表的查詢最佳化策略，可將不需要的分割區排除在資料表掃描外，進而改善效能。分割區剔除預設為啟用。如果已停用，請如下啟用。

```
SET enable_partition_pruning = on;
```

當 `WHERE` 子句包含用於分割的資料欄時，查詢可以利用分割區剔除。如需詳細資訊，請參閱 PostgreSQL 文件中的[分割區剔除](https://www.postgresql.org/docs/current/ddl-partitioning.html#DDL-PARTITION-PRUNING)。

### 移除不必要的索引
<a name="wait-event.lw-lock-manager.actions.indexes"></a>

資料庫可能包含未使用或很少使用的索引。若是如此，請考慮刪除這些索引。執行下列任何一項：
+ 請參閱 PostgreSQL Wiki 中的[未使用的索引](https://wiki.postgresql.org/wiki/Index_Maintenance#Unused_Indexes)，以了解如何尋找不必要的索引。
+ 執行 PG Collector。此 SQL 指令碼會收集資料庫資訊，並顯示在合併的 HTML 報告中。請檢查「Unused indexes (未使用的索引)」區段。如需詳細資訊，請參閱 AWS Labs GitHub 儲存庫中的 [pg-collector](https://github.com/awslabs/pg-collector)。

### 調校查詢以使用快速路徑鎖定
<a name="wait-event.lw-lock-manager.actions.tuning"></a>

若要查明查詢是否使用快速路徑鎖定，請查詢 `pg_locks` 資料表的 `fastpath` 資料欄。如果查詢未使用快速路徑鎖定，請嘗試將每個查詢的關聯數量減少到 16 以下。

### 調校其他等待事件
<a name="wait-event.lw-lock-manager.actions.other-waits"></a>

如果 `LWLock:lock_manager` 在最常等待名單中排行前兩名，請檢查下列等待事件是否也出現在名單中：
+ `Lock:Relation`
+ `Lock:transactionid`
+ `Lock:tuple`

如果上述事件在名單中排行前幾名，請考慮先調校這些等待事件。這些事件可能引發 `LWLock:lock_manager`。

### 降低硬體瓶頸
<a name="wait-event.lw-lock-manager.actions.hw-bottlenecks"></a>

您可能遇到硬體瓶頸，例如 CPU 不足或 Amazon EBS 頻寬耗盡。在這些情況下，請考慮降低硬體瓶頸。考慮下列動作：
+ 擴充執行個體類別的規模。
+ 將耗用大量 CPU 和記憶體的查詢最佳化。
+ 變更應用程式邏輯。
+ 封存資料。

如需 CPU、記憶體和 EBS 網路頻寬的詳細資訊，請參閱 [Amazon RDS 執行個體類型](https://aws.amazon.com/rds/instance-types/)。

### 使用連線集區
<a name="wait-event.lw-lock-manager.actions.pooler"></a>

如果作用中連線總數超過 vCPU 上限，表示需要 CPU 的作業系統程序超過執行個體類型可支援的數量。在此情況下，請考慮使用或調校連線集區。關於執行個體類型的 vCPU，如需詳細資訊，請參閱 [Amazon RDS 執行個體類型](https://aws.amazon.com/rds/instance-types/)。

如需連線集區的詳細資訊，請參閱下列資源：
+ [Amazon RDS Proxy ](rds-proxy.md)
+ [pgbouncer](http://www.pgbouncer.org/usage.html)
+ 《PostgreSQL 文件》**中的[連線集區和資料來源](https://www.postgresql.org/docs/7.4/jdbc-datasource.html)

### 升級 RDS for PostgreSQL 版本
<a name="wait-event.lw-lock-manager.actions.pg-version"></a>

如果您目前的 RDS for PostgreSQL 版本低於 12，請升級至第 12 版或更新版本。PostgreSQL 第 12 版和更新版本已改善分割機制。如需第 12 版的詳細資訊，請參閱 [PostgreSQL 12.0 版本備註]( https://www.postgresql.org/docs/release/12.0/)。如需升級 RDS for PostgreSQL 的詳細資訊，請參閱[RDS for PostgreSQL 資料庫引擎的升級](USER_UpgradeDBInstance.PostgreSQL.md)。

# LWLock:pg\$1stat\$1statements
<a name="apg-rpg-lwlockpgstat"></a>

當 `pg_stat_statements` 延伸對追蹤 SQL 陳述式的雜湊資料表進行獨佔鎖定時，就會發生 LWLock:pg\$1stat\$1statements 等待事件。這會發生在下列案例中：
+ 當追蹤的陳述式數量達到設定的 `pg_stat_statements.max` 參數值，而且需要為更多項目騰出空間時，延伸會對呼叫數量執行排序、移除 5% 的最少執行的陳述式，並使用剩餘的項目重新填入雜湊。
+ 當 `pg_stat_statements` 對磁碟上的 `pgss_query_texts.stat` 檔案執行 `garbage collection` 操作，並重新寫入檔案。

**Topics**
+ [支援的引擎版本](#apg-rpg-lwlockpgstat.supported)
+ [Context](#apg-rpg-lwlockpgstat.context)
+ [等待時間增加的可能原因](#apg-rpg-lwlockpgstat.causes)
+ [動作](#apg-rpg-lwlockpgstat.actions)

## 支援的引擎版本
<a name="apg-rpg-lwlockpgstat.supported"></a>

 所有 RDS for PostgreSQL 的版本都支援此等待事件資訊。

## Context
<a name="apg-rpg-lwlockpgstat.context"></a>

**了解 pg\$1stat\$1statements 延伸** – pg\$1stat\$1statements 延伸會追蹤雜湊資料表中的 SQL 陳述式執行統計資料。延伸會追蹤 SQL 陳述式，最高可達 `pg_stat_statements.max` 參數定義的限制。此參數會決定可追蹤的陳述式數目上限，對應至 pg\$1stat\$1statements 檢視中的資料列數目上限。

**陳述式統計資料持久性** – 延伸會保留執行個體重新啟動時的陳述式統計資料：
+ 將資料寫入名為 pg\$1stat\$1statements.stat 的檔案
+ 使用 pg\$1stat\$1statements.save 參數控制持久性行為

當 pg\$1stat\$1statements.save 設定為：
+ ON (預設)：統計資料會在關閉時儲存，並在伺服器啟動時重新載入
+ OFF：統計資料不會在關機時儲存，也不會在伺服器啟動時重新載入

**查詢文字儲存** – 延伸會將追蹤查詢的文字儲存在名為 `pgss_query_texts.stat` 的檔案中。在垃圾回收發生之前，此檔案可以成長為所有追蹤 SQL 陳述式的平均大小的兩倍。在清理操作和重寫 `pgss_query_texts.stat` 檔案期間，延伸需要對雜湊資料表進行獨佔鎖定。

**陳述式解除配置程序** – 當追蹤的陳述式數量達到 `pg_stat_statements.max` 限制且需要追蹤新的陳述式時，延伸會：
+ 在雜湊資料表上進行獨佔鎖定 (LWLock:pg\$1stat\$1statements)。
+ 將現有資料載入本機記憶體。
+ 根據呼叫次數執行快速排序。
+ 移除最少呼叫的陳述式 (底部 5%)。
+ 將剩餘項目重新填入雜湊資料表。

**監控陳述式解除配置** – 在 PostgreSQL 14 和更新版本中，您可以使用 pg\$1stat\$1statements\$1info 檢視來監控陳述式解除配置。此檢視包含解除配置欄，顯示陳述式被解除配置的次數，以便為新陳述式騰出空間

如果陳述式的解除配置頻繁發生，將導致磁碟上 `pgss_query_texts.stat` 檔案的垃圾回收更頻繁。

## 等待時間增加的可能原因
<a name="apg-rpg-lwlockpgstat.causes"></a>

增加 `LWLock:pg_stat_statements` 等待的典型原因包括：
+ 應用程式使用的唯一查詢數量增加。
+ 與使用的唯一查詢數目相比，`pg_stat_statements.max` 參數值很小。

## 動作
<a name="apg-rpg-lwlockpgstat.actions"></a>

根據等待事件的原因，我們會建議不同的動作。您可以使用 Amazon RDS Performance Insights 或查詢檢視 `pg_stat_activity` 來識別 `LWLock:pg_stat_statements` 事件。

調整下列 `pg_stat_statements` 參數以控制追蹤行為，並減少 LWLock:pg\$1stat\$1 陳述式等待事件。

**Topics**
+ [停用 pg\$1stat\$1statements.track 參數](#apg-rpg-lwlockpgstat.actions.disabletrack)
+ [增加 pg\$1stat\$1statements.max 參數](#apg-rpg-lwlockpgstat.actions.increasemax)
+ [停用 pg\$1stat\$1statements.track\$1utility 參數](#apg-rpg-lwlockpgstat.actions.disableutility)

### 停用 pg\$1stat\$1statements.track 參數
<a name="apg-rpg-lwlockpgstat.actions.disabletrack"></a>

如果 LWLock:pg\$1stat\$1statements 等待事件對資料庫效能造成負面影響，且在進一步分析 `pg_stat_statements` 檢視以找出根本原因之前需要快速解決方案，則可以將其設定為 `none` 來停用 `pg_stat_statements.track` 參數。這將停用陳述式統計資料的集合。

### 增加 pg\$1stat\$1statements.max 參數
<a name="apg-rpg-lwlockpgstat.actions.increasemax"></a>

若要減少解除配置並將磁碟上 `pgss_query_texts.stat` 檔案的垃圾回收降至最低，請增加 `pg_stat_statements.max` 參數的值。預設值為 `5,000`。

**注意**  
`pg_stat_statements.max` 參數設為靜態。您必須重新啟動資料庫執行個體，才能將任何變更套用至此參數。

### 停用 pg\$1stat\$1statements.track\$1utility 參數
<a name="apg-rpg-lwlockpgstat.actions.disableutility"></a>

您可以分析 pg\$1stat\$1statements 檢視，以判斷哪些公用程式命令耗用 `pg_stat_statements` 追蹤最多的資源。

`pg_stat_statements.track_utility` 參數可控制模組是否追蹤公用程式命令，其中包含 SELECT、INSERT、UPDATE、DELETE 和 MERGE 以外的所有命令。根據預設，此參數會設定為 `on`。

例如，當您的應用程式使用許多原本是唯一的儲存點查詢時，可能會增加陳述式解除配置。若要解決此問題，您可以停用 `pg_stat_statements.track_utility` 參數以防止 `pg_stat_statements` 追蹤儲存點查詢。

**注意**  
`pg_stat_statements.track_utility` 參數是動態參數。您可以變更其值，而無需重新啟動資料庫執行個體。

**Example pg\$1stat\$1statements 中唯一儲存點查詢的範例**  <a name="savepoint-queries"></a>

```
                     query                       |       queryid       
-------------------------------------------------+---------------------
 SAVEPOINT JDBC_SAVEPOINT_495701                 | -7249565344517699703
 SAVEPOINT JDBC_SAVEPOINT_1320                   | -1572997038849006629
 SAVEPOINT JDBC_SAVEPOINT_26739                  |  54791337410474486
 SAVEPOINT JDBC_SAVEPOINT_1294466                |  8170064357463507593
 ROLLBACK TO SAVEPOINT JDBC_SAVEPOINT_65016      | -33608214779996400
 SAVEPOINT JDBC_SAVEPOINT_14185                  | -2175035613806809562
 SAVEPOINT JDBC_SAVEPOINT_45837                  | -6201592986750645383
 SAVEPOINT JDBC_SAVEPOINT_1324                   |  6388797791882029332
```

PostgreSQL 17 為公用程式命令追蹤推出數種增強功能：
+ 儲存點名稱現在會顯示為常數。
+ 兩階段遞交命令的全域交易 IDs(GIDs) 現在會顯示為常數。
+ DEALLOCATE 陳述式的名稱會顯示為常數。
+ CALL 參數現在會顯示為常數。

# LWLock：SubtransSLRU (LWLock：SubtransControlLock)
<a name="wait-event.lwlocksubtransslru"></a>

`LWLock:SubtransSLRU` 和 `LWLock:SubtransBuffer`等待事件表示工作階段正在等待存取簡單的最近最少使用 (SLRU) 快取以取得子交易資訊。這會在判斷交易可見性和父子關係時發生。
+ `LWLock:SubtransSLRU`：程序正在等待為子交易存取簡單的最近最少使用 (SLRU) 快取。在版本 13 之前的 RDS for PostgreSQL 中，此等待事件稱為 `SubtransControlLock`。
+ `LWLock:SubtransBuffer`：程序正在等待簡單最近最少使用 (SLRU) 緩衝區上的輸入/輸出進行子交易。在版本 13 之前的 RDS for PostgreSQL 中，此等待事件稱為 `subtrans`。

**Topics**
+ [支援的引擎版本](#wait-event.lwlocksubtransslru.supported)
+ [Context](#wait-event.lwlocksubtransslru.context)
+ [等待時間增加的可能原因](#wait-event.lwlocksubtransslru.causes)
+ [動作](#wait-event.lwlocksubtransslru.actions)

## 支援的引擎版本
<a name="wait-event.lwlocksubtransslru.supported"></a>

所有 RDS for PostgreSQL 版本都支援此等待事件資訊。

## Context
<a name="wait-event.lwlocksubtransslru.context"></a>

**了解子交易** – 子交易是 PostgreSQL 中交易內的交易。它也稱為巢狀交易。

子交易通常會在您使用 時建立：
+ `SAVEPOINT` 命令
+ 例外狀況區塊 (`BEGIN/EXCEPTION/END`)

子交易可讓您復原部分交易，而不會影響整個交易。這可讓您精細控制交易管理。

**實作詳細資訊** – PostgreSQL 在主要交易中實作子交易做為巢狀結構。每個子交易都會取得自己的交易 ID。

關鍵實作層面：
+ 交易 IDs會在 中追蹤 `pg_xact`
+ 父子關係存放在 下的`pg_subtrans`子目錄中 `PGDATA`
+ 每個資料庫工作階段最多可以維持 個`64`作用中的子交易
+ 超過此限制會導致子交易溢位，這需要存取簡單的最近最少使用 (SLRU) 快取以取得子交易資訊

## 等待時間增加的可能原因
<a name="wait-event.lwlocksubtransslru.causes"></a>

子交易 SLRU 爭用的常見原因包括：
+ **過度使用 SAVEPOINT 和 EXCEPTION 處理** – PL/pgSQL 程序搭配`EXCEPTION`處理常式會自動建立隱含儲存點，無論是否發生例外狀況。每個 都會`SAVEPOINT`啟動新的子交易。當單一交易累積超過 64 個子交易時，會觸發子交易 SLRU 溢位。
+ **驅動程式和 ORM 組態** – `SAVEPOINT` 用量可以在應用程式程式碼中明確，或透過驅動程式組態隱含。許多常用的 ORM 工具和應用程式架構原生支援巢狀交易。以下是一些常見的範例：
  + 如果 JDBC 驅動程式參數 `autosave`設定為 `always`或 `conservative`，則 會在每次查詢之前產生儲存點。
  + 設定為 時的 Spring Framework 交易定義`propagation_nested`。
  + `requires_new: true` 已設定 時的 Rails。
  + 使用 `session.begin_nested` 時的 SQLAlchemy。
  + 使用巢狀`atomic()`區塊時的 Django。
  + 使用 `Savepoint` 時的 GORM。
  + psqlODBC 將回復層級設定設為陳述式層級回復時 （例如，`PROTOCOL=7.4-2`)。
+ **具有長時間執行交易和子交易的高並行工作負載** – 當子交易 SLRU 溢位發生在高並行工作負載和長時間執行的交易和子交易期間時，PostgreSQL 的爭用性會增加。這會顯示為 `LWLock:SubtransBuffer`和 `LWLock:SubtransSLRU`鎖定的較高等待事件。

## 動作
<a name="wait-event.lwlocksubtransslru.actions"></a>

根據等待事件的原因，我們會建議不同的動作。有些動作提供立即的緩解，有些則需要調查和長期更正。

**Topics**
+ [監控子交易用量](#wait-event.lwlocksubtransslru.actions.monitor)
+ [設定記憶體參數](#wait-event.lwlocksubtransslru.actions.memory)
+ [長期動作](#wait-event.lwlocksubtransslru.actions.longterm)

### 監控子交易用量
<a name="wait-event.lwlocksubtransslru.actions.monitor"></a>

對於 PostgreSQL 16.1 版和更新版本，請使用下列查詢來監控每個後端的子交易計數和溢位狀態。此查詢將後端統計資料與活動資訊聯結，以顯示哪些程序正在使用子交易：

```
SELECT a.pid, usename, query, state, wait_event_type,
       wait_event, subxact_count, subxact_overflowed
FROM (SELECT id, pg_stat_get_backend_pid(id) pid, subxact_count, subxact_overflowed
      FROM pg_stat_get_backend_idset() id
           JOIN LATERAL pg_stat_get_backend_subxact(id) AS s ON true
     ) a
JOIN pg_stat_activity b ON a.pid = b.pid;
```

對於 PostgreSQL 13.3 版和更新版本，請監控`pg_stat_slru`檢視是否有子交易快取壓力。下列 SQL 查詢會擷取 Subtrans 元件的 SLRU 快取統計資料：

```
SELECT * FROM pg_stat_slru WHERE name = 'Subtrans';
```

持續增加`blks_read`的值表示未快取子交易經常存取磁碟，發出潛在的 SLRU 快取壓力訊號。

### 設定記憶體參數
<a name="wait-event.lwlocksubtransslru.actions.memory"></a>

對於 PostgreSQL 17.1 和更新版本，您可以使用 `subtransaction_buffers` 參數設定子交易 SLRU 快取大小。下列組態範例示範如何設定子交易緩衝區參數：

```
subtransaction_buffers = 128
```

此參數指定用來快取子交易內容的共用記憶體數量 (`pg_subtrans`)。在沒有單位的情況下指定時，值代表`BLCKSZ`位元組區塊，通常每個區塊為 8KB。例如，將值設定為 128 會為子交易快取配置 1MB (128 \$1 8kB) 的記憶體。

**注意**  
您可以在叢集層級設定此參數，讓所有執行個體保持一致。測試並調整 值，以符合您的特定工作負載需求和執行個體類別。您必須重新啟動寫入器執行個體，參數變更才會生效。

### 長期動作
<a name="wait-event.lwlocksubtransslru.actions.longterm"></a>
+ **檢查應用程式碼和組態** – 檢閱應用程式碼和資料庫驅動程式組態，了解一般的明確和隱含`SAVEPOINT`用量和子交易用量。識別可能產生超過 64 個子交易的交易。
+ **減少儲存點用量** – 將交易中的儲存點用量降至最低：
  + 使用 EXCEPTION 區塊檢閱 PL/pgSQL 程序與函數。EXCEPTION 區塊會自動建立隱含儲存點，這可能會導致子交易溢位。無論執行期間是否實際發生例外狀況，每個 EXCEPTION 子句都會建立子交易。  
**Example**  

    範例 1：有問題的 EXCEPTION 區塊用量

    下列程式碼範例顯示建立多個子交易的有問題的 EXCEPTION 區塊用量：

    ```
    CREATE OR REPLACE FUNCTION process_user_data()
    RETURNS void AS $$
    DECLARE
        user_record RECORD;
    BEGIN
        FOR user_record IN SELECT * FROM users LOOP
            BEGIN
                -- This creates a subtransaction for each iteration
                INSERT INTO user_audit (user_id, action, timestamp)
                VALUES (user_record.id, 'processed', NOW());
                
                UPDATE users 
                SET last_processed = NOW() 
                WHERE id = user_record.id;
                
            EXCEPTION
                WHEN unique_violation THEN
                    -- Handle duplicate audit entries
                    UPDATE user_audit 
                    SET timestamp = NOW() 
                    WHERE user_id = user_record.id AND action = 'processed';
            END;
        END LOOP;
    END;
    $$ LANGUAGE plpgsql;
    ```

    下列改進的程式碼範例使用 UPSERT 而非例外狀況處理來減少子交易用量：

    ```
    CREATE OR REPLACE FUNCTION process_user_data()
    RETURNS void AS $$
    DECLARE
        user_record RECORD;
    BEGIN
        FOR user_record IN SELECT * FROM users LOOP
            -- Use UPSERT to avoid exception handling
            INSERT INTO user_audit (user_id, action, timestamp)
            VALUES (user_record.id, 'processed', NOW())
            ON CONFLICT (user_id, action) 
            DO UPDATE SET timestamp = NOW();
            
            UPDATE users 
            SET last_processed = NOW() 
            WHERE id = user_record.id;
        END LOOP;
    END;
    $$ LANGUAGE plpgsql;
    ```  
**Example**  

    範例 2：STRICT 例外狀況處理常式

    下列程式碼範例顯示使用 NO\$1DATA\$1FOUND 處理的問題：

    ```
    CREATE OR REPLACE FUNCTION get_user_email(p_user_id INTEGER)
    RETURNS TEXT AS $$
    DECLARE
        user_email TEXT;
    BEGIN
        BEGIN
            -- STRICT causes an exception if no rows or multiple rows found
            SELECT email INTO STRICT user_email 
            FROM users 
            WHERE id = p_user_id;
            
            RETURN user_email;
            
        EXCEPTION
            WHEN NO_DATA_FOUND THEN
                RETURN 'Email not found';
        END;
    END;
    $$ LANGUAGE plpgsql;
    ```

    下列改進的程式碼範例使用 IF NOT FOUND 而非例外狀況處理來避免子交易：

    ```
    CREATE OR REPLACE FUNCTION get_user_email(p_user_id INTEGER)
    RETURNS TEXT AS $$
    DECLARE
        user_email TEXT;
    BEGIN
         SELECT email INTO user_email 
         FROM users 
         WHERE id = p_user_id;
            
         IF NOT FOUND THEN
             RETURN 'Email not found';
         ELSE
             RETURN user_email;
         END IF;
    END;
    $$ LANGUAGE plpgsql;
    ```
  + JDBC 驅動程式 – `autosave` 如果 參數設定為 `always`或 `conservative`，則 會在每次查詢之前產生儲存點。評估您的應用程式是否可以接受`never`設定。
  + PostgreSQL ODBC 驅動程式 (psqlODBC) — 回復層級設定 （用於陳述式層級回復） 會建立隱含儲存點，以啟用陳述式回復功能。評估您的應用程式是否可以接受交易層級或無轉返。
  + 檢查 ORM 交易組態
  + 考慮不需要儲存點的替代錯誤處理策略
+ **最佳化交易設計** – 重組交易，以避免過度巢狀化，並減少子交易溢位情況的可能性。
+ **減少長時間執行的交易** – 長時間執行的交易可以透過保留更長的子交易資訊來加劇子交易問題。監控績效詳情指標並設定 `idle_in_transaction_session_timeout` 參數以自動終止閒置交易。
+ 監控績效詳情指標 – 追蹤指標，包括 `idle_in_transaction_count`（處於交易狀態的閒置工作階段數） 和 `idle_in_transaction_max_time`（最長執行閒置交易的持續時間），以偵測長時間執行的交易。
+ 設定 `idle_in_transaction_session_timeout` – 在參數群組中設定此參數，以在指定的持續時間後自動終止閒置交易。
+ 主動監控 - 監控 的頻繁出現，`LWLock:SubtransBuffer`並`LWLock:SubtransSLRU`等待事件以偵測與交易相關的爭用，然後再變得至關重要。

# Timeout:PgSleep
<a name="wait-event.timeoutpgsleep"></a>

`Timeout:PgSleep` 事件表示伺服器程序已呼叫 `pg_sleep` 函數，正在等待睡眠逾時到期。

**Topics**
+ [支援的引擎版本](#wait-event.timeoutpgsleep.context.supported)
+ [等待時間增加的可能原因](#wait-event.timeoutpgsleep.causes)
+ [動作](#wait-event.timeoutpgsleep.actions)

## 支援的引擎版本
<a name="wait-event.timeoutpgsleep.context.supported"></a>

所有 RDS for PostgreSQL 版本都支援此等待事件資訊。

## 等待時間增加的可能原因
<a name="wait-event.timeoutpgsleep.causes"></a>

此等待事件表示應用程式、預存函數或使用者發出的 SQL 陳述式呼叫下列其中一一個函數：
+ `pg_sleep`
+ `pg_sleep_for`
+ `pg_sleep_until`

上述函數會延遲執行，直到經過指定的秒數。例如，`SELECT pg_sleep(1)` 會暫停 1 秒。如需詳細資訊，請參閱 PostgreSQL 文件中的[延遲執行](https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-DELAY)。

## 動作
<a name="wait-event.timeoutpgsleep.actions"></a>

找出執行 `pg_sleep` 函數的陳述式。判斷使用此函數是否適當。

# Timeout:VacuumDelay
<a name="wait-event.timeoutvacuumdelay"></a>

`Timeout:VacuumDelay` 事件表示已超過清空 I/O 的成本限制，並且清空程序已進入休眠狀態。清空操作會停止一段時間，長度為各自成本延遲參數中指定的持續時間，然後恢復其運作。對於手動清空命令，延遲是在 `vacuum_cost_delay` 參數中指定。對於自動清空常駐程式，延遲是在 `autovacuum_vacuum_cost_delay parameter.` 中指定。

**Topics**
+ [支援的引擎版本](#wait-event.timeoutvacuumdelay.context.supported)
+ [Context](#wait-event.timeoutvacuumdelay.context)
+ [等待時間增加的可能原因](#wait-event.timeoutvacuumdelay.causes)
+ [動作](#wait-event.timeoutvacuumdelay.actions)

## 支援的引擎版本
<a name="wait-event.timeoutvacuumdelay.context.supported"></a>

所有 RDS for PostgreSQL 版本都支援此等待事件資訊。

## Context
<a name="wait-event.timeoutvacuumdelay.context"></a>

PostgreSQL 同時具有自動清空常駐程式和手動清空命令。對於 RDS for PostgreSQL 資料庫執行個體，自動清空程序預設為「開啟」。手動清空命令是根據需要而使用，例如，用來清除失效元組的資料表或產生新的統計資料。

進行清空時，PostgreSQL 會在系統執行各種 I/O 操作時，使用內部計數器來追蹤預估的成本。當計數器達到成本限制參數所指定的值時，執行操作的程序休眠一段時間，長度為成本延遲參數中指定的短暫持續時間。然後，它會重設計數器並繼續操作。

清空程序具有可以用來調節資源耗用的參數。自動清空和手動清空命令具有自己的參數，用於設定成本限制值。它們還有自己的參數來指定成本延遲，這是達到限制時將清空置於休眠狀態的時間量。如此一來，成本延遲參數會當作資源耗用的限流機制運作。在下列清單中，您可以找到這些參數的描述。

**影響自動清空常駐程式限流的參數**
+ `[autovacuum\$1vacuum\$1cost\$1limit](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-LIMIT)` – 指定用於自動清空操作的成本限制值。增加此參數的設定可讓清空程序使用更多資源並減少 `Timeout:VacuumDelay` 等待事件。
+ `[autovacuum\$1vacuum\$1cost\$1delay](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-DELAY)` – 指定用於自動清空操作的成本延遲值。預設值為 2 毫秒。將延遲參數設為 0 會關閉限流機制，因此 `Timeout:VacuumDelay` 等待事件不會出現。

如需詳細資訊，請參閱 PostgreSQL 文件中的[自動資料清理](https://www.postgresql.org/docs/current/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-DELAY)。

**影響手動清空程序限流的參數**
+ `vacuum_cost_limit` – 清空程序進入休眠狀態的閾值。根據預設，限制為 200。此數字代表各種資源所需額外 I/O 的累計成本預估值。增加此值可減少 `Timeout:VacuumDelay` 等待事件的數量。
+ `vacuum_cost_delay` – 達到清空成本限制時，清空程序休眠的時間量。預設設定為 0，表示此功能已關閉。您可以將此值設為整數值，以指定開啟此功能的毫秒數，但建議您將其保留為預設設定。

如需 `vacuum_cost_delay` 參數的詳細資訊，請參閱 PostgreSQL 文件中的[資源耗用](https://www.postgresql.org/docs/current/runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-VACUUM-COST)。

若要進一步了解如何設定和使用自動清空搭配 RDS for PostgreSQL，請參閱 [在 Amazon RDS for PostgreSQL 上使用 PostgreSQL 自動清空](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.md)。

## 等待時間增加的可能原因
<a name="wait-event.timeoutvacuumdelay.causes"></a>

`Timeout:VacuumDelay` 會受到成本限制參數設定 (`vacuum_cost_limit`、`autovacuum_vacuum_cost_limit`) 與控制清空休眠持續時間的成本延遲參數 (`vacuum_cost_delay`、`autovacuum_vacuum_cost_delay`) 之間的平衡影響。提高成本限制參數值允許清空使用更多資源，然後再進入休眠狀態。這會導致更少的 `Timeout:VacuumDelay` 等待事件。增加其中一個延遲參數會導致 `Timeout:VacuumDelay` 等待事件更頻繁地發生，時段更長。

`autovacuum_max_workers` 參數設定也可以增加 `Timeout:VacuumDelay` 的數量。每個額外的自動清空工作者程序都有助於內部計數器機制，因此可以比使用單一自動清空工作者程序更快地達到限制。由於達到成本限制的速度更快，成本延遲會更頻繁地生效，造成更多的 `Timeout:VacuumDelay` 等待事件。如需詳細資訊，請參閱 PostgreSQL 文件中的 [autovacuum\$1max\$1worker](https://www.postgresql.org/docs/current/runtime-config-autovacuum.html#GUC-AUTOVACUUM-MAX-WORKERS)。

大型物件 (例如 500 GB 或更大) 也會引發此等待事件，因為清空可能需要一些時間才能完成處理大型物件。

## 動作
<a name="wait-event.timeoutvacuumdelay.actions"></a>

如果清空操作如預期完成，則不需要修補。換言之，此等待事件不一定指出問題。其表示清空將進入休眠一段時間，長度為延遲參數中指定的時段，以便資源可以套用到需要完成的其他程序。

如果您想要清空操作更快地完成，則可以降低延遲參數。這可以縮短清空休眠的時間。

# 使用 Amazon DevOps Guru 主動洞察，調校 RDS for PostgreSQL
<a name="PostgreSQL.Tuning_proactive_insights"></a>

DevOps Guru 主動洞察會偵測可能在 RDS for PostgreSQL 資料庫執行個體 上造成問題的狀況，並在發生問題前即讓您了解狀況。主動式洞察可以提醒您交易連線中長時間執行的閒置。如需在交易連線中對長時間執行閒置進行疑難排解的詳細資訊，請參閱 [資料庫在交易連線中長時間閒置](#proactive-insights.idle-txn)

DevOps Guru 可以執行下列動作：
+ 透過交叉檢查一般建議設定與您的資料庫設定，避免許多常見的資料庫問題。
+ 警告您機群內的重大問題，若未勾選，可能導致更嚴重的問題。
+ 提醒您新發現的問題。

每個主動洞察都包含問題原因分析和修正動作建議。

如需 Amazon DevOps Guru for Amazon RDS 的詳細資訊，請參閱 [使用 Amazon DevOps Guru for Amazon RDS 分析效能異常](devops-guru-for-rds.md)。

## 資料庫在交易連線中長時間閒置
<a name="proactive-insights.idle-txn"></a>

資料庫的連線已經超過 1800 秒都處在 `idle in transaction` 狀態。

**Topics**
+ [支援的引擎版本](#proactive-insights.idle-txn.context.supported)
+ [Context](#proactive-insights.idle-txn.context)
+ [造成此問題的可能原因](#proactive-insights.idle-txn.causes)
+ [動作](#proactive-insights.idle-txn.actions)
+ [相關指標](#proactive-insights.idle-txn.metrics)

### 支援的引擎版本
<a name="proactive-insights.idle-txn.context.supported"></a>

所有版本的 RDS for PostgreSQL 皆支援此洞察資訊。

### Context
<a name="proactive-insights.idle-txn.context"></a>

`idle in transaction` 狀態的交易可以擁有封鎖其他查詢的鎖定。也可以防止 `VACUUM` (包含自動清空) 清理無效資料列，導致索引或資料表膨脹，或導致交易 ID 包圍。

### 造成此問題的可能原因
<a name="proactive-insights.idle-txn.causes"></a>

尚未使用 COMMIT、ROLLBACK 或 END 命令，關閉以 BEGIN 或 START TRANSACTION 在互動式工作階段中啟動的交易。這會導致交易移至 `idle in transaction` 狀態。

### 動作
<a name="proactive-insights.idle-txn.actions"></a>

您可以透過查詢 `pg_stat_activity`，找出閒置的交易。

請在您的 SQL 用戶端中執行下列查詢，以列出 `idle in transaction` 狀態的所有連線，並按持續時間排序：

```
SELECT now() - state_change as idle_in_transaction_duration, now() - xact_start as xact_duration,* 
FROM  pg_stat_activity 
WHERE state  = 'idle in transaction'
AND   xact_start is not null
ORDER BY 1 DESC;
```

根據洞察的原因，我們會建議不同的動作。

**Topics**
+ [End 交易](#proactive-insights.idle-txn.actions.end-txn)
+ [終止連線](#proactive-insights.idle-txn.actions.end-connection)
+ [設定 idle\$1in\$1transaction\$1session\$1timeout 參數](#proactive-insights.idle-txn.actions.parameter)
+ [檢查 AUTOCOMMIT 狀態](#proactive-insights.idle-txn.actions.autocommit)
+ [檢查應用程式程式碼中的交易邏輯](#proactive-insights.idle-txn.actions.app-logic)

#### End 交易
<a name="proactive-insights.idle-txn.actions.end-txn"></a>

使用 BEGIN 或 START TRANSACTION 在互動式工作階段中啟動交易時，該筆交易會移至 `idle in transaction` 狀態。交易會保持在此狀態，直到您發出 COMMIT、ROLLBACK、END 命令結束交易，或完全斷開連線以轉返結束交易。

#### 終止連線
<a name="proactive-insights.idle-txn.actions.end-connection"></a>

使用以下查詢，終止與閒置交易的連線：

```
SELECT pg_terminate_backend(pid);
```

pid 是連線的程序 ID。

#### 設定 idle\$1in\$1transaction\$1session\$1timeout 參數
<a name="proactive-insights.idle-txn.actions.parameter"></a>

在新的參數群組中設定 `idle_in_transaction_session_timeout` 參數。設定此參數的優點在於，不需要手動介入即可終止長時間閒置的交易。如需此參數的詳細資訊，請參閱 [PostgreSQL 文件](https://www.postgresql.org/docs/current/runtime-config-client.html)。

當交易處於 idle\$1in\$1transaction 狀態超過指定時間時，PostgreSQL 日誌檔會在連線終止之後報告下列訊息。

```
FATAL: terminating connection due to idle in transaction timeout
```

#### 檢查 AUTOCOMMIT 狀態
<a name="proactive-insights.idle-txn.actions.autocommit"></a>

根據預設，AUTOCOMMIT 為啟用狀態。但是，若客戶端意外將其關閉，請確認重啟。
+ 在 psql 用戶端執行下列命令：

  ```
  postgres=> \set AUTOCOMMIT on
  ```
+ 在 pgadmin 中，從向下箭頭選擇 AUTOCOMMIT 選項以將其開啟。  
![\[在 pgadmin 中，選擇 AUTOCOMMIT 將其開啟。\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/images/apg-insight-pgadmin-autocommit.png)

#### 檢查應用程式程式碼中的交易邏輯
<a name="proactive-insights.idle-txn.actions.app-logic"></a>

調查應用程式邏輯，找出可能的問題。考慮下列動作：
+ 檢查 JDBC 自動遞交是否在您的應用程式中設為 true。另外，請考慮在程式碼中使用明確的 `COMMIT` 命令。
+ 檢查錯誤處理邏輯，確認其是否會在發生錯誤後關閉交易。
+ 檢查交易開啟時，您的應用程式是否需要長時間處理查詢傳回的資料列。若是如此，請考慮對應用程式進行編碼，在處理資料列之前關閉交易。
+ 檢查交易是否包含許多長時間執行的操作。若是如此，請將單一交易分割為多筆交易。

### 相關指標
<a name="proactive-insights.idle-txn.metrics"></a>

下列 PI 指標與此洞察相關：
+ idle\$1in\$1transaction\$1count - 處於 `idle in transaction` 狀態的工作階段數量。
+ idle\$1in\$1transaction\$1max\$1time - 處於 `idle in transaction` 狀態的最長時間執行交易。

# 搭配 Amazon RDS for PostgreSQL 使用 PostgreSQL 擴充功能
<a name="Appendix.PostgreSQL.CommonDBATasks.Extensions"></a>

您可安裝各種擴充功能和模組來擴展 PostgreSQL 的功能。例如，若要使用空間資料，您可以安裝和使用 PostGIS 擴充功能。如需詳細資訊，請參閱 [使用 PostGIS 擴充功能管理空間資料](Appendix.PostgreSQL.CommonDBATasks.PostGIS.md)。另一個例子是，如果要改進極大型資料表的資料輸入，則可以考慮使用 `pg_partman` 擴充功能對資料進行分區。如需詳細資訊，請參閱 [使用 pg\$1partman 擴充功能來管理 PostgreSQL 分割區](PostgreSQL_Partitions.md)。

**注意**  
RDS for PostgreSQL 透過 `pg_tle` 延伸模組支援 PostgreSQL 的受信任語言延伸模組，您可以將其新增至資料庫執行個體。透過使用此延伸模組，開發人員可以在安全環境中建立自己的 PostgreSQL 延伸模組，這會簡化設定和組態需求。若要了解支援 `pg_tle` 延伸模組的 RDS for PostgreSQL 版本以及詳細資訊，請參閱 [使用適用於 PostgreSQL 的受信任語言延伸模組](PostgreSQL_trusted_language_extension.md)。

在某些情況下，您可以將特定模組新增至 RDS for PostgreSQL 資料庫叢集的自訂資料庫叢集參數群組中的 `shared_preload_libraries` 清單，而不是安裝延伸模組。一般而言，預設資料庫叢集參數群組只會載入 `pg_stat_statements`，但有數個其他模組可供新增至清單。例如，您可以新增 `pg_cron` 模組來新增排程功能，如[使用 PostgreSQL pg\$1cron 擴充功能排程維護](PostgreSQL_pg_cron.md)中所詳述。另一個範例是，您可以載入 `auto_explain` 模組來記錄查詢執行計劃。若要進一步了解，請參閱 AWS 知識中心的[記錄查詢的執行計畫](https://aws.amazon.com/premiumsupport/knowledge-center/rds-postgresql-tune-query-performance/#)。

根據 RDS for PostgreSQL 版本，安裝擴充功能可能需要 `rds_superuser` 許可權限，如下：
+ 若為 RDS for PostgreSQL 第 12 版和更早版本，安裝擴充功能需要 `rds_superuser` 權限。
+ 若為 RDS for PostgreSQL 第 13 版和更新版本，在給定資料庫執行個體上具建立許可權限的使用者 (角色) 可以安裝並使用任何*信任擴充功能*。如需信任擴充功能的清單，請參閱 [PostgreSQL 可信任延伸](PostgreSQL.Concepts.General.FeatureSupport.Extensions.md#PostgreSQL.Concepts.General.Extensions.Trusted)。

您還可在 `rds.allowed_extensions` 參數中列出擴充功能，精確指定可在 RDS for PostgreSQL 資料庫執行個體上安裝的擴充功能。如需詳細資訊，請參閱[限制安裝 PostgreSQL 擴充功能](PostgreSQL.Concepts.General.FeatureSupport.Extensions.md#PostgreSQL.Concepts.General.FeatureSupport.Extensions.Restriction)。

若要進一步了解 `rds_superuser` 角色，請參閱 [了解 PostgreSQL 角色和許可](Appendix.PostgreSQL.CommonDBATasks.Roles.md)。

**Topics**
+ [使用 Orafce 擴充功能中的函數](Appendix.PostgreSQL.CommonDBATasks.orafce.md)
+ [使用 PostgreSQL 的 Amazon RDS 委派延伸模組支援](RDS_delegated_ext.md)
+ [使用 pg\$1partman 擴充功能來管理 PostgreSQL 分割區](PostgreSQL_Partitions.md)
+ [使用 PgAudit 記錄資料庫活動](Appendix.PostgreSQL.CommonDBATasks.pgaudit.md)
+ [使用 PostgreSQL pg\$1cron 擴充功能排程維護](PostgreSQL_pg_cron.md)
+ [使用 pglogical 跨執行個體同步資料](Appendix.PostgreSQL.CommonDBATasks.pglogical.md)
+ [使用 pgactive 來支援主動-主動式複寫](Appendix.PostgreSQL.CommonDBATasks.pgactive.md)
+ [使用 pg\$1repack 擴充功能減少資料表和索引膨脹](Appendix.PostgreSQL.CommonDBATasks.pg_repack.md)
+ [升級和使用 PLV8 擴充功能](PostgreSQL.Concepts.General.UpgradingPLv8.md)
+ [使用 PL/Rust 以 Rust 語言撰寫 PostgreSQL 函數](PostgreSQL.Concepts.General.Using.PL_Rust.md)
+ [使用 PostGIS 擴充功能管理空間資料](Appendix.PostgreSQL.CommonDBATasks.PostGIS.md)

# 使用 Orafce 擴充功能中的函數
<a name="Appendix.PostgreSQL.CommonDBATasks.orafce"></a>

Orafce 擴充功能提供的函數和運算子，可以模擬來自 Oracle 資料庫的函數和軟體套件的子集合。Orafce 擴充功能可讓您更輕易地將 Oracle 應用程式移植到 PostgreSQL。RDS for PostgreSQL 9.6.6 版及更高版本支援此擴充功能。如需有關 Orafce 的詳細資訊，請參閱 GitHub 上的 [Orafce](https://github.com/orafce/orafce)。

**注意**  
RDS for PostgreSQL 不支援 `utl_file` 套件，該套件屬於 Orafce 擴充功能的一部分。這是因為 `utl_file` 結構描述函式雖能夠在作業系統的文字檔上進行讀取及寫入操作，但必須擁有基礎主機的超級使用者存取權，才能執行此類操作。RDS for PostgreSQL 為受管服務，不提供主機存取權。

**使用 Orafce 擴充功能**

1. 使用您用來建立資料庫執行個體的主要使用者名稱，來連線至資料庫執行個體。

   如果您想要在相同的資料庫執行個體中為不同的資料庫開啟 Orafce，請使用 `/c dbname` psql 命令。使用此命令，您可以在啟動連線後從主要資料庫進行變更。

1. 使用 `CREATE EXTENSION` 陳述式開啟 Orafce 擴充功能。

   ```
   CREATE EXTENSION orafce;
   ```

1. 使用 `ALTER SCHEMA` 陳述式將 oracle 結構描述的擁有權移轉至 rds\$1superuser 角色。

   ```
   ALTER SCHEMA oracle OWNER TO rds_superuser;
   ```

   如果您想要查看 oracle 結構描述的擁有者清單，請使用 `\dn` psql 命令。

# 使用 PostgreSQL 的 Amazon RDS 委派延伸模組支援
<a name="RDS_delegated_ext"></a>

使用 PostgreSQL 的 Amazon RDS 委派延伸模組支援，您可以將延伸模組管理委派給非 `rds_superuser` 的使用者。系統會透過此委派延伸模組支援，建立名為 `rds_extension` 的新角色，而您必須將此角色指派給使用者以管理其他延伸模組。此角色可以建立、更新和捨棄延伸模組。

您可在 `rds.allowed_extensions` 參數中列出延伸模組，藉以指定可在 RDS 資料庫執行個體上安裝的延伸模組。如需詳細資訊，請參閱[將 PostgreSQL 延伸模組與 Amazon RDS for PostgreSQL 搭配使用](https://docs.aws.amazon.com//AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Extensions.html)。

您可以使用 `rds.allowed_delegated_extensions` 參數，限制可由具有 `rds_extension` 角色的使用者所管理的可用延伸模組清單。

您可在下列版本中取得委派的延伸模組支援：
+ 所有更高版本
+ 16.4 和更高的第 16 版
+ 15.8 和更高的第 15 版
+ 14.13 和更高的第 14 版
+ 13.16 和更高的第 13 版
+ 12.20 和更高的第 12 版

**Topics**
+ [為使用者開啟委派延伸模組支援](#RDSPostgreSQL.delegated_ext_mgmt)
+ [在 PostgreSQL 的 RDS 委派延伸模組支援中使用的組態](#RDSPostgreSQL.delegated_ext_config)
+ [關閉委派延伸模組的支援](#RDSPostgreSQL.delegated_ext_disable)
+ [使用 Amazon RDS 委派延伸模組支援的優點](#RDSPostgreSQL.delegated_ext_benefits)
+ [PostgreSQL 的 Amazon RDS 委派延伸模組支援限制](#RDSPostgreSQL.delegated_ext_limit)
+ [特定延伸模組所需的許可](#RDSPostgreSQL.delegated_ext_perm)
+ [安全考量](#RDSPostgreSQL.delegated_ext_sec)
+ [已停用捨棄延伸模組層疊](#RDSPostgreSQL.delegated_ext_drop)
+ [可使用委派延伸模組支援新增的延伸模組範例](#RDSPostgreSQL.delegated_ext_support)

## 為使用者開啟委派延伸模組支援
<a name="RDSPostgreSQL.delegated_ext_mgmt"></a>

您必須執行下列動作，才能將延伸模組支援委派給使用者：

1. **將 `rds_extension` 角色授予使用者**：以 `rds_superuser` 身分連線至資料庫，以及執行下列命令：

   ```
   Postgres => grant rds_extension to user_name;
   ```

1. **設定可供委派使用者管理的延伸模組清單**：`rds.allowed_delegated_extensions` 可讓您在資料庫叢集參數中使用 `rds.allowed_extensions` 指定可用延伸模組子集。您可以在下列其中一個層級執行此操作：
   + 在叢集或執行個體參數群組中，透過 AWS 管理主控台 或 API。如需詳細資訊，請參閱[Amazon RDS 的參數群組](USER_WorkingWithParamGroups.md)。
   + 在資料庫層級使用以下命令：

     ```
     alter database database_name set rds.allowed_delegated_extensions = 'extension_name_1,
                         extension_name_2,...extension_name_n';
     ```
   + 在使用者層級使用以下命令：

     ```
     alter user user_name set rds.allowed_delegated_extensions = 'extension_name_1,
                         extension_name_2,...extension_name_n';
     ```
**注意**  
變更 `rds.allowed_delegated_extensions` 動態參數後，您就不需要重新啟動資料庫。

1. **允許委派使用者存取在延伸模組建立程序期間建立的物件**：某些延伸模組會建立需要授予額外許可的物件，才能讓具有 `rds_extension` 角色的使用者存取這些物件。`rds_superuser` 必須向委派的使用者授予對那些物件的存取權。其中一個選項是使用事件觸發，自動將許可授予委派的使用者。

   **事件觸發範例**

   如要允許具備 `rds_extension` 的委派使用者使用延伸模組，而這些延伸模組需要針對延伸模組建立的物件設定許可，您可以自訂下列事件觸發範例，並僅新增您希望委派使用者能夠存取完整功能的延伸模組。系統可以在 template1 (預設範本) 建立此事件觸發，因此從 template1 建立的所有資料庫都會具有該事件觸發。當委派的使用者安裝此延伸模組時，此觸發會針對延伸模組建立的物件自動授予擁有權。

   ```
   CREATE OR REPLACE FUNCTION create_ext()
   
     RETURNS event_trigger AS $$
   
   DECLARE
   
     schemaname TEXT;
     databaseowner TEXT;
   
     r RECORD;
   
   BEGIN
   
     IF tg_tag = 'CREATE EXTENSION' and current_user != 'rds_superuser' THEN
       RAISE NOTICE 'SECURITY INVOKER';
       RAISE NOTICE 'user: %', current_user;
       FOR r IN SELECT * FROM pg_catalog.pg_event_trigger_ddl_commands()
       LOOP
           CONTINUE WHEN r.command_tag != 'CREATE EXTENSION' OR r.object_type != 'extension';
   
           schemaname = (
               SELECT n.nspname
               FROM pg_catalog.pg_extension AS e
               INNER JOIN pg_catalog.pg_namespace AS n
               ON e.extnamespace = n.oid
               WHERE e.oid = r.objid
           );
   
           databaseowner = (
               SELECT pg_catalog.pg_get_userbyid(d.datdba)
               FROM pg_catalog.pg_database d
               WHERE d.datname = current_database()
           );
           RAISE NOTICE 'Record for event trigger %, objid: %,tag: %, current_user: %, schema: %, database_owenr: %', r.object_identity, r.objid, tg_tag, current_user, schemaname, databaseowner;
           IF r.object_identity = 'address_standardizer_data_us' THEN
               EXECUTE pg_catalog.format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.us_gaz TO %I WITH GRANT OPTION;', schemaname, databaseowner);
               EXECUTE pg_catalog.format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.us_lex TO %I WITH GRANT OPTION;', schemaname, databaseowner);
               EXECUTE pg_catalog.format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.us_rules TO %I WITH GRANT OPTION;', schemaname, databaseowner);
           ELSIF r.object_identity = 'dict_int' THEN
               EXECUTE pg_catalog.format('ALTER TEXT SEARCH DICTIONARY %I.intdict OWNER TO %I;', schemaname, databaseowner);
           ELSIF r.object_identity = 'pg_partman' THEN
               EXECUTE pg_catalog.format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.part_config TO %I WITH GRANT OPTION;', schemaname, databaseowner);
               EXECUTE pg_catalog.format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.part_config_sub TO %I WITH GRANT OPTION;', schemaname, databaseowner);
               EXECUTE pg_catalog.format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.custom_time_partitions TO %I WITH GRANT OPTION;', schemaname, databaseowner);
           ELSIF r.object_identity = 'postgis_topology' THEN
               EXECUTE pg_catalog.format('GRANT SELECT, UPDATE, INSERT, DELETE ON ALL TABLES IN SCHEMA topology TO %I WITH GRANT OPTION;', databaseowner);
               EXECUTE pg_catalog.format('GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA topology TO %I WITH GRANT OPTION;', databaseowner);
               EXECUTE pg_catalog.format('GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA topology TO %I WITH GRANT OPTION;', databaseowner);
               EXECUTE pg_catalog.format('GRANT USAGE ON SCHEMA topology TO %I WITH GRANT OPTION;', databaseowner);
           END IF;
       END LOOP;
     END IF;
   END;
   $$ LANGUAGE plpgsql SECURITY DEFINER;
   
   CREATE EVENT TRIGGER log_create_ext ON ddl_command_end EXECUTE PROCEDURE create_ext();
   ```

## 在 PostgreSQL 的 RDS 委派延伸模組支援中使用的組態
<a name="RDSPostgreSQL.delegated_ext_config"></a>


| 組態名稱 | Description | 預設值 | 備註 | 誰可以修改或授予許可 | 
| --- | --- | --- | --- | --- | 
| `rds.allowed_delegated_extensions` | 此參數會限制 rds\$1extension 角色可在資料庫中管理的延伸模組。其必須是 rds.allowed\$1extensions 的子集。 | 空字串 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/RDS_delegated_ext.html) 若要進一步了解如何設定此參數，請參閱[為使用者開啟委派延伸模組支援](#RDSPostgreSQL.delegated_ext_mgmt)。 | rds\$1superuser | 
| `rds.allowed_extensions` | 此參數可讓客戶限制 RDS 資料庫執行個體中可安裝的延伸模組。如需詳細資訊，請參閱[限制安裝 PostgreSQL 延伸模組](https://docs.aws.amazon.com//AmazonRDS/latest/UserGuide/CHAP_PostgreSQL.html#PostgreSQL.Concepts.General.FeatureSupport.Extensions.Restriction)。 | "\$1" | 根據預設，此參數會設為「\$1」，這表示具有必要權限的使用者都能夠建立 RDS for PostgreSQL 和 Aurora PostgreSQL 上支援的所有延伸模組。 空白表示無法在 RDS 資料庫執行個體中安裝任何延伸模組。 | 管理員 | 
| `rds-delegated_extension_allow_drop_cascade` | 此參數會控制具有 `rds_extension` 的使用者是否能使用層疊選項捨棄延伸模組。 | off | 根據預設，`rds-delegated_extension_allow_drop_cascade` 會設定為 `off`。這表示具有 `rds_extension` 的使用者無法使用層疊選項捨棄延伸模組。 若要授予該能力，則應將 `rds.delegated_extension_allow_drop_cascade` 參數設為 `on`。 | rds\$1superuser | 

## 關閉委派延伸模組的支援
<a name="RDSPostgreSQL.delegated_ext_disable"></a>

**部分關閉**  
委派的使用者無法建立新的延伸模組，但仍可以更新現有的延伸模組。
+ 將資料庫叢集參數群組中的 `rds.allowed_delegated_extensions` 重設為預設值。
+ 在資料庫層級使用以下命令：

  ```
  alter database database_name reset rds.allowed_delegated_extensions;
  ```
+ 在使用者層級使用以下命令：

  ```
  alter user user_name reset rds.allowed_delegated_extensions;
  ```

**完全關閉**  
從使用者撤銷 `rds_extension` 角色會將使用者還原為標準許可。使用者無法再建立、更新或捨棄延伸模組。

```
postgres => revoke rds_extension from user_name;
```

## 使用 Amazon RDS 委派延伸模組支援的優點
<a name="RDSPostgreSQL.delegated_ext_benefits"></a>

藉由使用 PostgreSQL 的 Amazon RDS 委派延伸模組支援，您就可以將延伸模組管理安全地委派給不具備 `rds_superuser` 角色的使用者。此功能提供下列優勢：
+ 您可以輕鬆地將延伸模組管理委派給所選的使用者。
+ 這不需要 `rds_superuser` 角色。
+ 提供支援相同資料庫叢集中不同資料庫不同延伸模組集的能力。

## PostgreSQL 的 Amazon RDS 委派延伸模組支援限制
<a name="RDSPostgreSQL.delegated_ext_limit"></a>
+ 在延伸模組建立程序期間建立的物件可能需要額外的權限，延伸模組才能正常運作。
+ 根據預設，委派的延伸模組使用者無法管理某些延伸模組，包括：`log_fdw`、`pg_cron`、`pg_tle`、`pgactive``pglogical`、`postgis_raster`、`postgis_tiger_geocoder`、`postgis_topology`。

## 特定延伸模組所需的許可
<a name="RDSPostgreSQL.delegated_ext_perm"></a>

為了建立、使用或更新下列延伸模組，委派的使用者應具備下列功能、資料表和結構描述的必要權限。


| 需要擁有權或許可的延伸模組 | 函式 | 表格 | 結構描述 | 文字搜尋字典 | Comment | 
| --- | --- | --- | --- | --- | --- | 
| address\$1standardizer\$1data\$1us | 無 | us\$1gaz、us\$1lex、us\$1lex、I.us\$1rules | 無 | 無 | 無 | 
| amcheck | bt\$1index\$1check、bt\$1index\$1parent\$1check | 無 | 無 | 無 | 無 | 
| dict\$1int | 無 | 無 | 無 | intdict | 無 | 
| pg\$1partman | 無 | custom\$1time\$1partitions、part\$1config、part\$1config\$1sub | 無 | 無 | 無 | 
| pg\$1stat\$1statements | 無 | 無 | 無 | 無 | 無 | 
| PostGIS | st\$1tileenvelope | spatial\$1ref\$1sys | 無 | 無 | 無 | 
| postgis\$1raster | 無 | 無 | 無 | 無 | 無 | 
| postgis\$1topology | 無 | 拓撲、層 | 拓撲 | 無 | 委派使用者必須是資料庫擁有者 | 
| log\$1fdw | create\$1foreign\$1table\$1for\$1log\$1file | 無 | 無 | 無 | 無 | 
| rds\$1tools | role\$1password\$1encryption\$1type | 無 | 無 | 無 | 無 | 
| postgis\$1tiger\$1geocoder | 無 | geocode\$1settings\$1default、geocode\$1settings | tiger | 無 | 無 | 
| pg\$1freespacemap | pg\$1freespace | 無 | 無 | 無 | 無 | 
| pg\$1visibility | pg\$1visibility | 無 | 無 | 無 | 無 | 

## 安全考量
<a name="RDSPostgreSQL.delegated_ext_sec"></a>

 請記住，具有 `rds_extension` 角色的使用者將能夠在其具有連線權限的所有資料庫上管理延伸模組。若需讓委派使用者管理單一資料庫的延伸模組，良好做法是撤銷每個資料庫上公有的所有權限，然後明確將該特定資料庫的連線權限授予委派的使用者。

 有多種延伸模組，使用者可透過這些延伸模組從多個資料庫存取資訊。在將這些延伸模組新增至 `rds.allowed_delegated_extensions` 前，請確定您授予 `rds_extension` 的使用者具有跨資料庫功能。例如，`postgres_fdw` 和 `dblink` 會提供在相同執行個體或遠端執行個體上跨資料庫查詢的功能。`log_fdw` 會讀取適用於執行個體中所有資料庫的 postgres 引擎日誌檔案，可能包含來自多個資料庫的緩慢查詢或錯誤訊息。`pg_cron` 會在資料庫執行個體上執行排程背景任務，並可將任務設定為在不同的資料庫中執行。

## 已停用捨棄延伸模組層疊
<a name="RDSPostgreSQL.delegated_ext_drop"></a>

 具有 `rds_extension` 角色的使用者是否能捨棄具有層疊選項的延伸模組，由 `rds.delegated_extension_allow_drop_cascade` 參數所控制。根據預設，`rds-delegated_extension_allow_drop_cascade` 會設定為 `off`。如以下查詢所示，這表示具有 `rds_extension` 角色的使用者不能使用層疊選項捨棄延伸模組。

```
DROP EXTENSION CASCADE;
```

因為這會自動捨棄相依於延伸模組的物件，進而捨棄所有相依於這些物件的物件。嘗試使用層疊選項將導致錯誤。

 若要授予該能力，則應將 `rds.delegated_extension_allow_drop_cascade` 參數設為 `on`。

 變更 `rds.delegated_extension_allow_drop_cascade` 動態參數不需要重新啟動資料庫。您可以在以下其中一個層級執行此操作：
+ 在叢集或執行個體參數群組中，透過 AWS 管理主控台 或 API。
+ 在資料庫層級使用下列命令：

  ```
  alter database database_name set rds.delegated_extension_allow_drop_cascade = 'on';
  ```
+ 在使用者層級使用下列命令：

  ```
  alter role tenant_user set rds.delegated_extension_allow_drop_cascade = 'on';
  ```

## 可使用委派延伸模組支援新增的延伸模組範例
<a name="RDSPostgreSQL.delegated_ext_support"></a>
+ `rds_tools`

  ```
  extension_test_db=> create extension rds_tools;
  CREATE EXTENSION
  extension_test_db=> SELECT * from rds_tools.role_password_encryption_type() where rolname = 'pg_read_server_files';
  ERROR: permission denied for function role_password_encryption_type
  ```
+ `amcheck`

  ```
  extension_test_db=> CREATE TABLE amcheck_test (id int);
  CREATE TABLE
  extension_test_db=> INSERT INTO amcheck_test VALUES (generate_series(1,100000));
  INSERT 0 100000
  extension_test_db=> CREATE INDEX amcheck_test_btree_idx ON amcheck_test USING btree (id);
  CREATE INDEX
  extension_test_db=> create extension amcheck;
  CREATE EXTENSION
  extension_test_db=> SELECT bt_index_check('amcheck_test_btree_idx'::regclass);
  ERROR: permission denied for function bt_index_check
  extension_test_db=> SELECT bt_index_parent_check('amcheck_test_btree_idx'::regclass);
  ERROR: permission denied for function bt_index_parent_check
  ```
+ `pg_freespacemap`

  ```
  extension_test_db=> create extension pg_freespacemap;
  CREATE EXTENSION
  extension_test_db=> SELECT * FROM pg_freespace('pg_authid');
  ERROR: permission denied for function pg_freespace
  extension_test_db=> SELECT * FROM pg_freespace('pg_authid',0);
  ERROR: permission denied for function pg_freespace
  ```
+ `pg_visibility`

  ```
  extension_test_db=> create extension pg_visibility;
  CREATE EXTENSION
  extension_test_db=> select * from pg_visibility('pg_database'::regclass);
  ERROR: permission denied for function pg_visibility
  ```
+ `postgres_fdw`

  ```
  extension_test_db=> create extension postgres_fdw;
  CREATE EXTENSION
  extension_test_db=> create server myserver foreign data wrapper postgres_fdw options (host 'foo', dbname 'foodb', port '5432');
  ERROR: permission denied for foreign-data wrapper postgres_fdw
  ```

# 使用 pg\$1partman 擴充功能來管理 PostgreSQL 分割區
<a name="PostgreSQL_Partitions"></a>

PostgreSQL 表格分割區提供了用於高性能處理資料輸入和報告的框架。對需要非常快速輸入大量資料的資料庫使用分割區。分割區還提供了更快的大型表格查詢。分割區有助於維護資料，而不會影響資料庫執行個體，因為它需要較少的輸入/輸出資源。

透過使用分割區，您可以將資料分割為自訂大小的區塊進行處理。例如，您可以分割時間序列資料，例如每小時、每日、每週、每月、每季、年度、自訂或以上任何組合。對於時間序列資料範例，如果您依小時分割資料表，則每個分割區都將包含一小時的資料。如果您依每日分割時間序列資料表，則每個分割區將保存一天的資料，依此類推。分割區索引鍵控制分割區的大小。

當您在分割表格上使用 `INSERT` 或 `UPDATE` SQL 命令時，資料庫引擎會將資料路由至適當的分割區。儲存資料的 PostgreSQL 表格分割區是主表格的子表格。

在資料庫查詢讀取期間，PostgreSQL 最佳化器會檢查查詢的 `WHERE` 子句，如果可能的話，將資料庫掃描導向僅相關的分割區。

從 10 版開始，PostgreSQL 使用宣告式分割來實作資料表分割區。這也被稱為原生 PostgreSQL 分割區。在 PostgreSQL 10 版之前，您已使用觸發器來實作分割區。

PostgreSQL 表格分割區提供下列功能：
+ 隨時建立新的分割區。
+ 可變的分割區範圍。
+ 使用資料定義語言 (DDL) 陳述式的可分離和可重新連接分割區。

  例如，可拆分的分割區對於從主磁碟分割區移除歷史資料，但保留歷史資料以供分析來說十分實用。
+ 新的分割區會繼承父資料庫表格屬性，包括以下各項：
  + 索引
  + 主索引鍵，其中必須包含分割區索引鍵資料欄
  + 外部索引鍵
  + 檢查限制
  + 參考
+ 建立完整資料表或每個特定分割區的索引。

您無法變更個別分割區的結構描述。不過，您可以變更父資料表格 (例如新增新資料欄)，此表格會傳播到分割區。

**Topics**
+ [PostgreSQL pg\$1partman 擴充功能概述](#PostgreSQL_Partitions.pg_partman)
+ [啟用 pg\$1partman 擴充功能](#PostgreSQL_Partitions.enable)
+ [使用 create\$1parent 函數設定分割區](#PostgreSQL_Partitions.create_parent)
+ [使用 run\$1maintenance\$1proc 函數來設定分割區維護](#PostgreSQL_Partitions.run_maintenance_proc)

## PostgreSQL pg\$1partman 擴充功能概述
<a name="PostgreSQL_Partitions.pg_partman"></a>

您可以使用 PostgreSQL `pg_partman` 擴充功能，以自動化資料表分割區的建立和維護。如需更多一般資訊，請參閱 `pg_partman` 文件中的 [PG 分割區管理員](https://github.com/pgpartman/pg_partman)。

**注意**  
RDS for PostgreSQL 版本 12.5 及更新版本支援此 `pg_partman` 擴充功能。

您可以使用下列設定來設定 `pg_partman`，而不必手動建立每個分割區：
+ 要分割的表格
+ 分割區類型
+ 分割區索引鍵
+ 分割區間隔
+ 分割區預先建立與管理選項

建立 PostgreSQL 分割區資料表之後，您可以透過呼叫 `create_parent` 函數，使用 `pg_partman` 進行註冊。這樣做會根據您傳遞給函數的參數來建立必要的分割區。

`pg_partman` 擴充功能還提供 `run_maintenance_proc` 函數，您可以按排程呼叫它以自動管理分割區。為了確保視需要建立適當的分割區，可以排程此函數定期執行 (例如每小時)。您還可以確保自動捨棄分割區。

## 啟用 pg\$1partman 擴充功能
<a name="PostgreSQL_Partitions.enable"></a>

如果您要管理相同 PostgreSQL 資料庫執行個體內多個資料庫的分割區，則必須分別為每個資料庫啟用 `pg_partman` 擴充功能。若要啟用特定資料庫的 `pg_partman` 擴充功能，請建立分割區維護結構描述，然後建立 `pg_partman` 擴充功能，如下所示。

```
CREATE SCHEMA partman;
CREATE EXTENSION pg_partman WITH SCHEMA partman;
```

**注意**  
若要建立 `pg_partman` 擴充功能，請確定您具有 `rds_superuser` 權限。

如果您收到下列錯誤訊息，請將`rds_superuser`權限授與帳戶或使用您的超級使用者帳戶。

```
ERROR: permission denied to create extension "pg_partman"
HINT: Must be superuser to create this extension.
```

若要授予 `rds_superuser` 權限，請連線至您的超級使用者帳戶並執行下列命令。

```
GRANT rds_superuser TO user-or-role;
```

以顯示使用 pg\$1partman 擴充功能舉例，我們使用下面的範例資料庫表和分割區。此資料庫使用以時間戳記為基礎的分割表格。結構描述`data_mart`包含一個名為`events`的表格和一個名為`created_at`的欄。下列設定包含在`events`表格中：
+  主索引鍵`event_id`和`created_at`，必須有用於引導分割區的欄。
+ 強制執行`ck_valid_operation`表格欄值的檢查約束`operation`。
+ 兩個外鍵，其中一個（`fk_orga_membership)`）指向外部表格`organization`，另一個（`fk_parent_event_id`）是自引用的外鍵。
+ 兩個索引，其中一個（`idx_org_id`）用於外鍵，另一個（`idx_event_type`）用於事件類型。

下列 DDL 陳述式會建立這些物件，這些物件會自動包含在每個分割區上。

```
CREATE SCHEMA data_mart;
CREATE TABLE data_mart.organization ( org_id BIGSERIAL,
        org_name TEXT,
        CONSTRAINT pk_organization PRIMARY KEY (org_id)  
    );

CREATE TABLE data_mart.events(
        event_id        BIGSERIAL, 
        operation       CHAR(1), 
        value           FLOAT(24), 
        parent_event_id BIGINT, 
        event_type      VARCHAR(25), 
        org_id          BIGSERIAL, 
        created_at      timestamp, 
        CONSTRAINT pk_data_mart_event PRIMARY KEY (event_id, created_at), 
        CONSTRAINT ck_valid_operation CHECK (operation = 'C' OR operation = 'D'), 
        CONSTRAINT fk_orga_membership 
            FOREIGN KEY(org_id) 
            REFERENCES data_mart.organization (org_id),
        CONSTRAINT fk_parent_event_id 
            FOREIGN KEY(parent_event_id, created_at) 
            REFERENCES data_mart.events (event_id,created_at)
    ) PARTITION BY RANGE (created_at);

CREATE INDEX idx_org_id     ON  data_mart.events(org_id);
CREATE INDEX idx_event_type ON  data_mart.events(event_type);
```



## 使用 create\$1parent 函數設定分割區
<a name="PostgreSQL_Partitions.create_parent"></a>

啟用 `pg_partman` 擴充功能之後，可以使用此 `create_parent` 函數來設定在分割維護結構描述內的分割區。以下範例使用在 `events` 中建立的 [啟用 pg\$1partman 擴充功能使用 run\$1maintenance\$1proc 函數來設定分割區維護](#PostgreSQL_Partitions.enable) 資料表範例。如下所示呼叫 `create_parent` 函數。

```
SELECT partman.create_parent( 
 p_parent_table => 'data_mart.events',
 p_control      => 'created_at',
 p_type         => 'range',
 p_interval     => '1 day',
 p_premake      => 30);
```

參數如下：
+ `p_parent_table` – 父項分割表格。此表必須已經存在，並且完全符合資格 (包括結構描述)。
+ `p_control` – 分割區依據的欄。資料類型必須是整數或以時間為基礎。
+ `p_type` – 類型可以是 `'range'` 或 `'list'`。
+ `p_interval` – 每個分割區的時間間隔或整數範圍。範例值包括 `1 day`、`1 hour` 等。
+ `p_premake` – 預先建立以支援新插入的分割區數目。

如需 `create_parent` 函數的完整描述，請參閱 `pg_partman` 文件中的[建立函數](https://github.com/pgpartman/pg_partman/blob/master/doc/pg_partman.md#user-content-creation-functions)。

## 使用 run\$1maintenance\$1proc 函數來設定分割區維護
<a name="PostgreSQL_Partitions.run_maintenance_proc"></a>

您可以執行分割區維護作業以自動建立新的分割區、分離分割區或移除舊的分割區。分割區維護依賴 `pg_partman` 擴充功能的 `run_maintenance_proc` 函數和 `pg_cron` 擴充功能，它們可以啟動內部排程器。`pg_cron`排程器會自動執行資料庫中定義的 SQL 陳述式、函數和程序。

下列範例使用中建立於`events`中的[啟用 pg\$1partman 擴充功能使用 run\$1maintenance\$1proc 函數來設定分割區維護](#PostgreSQL_Partitions.enable)表格範例，將分割區維護作業設定為自動執行。作為必要條件，將 `pg_cron` 新增至資料庫執行個體的參數群組中的 `shared_preload_libraries` 參數。

```
CREATE EXTENSION pg_cron;

UPDATE partman.part_config 
SET infinite_time_partitions = true,
    retention = '3 months', 
    retention_keep_table=true 
WHERE parent_table = 'data_mart.events';
SELECT cron.schedule('@hourly', $$CALL partman.run_maintenance_proc()$$);
```

您可以在下面找到上述範例的逐步說明：

1. 修改與資料庫執行個體關聯的參數群組，並新增`pg_cron`至`shared_preload_libraries`參數值。此變更需要重新啟動資料庫執行個體才能生效。如需詳細資訊，請參閱 [修改 Amazon RDS 中的資料庫參數群組中的參數](USER_WorkingWithParamGroups.Modifying.md)。

1. 使用具有 `CREATE EXTENSION pg_cron;` 許可的帳戶執行命令 `rds_superuser`。這會啟用 `pg_cron` 擴充功能。如需詳細資訊，請參閱 [使用 PostgreSQL pg\$1cron 擴充功能排程維護](PostgreSQL_pg_cron.md)。

1. 執行命令 `UPDATE partman.part_config` 以調整 `data_mart.events` 資料表的 `pg_partman` 設定。

1. 執行 `SET` . . . 命令 以使用這些子句設定 `data_mart.events` 資料表：

   1. `infinite_time_partitions = true,` – 將表格設定為能夠沒有任何限制，自動建立新的分割區。

   1. `retention = '3 months',` – 將表格設定為最多保留三個月。

   1. `retention_keep_table=true `– 設定資料表，以便在保留期限到期時，資料表不會自動刪除。相反地，比保留期間還舊的分割區只會從父表格分離。

1. 執行 `SELECT cron.schedule` . . . 命令 進行 `pg_cron` 函數呼叫。此呼叫定義排程器執行 `pg_partman` 維護程序 `partman.run_maintenance_proc` 的頻率。在此範例中，程序會每小時執行一次。

如需 `run_maintenance_proc` 函數的完整描述，請參閱 `pg_partman` 文件中的[維護函數](https://github.com/pgpartman/pg_partman/blob/master/doc/pg_partman.md#maintenance-functions)。

# 使用 PgAudit 記錄資料庫活動
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit"></a>

金融機構、政府機構和許多產業都需要保留「稽核日誌」**，以符合法規要求。透過使用 PostgreSQL 稽核擴充功能 (PgAudit) 搭配 RDS for PostgreSQL 資料庫執行個體，您可以擷取稽核人員通常需要的詳細記錄，以符合法規要求。例如，您可以設定 pgAudit 擴充功能來追蹤對特定資料庫和資料表所做的變更、記錄進行變更的使用者，以及許多其他詳細資訊。

pgAudit 擴充功能建置在原生 PostgreSQL 記錄基礎結構的功能之上，以更多的詳細資訊擴充日誌訊息。換言之，您可以使用與檢視任何日誌訊息相同的方法來檢視稽核日誌。如需 PostgreSQL 記錄的詳細資訊，請參閱 [ RDS for PostgreSQL 資料庫日誌檔案](USER_LogAccess.Concepts.PostgreSQL.md)。

pgAudit 擴充功能會從日誌中刪減敏感資料，例如純文字密碼。如果您的 RDS for PostgreSQL 資料庫執行個體設定為記錄資料操作語言 (DML) 陳述式 (如[開啟 RDS for PostgreSQL 資料庫執行個體的查詢記錄](USER_LogAccess.Concepts.PostgreSQL.Query_Logging.md)中所述)，您可以使用 PostgreSQL 稽核擴充功能避免純文字密碼問題。

您可以非常具體地設定對資料庫執行個體的稽核。您可以稽核所有資料庫和所有使用者。或者，您可以選擇僅稽核某些資料庫、使用者和其他物件。您也可以明確排除特定使用者和資料庫，使其不受稽核。如需更多詳細資訊，請參閱 [從稽核記錄中排除使用者或資料庫](Appendix.PostgreSQL.CommonDBATasks.pgaudit.exclude-user-db.md)。

鑑於可以擷取的詳細資訊量，我們建議您，如果的確使用 pgAudit，請監控您的儲存耗用量。

所有可用的 RDS for PostgreSQL 版本。如需可用的 RDS for PostgreSQL 版本支援的 pgSQL 版本清單，請參閱《Amazon RDS for PostgreSQL 版本資訊》**中的 [Amazon RDS for PostgreSQL 的擴充功能版本。](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html)

**Topics**
+ [設定 pgAudit 擴充功能](Appendix.PostgreSQL.CommonDBATasks.pgaudit.basic-setup.md)
+ [稽核資料庫物件](Appendix.PostgreSQL.CommonDBATasks.pgaudit.auditing.md)
+ [從稽核記錄中排除使用者或資料庫](Appendix.PostgreSQL.CommonDBATasks.pgaudit.exclude-user-db.md)
+ [pgAudit 擴充功能的參考](Appendix.PostgreSQL.CommonDBATasks.pgaudit.reference.md)

# 設定 pgAudit 擴充功能
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.basic-setup"></a>

若要在 RDS for PostgreSQL 資料庫執行個體上設定 PgAudit 擴充功能，您必須先將 PgAudit 新增至 RDS for PostgreSQL 資料庫執行個體的自訂資料庫參數群組上的共用程式庫。如需建立自訂資料庫叢集參數群組的相關資訊，請參閱 [Amazon RDS 的參數群組](USER_WorkingWithParamGroups.md)。接下來，您會安裝 pgAudit 擴充功能。最後，您會指定要稽核的資料庫和物件。本節中的程序展示做法。您可以使用 AWS 管理主控台 或 AWS CLI。

您必須具有做為 `rds_superuser` 角色的許可，才能執行所有這些任務。

以下步驟假設您的 RDS for PostgreSQL 資料庫執行個體與自訂資料庫參數群組相關聯。

## 主控台
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.basic-setup.CON"></a>

**設定 pgAudit 擴充功能**

1. 登入 AWS 管理主控台，開啟位於 [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/) 的 Amazon RDS 主控台。

1. 在導覽窗格中，選擇您的 RDS for PostgreSQL 資料庫執行個體。

1. 針對您的 開啟 **Configuration** (組態) 索引標籤。RDS for PostgreSQL 資料庫執行個體。在執行個體詳細資訊之間，尋找 **Parameter group** (參數群組) 連結。

1. 選擇連結以開啟與 相關聯的自訂參數。RDS for PostgreSQL 資料庫執行個體。

1. 在 **Parameters** (參數) 搜尋欄位中，輸入 `shared_pre` 以尋找 `shared_preload_libraries` 參數。

1. 選擇 **Edit parameters** (編輯參數) 以存取屬性值。

1. 在 **Values** (值) 欄位中，將 `pgaudit` 新增至清單。使用逗號區隔值清單中的項目。  
![\[已新增 pgAudit 之 shared_preload_libaries 參數的影像。\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/images/apg_rpg_shared_preload_pgaudit.png)

1. 重新啟動 RDS for PostgreSQL 資料庫執行個體，以便您對 `shared_preload_libraries` 參數所做的變更生效。

1. 當執行個體可用時，請驗證 pgAudit 是否已初始化。使用 `psql` 連線至 RDS for PostgreSQL 資料庫執行個體，然後執行下列命令。

   ```
   SHOW shared_preload_libraries;
   shared_preload_libraries 
   --------------------------
   rdsutils,pgaudit
   (1 row)
   ```

1. 在初始化 pgAudit 之後，您現在可以建立擴充功能。您必須在初始化程式庫之後建立擴充功能，因為 `pgaudit` 擴充功能會安裝事件觸發條件，以稽核資料定義語言 (DDL) 陳述式。

   ```
   CREATE EXTENSION pgaudit;
   ```

1. 關閉 `psql` 工作階段。

   ```
   labdb=> \q
   ```

1. 登入 AWS 管理主控台，開啟位於 [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/) 的 Amazon RDS 主控台。

1. 在清單中尋找 `pgaudit.log` 參數，並設定為適合您使用案例的適當值。例如，將 `pgaudit.log` 參數設定為 `write` (如下圖所示) 會擷取日誌的插入、更新、刪除，以及其他一些類型的變更。  
![\[pgaudit.log 參數與設定的影像。\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/images/rpg_set_pgaudit-log-level.png)

   您也可以針對 `pgaudit.log` 參數選擇下列其中一個值。
   + none – 這是預設值。不會記錄任何資料庫變更。
   + all – 記錄一切 (read、write、function、role、ddl、misc)。
   + ddl – 記錄未包含在 `ROLE` 類別中的所有資料定義語言 (DDL) 陳述式。
   + function – 記錄函數呼叫和 `DO` 區塊。
   + misc – 記錄其他命令，例如 `DISCARD`、`FETCH`、`CHECKPOINT`、`VACUUM` 和 `SET`。
   + read – 來源為關聯 (例如資料表) 或查詢時，記錄 `SELECT` 和 `COPY`。
   + role – 記錄與角色和權限相關的陳述式，例如 `GRANT`、`REVOKE`、`CREATE ROLE`、`ALTER ROLE` 和 `DROP ROLE`。
   + write – 目的地為關聯 (資料表) 時，記錄 `INSERT`、`UPDATE`、`DELETE`、`TRUNCATE` 和 `COPY`。

1. 選擇**儲存變更**。

1. 前往 [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/)，開啟 Amazon RDS 主控台。

1. 在資料庫清單中，選擇您的 RDS for PostgreSQL 資料庫執行個體。

## AWS CLI
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.basic-setup.CLI"></a>

**設定 pgAudit**

若要使用 AWS CLI 設定 pgAudit，請呼叫 [modify-db-parameter-group](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-parameter-group.html) 操作，來修改自訂參數群組中的稽核日誌參數，如下列程序所示。

1. 使用下列 AWS CLI 命令，將 `pgaudit` 新增至 `shared_preload_libraries` 參數。

   ```
   aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=shared_preload_libraries,ParameterValue=pgaudit,ApplyMethod=pending-reboot" \
      --region aws-region
   ```

1. 使用下列 AWS CLI 命令重新啟動 RDS for PostgreSQL 資料庫執行個體，以便初始化 pgaudit 程式庫。

   ```
   aws rds reboot-db-instance \
       --db-instance-identifier your-instance \
       --region aws-region
   ```

1. 當執行個體可用時，您可以驗證 `pgaudit` 是否已初始化。使用 `psql` 連線至 RDS for PostgreSQL 資料庫執行個體，然後執行下列命令。

   ```
   SHOW shared_preload_libraries;
   shared_preload_libraries 
   --------------------------
   rdsutils,pgaudit
   (1 row)
   ```

   在初始化 PgAudit 之後，您現在可以建立擴充功能。

   ```
   CREATE EXTENSION pgaudit;
   ```

1. 關閉 `psql` 工作階段，以便您可以使用 AWS CLI。

   ```
   labdb=> \q
   ```

1. 使用下列 AWS CLI 命令，來指定要由工作階段稽核記錄所記錄的陳述式類別。此範例會將 `pgaudit.log` 參數設定為 `write`，此參數會擷取日誌的插入、更新和刪除操作。

   ```
   aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=pgaudit.log,ParameterValue=write,ApplyMethod=pending-reboot" \
      --region aws-region
   ```

   您也可以針對 `pgaudit.log` 參數選擇下列其中一個值。
   + none – 這是預設值。不會記錄任何資料庫變更。
   + all – 記錄一切 (read、write、function、role、ddl、misc)。
   + ddl – 記錄未包含在 `ROLE` 類別中的所有資料定義語言 (DDL) 陳述式。
   + function – 記錄函數呼叫和 `DO` 區塊。
   + misc – 記錄其他命令，例如 `DISCARD`、`FETCH`、`CHECKPOINT`、`VACUUM` 和 `SET`。
   + read – 來源為關聯 (例如資料表) 或查詢時，記錄 `SELECT` 和 `COPY`。
   + role – 記錄與角色和權限相關的陳述式，例如 `GRANT`、`REVOKE`、`CREATE ROLE`、`ALTER ROLE` 和 `DROP ROLE`。
   + write – 目的地為關聯 (資料表) 時，記錄 `INSERT`、`UPDATE`、`DELETE`、`TRUNCATE` 和 `COPY`。

   使用下列 AWS CLI 命令，重新啟動 RDS for PostgreSQL 資料庫執行個體。

   ```
   aws rds reboot-db-instance \
       --db-instance-identifier your-instance \
       --region aws-region
   ```

# 稽核資料庫物件
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.auditing"></a>

在您的 RDS for PostgreSQL 資料庫執行個體上設定 pgAudit，並針對您的要求進行設定後，會在 PostgreSQL 日誌中擷取更詳細的資訊。例如，雖然預設 PostgreSQL 記錄組態會識別在資料庫資料表中進行變更的日期和時間，但使用 pgAudit 擴充功能時，日誌項目可以包括結構描述、進行變更的使用者，以及其他詳細資訊，視擴充功能參數的設定方式而定。您可以將稽核設定為以下列方式追蹤變更。
+ 對於每個工作階段，依使用者。對於工作階段層級，您可以擷取完整的命令文字。
+ 對於每個物件，依使用者和資料庫。

在系統上建立 `rds_pgaudit` 角色，然後將此角色新增至自訂參數群組中的 `pgaudit.role` 參數時，便會啟用物件稽核功能。根據預設，未設定 `pgaudit.role` 參數，且唯一允許的值為 `rds_pgaudit`。下列步驟假設 `pgaudit` 已初始化，且您已遵循[設定 pgAudit 擴充功能](Appendix.PostgreSQL.CommonDBATasks.pgaudit.basic-setup.md)中的程序建立 `pgaudit` 擴充功能。

![\[設定 pgAudit 後 PostgreSQL 日誌檔的影像。\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/images/pgaudit-log-example.png)


如此範例所示，「LOG: AUDIT: SESSION」一行提供資料表及其結構描述的相關資訊，以及其他詳細資訊。

**設定物件稽核**

1. 使用 `psql` 連線至 RDS for PostgreSQL 資料庫執行個體。。

   ```
   psql --host=your-instance-name.aws-region.rds.amazonaws.com --port=5432 --username=postgrespostgres --password --dbname=labdb
   ```

1. 使用下列命令建立名為 `rds_pgaudit` 的資料庫角色。

   ```
   labdb=> CREATE ROLE rds_pgaudit;
   CREATE ROLE
   labdb=>
   ```

1. 關閉 `psql` 工作階段。

   ```
   labdb=> \q
   ```

   在接下來的幾個步驟中，使用 AWS CLI 修改自訂參數群組中的稽核日誌參數。

1. 使用下列 AWS CLI 命令，將 `pgaudit.role` 參數設定為 `rds_pgaudit`。根據預設，此參數是空的，且 `rds_pgaudit` 是唯一允許的值。

   ```
   aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=pgaudit.role,ParameterValue=rds_pgaudit,ApplyMethod=pending-reboot" \
      --region aws-region
   ```

1. 使用下列 AWS CLI 命令，重新啟動 RDS for PostgreSQL 資料庫執行個體，以便您對參數所做的變更生效。

   ```
   aws rds reboot-db-instance \
       --db-instance-identifier your-instance \
       --region aws-region
   ```

1. 執行下列命令來確認 `pgaudit.role` 已設定為 `rds_pgaudit`。

   ```
   SHOW pgaudit.role;
   pgaudit.role 
   ------------------
   rds_pgaudit
   ```

如要測試 pgAudit 記錄功能，您可以執行幾個要稽核的範例命令。例如，您可以執行下列命令。

```
CREATE TABLE t1 (id int);
GRANT SELECT ON t1 TO rds_pgaudit;
SELECT * FROM t1;
id 
----
(0 rows)
```

資料庫記錄應包含類似以下的項目。

```
...
2017-06-12 19:09:49 UTC:...:rds_test@postgres:[11701]:LOG: AUDIT:
OBJECT,1,1,READ,SELECT,TABLE,public.t1,select * from t1;
...
```

如需有關檢視日誌的資訊，請參閱 [監控 Amazon RDS 日誌檔案](USER_LogAccess.md)。

若要進一步了解 pgAudit 擴充功能，請參閱 GitHub 上的 [pgAudit](https://github.com/pgaudit/pgaudit/blob/master/README.md)。

# 從稽核記錄中排除使用者或資料庫
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.exclude-user-db"></a>

如[ RDS for PostgreSQL 資料庫日誌檔案](USER_LogAccess.Concepts.PostgreSQL.md)中所述，PostgreSQL 日誌會取用儲存空間。使用 pgAudit 擴充功能會在不同程度上增加日誌中收集的資料量，取決於您追蹤的變更。您可能不需要稽核 中的每個使用者或資料庫。RDS for PostgreSQL 資料庫執行個體。

若要將對儲存的影響降到最低，並避免不必要地擷取稽核記錄，您可以將使用者和資料庫排除在稽核之外。您也可以在給定的工作階段中變更記錄。下列範例向您展示做法。

**注意**  
優先處理工作階段層級的參數設定，再處理 RDS for PostgreSQL 資料庫執行個體中的設定。如果您不想要資料庫使用者略過稽核記錄組態設定，請務必變更其許可。

假設您的 RDS for PostgreSQL 資料庫執行個體已設定為稽核所有使用者和資料庫的相同層級活動。然後，您決定不想要稽核使用者 `myuser`。您可以使用下列 SQL 命令來關閉 `myuser` 的稽核。

```
ALTER USER myuser SET pgaudit.log TO 'NONE';
```

然後，您可以使用下列查詢來檢查 `pgaudit.log` 的 `user_specific_settings` 欄，以確認參數已設定為 `NONE`。

```
SELECT
    usename AS user_name,
    useconfig AS user_specific_settings
FROM
    pg_user
WHERE
    usename = 'myuser';
```

您會看到如下輸出。

```
 user_name | user_specific_settings
-----------+------------------------
 myuser    | {pgaudit.log=NONE}
(1 row)
```

您可以使用下列命令，在資料庫的工作階段當中關閉特定使用者的記錄。

```
ALTER USER myuser IN DATABASE mydatabase SET pgaudit.log TO 'none';
```

使用下列查詢，針對特定使用者和資料庫組合檢查 pgaudit.log 的 settings 欄。

```
SELECT
    usename AS "user_name",
    datname AS "database_name",
    pg_catalog.array_to_string(setconfig, E'\n') AS "settings"
FROM
    pg_catalog.pg_db_role_setting s
    LEFT JOIN pg_catalog.pg_database d ON d.oid = setdatabase
    LEFT JOIN pg_catalog.pg_user r ON r.usesysid = setrole
WHERE
    usename = 'myuser'
    AND datname = 'mydatabase'
ORDER BY
    1,
    2;
```

您會看到類似下列的輸出。

```
  user_name | database_name |     settings
-----------+---------------+------------------
 myuser    | mydatabase    | pgaudit.log=none
(1 row)
```

在關閉 `myuser` 的稽核之後，您決定不想要追蹤 `mydatabase` 的變更。您可以使用下列命令來關閉該特定資料庫的稽核。

```
ALTER DATABASE mydatabase SET pgaudit.log to 'NONE';
```

然後，使用下列查詢來檢查 database\$1specific\$1settings 欄，以確認 pgaudit.log 已設定為 NONE。

```
SELECT
a.datname AS database_name,
b.setconfig AS database_specific_settings
FROM
pg_database a
FULL JOIN pg_db_role_setting b ON a.oid = b.setdatabase
WHERE
a.datname = 'mydatabase';
```

您會看到如下輸出。

```
 database_name | database_specific_settings
---------------+----------------------------
 mydatabase    | {pgaudit.log=NONE}
(1 row)
```

若要將設定回復為 myuser 的預設設定，請使用下列命令：

```
ALTER USER myuser RESET pgaudit.log;
```

若要將設定回復為資料庫的預設設定，請使用下列命令。

```
ALTER DATABASE mydatabase RESET pgaudit.log;
```

若要將使用者和資料庫重設為預設設定，請使用下列命令。

```
ALTER USER myuser IN DATABASE mydatabase RESET pgaudit.log;
```

您也可以將 `pgaudit.log` 設定為 `pgaudit.log` 參數的其他允許值之一，將特定事件擷取至日誌。如需更多詳細資訊，請參閱 [允許的 `pgaudit.log` 參數設定清單](Appendix.PostgreSQL.CommonDBATasks.pgaudit.reference.md#Appendix.PostgreSQL.CommonDBATasks.pgaudit.reference.pgaudit-log-settings)。

```
ALTER USER myuser SET pgaudit.log TO 'read';
ALTER DATABASE mydatabase SET pgaudit.log TO 'function';
ALTER USER myuser IN DATABASE mydatabase SET pgaudit.log TO 'read,function'
```

# pgAudit 擴充功能的參考
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.reference"></a>

您可以變更本節中列出的一或多個參數，針對稽核日誌指定您所需的詳細資訊層級。

## 控制 pgAudit 行為
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.reference.basic-setup.parameters"></a>

您可以變更下表中列出的一或多個參數來控制稽核記錄。


| 參數 | Description | 
| --- | --- | 
| `pgaudit.log`  | 指定工作階段稽核記錄將記錄哪些陳述式類別。允許的值包括 ddl、function、misc、read、role、write、none、all。如需詳細資訊，請參閱[允許的 `pgaudit.log` 參數設定清單](#Appendix.PostgreSQL.CommonDBATasks.pgaudit.reference.pgaudit-log-settings)。 | 
| `pgaudit.log_catalog` | 開啟 (設定為 1) 時，如果陳述式中的所有關聯都在 pg\$1catalog 中，則會將陳述式新增至稽核線索。 | 
| `pgaudit.log_level` | 指定要用於日誌項目的日誌層級。允許的值：disabled、debug5、debug4、debug3、debug2、debug1、info、notice、warning、log | 
| `pgaudit.log_parameter` | 開啟 (設定為 1) 時，會在稽核日誌中擷取隨陳述式傳遞的參數。 | 
| `pgaudit.log_relation` | 開啟 (設定為 1) 時，工作階段的稽核日誌會為 SELECT 或 DML 陳述式中參考的每個關聯 (TABLE、VIEW 等) 建立個別的日誌項目。 | 
| `pgaudit.log_statement_once` | 指定日誌記錄包含的陳述式文字和參數，具有陳述式/子陳述式組合的第一個日誌項目，還是具有每個項目。 | 
| `pgaudit.role` | 指定用於物件稽核日誌記錄的主要角色。唯一允許的項目為 `rds_pgaudit`。 | 

## 允許的 `pgaudit.log` 參數設定清單
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.reference.pgaudit-log-settings"></a>

 


| Value | Description | 
| --- | --- | 
| 無 | 這是預設值。不會記錄任何資料庫變更。 | 
| 全部 | 記錄一切 (read、write、function、role、ddl、misc)。 | 
| ddl | 記錄未包含在 `ROLE` 類別中的所有資料定義語言 (DDL) 陳述式。 | 
| 函數 | 記錄函數呼叫和 `DO` 區塊。 | 
| misc | 記錄其他命令，例如 `DISCARD`、`FETCH`、`CHECKPOINT`、`VACUUM` 和 `SET`。 | 
| 讀取 | 來源為關聯 (例如資料表) 或查詢時，記錄 `SELECT` 和 `COPY`。 | 
| role | 記錄與角色和權限相關的陳述式，例如 `GRANT`、`REVOKE`、`CREATE ROLE`、`ALTER ROLE` 和 `DROP ROLE`。 | 
| write | 目的地為關聯 (資料表) 時，記錄 `INSERT`、`UPDATE`、`DELETE`、`TRUNCATE` 和 `COPY`。 | 

若要使用工作階段稽核功能記錄多個事件類型，請使用逗號分隔清單。若要記錄所有事件類型，請將 `pgaudit.log` 設定為 `ALL`。重新啟動資料庫執行個體以套用變更。

您可以透過物件稽核，調整稽核記錄以使用特定關聯。例如，您可以指定您想要針對一或多個資料表上的 `READ` 操作稽核記錄。

# 使用 PostgreSQL pg\$1cron 擴充功能排程維護
<a name="PostgreSQL_pg_cron"></a>

您可以使用 PostgreSQL `pg_cron` 擴充功能，來排程 PostgreSQL 資料庫內的維護命令。如需擴充功能的詳細資訊，請參閱 pg\$1cron 文件中的[什麼是 pg\$1cron？](https://github.com/citusdata/pg_cron)。

RDS for PostgreSQL 引擎 12.5 版及更新版本支援 `pg_cron` 擴充功能。

若要深入了解如何使用 `pg_cron`，請參閱[在 RDS for PostgreSQL 或 Aurora PostgreSQL 相容版本資料庫上使用 pg\$1cron 排程任務](https://aws.amazon.com/blogs/database/schedule-jobs-with-pg_cron-on-your-amazon-rds-for-postgresql-or-amazon-aurora-for-postgresql-databases/)

**注意**  
`pg_cron` 延伸版本會在 pg\$1available\$1extensions 檢視中顯示為兩個數字的版本，例如 1.6。雖然在某些內容中可能會看到三個數字的版本，例如 1.6.4 或 1.6.5，但您必須在執行延伸升級時指定兩個數字的版本。

**Topics**
+ [設定 pg\$1cron 擴充功能](#PostgreSQL_pg_cron.enable)
+ [授與資料車使用者使用 pg\$1cron 的許可](#PostgreSQL_pg_cron.permissions)
+ [排定 pg\$1cron 任務](#PostgreSQL_pg_cron.examples)
+ [pg\$1cron 擴充功能的參考](#PostgreSQL_pg_cron.reference)

## 設定 pg\$1cron 擴充功能
<a name="PostgreSQL_pg_cron.enable"></a>

設定 `pg_cron` 擴充功能，如下所示：

1. 修改與 PostgreSQL 資料庫執行個體關聯的自訂參數群組，並將 `pg_cron` 新增至 `shared_preload_libraries` 參數值。
   + 如果 RDS for PostgreSQL 資料庫執行個體使用 `rds.allowed_extensions` 參數顯式列可以安裝的擴展名清單，您需要將 `pg_cron` 擴展功能新增至清單。只有特定版本的 RDS for PostgreSQL 支援 `rds.allowed_extensions` 參數。根據預設，允許所有可用的擴充功能。如需詳細資訊，請參閱[限制安裝 PostgreSQL 擴充功能](PostgreSQL.Concepts.General.FeatureSupport.Extensions.md#PostgreSQL.Concepts.General.FeatureSupport.Extensions.Restriction)。

   重新啟動 PostgreSQL 資料庫執行個體，使參數群組的變更生效。若要深入了解如何使用參數群組，請參閱 [修改 Amazon RDS 中的資料庫參數群組中的參數](USER_WorkingWithParamGroups.Modifying.md)。 

1. 重新啟動 PostgreSQL 資料庫執行個體之後，請使用具有 `rds_superuser` 許可的帳戶執行下列命令。例如，如果您在為 RDS for PostgreSQL 資料庫執行個體建立 RDS 時使用了預設設定，請以使用者 `postgres` 身分連接並建立擴充功能。

   ```
   CREATE EXTENSION pg_cron;
   ```

   `pg_cron` 排程器設定於名為 `postgres` 的預設 PostgreSQL 資料庫內。`pg_cron` 物件會在此 `postgres` 資料庫中建立，而且所有排程動作都會在此資料庫中執行。

1. 您可以使用預設設定，或將任務排程在 PostgreSQL 資料庫執行個體的其他資料庫中執行。若要將任務排程至 PostgreSQL 資料庫執行個體中的其他資料庫，請參閱 [為預設資料庫以外的資料庫排程 cron 任務](#PostgreSQL_pg_cron.otherDB) 中的範例。

## 授與資料車使用者使用 pg\$1cron 的許可
<a name="PostgreSQL_pg_cron.permissions"></a>

安裝 `pg_cron` 擴充功能需要 `rds_superuser` 權限。然而，使用 `pg_cron` 的許可能夠授予 (由 `rds_superuser` 群組/角色的成員) 其他資料庫使用者，讓他們可以安排自己的任務。建議您只有在能改善生產環境中的作業時，才視需要授予對 `cron` 結構描述的許可。

若要授予資料庫使用者對 `cron` 結構描述的許可，請執行以下命令：

```
postgres=> GRANT USAGE ON SCHEMA cron TO db-user;
```

這樣會給予 *db-user* 存取 `cron` 結構描述的許可，以針對它們有權存取的物件排程 cron 作業。如果資料庫使用者沒有許可，則作業會在將錯誤訊息發佈至 `postgresql.log` 檔案後失敗，如下所示：

```
2020-12-08 16:41:00 UTC::@:[30647]:ERROR: permission denied for table table-name
2020-12-08 16:41:00 UTC::@:[27071]:LOG: background worker "pg_cron" (PID 30647) exited with exit code 1
```

換句話說，請確保被授予 `cron` 結構描述許可的資料庫使用者也具有計劃排程之物件 (資料表、結構描述等) 的許可。

Cron 作業及其成功或失敗的詳細資訊也會擷取於 `cron.job_run_details` 資料表。如需詳細資訊，請參閱[用於排程工作和擷取狀態的資料表](#PostgreSQL_pg_cron.tables)。

## 排定 pg\$1cron 任務
<a name="PostgreSQL_pg_cron.examples"></a>

以下各節示範如何使用 `pg_cron` 任務排程各種管理任務。

**注意**  
建立 `pg_cron` 工作時，請檢查 `max_worker_processes` 設定大於數目 `cron.max_running_jobs`。如果 `pg_cron` 任務耗盡背景工作者程序，則會失敗。`pg_cron` 任務的預設數字為 `5`。如需詳細資訊，請參閱[用於管理 pg\$1cron 擴充功能的參數](#PostgreSQL_pg_cron.parameters)。

**Topics**
+ [正在清理資料表](#PostgreSQL_pg_cron.vacuum)
+ [正在清除 pg\$1cron 歷史記錄資料表](#PostgreSQL_pg_cron.job_run_details)
+ [僅將錯誤記錄到 postgresql.log 檔案](#PostgreSQL_pg_cron.log_run)
+ [為預設資料庫以外的資料庫排程 cron 任務](#PostgreSQL_pg_cron.otherDB)

### 正在清理資料表
<a name="PostgreSQL_pg_cron.vacuum"></a>

自動資料清理功能可處理大多數情況下的清理維護。但是，您可能想要在您選定的時間來排定清理特定的資料表。

另請參閱 [在 Amazon RDS for PostgreSQL 上使用 PostgreSQL 自動清空](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.md)。

以下為使用 `cron.schedule` 函數來設定一個任務，以在每天 22:00 (GMT) 於特定資料表上使用 `VACUUM FREEZE` 的範例。

```
SELECT cron.schedule('manual vacuum', '0 22 * * *', 'VACUUM FREEZE pgbench_accounts');
 schedule
----------
1
(1 row)
```

執行上述範例之後，您可以如下所示檢查 `cron.job_run_details` 資料表中的歷史記錄。

```
postgres=> SELECT * FROM cron.job_run_details;
jobid  | runid | job_pid | database | username | command                        | status    | return_message | start_time                    | end_time
-------+-------+---------+----------+----------+--------------------------------+-----------+----------------+-------------------------------+-------------------------------
 1     | 1     | 3395    | postgres | adminuser| vacuum freeze pgbench_accounts | succeeded | VACUUM         | 2020-12-04 21:10:00.050386+00 | 2020-12-04 21:10:00.072028+00
(1 row)
```

以下是查詢 `cron.job_run_details` 資料表以查看失敗的任務。

```
postgres=> SELECT * FROM cron.job_run_details WHERE status = 'failed';
jobid | runid | job_pid | database | username | command                       | status | return_message                                   | start_time                    | end_time
------+-------+---------+----------+----------+-------------------------------+--------+--------------------------------------------------+-------------------------------+------------------------------
 5    | 4     | 30339   | postgres | adminuser| vacuum freeze pgbench_account | failed | ERROR: relation "pgbench_account" does not exist | 2020-12-04 21:48:00.015145+00 | 2020-12-04 21:48:00.029567+00
(1 row)
```

如需詳細資訊，請參閱[用於排程工作和擷取狀態的資料表](#PostgreSQL_pg_cron.tables)。

### 正在清除 pg\$1cron 歷史記錄資料表
<a name="PostgreSQL_pg_cron.job_run_details"></a>

`cron.job_run_details` 資料表包含 cron 任務的歷史記錄，它可能會隨著時間的推移而變得非常大。建議您排程清除此資料表的任務。例如，保留一週的項目可能足以進行疑難排解。

下列範例會使用 [cron.schedule](#PostgreSQL_pg_cron.schedule) 函數來排程每天在午夜執行的任務，以清除 `cron.job_run_details` 資料表。這項任務只保留過去七天。如下所示使用您的 `rds_superuser` 帳戶來排程任務。

```
SELECT cron.schedule('0 0 * * *', $$DELETE 
    FROM cron.job_run_details 
    WHERE end_time < now() - interval '7 days'$$);
```

如需詳細資訊，請參閱[用於排程工作和擷取狀態的資料表](#PostgreSQL_pg_cron.tables)。

### 僅將錯誤記錄到 postgresql.log 檔案
<a name="PostgreSQL_pg_cron.log_run"></a>

若要防止寫入至 `cron.job_run_details` 資料表，請修改與 PostgreSQL 資料庫執行個體關聯的參數群組，並將 `cron.log_run` 參數設定為關閉。`pg_cron` 延伸模組不再寫入至資料表，而且只會將錯誤擷取至 `postgresql.log` 檔案。如需詳細資訊，請參閱[修改 Amazon RDS 中的資料庫參數群組中的參數](USER_WorkingWithParamGroups.Modifying.md)。

使用下列命令來檢查 `cron.log_run` 參數的值。

```
postgres=> SHOW cron.log_run;
```

如需詳細資訊，請參閱[用於管理 pg\$1cron 擴充功能的參數](#PostgreSQL_pg_cron.parameters)。

### 為預設資料庫以外的資料庫排程 cron 任務
<a name="PostgreSQL_pg_cron.otherDB"></a>

`pg_cron` 的中繼資料都保留在名為 `postgres` 的 PostgreSQL 預設資料庫中。由於使用背景工作者來執行維護 cron 任務，因此您可以在 PostgreSQL 資料庫執行個體內的任何資料庫中排程任務︰

**注意**  
只有具有 `rds_superuser` 角色或 `rds_superuser` 權限的使用者才能列出資料庫中的所有 Cron 任務。其他使用者在 `cron.job` 資料表中只能檢視自己的任務。

1. 在 cron 資料庫中，使用 [cron.schedule](#PostgreSQL_pg_cron.schedule) 如常排程任務。

   ```
   postgres=> SELECT cron.schedule('database1 manual vacuum', '29 03 * * *', 'vacuum freeze test_table');
   ```

1. 作為使用 `rds_superuser` 角色的使用者，請為您剛建立的任務更新資料庫欄，以便在 PostgreSQL 資料庫執行個體內的另一個資料庫中執行。

   ```
   postgres=> UPDATE cron.job SET database = 'database1' WHERE jobid = 106;
   ```

1.  透過查詢 `cron.job` 資料表進行驗證。

   ```
   postgres=> SELECT * FROM cron.job;
   jobid | schedule    | command                        | nodename  | nodeport | database | username  | active | jobname
   ------+-------------+--------------------------------+-----------+----------+----------+-----------+--------+-------------------------
   106   | 29 03 * * * | vacuum freeze test_table       | localhost | 8192     | database1| adminuser | t      | database1 manual vacuum
     1   | 59 23 * * * | vacuum freeze pgbench_accounts | localhost | 8192     | postgres | adminuser | t      | manual vacuum
   (2 rows)
   ```

**注意**  
在某些情況下，您可能會新增一個打算在其他資料庫上執行的 cron 任務。在此情況下，任務可能會嘗試在預設資料庫 (`postgres`) 中執行，然後再更新正確的資料庫資料欄。如果使用者名稱具有許可，則任務會在預設資料庫中成功執行。

## pg\$1cron 擴充功能的參考
<a name="PostgreSQL_pg_cron.reference"></a>

您可以使用下列參數、函數和資料表搭配 `pg_cron` 擴充功能。如需詳細資訊，請參閱 pg\$1cron 文件中的[什麼是 pg\$1cron？](https://github.com/citusdata/pg_cron)。

**Topics**
+ [用於管理 pg\$1cron 擴充功能的參數](#PostgreSQL_pg_cron.parameters)
+ [函數參考：cron.schedule](#PostgreSQL_pg_cron.schedule)
+ [函數參考：cron.unschedule](#PostgreSQL_pg_cron.unschedule)
+ [用於排程工作和擷取狀態的資料表](#PostgreSQL_pg_cron.tables)

### 用於管理 pg\$1cron 擴充功能的參數
<a name="PostgreSQL_pg_cron.parameters"></a>

以下是用來控制 `pg_cron` 擴充功能行為的參數清單。


| 參數 | Description | 
| --- | --- | 
| cron.database\$1name |  在其中保留 `pg_cron` 中繼資料的資料庫。  | 
| cron.host |  要連線至 PostgreSQL 的主機名稱。您無法修改此值。  | 
| cron.log\$1run |  記錄 `job_run_details` 資料表執行的每個任務。值為 `on` 或 `off`。如需詳細資訊，請參閱 [用於排程工作和擷取狀態的資料表](#PostgreSQL_pg_cron.tables)。  | 
| cron.log\$1statement |  在執行之前記錄所有 cron 陳述式。值為 `on` 或 `off`。  | 
| cron.max\$1running\$1jobs |  可同時執行的任務數量上限。  | 
| cron.use\$1background\$1workers |  使用背景工作者而不是用戶端工作階段。您無法修改此值。  | 

使用下列 SQL 命令來顯示這些參數及其值。

```
postgres=> SELECT name, setting, short_desc FROM pg_settings WHERE name LIKE 'cron.%' ORDER BY name;
```

### 函數參考：cron.schedule
<a name="PostgreSQL_pg_cron.schedule"></a>

這個函數會排程一個 cron 任務。任務最初是在預設 `postgres` 資料庫中進行排程。該函數會返回表示任務識別符的 `bigint` 值。若要將任務排程在 PostgreSQL 資料庫執行個體中的其他資料庫中執行，請參閱 [為預設資料庫以外的資料庫排程 cron 任務](#PostgreSQL_pg_cron.otherDB) 中的範例。

該函數有兩種語法格式。

**語法**  

```
cron.schedule (job_name,
    schedule,
    command
);

cron.schedule (schedule,
    command
);
```

**參數**      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/PostgreSQL_pg_cron.html)

**範例**  

```
postgres=> SELECT cron.schedule ('test','0 10 * * *', 'VACUUM pgbench_history');
 schedule
----------
      145
(1 row)

postgres=> SELECT cron.schedule ('0 15 * * *', 'VACUUM pgbench_accounts');
 schedule
----------
      146
(1 row)
```

### 函數參考：cron.unschedule
<a name="PostgreSQL_pg_cron.unschedule"></a>

這個函數會刪除 cron 任務。您可以指定 `job_name` 或 `job_id`，兩者之一。政策可確保您是移除任務排程的擁有者。該函數會返回一個表示成功或失敗的布林值。

此函數的語法格示如下。

**語法**  

```
cron.unschedule (job_id);

cron.unschedule (job_name);
```

**參數**      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/PostgreSQL_pg_cron.html)

**範例**  

```
postgres=> SELECT cron.unschedule(108);
 unschedule
------------
 t
(1 row)

postgres=> SELECT cron.unschedule('test');
 unschedule
------------
 t
(1 row)
```

### 用於排程工作和擷取狀態的資料表
<a name="PostgreSQL_pg_cron.tables"></a>

下表用於排程 cron 任務以及記錄任務完成的方式。


| 表格 | 描述 | 
| --- | --- | 
| cron.job |  包含每個排程任務的中繼資料。大部分與此資料表的互動應透過使用 `cron.schedule` 和 `cron.unschedule` 函數來完成。  我們建議您不要將更新或插入權限直接提供給此資料表。這樣做將允許使用者更新 `username` 資料欄，以 `rds-superuser` 身分執行任務。   | 
| cron.job\$1run\$1details |  包含過去排程任務執行的歷史記錄資訊。這對於調查任務執行的狀態、傳回訊息以及開始和結束時間非常有用。  若要防止此資料表無限期增長，請定期清除。如需範例，請參閱 [正在清除 pg\$1cron 歷史記錄資料表](#PostgreSQL_pg_cron.job_run_details)。   | 

# 使用 pglogical 跨執行個體同步資料
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical"></a>

所有目前可用的 RDS for PostgreSQL 版本都支援 `pglogical` 延伸模組。pglogical 延伸模組早於 PostgreSQL 在第 10 版中引入的功能，其類似於邏輯複寫功能。如需詳細資訊，請參閱 [為 Amazon RDS for PostgreSQL 執行邏輯複寫](PostgreSQL.Concepts.General.FeatureSupport.LogicalReplication.md)。

`pglogical` 延伸模組支援在兩個或以上 之間進行邏輯複寫。RDS for PostgreSQL 資料庫執行個體。它也支援在不同的 PostgreSQL 版本之間，以及在 RDS for PostgreSQL 資料庫執行個體和 Aurora PostgreSQL 資料庫叢集上執行的資料庫之間進行複寫。`pglogical` 延伸模組會使用發佈-訂閱模型，將資料表和其他物件 (例如序列) 的變更從發佈者複製到訂閱者。它依賴複寫槽，以確保變更從發佈者節點同步到訂閱者節點，其定義如下。
+ *發佈者節點*是 RDS for PostgreSQL 資料庫執行個體，其是要複寫到其他節點的資料來源。發佈者節點定義要在發佈集中複製的資料表。
+ *訂閱者節點*是 RDS for PostgreSQL 資料庫執行個體，其會從發佈者接收 WAL 更新。訂閱者會建立訂閱以連線至發佈者，並取得解碼的 WAL 資料。訂閱者建立訂閱時，系統會在發佈者節點上建立複寫槽。

您可以在以下內容中找到如何設定 `pglogical` 延伸模組的相關資訊。

**Topics**
+ [pglogical 延伸模組的需求和限制](#Appendix.PostgreSQL.CommonDBATasks.pglogical.requirements-limitations)
+ [設定 pglogical 延伸模組](Appendix.PostgreSQL.CommonDBATasks.pglogical.basic-setup.md)
+ [針對 RDS for PostgreSQL 資料庫執行個體設定邏輯複寫](Appendix.PostgreSQL.CommonDBATasks.pglogical.setup-replication.md)
+ [在重大升級之後重新建立邏輯複寫](Appendix.PostgreSQL.CommonDBATasks.pglogical.recover-replication-after-upgrade.md)
+ [管理 RDS for PostgreSQL 的邏輯複寫槽](Appendix.PostgreSQL.CommonDBATasks.pglogical.handle-slots.md)
+ [pglogical 延伸模組的參數參考](Appendix.PostgreSQL.CommonDBATasks.pglogical.reference.md)

## pglogical 延伸模組的需求和限制
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.requirements-limitations"></a>

所有目前可用的 RDS for PostgreSQL 版本都支援 `pglogical` 延伸模組。

發佈者節點和訂閱者節點都必須針對邏輯複寫進行設定。

您想要從發佈者複寫到訂閱者的資料表必須具有相同的名稱和相同的結構描述。這些資料表亦須包含相同的資料欄，而且這些資料欄必須使用相同的資料類型。發佈者和訂閱者資料表都必須具有相同的主索引鍵。建議您僅使用 PRIMARY KEY 作為唯一限制條件。

對於 CHECK 限制條件和 NOT NULL 限制條件，訂閱者節點上的資料表與發佈者節點上的資料表相比之下，可以具有更寬鬆的限制條件。

`pglogical` 延伸模組會提供 PostgreSQL (第 10 版及更新版本) 內建邏輯複寫功能不支援的功能，例如雙向複寫。如需詳細資訊，請參閱[使用 pglogical 進行 PostgreSQL 雙向複寫](https://aws.amazon.com/blogs/database/postgresql-bi-directional-replication-using-pglogical/)。

# 設定 pglogical 延伸模組
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.basic-setup"></a>

若要在 RDS for PostgreSQL 資料庫執行個體上設定 `pglogical` 延伸模組，請將 `pglogical` 新增至下列群組上的共用程式庫：RDS for PostgreSQL 資料庫執行個體的自訂資料庫參數群組。您亦需將 `rds.logical_replication` 參數的值設為 `1`，以開啟邏輯解碼。最後，您可以在資料庫中建立延伸模組。您可以使用 AWS 管理主控台 或 AWS CLI 進行這些任務。

您必須具有做為 `rds_superuser` 角色的許可，才能執行這些任務。

以下步驟假設您的 RDS for PostgreSQL 資料庫執行個體與自訂資料庫參數群組相關聯。如需建立自訂資料庫叢集參數群組的相關資訊，請參閱 [Amazon RDS 的參數群組](USER_WorkingWithParamGroups.md)。

## 主控台
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.basic-setup.CON"></a>

**設定 pglogical 延伸模組**

1. 登入 AWS 管理主控台 ，並在 [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/)：// 開啟 Amazon RDS 主控台。

1. 在導覽窗格中，選擇您的 RDS for PostgreSQL 資料庫執行個體。

1. 針對您的 開啟 **Configuration** (組態) 索引標籤。RDS for PostgreSQL 資料庫執行個體。在執行個體詳細資訊之間，尋找 **Parameter group** (參數群組) 連結。

1. 選擇連結以開啟與 相關聯的自訂參數。RDS for PostgreSQL 資料庫執行個體。

1. 在 **Parameters** (參數) 搜尋欄位中，輸入 `shared_pre` 以尋找 `shared_preload_libraries` 參數。

1. 選擇 **Edit parameters** (編輯參數) 以存取屬性值。

1. 在 **Values** (值) 欄位中，將 `pglogical` 新增至清單。使用逗號區隔值清單中的項目。  
![\[已新增 pglogical 之 shared_preload_libraries 參數的影像。\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/images/apg_rpg_shared_preload_pglogical.png)

1. 尋找 `rds.logical_replication` 參數並將其設為 `1`，以開啟邏輯複寫。

1. 重新啟動 RDS for PostgreSQL 資料庫執行個體，讓您的變更生效。

1. 當執行個體可用時，您可以使用 `psql` (或 pgAdmin) 連線至 RDS for PostgreSQL 資料庫執行個體。。

   ```
   psql --host=111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=labdb
   ```

1. 若要驗證 pglogical 是否已初始化，請執行下列命令。

   ```
   SHOW shared_preload_libraries;
   shared_preload_libraries 
   --------------------------
   rdsutils,pglogical
   (1 row)
   ```

1. 驗證啟用邏輯解碼的設定，如下所示。

   ```
   SHOW wal_level;
   wal_level
   -----------
    logical
   (1 row)
   ```

1. 建立延伸模組，如下所示。

   ```
   CREATE EXTENSION pglogical;
   EXTENSION CREATED
   ```

1. 選擇**儲存變更**。

1. 前往 [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/)，開啟 Amazon RDS 主控台。

1. 從資料庫清單中選擇 RDS for PostgreSQL 資料庫執行個體以選取它，然後從 Actions (動作) 功能表中選擇 **Reboot** (重新啟動)。

## AWS CLI
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.basic-setup.CLI"></a>

**設定 pglogical 延伸模組**

若要使用 設定 pglogical AWS CLI，您可以呼叫 [modify-db-parameter-group](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-parameter-group.html) 操作來修改自訂參數群組中的特定參數，如下列程序所示。

1. 使用下列 AWS CLI 命令將 `pglogical`新增至 `shared_preload_libraries` 參數。

   ```
   aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=shared_preload_libraries,ParameterValue=pglogical,ApplyMethod=pending-reboot" \
      --region aws-region
   ```

1. 使用下列 AWS CLI 命令將 `rds.logical_replication` 設定為 `1`，以開啟 RDS for PostgreSQL 資料庫執行個體。

   ```
   aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=rds.logical_replication,ParameterValue=1,ApplyMethod=pending-reboot" \
      --region aws-region
   ```

1. 使用以下 AWS CLI 命令重新啟動 RDS for PostgreSQL 資料庫執行個體，以便初始化 pglogical 程式庫。

   ```
   aws rds reboot-db-instance \
       --db-instance-identifier your-instance \
       --region aws-region
   ```

1. 當執行個體可用時，請使用 `psql` 連線至 RDS for PostgreSQL 資料庫執行個體。。

   ```
   psql --host=111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=labdb
   ```

1. 建立延伸模組，如下所示。

   ```
   CREATE EXTENSION pglogical;
   EXTENSION CREATED
   ```

1. 使用以下 AWS CLI 命令重新啟動 RDS for PostgreSQL 資料庫執行個體。

   ```
   aws rds reboot-db-instance \
       --db-instance-identifier your-instance \
       --region aws-region
   ```

# 針對 RDS for PostgreSQL 資料庫執行個體設定邏輯複寫
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.setup-replication"></a>

下列程序說明如何在兩個 RDS for PostgreSQL 資料庫執行個體之間啟動邏輯複寫。這些步驟假設來源 (發佈者) 和目標 (訂閱者) 都已設定 `pglogical` 延伸模組，如 [設定 pglogical 延伸模組](Appendix.PostgreSQL.CommonDBATasks.pglogical.basic-setup.md) 中所述。

**注意**  
訂閱者節點的 `node_name` 不能以 `rds` 開頭。

**建立發佈者節點並定義要複製的資料表**

這些步驟假設您的 RDS for PostgreSQL 資料庫執行個體具有一個資料庫，其中包含一或多個您要複寫到另一個節點的資料表。您必須在訂閱者上重新建立來自發佈者的資料表結構，因此必要時先取得資料表結構。您可以使用 `psql` 中繼命令 `\d tablename`，然後在訂閱者執行個體上建立相同的資料表，以執行該操作。下列程序會在發佈者 (來源) 上建立範例資料表，以供示範之用。

1. 使用 `psql` 連線至具有資料表的執行個體，您想要將該資料表用作訂閱者的來源。

   ```
   psql --host=source-instance.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=labdb
   ```

   如果您沒有要複寫的現有資料表，則可以建立如下的範例資料表。

   1. 使用下列 SQL 陳述式建立範例資料表。

      ```
      CREATE TABLE docs_lab_table (a int PRIMARY KEY);
      ```

   1. 使用下列 SQL 陳述式，將產生的資料填入資料表中。

      ```
      INSERT INTO docs_lab_table VALUES (generate_series(1,5000));
      INSERT 0 5000
      ```

   1. 使用下列 SQL 陳述式，驗證資料是否存在於資料表中。

      ```
      SELECT count(*) FROM docs_lab_table;
      ```

1. 將此 RDS for PostgreSQL 資料庫執行個體識別為發佈者節點，如下所示。

   ```
   SELECT pglogical.create_node(
       node_name := 'docs_lab_provider',
       dsn := 'host=source-instance.aws-region.rds.amazonaws.com port=5432 dbname=labdb');
    create_node
   -------------
      3410995529
   (1 row)
   ```

1. 將您要複寫的資料表新增至預設複寫集。如需複寫集的詳細資訊，請參閱 pglogical 文件中的 [Replication sets](https://github.com/2ndQuadrant/pglogical/tree/REL2_x_STABLE/docs#replication-sets) (複寫集)。

   ```
   SELECT pglogical.replication_set_add_table('default', 'docs_lab_table', 'true', NULL, NULL);
    replication_set_add_table
     ---------------------------
     t
     (1 row)
   ```

發佈者節點設定完成。您現在可以設定訂閱者節點，從發佈者接收更新。

**設定訂閱者節點並建立訂閱來接收更新**

這些步驟假設 RDS for PostgreSQL 資料庫執行個體已使用 `pglogical` 延伸模組進行設定。如需詳細資訊，請參閱[設定 pglogical 延伸模組](Appendix.PostgreSQL.CommonDBATasks.pglogical.basic-setup.md)。

1. 使用 `psql` 來連線至您想要從發佈者接收更新的執行個體。

   ```
   psql --host=target-instance.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=labdb
   ```

1. 在訂閱者 RDS for PostgreSQL 資料庫執行個體上，建立存在於發佈者上的相同資料表。在此範例中，資料表是 `docs_lab_table`。您可以建立資料表，如下所示。

   ```
   CREATE TABLE docs_lab_table (a int PRIMARY KEY);
   ```

1. 驗證此資料表是否為空的。

   ```
   SELECT count(*) FROM docs_lab_table;
    count
   -------
     0
   (1 row)
   ```

1. 將此 RDS for PostgreSQL 資料庫執行個體識別為訂閱者節點，如下所示。

   ```
   SELECT pglogical.create_node(
       node_name := 'docs_lab_target',
       dsn := 'host=target-instance.aws-region.rds.amazonaws.com port=5432 sslmode=require dbname=labdb user=postgres password=********');
    create_node
   -------------
      2182738256
   (1 row)
   ```

1. 建立訂閱。

   ```
   SELECT pglogical.create_subscription(
      subscription_name := 'docs_lab_subscription',
      provider_dsn := 'host=source-instance.aws-region.rds.amazonaws.com port=5432 sslmode=require dbname=labdb user=postgres password=*******',
      replication_sets := ARRAY['default'],
      synchronize_data := true,
      forward_origins := '{}' );  
    create_subscription
   ---------------------
   1038357190
   (1 row)
   ```

   完成此步驟時，會在訂閱者上的資料表中建立來自發佈者上資料表的資料。您可以使用下列 SQL 查詢來驗證是否已發生此情況。

   ```
   SELECT count(*) FROM docs_lab_table;
    count
   -------
     5000
   (1 row)
   ```

從此開始，對發佈者上資料表所做的變更會複寫到訂閱者上的資料表。

# 在重大升級之後重新建立邏輯複寫
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.recover-replication-after-upgrade"></a>

在對設為邏輯複寫之發佈者節點的 RDS for PostgreSQL 資料庫執行個體執行主要版本升級之前，您必須捨棄所有複寫槽，即使是未作用中的複寫槽也一樣。建議您暫時從發佈者節點轉移資料庫交易、捨棄複寫槽、升級 RDS for PostgreSQL 資料庫執行個體，然後重新建立並重新啟動複寫。

複寫槽僅託管於發佈者節點上。邏輯複寫案例中的 RDS for PostgreSQL 訂閱者節點沒有要捨棄的複寫槽，但在其指定為具有發佈者訂閱的訂閱者節點時，無法升級至主要版本。在升級 RDS for PostgreSQL 訂閱者節點之前，請先捨棄訂閱和節點。如需詳細資訊，請參閱 [管理 RDS for PostgreSQL 的邏輯複寫槽](Appendix.PostgreSQL.CommonDBATasks.pglogical.handle-slots.md)。

## 判斷邏輯複寫是否已中斷
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.recover-replication-after-upgrade.identifying-the-issue"></a>

您可以查詢發佈者節點或訂閱者節點，來判斷複寫程序是否已中斷，如下所示。

**檢查發佈者節點**
+ 使用 `psql` 連線到發佈者節點，然後查詢 `pg_replication_slots` 函數。請注意作用中資料欄中的值。通常，這會傳回 `t` (true)，表明複寫作用中。如果查詢傳回 `f` (false)，表示已停止複寫至訂閱者。

  ```
  SELECT slot_name,plugin,slot_type,active FROM pg_replication_slots;
                      slot_name              |      plugin      | slot_type | active
  -------------------------------------------+------------------+-----------+--------
   pgl_labdb_docs_labcb4fa94_docs_lab3de412c | pglogical_output | logical   | f
  (1 row)
  ```

**檢查訂閱者節點**

在訂閱者節點上，您可以採取三種不同的方式來檢查複寫的狀態。
+ 查看訂閱者節點上的 PostgreSQL 日誌，以找出失敗訊息。日誌會以包含結束代碼 1 的訊息識別失敗，如下所示。

  ```
  2022-07-06 16:17:03 UTC::@:[7361]:LOG: background worker "pglogical apply 16404:2880255011" (PID 14610) exited with exit code 1
  2022-07-06 16:19:44 UTC::@:[7361]:LOG: background worker "pglogical apply 16404:2880255011" (PID 21783) exited with exit code 1
  ```
+ 查詢 `pg_replication_origin` 函數。使用 `psql` 連線至訂閱者節點上的資料庫，然後查詢 `pg_replication_origin` 函數，如下所示。

  ```
  SELECT * FROM pg_replication_origin;
   roident | roname
  ---------+--------
  (0 rows)
  ```

  空白結果集表示複寫已中斷。通常，您會看到如下輸出。

  ```
     roident |                       roname
    ---------+----------------------------------------------------
           1 | pgl_labdb_docs_labcb4fa94_docs_lab3de412c
    (1 row)
  ```
+ 查詢 `pglogical.show_subscription_status` 函數，如下列範例所示。

  ```
  SELECT subscription_name,status,slot_name FROM pglogical.show_subscription_status();
       subscription_name | status |              slot_name
  ---====----------------+--------+-------------------------------------
   docs_lab_subscription | down   | pgl_labdb_docs_labcb4fa94_docs_lab3de412c
  (1 row)
  ```

  此輸出表明複寫已中斷。其狀態為 `down`。通常，輸出會將狀態顯示為 `replicating`。

如果您的邏輯複寫程序已中斷，您可以遵循下列步驟重新建立複寫。

**重新建立發佈者與訂閱者節點之間的邏輯複寫**

若要重新建立複寫，首先中斷訂閱者與發佈者節點的連線，然後重新建立訂閱，如下列步驟所述。

1. 使用 `psql` 連線至訂閱者節點，如下所示。

   ```
   psql --host=222222222222.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=labdb
   ```

1. 使用 `pglogical.alter_subscription_disable` 函數停用訂閱。

   ```
   SELECT pglogical.alter_subscription_disable('docs_lab_subscription',true);
    alter_subscription_disable
   ----------------------------
    t
   (1 row)
   ```

1. 透過查詢 `pg_replication_origin` 取得發佈者節點的識別符，如下所示。

   ```
   SELECT * FROM pg_replication_origin;
    roident |               roname
   ---------+-------------------------------------
          1 | pgl_labdb_docs_labcb4fa94_docs_lab3de412c
   (1 row)
   ```

1. 使用上一個步驟的回應搭配 `pg_replication_origin_create` 命令，來指派訂閱可在重新建立時使用的識別符。

   ```
   SELECT pg_replication_origin_create('pgl_labdb_docs_labcb4fa94_docs_lab3de412c');
     pg_replication_origin_create
   ------------------------------
                               1
   (1 row)
   ```

1. 透過傳送訂閱的名稱來開啟訂閱，其狀態為 `true`，如下列範例所示。

   ```
   SELECT pglogical.alter_subscription_enable('docs_lab_subscription',true);
     alter_subscription_enable
   ---------------------------
    t
   (1 row)
   ```

檢查節點的狀態。其狀態應為 `replicating`，如這個範例所示。

```
SELECT subscription_name,status,slot_name
  FROM pglogical.show_subscription_status();
             subscription_name |   status    |              slot_name
-------------------------------+-------------+-------------------------------------
 docs_lab_subscription         | replicating | pgl_labdb_docs_lab98f517b_docs_lab3de412c
(1 row)
```

檢查發佈者節點上訂閱者複寫槽的狀態。複寫槽的 `active` 資料欄應傳回 `t` (true)，表示已重新建立複寫。

```
SELECT slot_name,plugin,slot_type,active
  FROM pg_replication_slots;
                    slot_name              |      plugin      | slot_type | active
-------------------------------------------+------------------+-----------+--------
 pgl_labdb_docs_lab98f517b_docs_lab3de412c | pglogical_output | logical   | t
(1 row)
```

# 管理 RDS for PostgreSQL 的邏輯複寫槽
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.handle-slots"></a>

在對充當邏輯複寫案例中發佈者節點的 RDS for PostgreSQL 資料庫執行個體執行主要版本升級之前，您必須捨棄執行個體上的複寫槽。主要版本升級預先檢查程序會通知您，除非捨棄複寫槽，否則升級無法繼續進行。

若要從 RDS for PostgreSQL 資料庫執行個體中捨棄複寫槽，請先捨棄訂閱，然後捨棄複寫槽。

若要識別已使用 `pglogical` 延伸模組建立的複寫槽，請登入每個資料庫並取得節點的名稱。查詢訂閱者節點時，您會在輸出中同時取得發佈者和訂閱者節點，如本範例所示。

```
SELECT * FROM pglogical.node;
node_id   |     node_name
------------+-------------------
 2182738256 | docs_lab_target
 3410995529 | docs_lab_provider
(2 rows)
```

您可以使用下列查詢，取得有關訂閱的詳細資訊。

```
SELECT sub_name,sub_slot_name,sub_target
  FROM pglogical.subscription;
 sub_name |         sub_slot_name          | sub_target
----------+--------------------------------+------------
  docs_lab_subscription     | pgl_labdb_docs_labcb4fa94_docs_lab3de412c | 2182738256
(1 row)
```

您現在可以捨棄訂閱，如下所示。

```
SELECT pglogical.drop_subscription(subscription_name := 'docs_lab_subscription');
 drop_subscription
-------------------
                 1
(1 row)
```

捨棄訂閱之後，您可以刪除節點。

```
SELECT pglogical.drop_node(node_name := 'docs-lab-subscriber');
 drop_node
-----------
 t
(1 row)
```

您可以驗證節點是否不再存在，如下所示。

```
SELECT * FROM pglogical.node;
 node_id | node_name
---------+-----------
(0 rows)
```

# pglogical 延伸模組的參數參考
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.reference"></a>

在資料表中，您可以尋找與 `pglogical` 延伸模組相關聯的參數。`pglogical.conflict_log_level` 和 `pglogical.conflict_resolution` 這類參數用來處理更新衝突。對從發佈者訂閱變更的相同資料表進行本機變更時，可能會出現衝突。在各種案例期間 (例如雙向複寫或從相同發佈者複寫多個訂閱者時)，也會發生衝突。如需詳細資訊，請參閱[使用 pglogical 進行 PostgreSQL 雙向複寫](https://aws.amazon.com/blogs/database/postgresql-bi-directional-replication-using-pglogical/)。


| 參數 | Description | 
| --- | --- | 
| pglogical.batch\$1inserts | 可能情況下批次插入。依預設不會設定。變更為 '1' 以開啟、變更為 '0' 以關閉。 | 
| pglogical.conflict\$1log\$1level | 設定用於記錄已解決衝突的日誌層級。支援的字串值為 debug5、debug4、debug3、debug2、debug1、info、notice、warning、error、log、fatal、panic。 | 
| pglogical.conflict\$1resolution | 設定用來在衝突可解決時解決衝突的方法。支援的字串值為 error、apply\$1remote、keep\$1local、last\$1update\$1wins、first\$1update\$1wins。 | 
| pglogical.extra\$1connection\$1options | 要新增到所有對等節點連線的連線選項。 | 
| pglogical.synchronous\$1commit | pglogical 特定的同步遞交值 | 
| pglogical.use\$1spi | 使用 SPI (伺服器程式設計介面) 而不是低階 API 來套用變更。設為 '1' 以開啟、設為 '0' 以關閉。如需 SPI 的詳細資訊，請參閱 PostgreSQL 文件中的 [Server Programming Interface](https://www.postgresql.org/docs/current/spi.html) (伺服器程式設計介面)。 | 

# 使用 pgactive 來支援主動-主動式複寫
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive"></a>

`pgactive` 延伸模組使用主動-主動式複寫來支援和協調多個 RDS for PostgreSQL 資料庫上的寫入操作。Amazon RDS for PostgreSQL 的下列版本支援 `pgactive` 延伸模組：
+ RDS for PostgreSQL 17.0 版和更新版本
+ RDS for PostgreSQL 16.1 和更高的第 16 版
+ RDS for PostgreSQL 15.4-R2 及更高的 15 版本
+ RDS for PostgreSQL 14.10 及更高的 14 版本
+ RDS for PostgreSQL 13.13 及更高的 13 版本
+ RDS for PostgreSQL 12.17 及更高的 12 版本
+ RDS for PostgreSQL 11.22

**注意**  
當複寫組態中的多個資料庫上有寫入操作時，可能會發生衝突。如需詳細資訊，請參閱[處理主動-主動式複寫中的衝突](Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-conflicts.md)

**Topics**
+ [pgactive 延伸模組的現制](#Appendix.PostgreSQL.CommonDBATasks.pgactive.requirements-limitations)
+ [初始化 pgactive 延伸模組功能](Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup.md)
+ [針對 RDS for PostgreSQL 資料庫執行個體設定主動-主動式複寫](Appendix.PostgreSQL.CommonDBATasks.pgactive.setup-replication.md)
+ [測量 pgactive 成員之間的複寫延遲](Appendix.PostgreSQL.CommonDBATasks.pgactive.replicationlag.md)
+ [設定 pgactive 延伸模組的參數設定](Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.md)
+ [了解主動-主動衝突](Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.replication.md)
+ [了解 pgactive 結構描述](Appendix.PostgreSQL.CommonDBATasks.pgactive.schema.md)
+ [pgactive 函數參考](pgactive-functions-reference.md)
+ [處理主動-主動式複寫中的衝突](Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-conflicts.md)
+ [處理主動-主動式複寫中的序列](Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-sequences.md)

## pgactive 延伸模組的現制
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.requirements-limitations"></a>
+ 所有資料表都需有主索引鍵，否則不允許更新和刪除操作。主索引鍵欄中的值不應更新。
+ 序列可能有間隙，有時可能不按順序。序列未複寫。如需詳細資訊，請參閱[處理主動-主動式複寫中的序列](Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-sequences.md)。
+ DDL 和大型物件未複寫。
+ 次要唯一索引可能會導致資料差異。
+ 群組中所有節點的定序都必須相同。
+ 節點之間的負載平衡是一種反模式。
+ 大型交易可能造成複寫延遲。

# 初始化 pgactive 延伸模組功能
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup"></a>

若要在 RDS for PostgreSQL 資料庫執行個體上初始化 `pgactive` 延伸模組，請將 `rds.enable_pgactive` 參數值設定為 `1`，然後在資料庫中建立延伸模組。這樣做就會自動開啟參數 `rds.logical_replication` 和 `track_commit_timestamp`，並將 `wal_level` 的值設定為 `logical`。

您必須具有做為 `rds_superuser` 角色的許可，才能執行這些任務。

您可以使用 AWS 管理主控台 或 AWS CLI 來建立所需的 RDS for PostgreSQL 資料庫執行個體。下列步驟假設您的 RDS for PostgreSQL 資料庫執行個體與自訂資料庫參數群組相關聯。如需建立自訂資料庫參數群組的相關資訊，請參閱 [Amazon RDS 的參數群組](USER_WorkingWithParamGroups.md)。

## 主控台
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup.CON"></a>

**若要初始化 pgactive 延伸模組功能**

1. 登入 AWS 管理主控台 ，並在 [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/)：// 開啟 Amazon RDS 主控台。

1. 在導覽窗格中，選擇您的 RDS for PostgreSQL 資料庫執行個體。

1. 針對您的 RDS for PostgreSQL 資料庫執行個體開啟**組態**索引標籤。在執行個體詳細資訊中，找到**資料庫執行個體參數群組**連結。

1. 選擇連結以開啟與您的 RDS for PostgreSQL 資料庫執行個體相關聯的自訂參數。

1. 找到 `rds.enable_pgactive` 參數，並將其設定為 `1` 以初始化 `pgactive` 功能。

1. 選擇**儲存變更**。

1. 從 Amazon RDS 主控台的導覽窗格中，選擇**資料庫**。

1. 選取您的 RDS for PostgreSQL 資料庫執行個體，然後從**動作**選單中選擇**重新開機**。

1. 確認資料庫執行個體重新開機，以讓您的變更生效。

1. 當資料庫執行個體可用時，您可以使用 `psql` 或任何其他 PostgreSQL 用戶端連線至 RDS for PostgreSQL 資料庫執行個體。

   下列範例假設您的 RDS for PostgreSQL 資料庫執行個體擁有名為 *postgres* 的預設資料庫。

   ```
   psql --host=mydb.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password=PASSWORD --dbname=postgres
   ```

1. 若要驗證 pgactive 是否已初始化，請執行下列命令。

   ```
   postgres=>SELECT setting ~ 'pgactive' 
   FROM pg_catalog.pg_settings
   WHERE name = 'shared_preload_libraries';
   ```

   如果 `pgactive` 在 `shared_preload_libraries` 中，則上述命令將傳回以下內容：

   ```
   ?column? 
   ----------
    t
   ```

## AWS CLI
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup.CLI"></a>

**若要初始化 pgactive 延伸模組功能**

若要`pgactive`使用 初始化 AWS CLI，請呼叫 [modify-db-parameter-group](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-parameter-group.html) 操作來修改自訂參數群組中的特定參數，如下列程序所示。

1. 使用下列 AWS CLI 命令將 `rds.enable_pgactive` 設定為 `1`，以初始化 RDS for PostgreSQL 資料庫執行個體`pgactive`的功能。

   ```
   postgres=>aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=rds.enable_pgactive,ParameterValue=1,ApplyMethod=pending-reboot" \
      --region aws-region
   ```

1. 使用以下 AWS CLI 命令重新啟動 RDS for PostgreSQL 資料庫執行個體，以便初始化`pgactive`程式庫。

   ```
   aws rds reboot-db-instance \
       --db-instance-identifier your-instance \
       --region aws-region
   ```

1. 當執行個體可用時，請使用 `psql` 連線至 RDS for PostgreSQL 資料庫執行個體。。

   ```
   psql --host=mydb.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=master user --password=PASSWORD --dbname=postgres
   ```

1. 若要驗證 pgactive 是否已初始化，請執行下列命令。

   ```
   postgres=>SELECT setting ~ 'pgactive' 
   FROM pg_catalog.pg_settings
   WHERE name = 'shared_preload_libraries';
   ```

   如果 `pgactive` 在 `shared_preload_libraries` 中，則上述命令將傳回以下內容：

   ```
   ?column? 
   ----------
    t
   ```

# 針對 RDS for PostgreSQL 資料庫執行個體設定主動-主動式複寫
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.setup-replication"></a>

下列程序說明如何在兩個 RDS for PostgreSQL 資料庫執行個體 (其中 `pgactive` 可用) 之間啟動主動-主動複寫。若要執行多區域高可用性範例，您需要在兩個不同的區域部署 Amazon RDS for PostgreSQL 執行個體，並設定 VPC 對等互連。如需詳細資訊，請參閱 [VPC 對等互連](https://docs.aws.amazon.com/vpc/latest/peering/what-is-vpc-peering.html)。

**注意**  
在多個地區之間傳送流量可能會產生額外費用。

這些步驟假設 RDS for PostgreSQL 資料庫執行個體已使用 `pgactive` 延伸模組啟用。如需詳細資訊，請參閱[初始化 pgactive 延伸模組功能](Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup.md)。

**若要設定第一個具有 `pgactive` 延伸模組的 RDS for PostgreSQL 資料庫執行個體**

下列範例說明如何建立 `pgactive` 群組，以及在 RDS for PostgreSQL 資料庫執行個體上建立 `pgactive` 延伸模組所需的其他步驟。

1. 使用 `psql` 或其他用戶端工具連線至您的第一個 RDS for PostgreSQL 資料庫執行個體。

   ```
   psql --host=firstinstance.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password=PASSWORD --dbname=postgres
   ```

1. 使用下列命令在 RDS for PostgreSQL 執行個體上建立資料庫：

   ```
   postgres=> CREATE DATABASE app;
   ```

1. 使用下列命令將連線切換至新資料庫：

   ```
   \c app
   ```

1. 使用下列 SQL 陳述式建立並填入範例資料表：

   1. 使用下列 SQL 陳述式建立範例資料表。

      ```
      app=> CREATE SCHEMA inventory;
      CREATE TABLE inventory.products (
      id int PRIMARY KEY, product_name text NOT NULL,
      created_at timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP);
      ```

   1. 使用下列 SQL 陳述式在資料表中填入一些範例資料。

      ```
      app=> INSERT INTO inventory.products (id, product_name)
      VALUES (1, 'soap'), (2, 'shampoo'), (3, 'conditioner');
      ```

   1. 使用下列 SQL 陳述式，驗證資料是否存在於資料表中。

      ```
       app=>SELECT count(*) FROM inventory.products;
      
       count
      -------
       3
      ```

1. 在現有資料庫上建立 `pgactive` 延伸模組。

   ```
   app=> CREATE EXTENSION pgactive;
   ```

1. 若要安全地建立並初始化 pgactive 群組，請使用下列命令：

   ```
   app=>
   -- connection info for endpoint1
   CREATE SERVER pgactive_server_endpoint1
       FOREIGN DATA WRAPPER pgactive_fdw
       OPTIONS (host '<endpoint1>', dbname 'app');
   CREATE USER MAPPING FOR postgres
       SERVER pgactive_server_endpoint1
       OPTIONS (user 'postgres', password '<password>');
         -- connection info for endpoint2
   CREATE SERVER pgactive_server_endpoint2
       FOREIGN DATA WRAPPER pgactive_fdw
       OPTIONS (host '<endpoint2>', dbname 'app');
   CREATE USER MAPPING FOR postgres
       SERVER pgactive_server_endpoint2
       OPTIONS (user 'postgres', password '<password>');
   ```

   現在您可以初始化複寫群組並新增第一個執行個體：

   ```
   SELECT pgactive.pgactive_create_group(
       node_name := 'endpoint1-app',
       node_dsn := 'user_mapping=postgres pgactive_foreign_server=pgactive_server_endpoint1'
   
   );
   ```

   使用下列命令做為替代但較不安全的方法，來建立和初始化 pgactive 群組：

   ```
   app=> SELECT pgactive.pgactive_create_group(
       node_name := 'node1-app',
       node_dsn := 'dbname=app host=firstinstance.111122223333.aws-region.rds.amazonaws.com user=postgres password=PASSWORD');
   ```

   node1-app 是您指派的名稱，用於單獨識別 `pgactive` 群組中的節點。
**注意**  
若要在可公開存取的資料庫執行個體上成功執行此步驟，您必須將 `rds.custom_dns_resolution` 參數設定為 `1` 以將它開啟。

1. 若要檢查資料庫執行個體是否已就緒，請使用下列命令：

   ```
   app=> SELECT pgactive.pgactive_wait_for_node_ready();
   ```

   如果命令成功，您會看到以下輸出內容：

   ```
   pgactive_wait_for_node_ready 
   ------------------------------ 
   (1 row)
   ```

**若要設定第二個 RDS for PostgreSQL 執行個體，並將其加入 `pgactive` 群組**

下列範例說明如何建立將 RDS for PostgreSQL 資料庫執行個體加入 `pgactive` 群組，以及在資料庫執行個體上建立 `pgactive` 延伸模組所需的其他步驟。

這些步驟假設已有另一個 RDS for PostgreSQL 資料庫執行個體使用 `pgactive` 延伸模組設定完成。如需詳細資訊，請參閱[初始化 pgactive 延伸模組功能](Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup.md)。

1. 使用 `psql` 來連線至您想要從發佈者接收更新的執行個體。

   ```
   psql --host=secondinstance.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password=PASSWORD --dbname=postgres
   ```

1. 使用下列命令在第二個 RDS for PostgreSQL 資料庫執行個體上建立資料庫：

   ```
   postgres=> CREATE DATABASE app;
   ```

1. 使用下列命令將連線切換至新資料庫：

   ```
   \c app
   ```

1. 在現有資料庫上建立 `pgactive` 延伸模組。

   ```
   app=> CREATE EXTENSION pgactive;
   ```

1. 使用下列命令，以更安全的方法將 RDS for PostgreSQL 第二個資料庫執行個體加入 `pgactive` 群組：

   ```
   -- connection info for endpoint1
   CREATE SERVER pgactive_server_endpoint1
       FOREIGN DATA WRAPPER pgactive_fdw
       OPTIONS (host '<endpoint1>', dbname 'app');
   CREATE USER MAPPING FOR postgres
       SERVER pgactive_server_endpoint1
       OPTIONS (user 'postgres', password '<password>');
   
   -- connection info for endpoint2
   CREATE SERVER pgactive_server_endpoint2
       FOREIGN DATA WRAPPER pgactive_fdw
       OPTIONS (host '<endpoint2>', dbname 'app');
   CREATE USER MAPPING FOR postgres
       SERVER pgactive_server_endpoint2
       OPTIONS (user 'postgres', password '<password>');
   ```

   ```
   SELECT pgactive.pgactive_join_group(
       node_name := 'endpoint2-app',
       node_dsn := 'user_mapping=postgres pgactive_foreign_server=pgactive_server_endpoint2',
       join_using_dsn := 'user_mapping=postgres pgactive_foreign_server=pgactive_server_endpoint1'
   );
   ```

   使用下列命令做為替代但較不安全的方法，將 RDS for PostgreSQL 第二個資料庫執行個體加入 `pgactive` 群組

   ```
   app=> SELECT pgactive.pgactive_join_group(
   node_name := 'node2-app',
   node_dsn := 'dbname=app host=secondinstance.111122223333.aws-region.rds.amazonaws.com user=postgres password=PASSWORD',
   join_using_dsn := 'dbname=app host=firstinstance.111122223333.aws-region.rds.amazonaws.com user=postgres password=PASSWORD');
   ```

   node2-app 是您指派的名稱，用於單獨識別 `pgactive` 群組中的節點。

1. 若要檢查資料庫執行個體是否已就緒，請使用下列命令：

   ```
   app=> SELECT pgactive.pgactive_wait_for_node_ready(); 
   ```

   如果命令成功，您會看到以下輸出內容：

   ```
   pgactive_wait_for_node_ready 
   ------------------------------ 
   (1 row)
   ```

   如果第一個 RDS for PostgreSQL 資料庫相對較大，您會看到 `pgactive.pgactive_wait_for_node_ready()` 發出還原操作的進度報告。輸出結果類似如下：

   ```
   NOTICE:  restoring database 'app', 6% of 7483 MB complete
   NOTICE:  restoring database 'app', 42% of 7483 MB complete
   NOTICE:  restoring database 'app', 77% of 7483 MB complete
   NOTICE:  restoring database 'app', 98% of 7483 MB complete
   NOTICE:  successfully restored database 'app' from node node1-app in 00:04:12.274956
    pgactive_wait_for_node_ready 
   ------------------------------ 
   (1 row)
   ```

   從這裡開始，`pgactive` 會在兩個資料庫執行個體之間同步資料。

1. 您可以使用下列命令來驗證第二個資料庫執行個體的資料庫是否有資料：

   ```
   app=> SELECT count(*) FROM inventory.products;
   ```

   如果資料已成功同步，您會看到下列輸出內容：

   ```
    count
   -------
    3
   ```

1. 執行下列命令以插入新值：

   ```
   app=> INSERT INTO inventory.products (id, product_name) VALUES (4, 'lotion');
   ```

1. 連線至第一個資料庫執行個體的資料庫，然後執行下列查詢：

   ```
   app=> SELECT count(*) FROM inventory.products;
   ```

   如果主動-主動式複寫已初始化，則會輸出類似下列內容：

   ```
   count
   -------
    4
   ```

**從 `pgactive` 群組卸離並移除資料庫執行個體**

您可以利用下列步驟將資料庫執行個體從 `pgactive` 群組卸離並移除：

1. 您可以使用下列命令將第二個資料庫執行個體從第一個資料庫執行個體卸離：

   ```
   app=> SELECT * FROM pgactive.pgactive_detach_nodes(ARRAY[‘node2-app']);
   ```

1. 使用下列命令從第二個資料庫執行個體移除 `pgactive` 延伸模組：

   ```
   app=> SELECT * FROM pgactive.pgactive_remove();
   ```

   若要強制移除延伸模組：

   ```
   app=> SELECT * FROM pgactive.pgactive_remove(true);
   ```

1. 使用以下命令刪除延伸模組：

   ```
   app=> DROP EXTENSION pgactive;
   ```

# 測量 pgactive 成員之間的複寫延遲
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.replicationlag"></a>

您可以使用下列查詢來檢視 `pgactive` 成員之間的複寫延遲。在每個 `pgactive` 節點上執行此查詢以取得全貌。

```
    
app=> SELECT * FROM pgactive.pgactive_get_replication_lag_info();
│-[ RECORD 1 ]--------+---------------------------------------------
│node_name            | node2-app
│node_sysid           | 7481018224801653637
│application_name     | pgactive:7481018224801653637:send
│slot_name            | pgactive_16385_7481018224801653637_0_16385__
│active               | t
│active_pid           | 783486
│pending_wal_decoding | 0
│pending_wal_to_apply | 0
│restart_lsn          | 0/2108150
│confirmed_flush_lsn  | 0/2154690
│sent_lsn             | 0/2154690
│write_lsn            | 0/2154690
│flush_lsn            | 0/2154690
│replay_lsn           | 0/2154690
│-[ RECORD 2 ]--------+---------------------------------------------
│node_name            | node1-app
│node_sysid           | 7481018033434600853
│application_name     | pgactive:7481018033434600853:send
│slot_name            | pgactive_16385_7481018033434600853_0_16385__
│active               | t
│active_pid           | 783488
│pending_wal_decoding | 0
│pending_wal_to_apply | 0
│restart_lsn          | 0/20F5AD0
│confirmed_flush_lsn  | 0/214EF68
│sent_lsn             | 0/214EF68
│write_lsn            | 0/214EF68
│flush_lsn            | 0/214EF68
│replay_lsn           | 0/214EF68
```

至少監控下列診斷：

active  
設定作用中為 false 時的警示，表示插槽目前未使用 (訂閱者執行個體已與發佈者中斷連線)。

pending\$1wal\$1decoding  
在 PostgreSQL 的邏輯複寫中，WAL 檔案會以二進位格式儲存。發佈者必須解碼這些 WAL 變更，並將其轉換為邏輯變更 (例如插入、更新或刪除操作)。  
指標 pending\$1wal\$1decoding 會顯示在發佈者端等待解碼的 WAL 檔案數目。  
此數字可能會因為下列因素而增加：  
+ 當訂閱者未連線時，作用中狀態將為 false，而 pending\$1wal\$1decoding 將會增加
+ 插槽處於作用中狀態，但發佈者無法跟上 WAL 變更的數量

pending\$1wal\$1to\$1apply  
指標 pending\$1wal\$1apply 表示在訂閱者端等待套用的 WAL 檔案數目。  
有幾個因素可能會阻止訂閱者套用變更，並可能導致磁碟已滿的情況：  
+ 結構描述差異 - 例如，當您對名為範例的資料表進行 WAL 串流的變更，但訂閱者端不存在該資料表時
+ 主索引鍵資料行中的值已更新
+ 次要唯一索引可能會導致資料差異。

# 設定 pgactive 延伸模組的參數設定
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters"></a>

您可以使用下列查詢來檢視與 `pgactive` 延伸模組相關聯的所有參數。

```
app=> SELECT * FROM pg_settings WHERE name LIKE 'pgactive.%';
```

您可以使用各種參數來設定 `pgactive` 延伸模組。這些參數可以透過 AWS 管理主控台 或 AWS CLI 界面設定。

## 主要 pgactive 延伸模組參數
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.mainparams"></a>

下表提供 `pgactive` 延伸模組主要參數的參考：


| 參數 | 單位 | 預設 | Description | 
| --- | --- | --- | --- | 
| pgactive.conflict\$1logging\$1include\$1tuples | `boolean` | –  | 記錄 `pgactive` 延伸模組的完整元組資訊。  需要重新啟動伺服器，變更才會生效。  | 
| pgactive.log\$1conflicts\$1to\$1table | `boolean` | –  | 決定 `pgactive` 延伸模組是否將偵測到的衝突記錄到 `pgactive.pgactive_conflict_history` 資料表。如需詳細資訊，請參閱衝突記錄以取得詳細資訊。  需要重新啟動伺服器，變更才會生效。  | 
| pgactive.log\$1conflicts\$1to\$1logfile | `boolean` | –  | 決定 `pgactive` 延伸模組是否將偵測到的衝突記錄到 PostgreSQL 日誌檔案。如需詳細資訊，請參閱衝突記錄以取得詳細資訊。  需要重新啟動伺服器，變更才會生效。  | 
| pgactive.synchronous\$1commit | `boolean` | off | 決定 pgactive 套用工作者的遞交行為。當停用 (關閉) 時，套用工作者會執行非同步遞交，這可在套用操作期間改善 PostgreSQL 輸送量，但會延遲對上游的重新執行確認。將其設定為 `off` 一律是安全的，不會導致交易遺失或略過。此設定只會影響下游節點上磁碟排清的時間，以及確認傳送至上游的時間。系統會延遲傳送重新執行排清確認，直到透過檢查點或定期工作等不相關的操作將遞交排清至磁碟為止。不過，如果上游在 `synchronous_standby_names` 中列出下游，則將其設定為 `off` 會導致上游的同步遞交需要更長的時間才能向用戶端報告成功。在此案例中，請將參數設定為 `on`。  即使此參數設為 `on` 且節點列在 `synchronous_standby_names` 中，在主動-主動組態中仍可能發生複寫衝突。這是因為系統缺少節點間鎖定和全域快照管理，允許不同節點上的並行交易修改相同的元組。此外，交易只有在上游節點上遞交之後才會開始複寫。啟用同步遞交不會將 pgactive 延伸模組轉換為始終一致的系統。  | 
| pgactive.temp\$1dump\$1directory | `string` | – | 定義初始設定期間資料庫複製操作所需的臨時儲存路徑。此目錄必須可由 postgres 使用者寫入，並且有足夠的儲存空間來包含完整的資料庫傾印。系統只會在具有邏輯複製操作的初始資料庫設定期間使用此位置。`pgactive_init_copy command` 不會使用此參數。 | 
| pgactive.max\$1ddl\$1lock\$1delay | `milliseconds` | `-1` | 指定強制中止並行寫入交易之前 DDL 鎖定的等待時間上限。預設值為 `-1`，採用 `max_standby_streaming_delay` 中設定的值。此參數接受時間單位。例如，您可以將其設定為 10s，代表 10 秒。在此等待期間，系統會嘗試取得 DDL 鎖定，同時等待進行中的寫入交易遞交或復原。如需詳細資訊，請參閱「DDL 鎖定」。 | 
| pgactive.ddl\$1lock\$1timeout | `milliseconds` | `-1` | 指定 DDL 鎖定嘗試等待多久才能取得鎖定。預設值為 `-1`，使用 lock\$1timeout 中指定的值。您可以使用時間單位設定此參數，例如 10s，代表 10 秒。此計時器只會控制取得 DDL 鎖定的等待期間。一旦系統取得鎖定並開始 DDL 操作，計時器就會停止。此參數不會限制可保留 DDL 鎖定的持續時間總計或整體 DDL 操作時間。若要控制操作的持續時間總計，請改用 `statement_timeout`。如需詳細資訊，請參閱「DDL 鎖定」。 | 
| pgactive.debug\$1trace\$1ddl\$1locks\$1level | `boolean` | –  | 覆寫 `pgactive` 延伸模組中 DDL 鎖定操作的預設偵錯日誌層級。設定時，此設定會導致 DDL 鎖定相關的訊息在 LOG 偵錯層級發出，而不是其預設層級。使用此參數來監控 DDL 鎖定活動，而無需在整個伺服器上啟用詳細 `DEBUG1` 或 `DEBUG2` 日誌層級。 可用日誌層級，依詳細程度增加： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) 如需監控選項的詳細資訊，請參閱「監控全域 DDL 鎖定」。  當您重新載入組態時，此設定的變更會生效。您不需要重新啟動伺服器。   | 

## 其他 pgactive 延伸模組參數
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.addparams"></a>

下表顯示 `pgactive` 延伸模組可用的較不常用和內部組態選項。


| 參數 | 單位 | 預設 | Description | 
| --- | --- | --- | --- | 
| pgactive.debug\$1apply\$1delay | `integer` | – |  為在其 `pgactive.pgactive_connections` 項目中沒有明確套用延遲的已設定連線設定套用延遲 (以毫秒為單位)。此延遲是在節點建立或聯結時間期間設定，且 pgactive 在遞交後至少經過指定的毫秒數之前，不會在對等節點上重新執行交易。 主要用於在測試環境中模擬高延遲網路，以更輕鬆地建立衝突。例如，在節點 A 和 B 上延遲 500 毫秒的情況下，在節點 A 上插入值後，您有至少 500 毫秒的時間在節點 B 上執行衝突的插入。  需要重新載入伺服器或重新啟動套用工作者才能生效。  | 
| pgactive.connectability\$1check\$1duration | `integer` | –  | 指定資料庫工作者在失敗嘗試期間嘗試建立連線的持續時間 (以秒為單位)。工作者會每秒進行一次連線嘗試，直到連線成功或達到此逾時值為止。當資料庫引擎在工作者準備好建立連線之前啟動時，此設定很有用。 | 
| pgactive.skip\$1ddl\$1replication | `boolean` | `on` | 在已啟用 `pgactive` 的情況下，控制在 Amazon RDS 中複寫或處理 DDL 變更的方式。設定為 `on` 時，節點會像非 pgcctive 節點一樣處理 DDL 變更。使用此參數時適用以下要求： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) 您可以使用兩種超級使用者權限來修改此參數：全域、本機 (工作階段層級)。  不正確地變更此參數可能會中斷複寫設定。  | 
| pgactive.do\$1not\$1replicate | `boolean` | – | 此參數僅供內部使用。當您在交易中設定此參數時，變更不會複寫至資料庫叢集中的其他節點。  不正確地變更此參數可能會中斷複寫設定。  | 
| pgactive.discard\$1mismatched\$1row\$1attributes | `boolean` | –  | 此參數僅供專家使用。建議您只在針對特定複寫問題進行疑難排解時，才使用此參數。在下列情況時使用此參數： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) 此設定會覆寫下列錯誤訊息，並允許出現資料差異，讓複寫繼續：`cannot right-pad mismatched attributes; attno %u is missing in local table and remote row has non-null, non-dropped value for this attribute`  不正確地變更此參數可能會中斷複寫設定。   | 
| pgactive.debug\$1trace\$1replay | `boolean` | – | 設定為 `on` 時，它會針對下游套用工作者程序的每個遠端動作發出日誌訊息。日誌包括： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) 日誌也會擷取排入佇列的 DDL 命令和資料表捨棄。para> 根據預設，日誌不包含資料列欄位內容。若要在日誌中包含資料列值，您必須重新編譯並啟用下列旗標： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html)  啟用此記錄設定可能會影響效能。建議您僅在需要進行疑難排解時啟用它。當您重新載入組態時，此設定的變更會生效。您不需要重新啟動伺服器。   | 
| pgactive.extra\$1apply\$1connection\$1options |  | – | 您可以為具有 pgactive 節點的所有對等節點連線設定連線參數。這些參數會控制保持連線和 SSL 模式等設定。根據預設，pgactive 會使用下列連線參數： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) 若要覆寫預設參數，請使用下列類似命令： pgactive.extra\$1apply\$1connection\$1options = 'keepalives=0' 個別節點連線字串優先於這些設定和 pgactive 的內建連線選項。如需連線字串格式的詳細資訊，請參閱 [libpq 連線字串](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING)。 建議您保持預設保持連線設定為啟用狀態。只有在大型交易透過不可靠的網路完成時遇到問題的情況下，才停用保持連線。  建議您保持預設保持連線設定為啟用狀態。只有在大型交易透過不可靠的網路完成時遇到問題的情況下，才停用保持連線。當您重新載入組態時，此設定的變更會生效。您不需要重新啟動伺服器。  | 
| pgactive.init\$1node\$1parallel\$1jobs (int) |  | – | 指定 `pg_dump` 和 `pg_restore` 可在與 `pgactive.pgactive_join_group` 函數的邏輯節點聯結期間使用的平行任務數目。 當您重新載入組態時，此設定的變更會生效。您不需要重新啟動伺服器。 | 
| pgactive.max\$1nodes | `int` | 4 |  指定 pgactive 延伸模組群組中允許的節點數目上限。預設值為 4 個節點。設定此參數的值時，您必須考量下列事項： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) 您有兩種方式可以設定此參數：在組態檔案中，使用 `ALTER SYSTEM SET` 命令 此參數的預設值為 `4`，表示 `pgactive` 延伸模組群組在任何時間點最多可以有 4 個節點。  變更會在您重新啟動伺服器後生效。  | 
| pgactive.permit\$1node\$1identifier\$1getter\$1function\$1creation | `boolean` | – | 此參數僅供內部使用。啟用時，`pgactive` 延伸模組允許建立 pgactive 節點識別符 getter 函數。 | 

# 了解主動-主動衝突
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.replication"></a>

當您在主動-主動模式下使用 pgactive 時，從多個節點寫入相同的資料表可能會產生資料衝突。雖然某些叢集系統使用分散式鎖定來防止並行存取，但 pgactive 採取了更樂觀的方法，更適合地理分散式應用程式。

有些資料庫叢集系統會使用分散式鎖定來防止並行資料存取。雖然此方法可在伺服器接近時運作，但它不支援地理分散式應用程式，因為它需要極低的延遲才能獲得良好的效能。pgactive 延伸模組使用樂觀的方法，而不是使用分散式鎖定 (悲觀方法)。這表示：
+ 協助您盡可能避免衝突。
+ 允許發生特定類型的衝突。
+ 在發生衝突時提供衝突解決方法。

此方法可讓您在建置分散式應用程式時更具彈性。

## 衝突的發生方式
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.howconflicts"></a>

如果所有涉及的交易都在相同節點上同時發生，則無法發生的事件序列會產生節點間衝突。由於節點只會在交易遞交之後交換變更，因此每個交易個別對其遞交的節點有效，但如果在同時完成其他工作的另一個節點上執行，則會無效。由於 pgactive 套用基本上會在其他節點上重新執行交易，如果套用的交易與在接收節點上遞交的交易之間發生衝突，則重新執行操作可能會失敗。

 當所有交易都在單一節點上執行時，大多數衝突不會發生的原因是 PostgreSQL 具有防止衝突的交易間通訊機制，包括：
+ UNIQUE 索引
+ 序列
+ 資料列和關聯鎖定
+ SERIALIZABLE 相依性追蹤

這裡的所有機制都是在交易之間進行通訊的方式，以防止不需要的並行問題

pgactive 可實現低延遲並妥善處理網路分割區，因為它不使用分散式交易管理員或鎖定管理員。不過，這表示不同節點上交易的執行彼此完全隔離。雖然隔離通常會改善資料庫一致性，但在這種情況下，您需要減少隔離以防止衝突。

## 衝突類型
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflicttypes"></a>

可能發生的衝突包括：

**Topics**
+ [PRIMARY KEY 或 UNIQUE 衝突](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict1)
+ [INSERT/INSERT 衝突](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict2)
+ [違反多個 UNIQUE 限制條件的 INSERT](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict3)
+ [UPDATE/UPDATE 衝突](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict4)
+ [PRIMARY KEY 上的 UPDATE 衝突](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict5)
+ [違反多個 UNIQUE 限制條件的 UPDATE](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict6)
+ [UPDATE/DELETE 衝突](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict7)
+ [INSERT/UPDATE 衝突](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict8)
+ [DELETE/DELETE 衝突](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict9)
+ [外部索引鍵限制條件衝突](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict10)
+ [排除限制條件衝突](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict11)
+ [全域資料衝突](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict12)
+ [鎖定衝突和死鎖中止](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict13)
+ [分歧衝突](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict14)

### PRIMARY KEY 或 UNIQUE 衝突
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict1"></a>

當多個操作嘗試以在單一節點上不可行的方式修改相同的資料列索引鍵時，就會發生資料列衝突。這些衝突代表最常見的資料衝突類型。

pgactive 透過 last-update-wins 處理或您的自訂衝突處理常式來解決偵測到的衝突。

資料列衝突包括：
+ INSERT 與 INSERT
+ INSERT 與 UPDATE
+ UPDATE 與 DELETE
+ INSERT 與 DELETE
+ DELETE 與 DELETE
+ INSERT 與 DELETE

### INSERT/INSERT 衝突
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict2"></a>

當兩個不同節點上的 INSERT 建立具有相同 PRIMARY KEY 值 (或不存在 PRIMARY KEY 時相同的 UNIQUE 限制條件值) 的元組時，就會發生此最常見的衝突。

pgactivelink 使用來自原始主機的時間戳記來保留最新的元組，以解決 INSERT 衝突。您可以使用自訂衝突處理常式覆寫此預設行為。雖然此程序不需要特殊管理員動作，但請注意，pgactivelink 會捨棄所有節點的其中一個 INSERT 操作。除非您的自訂處理常式實作，否則不會自動合併資料。

pgactivelink 只能解決涉及單一限制條件違規的衝突。如果 INSERT 違反多個 UNIQUE 限制條件，您必須實作額外的衝突解決策略。

### 違反多個 UNIQUE 限制條件的 INSERT
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict3"></a>

INSERT/INSERT 衝突可能會違反多個 UNIQUE 限制條件，包括 PRIMARY KEY。pgactivelink 只能處理涉及單一 UNIQUE 限制條件的衝突。當衝突違反多個 UNIQUE 限制條件時，套用工作者會失敗並傳回下列錯誤：

`multiple unique constraints violated by remotely INSERTed tuple.`

在較舊版本中，此情況會產生「發散唯一性衝突」錯誤。

若要解決這些衝突，您必須採取手動動作。針對衝突的本機元組進行 DELETE 操作或進行 UPDATE 操作，以移除與新遠端元組的衝突。請注意，您可能需要處理多個衝突元組。目前，pgactivelink 不提供內建功能來忽略、捨棄或合併違反多個唯一限制條件的元組。

**注意**  
如需詳細資訊，請參閱違反多個 UNIQUE 限制條件的 UPDATE。

### UPDATE/UPDATE 衝突
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict4"></a>

當兩個節點同時修改相同的元組而不變更其 PRIMARY KEY 時，就會發生此衝突。如果已定義，pgactivelink 會使用 last-update-wins 邏輯或您的自訂衝突處理常式來解決這些衝突。PRIMARY KEY 對於元組比對和衝突解決至關重要。對於沒有 PRIMARY KEY 的資料表，pgactivelink 會拒絕 UPDATE 操作，並顯示下列錯誤：

`Cannot run UPDATE or DELETE on table (tablename) because it does not have a primary key.`

### PRIMARY KEY 上的 UPDATE 衝突
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict5"></a>

pgactive 在處理 PRIMARY KEY 更新時有限制。雖然您可以在 PRIMARY KEY 上執行 UPDATE 操作，但 pgactive 無法針對這些操作使用 last-update-wins 邏輯自動解決衝突。您必須確保 PRIMARY KEY 更新不會與現有值衝突。如果在 PRIMARY KEY 更新期間發生衝突，它們會成為需要您手動介入的分歧衝突。如需處理這些情況的詳細資訊，請參閱 [分歧衝突](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict14)。

### 違反多個 UNIQUE 限制條件的 UPDATE
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict6"></a>

當傳入 UPDATE 違反多個 UNIQUE 限制條件或 PRIMARY KEY 值時，pgactivelink 無法套用 last-update-wins 衝突解決方法。此行為類似於違反多個限制條件的 INSERT 操作。這些情況會產生需要您手動介入的分歧衝突。如需詳細資訊，請參閱[分歧衝突](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict14)。

### UPDATE/DELETE 衝突
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict7"></a>

當一個節點對資料列進行 UPDATE 操作，而另一個節點同時對資料列進行 DELETE 操作時，就會發生此衝突。在此情況下，重新執行時會發生 UPDATE/DELETE 衝突。解決方法是捨棄 DELETE 之後到達的任何 UPDATE，除非您的自訂衝突處理常式另有指定。

pgactivelink 需要 PRIMARY KEY 以比對元組並解決衝突。對於沒有 PRIMARY KEY 的資料表，它會拒絕 DELETE 操作，並顯示下列錯誤：

`Cannot run UPDATE or DELETE on table (tablename) because it does not have a primary key.`

**注意**  
pgactivelink 無法區分 UPDATE/DELETE 和 INSERT/UPDATE 衝突。在這兩種情況下，UPDATE 都會影響不存在的資料列。由於非同步複寫和節點之間缺少重新執行順序，pgactivelink 無法判斷 UPDATE 是用於新資料列 (尚未收到 INSERT) 或刪除的資料列。在這兩種情況下，pgactivelink 都會捨棄 UPDATE。

### INSERT/UPDATE 衝突
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict8"></a>

此衝突可能發生在多節點環境中。當一個節點針對資料列進行 INSERT 操作、第二個節點進行 UPDATE 操作，以及第三個節點在原始 INSERT 之前收到 UPDATE 時，就會發生這種情況。根據預設，除非您的自訂衝突觸發條件另有指定，否則 pgactivelink 會透過捨棄 UPDATE 來解決這些衝突。請注意，此解決方法可能會導致節點之間的資料不一致。如需類似案例及其處理方式的詳細資訊，請參閱 [UPDATE/DELETE 衝突](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict7)。

### DELETE/DELETE 衝突
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict9"></a>

當兩個不同的節點同時刪除相同的元組時，就會發生此衝突。pgactivelink 會將這些衝突視為無害，因為這兩個 DELETE 操作都有相同的最終結果。在此案例中，pgactivelink 會安全地忽略其中一個 DELETE 操作，而不會影響資料一致性。

### 外部索引鍵限制條件衝突
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict10"></a>

FOREIGN KEY 限制條件可能會在將遠端交易套用至現有本機資料時造成衝突。當交易套用的順序與原始節點上的邏輯順序不同時，通常會發生這些衝突。

根據預設，pgactive 會將 session\$1replication\$1role 的變更套用為 `replica`，這會在複寫期間略過外部索引鍵檢查。在主動-主動組態中，這可能會導致外部索引鍵違規。大多數違規都是暫時性的，一旦複寫追上進度就會解決。不過，由於 pgactive 不支援跨節點資料列鎖定，因此可能會發生外部索引鍵懸置。

這是分區容限非同步主動-主動系統的固有行為。例如，節點 A 可能會插入新的子資料列，而節點 B 在此同時刪除其父資料列。系統無法防止跨節點進行此類並行修改。

若要將外部索引鍵衝突降至最低，建議您執行下列動作：
+ 將外部索引鍵關係限制在密切相關的實體。
+ 盡可能從單一節點修改相關實體。
+ 選擇很少需要修改的實體。
+ 實作應用程式層級並行控制以進行修改。

### 排除限制條件衝突
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict11"></a>

 pgactive 連結不支援排除限制條件，並限制其建立。

**注意**  
如果您將現有的獨立資料庫轉換為 pgactivelink 資料庫，請手動捨棄所有排除限制條件。

在分散式非同步系統中，無法保證沒有任何一組資料列違反限制條件。這是因為不同節點上的所有交易都完全隔離。排除限制條件可能會導致重新執行死鎖，其中由於違反排除限制條件，重新執行無法從任何節點進展到另一個節點。

如果您強制 pgactive 連結建立排除限制條件，或在將獨立資料庫轉換為 pgactive 連結時未捨棄現有限制條件，複寫可能會中斷。若要還原複寫進度，請移除或更改與傳入遠端元組衝突的本機元組，以便套用遠端交易。

### 全域資料衝突
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict12"></a>

使用 pgactivelink 時，如果節點具有不同的全域 PostgreSQL 全系統資料 (例如角色)，可能會發生衝突。這些衝突可能會導致操作 (主要是 DDL) 在一個節點上成功並遞交，但無法套用至其他節點。

如果使用者存在於一個節點，但不存在於另一個節點，則可能會發生複寫問題：
+ Node1 有名為 `fred` 的使用者，但 Node2 上不存在此使用者
+ 當 `fred` 在 Node1 上建立資料表時，資料表會以具備擁有者身分的 `fred` 進行複寫
+ 當此 DDL 命令套用至 Node2 時會失敗，因為使用者 `fred` 不存在
+ 此失敗會在 Node2 上的 PostgreSQL 日誌中產生錯誤，並讓 `pgactive.pgactive_stats.nr_rollbacks` 計數器增量

**解決方案：**在 Node2 上建立使用者 `fred`。使用者不需要相同的許可，但必須同時存在於兩個節點上。

如果資料表存在於一個節點，但不存在於另一個節點，資料修改操作將會失敗：
+ Node1 具有名為 `foo` 的資料表，該資料表不存在於 Node2
+ 複寫至 Node2 時，Node1 上 `foo` 資料表上的任何 DML 操作都會失敗

**解決方案：**在 Node2 上使用相同結構建立資料表 `foo`。

**注意**  
pgactivelink 目前不會複寫 CREATE USER 命令或 DDL 操作。DDL 複寫計畫用於未來版本。

### 鎖定衝突和死鎖中止
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict13"></a>

由於 pgactive 套用程序的運作方式與一般使用者工作階段類似，因此會遵循標準資料列和資料表鎖定規則。這可能會導致 pgactivelink 套用程序等待使用者交易或其他套用程序所保留的鎖定。

下列類型的鎖定可能會影響套用程序：
+ 依使用者工作階段的明確資料表層級鎖定 (LOCK TABLE ...)
+ 依使用者工作階段的明確資料列層級鎖定 (SELECT ... FOR UPDATE/FOR SHARE)
+ 從外部索引鍵鎖定
+ 從本機活動或從其他伺服器套用，由於資料列 UPDATE、INSERT 或 DELETE 的隱含鎖定

死鎖可能在以下項目之間發生：
+ pgactivelink 套用程序和使用者交易
+ 兩個套用程序

發生死鎖時，PostgreSQL 的死鎖偵測器會終止其中一個問題交易。如果 pgactivelink 套用工作者的程序已終止，則會自動重試，且通常會成功。

**注意**  
這些問題是暫時性的，通常不需要管理員介入。如果閒置使用者工作階段上的鎖定封鎖套用程序一段時間，您可以終止使用者工作階段以繼續複寫。這種情況類似於當使用者保留會影響另一個使用者工作階段的長鎖定時。
若要識別鎖定相關重新執行延遲，請在 PostgreSQL 中啟用 `log_lock_waits` 設施。

### 分歧衝突
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict14"></a>

當節點之間應該相同的資料意外不同時，就會發生分歧衝突。雖然不應發生這些衝突，但無法在目前的實作中可靠地防止所有衝突。

**注意**  
 如果另一個節點在所有節點處理變更之前變更相同資料列的索引鍵，修改資料列的 PRIMARY KEY 可能會導致分歧衝突。避免變更主索引鍵，或將變更限制在一個指定的節點。如需詳細資訊，請參閱[PRIMARY KEY 上的 UPDATE 衝突](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict5)。

涉及資料列資料的分歧衝突通常需要管理員介入。若要解決這些衝突，您必須手動調整一個節點上的資料以符合另一個節點，同時使用 `pgactive.pgactive_do_not_replicate` 暫時停用複寫。當您依照文件記錄使用 pgactive，並避免將設定或函數標記為不安全時，不應發生這些衝突。

 身為管理員，您必須手動解決這些衝突。根據衝突類型，您需要使用進階選項，例如 `pgactive.pgactive_do_not_replicate`。請謹慎使用這些選項，因為不當使用可能會使情況惡化。由於各種可能的衝突，我們無法提供通用的解決方法指示。

當不同節點之間應該相同的資料意外不同時，就會發生分歧衝突。雖然不應發生這些衝突，但無法在目前的實作中可靠地防止所有此類衝突。

## 避免或容忍衝突
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.avoidconflicts"></a>

 在大多數情況下，您可以使用適當的應用程式設計來避免衝突，或讓您的應用程式能夠容忍衝突。

 只有在多個節點上同時發生操作時，才會發生衝突。若要避免衝突：
+ 僅寫入一個節點
+ 寫入每個節點上的獨立資料庫子集 (例如，為每個節點指派個別結構描述)

對於 INSERT 與 INSERT 衝突，請使用全域序列來完全防止衝突。

 如果您的使用案例無法接受衝突，請考慮在應用程式層級實作分散式鎖定。最佳方法通常是設計您的應用程式以使用 pgactive 的衝突解決機制，而不是嘗試防止所有衝突。如需詳細資訊，請參閱[衝突類型](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflicttypes)。

## 衝突記錄
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflictlogging"></a>

pgactivelink 會在 `pgactive.pgactive_conflict_history` 資料表中記錄衝突事件，協助您診斷和處理主動-主動衝突。只有在您將 `pgactive.log_conflicts_to_table` 設定為 true 時，才會將衝突記錄到此資料表。當 log\$1min\$1messages 設定為 `LOG` 或 `lower` 時，無論 `pgactive.log_conflicts_to_table` 設定為何，pgactive 延伸模組也會將衝突記錄到 PostgreSQL 日誌檔案。

 使用衝突歷史記錄資料表：
+ 測量應用程式產生衝突的頻率
+ 識別衝突發生的位置
+ 改善您的應用程式以降低衝突率
+ 偵測衝突解決方法未產生所需結果的情況
+ 判斷您需要使用者定義的衝突觸發條件或應用程式設計變更的位置

 對於資料列衝突，您可以選擇性地記錄資料列值。這是由 `pgactive.log_conflicts_to_table` 設定所控制。請注意：
+ 這是全域全資料庫選項
+ 無法對資料列值記錄進行每個資料表控制
+ 欄位號碼、陣列元素或欄位長度未套用任何限制
+ 如果您使用可能觸發衝突的多 MB 資料列，則不建議啟用此功能

 由於衝突歷史記錄資料表包含資料庫中每個資料表的資料 (每個資料庫可能有不同的結構描述)，因此記錄的資料列值會儲存為 JSON 欄位。JSON 是使用 `row_to_json` 建立的，類似於直接從 SQL 呼叫它。PostgreSQL 不提供 `json_to_row` 函數，因此您需要資料表特定的程式碼 (PL/pgSQL、PL/Python、PL/Perl 等)，才能從記錄的 JSON 重建複合類型元組。

**注意**  
使用者定義衝突的支援會規劃為未來的延伸模組功能。

# 了解 pgactive 結構描述
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.schema"></a>

pgactive 結構描述會管理 RDS for PostgreSQL 中的主動-主動複寫。此結構描述包含儲存複寫組態和狀態資訊的資料表。

**注意**  
pgactive 結構描述正在演進，可能會有所變更。請勿直接修改這些資料表中的資料。

pgactive 結構描述中的索引鍵資料表包括：
+ `pgactive_nodes` – 儲存主動-主動複寫群組中節點的相關資訊。
+ `pgactive_connections` – 儲存每個節點的連線詳細資訊。

## pgactive\$1nodes
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.schema.nodes"></a>

pgactive\$1nodes 會儲存參與主動-主動複寫群組之節點的相關資訊。


| 資料行 | Type | 定序 | Nullable | 預設 | 
| --- | --- | --- | --- | --- | 
| node\$1sysid | text | – | 非 NULL | – | 
| node\$1timeline | oid | – | 非 NULL | – | 
| node\$1dboid | oid | – | 非 NULL | – | 
| node\$1status | char | – | 非 NULL | – | 
| node\$1name | text | – | 非 NULL | – | 
| node\$1dsn | text | – | 非 NULL | – | 
| node\$1init\$1from\$1dsn | text | – | 非 NULL | – | 
| node\$1read\$1only | boolean | – | – | false | 
| node\$1seq\$1id | smallint | – | 非 NULL | – | 

**node\$1sysid**  
節點的唯一 ID，在 `pgactive_create_group` 或 `pgactive_join_group` 期間產生

**node\$1status**  
節點的整備程度：  
+ **b** - 開始設定
+ **i** - 初始化
+ **c** - 追趕
+ **o** - 建立傳出插槽
+ **r** - 就緒
+ **k** - 已終止
此資料行不會指出節點是否已連線或中斷連線。

**node\$1name**  
使用者提供的唯一節點名稱。

**node\$1dsn**  
連線字串或使用者映射名稱

**node\$1init\$1from\$1dsn**  
建立此節點的 DSN。

## pgactive\$1connection
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.schema.connection"></a>

pgactive\$1connections 會儲存每個節點的連線詳細資訊。


| 資料行 | Type | 定序 | Nullable | 預設 | 
| --- | --- | --- | --- | --- | 
| conn\$1sysid | text | 無 | 非 NULL | 無 | 
| conn\$1timeline | oid | 無 | 非 NULL | 無 | 
| conn\$1dboid | oid | 無 | 非 NULL | 無 | 
| conn\$1dsn | text | 無 | 非 NULL | 無 | 
| conn\$1apply\$1delay | integer | 無 | 無 | 無 | 
| conn\$1replication\$1sets | text | 無 | 無 | 無 | 

conn\$1sysid  
此項目所參考節點的節點識別符。

conn\$1dsn  
與 pgactive.pgactive\$1nodes `node_dsn` 相同。

conn\$1apply\$1delay  
如果設定，在從遠端節點套用每個交易之前，要等待的毫秒數。主要用於偵錯。如果為 null，則套用全域預設值。

## 使用複寫集
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.replication"></a>

複寫集會決定要從複寫操作中包含或排除哪些資料表。根據預設，除非您使用下列函數另外指定，否則會複寫所有資料表：
+ `pgactive_exclude_table_replication_set()` - 從複寫中排除指定的資料表
+ `pgactive_include_table_replication_set()` - 在複寫中包含指定的資料表

**注意**  
設定複寫集之前，請考慮下列事項：  
您只能在執行 `pgactive_create_group()` 之後但在 `pgactive_join_group()` 之前設定資料表包含或排除。
使用 `pgactive_exclude_table_replication_set()` 之後，您就無法使用 `pgactive_include_table_replication_set()`。
使用 `pgactive_include_table_replication_set()` 之後，您就無法使用 `pgactive_exclude_table_replication_set()`。

系統會根據您的初始組態，以不同的方式處理新建立的資料表：
+ 如果您排除資料表：在 `pgactive_join_group()` 之後建立的任何新資料表都會自動包含在複寫中
+ 如果您包含資料表：在 `pgactive_join_group()` 之後建立的任何新資料表都會自動從複寫中排除。

若要檢視特定資料表的複寫集組態，請使用 `pgactive.pgactive_get_table_replication_sets()` 函數。

# pgactive 函數參考
<a name="pgactive-functions-reference"></a>

以下列出 pgactive 函數及其參數、傳回值，和協助您有效加以使用的實務使用須知：

## get\$1last\$1applied\$1xact\$1info
<a name="get-last-applied-xact-info"></a>

擷取指定節點的上次套用交易資訊。

**Arguments (引數)**  
+ sysid (文字) - 時間軸 OID
+ dboid (OID)

**傳回類型**  
會記錄下列項目：  
+ last\$1applied\$1xact\$1id (OID)
+ last\$1applied\$1xact\$1committs (含時區的時間戳記)
+ last\$1applied\$1xact\$1at (含時區的時間戳記)

**使用須知**  
使用此函數可擷取指定節點的上次套用交易資訊。

## pgactive\$1apply\$1pause
<a name="pgactive-apply-pause"></a>

暫停複寫套用程序。

**Arguments (引數)**  
無

**傳回類型**  
boolean

**使用須知**  
呼叫此函數可暫停複寫套用程序。

## pgactive\$1apply\$1resume
<a name="pgactive-apply-resume"></a>

繼續複寫套用程序。

**Arguments (引數)**  
無

**傳回類型**  
void

**使用須知**  
呼叫此函數可繼續複寫套用程序。

## pgactive\$1is\$1apply\$1paused
<a name="pgactive-is-apply-paused"></a>

檢查複寫目前是否暫停。

**Arguments (引數)**  
無

**傳回類型**  
boolean

**使用須知**  
使用此函數可檢查複寫套用目前是否暫停。

## pgactive\$1create\$1group
<a name="pgactive-create-group"></a>

藉由將獨立資料庫轉換為初始節點，來建立 pgactive 群組。



**Arguments (引數)**  
+ node\$1name (文字)
+ node\$1dsn (文字)
+ apply\$1delay integer DEFAULT NULL::integer - replication\$1sets text[] DEFAULT ARRAY[‘default’::text]

**傳回類型**  
void

**使用須知**  
藉由將獨立資料庫轉換為初始節點，來建立 pgactive 群組。此函數會在節點轉換為 pgactive 節點之前執行健全性檢查。使用此函數之前，請確定 PostgreSQL 叢集有足夠的 `max_worker_processes` 可支援 pgactive 背景工作者。

## pgactive\$1detach\$1nodes
<a name="pgactive-detach-nodes"></a>

從 pgactive 群組中移除指定的節點。

**Arguments (引數)**  
+ p\$1nodes (text[])

**傳回類型**  
void

**使用須知**  
使用此函數可從 pgactive 群組中移除指定的節點。

## pgactive\$1exclude\$1table\$1replication\$1set
<a name="pgactive-exclude-table-replication-set"></a>

將特定資料表排除於複寫外。

**Arguments (引數)**  
+ p\$1relation (regclass)

**傳回類型**  
void

**使用須知**  
使用此函數可將特定資料表排除於複寫外。

## pgactive\$1get\$1replication\$1lag\$1info
<a name="pgactive-get-replication-lag-info"></a>

擷取詳細的複寫延遲資訊，包括節點詳細資訊、WAL 狀態和 LSN 值。

**Arguments (引數)**  
無

**傳回類型**  
SETOF 記錄 - node\$1name text - node\$1sysid text - application\$1name text - slot\$1name text - active boolean - active\$1pid integer - pending\$1wal\$1decoding bigint - 在寄件者節點上解碼的 WAL 約略大小 (位元組) - pending\$1wal\$1to\$1apply bigint - 要在接收節點上套用的 WAL 約略大小 (位元組) - restart\$1lsn pg\$1lsn - confirmed\$1flush\$1lsn pg\$1lsn - sent\$1lsn pg\$1lsn - write\$1lsn pg\$1lsn - flush\$1lsn pg\$1lsn - replay\$1lsn pg\$1lsn

**使用須知**  
呼叫此函數可擷取複寫延遲資訊，包括節點詳細資訊、WAL 狀態和 LSN 值。

## pgactive\$1get\$1stats
<a name="pgactive-get-stats"></a>

擷取 pgactive 複寫統計資料。

**Arguments (引數)**  
無

**傳回類型**  
SETOF 記錄 - rep\$1node\$1id oid - rilocalid oid - riremoteid text - nr\$1commit bigint - nr\$1rollback bigint - nr\$1insert bigint - nr\$1insert\$1conflict bigint - nr\$1update bigint - nr\$1update\$1conflict bigint - nr\$1delete bigint - nr\$1delete\$1conflict bigint - nr\$1disconnect bigint

**使用須知**  
使用此函數可擷取 pgactive 複寫統計資料。

## pgactive\$1get\$1table\$1replication\$1sets
<a name="pgactive-get-table-replication-sets"></a>

取得特定關係的複寫集組態。

**Arguments (引數)**  
+ relation (regclass)

**傳回類型**  
SETOF 記錄

**使用須知**  
呼叫此函數可取得特定關係的複寫集組態。

## pgactive\$1include\$1table\$1replication\$1set
<a name="pgactive-include-table-replication-set"></a>

在複寫中包含特定資料表。

**Arguments (引數)**  
+ p\$1relation (regclass)

**傳回類型**  
void

**使用須知**  
使用此函數可在複寫中包含特定資料表。

## pgactive\$1join\$1group
<a name="pgactive-join-group"></a>

將節點新增至現有的 pgactive 群組。

**Arguments (引數)**  
+ node\$1name (文字)
+ node\$1dsn (文字)
+ join\$1using\$1dsn (文字)
+ apply\$1delay (整數，選用)
+ replication\$1sets (text[]，預設值：['default'])
+ bypass\$1collation\$1check (布林值，預設值：false)
+ bypass\$1node\$1identifier\$1creation (布林值，預設值：false)
+ bypass\$1user\$1tables\$1check (布林值，預設值：false)

**傳回類型**  
void

**使用須知**  
呼叫此函數，可將節點新增至現有的 pgactive 群組。請確定您的 PostgreSQL 叢集有足夠的 max\$1worker\$1processes 供 pgactive 背景工作者使用。

## pgactive\$1remove
<a name="pgactive-remove"></a>

從本機節點中移除所有 pgactive 元件。

**Arguments (引數)**  
+ force (布林值，預設值：false)

**傳回類型**  
void

**使用須知**  
呼叫此函數，從本機節點中移除所有 pgactive 元件。

## pgactive\$1snowflake\$1id\$1nextval
<a name="pgactive-snowflake-id-nextval"></a>

產生節點特定的唯一序列值。

**Arguments (引數)**  
+ regclass

**傳回類型**  
bigint

**使用須知**  
使用此函數可產生節點特定的唯一序列值。

## pgactive\$1update\$1node\$1conninfo
<a name="pgactive-update-node-conninfo"></a>

更新 pgactive 節點的連線資訊。

**Arguments (引數)**  
+ node\$1name\$1to\$1update (文字)
+ node\$1dsn\$1to\$1update (文字)

**傳回類型**  
void

**使用須知**  
使用此函數可更新 pgactive 節點的連線資訊。

## pgactive\$1wait\$1for\$1node\$1ready
<a name="pgactive-wait-for-node-ready"></a>

監控群組建立或加入操作的進度。

**Arguments (引數)**  
+ 逾時 (整數，預設值：0)
+ progress\$1interval (整數，預設值：60)

**傳回類型**  
void

**使用須知**  
呼叫此函數可監控群組建立或加入操作的進度。

# 處理主動-主動式複寫中的衝突
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-conflicts"></a>

`pgactive` 延伸模組是在每個資料庫上運作，而不是每個叢集。使用 `pgactive` 的每個資料庫執行個體都是獨立的執行個體，可接受任何來源的資料變更。將變更傳送至資料庫執行個體時，PostgreSQL 會在本機上遞交該變更，然後使用 `pgactive` 以非同步方式將變更複寫到其他資料庫執行個體。當兩個 PostgreSQL 資料庫執行個體幾乎同時更新相同的記錄時，可能會發生衝突。

`pgactive` 延伸模組提供了衝突偵測和自動解決的機制。它會追蹤交易在兩個資料庫執行個體上得到認可的時間戳記，並自動套用具有最新時間戳記的變更。`pgactive` 延伸模組也會記錄 `pgactive.pgactive_conflict_history` 資料表中發生的衝突。

`pgactive.pgactive_conflict_history` 會持續成長。您可能想要定義清除政策。這可以透過定期刪除一些記錄或定義此關係的分割結構描述 (以及稍後分離、捨棄、截斷感興趣的分割區) 來完成。若要定期實作清除政策，其中一個選項是使用 `pg_cron` 延伸模組。請參閱 `pg_cron` 歷史記錄資料表範例的下列資訊，[使用 PostgreSQL pg\$1cron 延伸模組排程維護](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/PostgreSQL_pg_cron.html)。

# 處理主動-主動式複寫中的序列
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-sequences"></a>

具有 `pgactive` 延伸模組的 RDS for PostgreSQL 資料庫執行個體使用兩種不同的序列機制來產生唯一值。

**全域序列**  
若要使用全域序列，請使用 `CREATE SEQUENCE` 陳述式建立本機序列。不要使用 `usingnextval(seqname)`，而是使用 `pgactive.pgactive_snowflake_id_nextval(seqname)` 來取得序列中的下一個唯一值。

下列範例會建立全域序列：

```
app=> CREATE TABLE gstest (
      id bigint primary key,
      parrot text
    );
```

```
app=>CREATE SEQUENCE gstest_id_seq OWNED BY gstest.id;
```

```
app=> ALTER TABLE gstest \
      ALTER COLUMN id SET DEFAULT \
      pgactive.pgactive_snowflake_id_nextval('gstest_id_seq');
```

**分割序列**  
在拆分步驟或分割序列中，每個節點上會使用標準 PostgreSQL 序列。每個序列會以相同的量遞增，並從不同的偏移量開始。例如，若是步進 100，節點 1 會產生序列為 101、201、301，依此類推，而節點 2 會產生序列為 102、202、302，依此類推。即使節點無法長時間通訊，此結構仍能正常運作，但是設計人員必須在建立結構描述時指定最大節點數，並且需要每個節點的組態。若發生錯誤，便容易導致序列重疊。

透過在節點上建立所需的序列來對 `pgactive` 設定此方法相對較為簡單，如下所示：

```
CREATE TABLE some_table (generated_value bigint primary key);
```

```
app=> CREATE SEQUENCE some_seq INCREMENT 100 OWNED BY some_table.generated_value;
```

```
app=> ALTER TABLE some_table ALTER COLUMN generated_value SET DEFAULT nextval('some_seq');
```

然後在每個節點上呼叫，以提供不同的偏移量起始值，如下所示。

```
app=>
-- On node 1
SELECT setval('some_seq', 1);

-- On node 2
SELECT setval('some_seq', 2);
```

# 使用 pg\$1repack 擴充功能減少資料表和索引膨脹
<a name="Appendix.PostgreSQL.CommonDBATasks.pg_repack"></a>

您可以使用 `pg_repack` 延伸模組，移除資料表和索引膨脹情形，做為 `VACUUM FULL` 的替代項目。RDS for PostgreSQL 9.6.3 及更新版本支援此擴充功能。如需 `pg_repack` 延伸模組和完整資料表重新封裝的詳細資訊，請參閱 [GitHub 專案文件](https://reorg.github.io/pg_repack/)。

與 `VACUUM FULL` 不同，在下列情況下，`pg_repack` 延伸模組在資料表重建操作期間只需要短暫的專屬鎖定 (AccessExclusiveLock)：
+ 初始建立日誌資料表 – 建立日誌資料表以記錄資料初始複製期間發生的變更，如下列範例所示：

  ```
  postgres=>\dt+ repack.log_*
  List of relations
  -[ RECORD 1 ]-+----------
  Schema        | repack
  Name          | log_16490
  Type          | table
  Owner         | postgres
  Persistence   | permanent
  Access method | heap
  Size          | 65 MB
  Description   |
  ```
+ 最終交換放置階段。

對於其他重建操作，只需要 `ACCESS SHARE` 鎖定原始資料表，即可將資料列從原始資料表複製到新資料表。這有助於 INSERT、UPDATE 和 DELETE 操作照常繼續進行。

## 建議
<a name="Appendix.PostgreSQL.CommonDBATasks.pg_repack.Recommen"></a>

當您使用 `pg_repack` 延伸模組從資料表和索引中移除膨脹時，適用下列建議：
+ 在非上班時間或維護時段執行重新封裝，將對其他資料庫活動效能的影響降至最低。
+ 在重建活動期間密切監控封鎖工作階段，並確保原始資料表上沒有可能封鎖 `pg_repack` 的活動，特別是在最終交換放置階段需要對原始資料表進行專屬鎖定時。如需詳細資訊，請參閱[識別封鎖查詢的項目](https://repost.aws/knowledge-center/rds-aurora-postgresql-query-blocked)。

  當您看到封鎖工作階段時，您可以在仔細考慮後使用下列命令將其終止。這有助於繼續 `pg_repack` 以完成重建：

  ```
  SELECT pg_terminate_backend(pid);
  ```
+ 在交易速率非常高的系統上套用 `pg_repack's` 日誌資料表中累積的變更時，套用程序可能無法跟上變更速率。在這種情況下，`pg_repack` 無法完成套用程序。如需詳細資訊，請參閱[在重新封裝期間監控新資料表](#Appendix.PostgreSQL.CommonDBATasks.pg_repack.Monitoring)。如果索引嚴重膨脹，替代解決方案是執行僅限索引重新封裝。這也有助於 VACUUM 的索引清除週期更快完成。

  您可以使用 PostgreSQL 第 12 版的手動 VACUUM 以略過索引清除階段，並在 PostgreSQL 第 14 版的緊急自動清空期間自動略過。這有助於 VACUUM 更快速地完成，無需移除索引膨脹，而且僅適用於防止包圍 VACUUM 等緊急狀況。如需詳細資訊，請參閱《Amazon Aurora 使用者指南》中的[避免在索引中膨脹](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.diag-table-ind-bloat.html#AuroraPostgreSQL.diag-table-ind-bloat.AvoidinginIndexes)。

## 先決條件
<a name="Appendix.PostgreSQL.CommonDBATasks.pg_repack.Prereq"></a>
+ 資料表必須具有 PRIMARY KEY 或非 null UNIQUE 限制條件。
+ 用戶端和伺服器的延伸模組版本必須相同。
+ 確保 RDS 執行個體具有比沒有膨脹的資料表大小總計更多的 `FreeStorageSpace`。例如，請考慮資料表的大小總計，包括 TOAST 和索引為 2TB，資料表中的膨脹總計為 1TB。必要的 `FreeStorageSpace` 必須大於下列計算傳回的值：

   `2TB (Table size)` - `1TB (Table bloat)` = `1TB`

  您可以使用下列查詢來檢查資料表的大小總計，並使用 `pgstattuple` 衍生膨脹。如需詳細資訊，請參閱《Amazon Aurora 使用者指南》中的[診斷資料表和索引膨脹](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.diag-table-ind-bloat.html) 

  ```
  SELECT pg_size_pretty(pg_total_relation_size('table_name')) AS total_table_size;
  ```

  此空間會在活動完成後回收。
+ 確保 RDS 執行個體有足夠的運算和 IO 容量來處理重新封裝操作。您可以考慮向上擴展執行個體類別，以獲得最佳效能平衡。

**使用 `pg_repack` 延伸模組**

1. 執行以下命令，在 RDS for PostgreSQL 資料庫執行個體上安裝 `pg_repack` 擴充功能。

   ```
   CREATE EXTENSION pg_repack;
   ```

1. 執行下列命令授予 `pg_repack` 所建立暫存日誌資料表的寫入存取權。

   ```
   ALTER DEFAULT PRIVILEGES IN SCHEMA repack GRANT INSERT ON TABLES TO PUBLIC;
   ALTER DEFAULT PRIVILEGES IN SCHEMA repack GRANT USAGE, SELECT ON SEQUENCES TO PUBLIC;
   ```

1. 使用 `pg_repack` 用戶端公用程式來連線至資料庫。使用具有 `rds_superuser` 權限的帳戶。舉例來說，假設 `rds_test` 角色具有 `rds_superuser` 權限。下列語法會針對完整資料表執行 `pg_repack`，包括 `postgres` 資料庫中的所有資料表索引。

   ```
   pg_repack -h db-instance-name.111122223333.aws-region.rds.amazonaws.com -U rds_test -k postgres
   ```
**注意**  
您必須使用 -k 選項進行連線。不支援 -a 選項。

   來自 `pg_repack` 用戶端的回應會提供資料庫執行個體上已重新封裝之資料表的資訊。

   ```
   INFO: repacking table "pgbench_tellers"
   INFO: repacking table "pgbench_accounts"
   INFO: repacking table "pgbench_branches"
   ```

1. 下列語法會重新封裝單一資料表 `orders`，包括 `postgres` 資料庫中的索引。

   ```
   pg_repack -h db-instance-name.111122223333.aws-region.rds.amazonaws.com -U rds_test --table orders -k postgres
   ```

   下列語法只會重新封裝 `postgres` 資料庫中 `orders` 資料表的索引。

   ```
   pg_repack -h db-instance-name.111122223333.aws-region.rds.amazonaws.com -U rds_test --table orders --only-indexes -k postgres
   ```

## 在重新封裝期間監控新資料表
<a name="Appendix.PostgreSQL.CommonDBATasks.pg_repack.Monitoring"></a>
+ 資料庫的大小會增加資料表的大小總計減去膨脹，直到重新封裝的交換放置階段為止。您可以監控資料庫大小的成長速率、計算重新封裝的速度，以及大概預估完成初始資料傳輸所需的時間。

  例如，將資料表的大小總計視為 2TB、將資料庫的大小視為 4TB，並將資料表中的膨脹總計視為 1TB。重新封裝操作結束時，計算傳回的資料庫大小總計值如下：

   `2TB (Table size)` \$1 `4 TB (Database size)` - `1TB (Table bloat)` = `5TB`

  您可以透過取樣兩個時間點之間的成長率 (以位元組為單位)，大致估計重新封裝操作的速度。如果成長率為每分鐘 1GB，則可能需要 1000 分鐘或 16.6 小時左右才能完成初始資料表建置操作。除了初始資料表建置之外，`pg_repack` 也需要套用累積的變更。所需的時間取決於套用持續變更以及累積變更的速率。
**注意**  
您可以使用 `pgstattuple` 延伸模組來計算資料表中的膨脹。如需更多詳細資訊，請參閱 [pgstattuple](https://www.postgresql.org/docs/current/pgstattuple.html)。
+ `pg_repack's` 日誌資料表中的資料列數目，在重新封裝結構描述下，代表待定在初始載入後套用至新資料表的變更量。

  您可以在 `pg_stat_all_tables` 中檢查 `pg_repack's` 日誌資料表，以監控套用至新資料表的變更。`pg_stat_all_tables.n_live_tup` 表示待定套用至新資料表的記錄數目。如需詳細資訊，請參閱 [pg\$1stat\$1all\$1tables](https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-ALL-TABLES-VIEW)。

  ```
  postgres=>SELECT relname,n_live_tup FROM pg_stat_all_tables WHERE schemaname = 'repack' AND relname ILIKE '%log%';
          
  -[ RECORD 1 ]---------
  relname    | log_16490
  n_live_tup | 2000000
  ```
+ 您可以使用 `pg_stat_statements` 延伸模組來了解重新封裝操作中每個步驟所花費的時間。這有助於準備在生產環境中套用相同的重新封裝操作。您可以調整 `LIMIT` 子句以進一步擴展輸出。

  ```
  postgres=>SELECT
       SUBSTR(query, 1, 100) query,
       round((round(total_exec_time::numeric, 6) / 1000 / 60),4) total_exec_time_in_minutes
   FROM
       pg_stat_statements
   WHERE
       query ILIKE '%repack%'
   ORDER BY
       total_exec_time DESC LIMIT 5;
          
   query                                                                 | total_exec_time_in_minutes
  -----------------------------------------------------------------------+----------------------------
   CREATE UNIQUE INDEX index_16493 ON repack.table_16490 USING btree (a) |                     6.8627
   INSERT INTO repack.table_16490 SELECT a FROM ONLY public.t1           |                     6.4150
   SELECT repack.repack_apply($1, $2, $3, $4, $5, $6)                    |                     0.5395
   SELECT repack.repack_drop($1, $2)                                     |                     0.0004
   SELECT repack.repack_swap($1)                                         |                     0.0004
  (5 rows)
  ```

重新封裝完全是空間外的作業，因此原始資料表不會受到影響，而且我們預期不會有任何需要復原原始資料表的意外挑戰。如果重新封裝意外失敗，您必須檢查錯誤的原因並加以解決。

問題解決後，請在資料表所在的資料庫中捨棄並重新建立 `pg_repack` 延伸模組，然後重試 `pg_repack` 步驟。此外，運算資源的可用性和資料表的並行可存取性在重新封裝操作的及時完成中扮演了關鍵角色。

# 升級和使用 PLV8 擴充功能
<a name="PostgreSQL.Concepts.General.UpgradingPLv8"></a>

PLV8 是值得信賴的 JavaScript 語言擴充功能，適用於 PostgreSQL。您可用於存放的程序、觸發程序和可從 SQL 呼叫的其他程序性程式碼。所有目前版本的 PostgreSQL 都支援此語言擴充功能。

如果您使用 [PLV8](https://plv8.github.io/) 並將 PostgreSQL 升級至新的 PLV8 版本，即可立即利用新的擴充功能套件。執行下列步驟，同步目錄中繼資料與新版的 PLV8。這些步驟為選用，但強烈建議您完成步驟以避免中繼資料不符的警告。

升級程序會捨棄您現有的所有 PLV8 函數。因此，我們建議您在升級之前建立 RDS for PostgreSQL 資料庫執行個體的快照。如需詳細資訊，請參閱[為 Amazon RDS 的單一可用區域資料庫執行個體建立資料庫快照](USER_CreateSnapshot.md)。

**重要**  
從 PostgreSQL 第 18 版開始，Amazon RDS for PostgreSQL 將棄用 `plcoffee` 和 `plls` PostgreSQL 延伸模組。建議您在應用程式中停止使用 CoffeeScript 和 LiveScript，以確保您具有未來引擎版本升級的升級路徑。

**如何同步目錄中繼資料與新版 PLV8**

1. 確認您需要更新。若要執行此動作，請在已連接至執行個體的情況下，執行下列命令。

   ```
   SELECT * FROM pg_available_extensions WHERE name IN ('plv8','plls','plcoffee');
   ```

   如果結果包含一個已安裝之版本的值，而此版本的編號小於預設版本，則請繼續此程序來更新擴充功能套件。例如，下列結果集表示您應該更新。

   ```
   name    | default_version | installed_version |                     comment
   --------+-----------------+-------------------+--------------------------------------------------
   plls    | 2.1.0           | 1.5.3             | PL/LiveScript (v8) trusted procedural language
   plcoffee| 2.1.0           | 1.5.3             | PL/CoffeeScript (v8) trusted procedural language
   plv8    | 2.1.0           | 1.5.3             | PL/JavaScript (v8) trusted procedural language
   (3 rows)
   ```

1. 如果您尚未建立 RDS for PostgreSQL 資料庫執行個體的快照，請建立一個。建立快照時，您可以繼續執行下列步驟。

1. 取得資料庫執行個體中的 PLV8 函數計數，以驗證升級之後函數全部存在。例如，下列 SQL 查詢會傳回 PLV8、plcoffee 和 plls 中寫入的函數數目。

   ```
   SELECT proname, nspname, lanname 
   FROM pg_proc p, pg_language l, pg_namespace n
   WHERE p.prolang = l.oid
   AND n.oid = p.pronamespace
   AND lanname IN ('plv8','plcoffee','plls');
   ```

1. 使用 pg\$1dump 建立只含結構描述的傾印檔案。例如，在 `/tmp` 目錄中建立用戶端機器上的檔案。

   ```
   ./pg_dump -Fc --schema-only -U master postgres >/tmp/test.dmp
   ```

   此範例使用下列選項：
   + `-Fc` – 自訂格式
   + --schema-only – 僅傾印建立結構描述所需的命令 (我們案例中的函數)
   + `-U` – RDS 主要使用者名稱
   + `database` – 資料庫執行個體上的資料庫名稱

   如需有關 pg\$1dump 的詳細資訊，請參閱 PostgreSQL 文件中的 [pg\$1dump](https://www.postgresql.org/docs/current/static/app-pgdump.html )。

1. 擷取傾印檔案中存在的「CREATE FUNCTION」DDL 陳述式。下列範例使用 `grep` 命令擷取用於建立函數並儲存到檔案中的 DDL 陳述式。您將於後續步驟中使用此 ddl 來重新建立函數。

   ```
   ./pg_restore -l /tmp/test.dmp | grep FUNCTION > /tmp/function_list
   ```

   如需有關 pg\$1restore 的詳細資訊，請參閱 PostgreSQL 文件中的 [pg\$1restore](https://www.postgresql.org/docs/current/static/app-pgrestore.html)。

1. 捨棄函數和擴充功能。下列範例會捨棄任何以 PLV8 為基礎的物件。cascade 選項可確保捨棄任何相依物件。

   ```
   DROP EXTENSION plv8 CASCADE;
   ```

   如果 PostgreSQL 執行個體包含以 plcoffee 或 plls 為基礎的物件，請對這些擴充功能重複此步驟。

1. 建立擴充功能。下列範例會建立 plv8、plcoffee 和 plls 擴充功能。

   ```
   CREATE EXTENSION plv8;
   CREATE EXTENSION plcoffee;
   CREATE EXTENSION plls;
   ```

1. 使用傾印檔案和「驅動程式」檔案建立函數。

   下列範例會重新建立您先前擷取的函數。

   ```
   ./pg_restore -U master -d postgres -Fc -L /tmp/function_list /tmp/test.dmp
   ```

1. 使用以下查詢驗證是否已重新建立所有函數。

   ```
   SELECT * FROM pg_available_extensions WHERE name IN ('plv8','plls','plcoffee'); 
   ```

   PLV8 第 2 版會將以下額外的資料列新增至結果集：

   ```
       proname    |  nspname   | lanname
   ---------------+------------+----------
    plv8_version  | pg_catalog | plv8
   ```

# 使用 PL/Rust 以 Rust 語言撰寫 PostgreSQL 函數
<a name="PostgreSQL.Concepts.General.Using.PL_Rust"></a>

PL/Rust 是 PostgreSQL 的受信任 Rust 語言延伸模組。您可以將其用於預存程序、函數，以及可從 SQL 呼叫的其他程序性程式碼。下列版本提供 PL/Rust 語言延伸模組：
+ RDS for PostgreSQL 17.1 和更高的第 17 版
+ RDS for PostgreSQL 16.1 和更高的第 16 版
+ RDS for PostgreSQL 15.2-R2 及更高的 15 版本
+ RDS for PostgreSQL 14.9 及更高的 14 版本
+ RDS for PostgreSQL 13.12 及更高的 13 版本

如需詳細資訊，請參閱 GitHub 上的 [PL/Rust](https://github.com/tcdi/plrust#readme)。

**Topics**
+ [設定 PL/Rust](#PL_Rust-setting-up)
+ [使用 PL/Rust 建立函數](#PL_Rust-create-function)
+ [使用套件搭配 PL/Rust](#PL_Rust-crates)
+ [PL/Rust 限制](#PL_Rust-limitations)

## 設定 PL/Rust
<a name="PL_Rust-setting-up"></a>

若要在資料庫執行個體上安裝 plrust 延伸模組，請將 plrust 新增至與資料庫執行個體相關聯之資料庫參數群組中的 `shared_preload_libraries` 參數。安裝 plrust 延伸模組後，您可以建立函數。

若要修改 `shared_preload_libraries` 參數，您的資料庫執行個體必須與自訂參數群組相關聯。如需建立自訂資料庫參數群組的相關資訊，請參閱 [Amazon RDS 的參數群組](USER_WorkingWithParamGroups.md)。

您可以使用 AWS 管理主控台 或 安裝 plrust 擴充功能 AWS CLI。

下列步驟假設您的資料庫執行個體與自訂資料庫參數群組相關聯。

### 主控台
<a name="PL_Rust-setting-up.CON"></a>

**在 `shared_preload_libraries` 參數中安裝 plrust 延伸模組**

使用屬於 `rds_superuser` 群組 (角色) 成員的帳戶完成下列步驟。

1. 登入 AWS 管理主控台 ，並在 [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/)：// 開啟 Amazon RDS 主控台。

1. 在導覽窗格中，選擇 **Databases** (資料庫)。

1. 選擇資料庫執行個體的名稱以顯示其詳細資訊。

1. 開啟資料庫執行個體的**組態**索引標籤，然後尋找資料庫執行個體參數群組連結。

1. 選擇連結以開啟與資料庫執行個體相關聯的自訂參數。

1. 在 **Parameters** (參數) 搜尋欄位中，輸入 `shared_pre` 以尋找 **`shared_preload_libraries`** 參數。

1. 選擇 **Edit parameters** (編輯參數) 以存取屬性值。

1. 在**值**欄位中，將 plrust 新增至清單。使用逗號區隔值清單中的項目。

1. 重新啟動資料庫執行個體，以便您對 `shared_preload_libraries` 參數的變更生效。初始重新啟動可能需要額外的時間才能完成。

1. 當執行個體可用時，請驗證 plrust 是否已初始化。使用 `psql` 連線至資料庫執行個體，然後執行下列命令。

   ```
   SHOW shared_preload_libraries;
   ```

   您的輸出應該類似以下內容：

   ```
   shared_preload_libraries 
   --------------------------
   rdsutils,plrust
   (1 row)
   ```

### AWS CLI
<a name="PL_Rust-setting-up-CLI"></a>

**在 shared\$1preload\$1libraries 參數中安裝 plrust 延伸模組**

使用屬於 `rds_superuser` 群組 (角色) 成員的帳戶完成下列步驟。

1. 使用 [modify-db-parameter-group](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-parameter-group.html) AWS CLI 命令將 plrust 新增至 `shared_preload_libraries` 參數。

   ```
   aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=shared_preload_libraries,ParameterValue=plrust,ApplyMethod=pending-reboot" \
      --region aws-region
   ```

1. 使用 [reboot-db-instance](https://docs.aws.amazon.com/cli/latest/reference/rds/reboot-db-instance) AWS CLI 命令重新啟動資料庫執行個體並初始化 plrust 程式庫。初始重新啟動可能需要額外的時間才能完成。

   ```
   aws rds reboot-db-instance \
       --db-instance-identifier your-instance \
       --region aws-region
   ```

1. 當執行個體可用時，您可以驗證 plrust 是否已初始化。使用 `psql` 連線至資料庫執行個體，然後執行下列命令。

   ```
   SHOW shared_preload_libraries;
   ```

   您的輸出應該類似以下內容：

   ```
   shared_preload_libraries
   --------------------------
   rdsutils,plrust
   (1 row)
   ```

## 使用 PL/Rust 建立函數
<a name="PL_Rust-create-function"></a>

PL/Rust 會將函數編譯為動態程式庫、載入它，然後執行它。

以下 Rust 函數會從陣列中篩選出倍數。

```
postgres=> CREATE LANGUAGE plrust;
CREATE EXTENSION
```

```
CREATE OR REPLACE FUNCTION filter_multiples(a BIGINT[], multiple BIGINT) RETURNS BIGINT[]
    IMMUTABLE STRICT
    LANGUAGE PLRUST AS
$$
    Ok(Some(a.into_iter().filter(|x| x.unwrap() % multiple != 0).collect()))
$$;
        
WITH gen_values AS (
SELECT ARRAY(SELECT * FROM generate_series(1,100)) as arr)
SELECT filter_multiples(arr, 3)
from gen_values;
```

## 使用套件搭配 PL/Rust
<a name="PL_Rust-crates"></a>

在 RDS for PostgreSQL 16.3-R2 和更高版本、15.7-R2 和更高的第 15 版、14.12-R2 和更高的第 14 版，以及 13.15-R2 和更高的第 13 版中，PL/Rust 支援額外的壓縮容器格式：
+ `url` 
+ `regex` 
+ `serde` 
+ `serde_json` 

在 RDS for PostgreSQL 15.5-R2 和更高版本、14.10-R2 和更高的第 14 版、13.13-R2 和更高的第 13 版中，PL/Rust 支援兩個額外的壓縮容器格式：
+ `croaring-rs` 
+ `num-bigint` 

從 Amazon RDS for PostgreSQL 15.4、14.9 及 13.12 版開始，PL/Rust 支援下列壓縮容器格式：
+ `aes` 
+ `ctr` 
+ `rand` 

這些套件僅支援預設功能。新的 RDS for PostgreSQL 版本可能包含更新的套件版本，而且可能不再支援較舊的套件版本。

請遵循執行主要版本升級的最佳實務來進行測試，了解您的 PL/Rust 函數是否與新的主要版本相容。如需詳細資訊，請參閱部落格 [Best practices for upgrading Amazon RDS to major and minor versions of PostgreSQL](https://aws.amazon.com/blogs/database/best-practices-for-upgrading-amazon-rds-to-major-and-minor-versions-of-postgresql/) (將 Amazon RDS 升級至 PostgreSQL 的主要和次要版本的最佳實務)，以及《Amazon RDS 使用者指南》中的[升級 Amazon RDS 的 PostgreSQL 資料庫引擎](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_UpgradeDBInstance.PostgreSQL.html)。

[使用相依性](https://tcdi.github.io/plrust/use-plrust.html#use-dependencies)中提供了建立 PL/Rust 函數時使用相依性的範例。

## PL/Rust 限制
<a name="PL_Rust-limitations"></a>

根據預設，資料庫使用者無法使用 PL/Rust。若要提供 PL/Rust 的存取權，請以具有 rds\$1superuser 權限的使用者身分連線，然後執行下列命令：

```
postgres=> GRANT USAGE ON LANGUAGE PLRUST TO user;
```

# 使用 PostGIS 擴充功能管理空間資料
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS"></a>

PostGIS 是 PostgreSQL 的擴充功能，可用於儲存和管理空間資訊。若要進一步了解 PostGIS，請參閱 [PostGIS.net](https://postgis.net/)。

從 10.5 版開始，PostgreSQL 即支援 PostGIS 用於處理 Mapbox向量圖標資料的 libprotobuf 1.3.0 程式庫。

設定 PostGIS 擴充功能需要 `rds_superuser` 權限。我們建議您建立一使用者 (角色) 來管理 PostGIS 擴充功能及您的空間資料。PostGIS 擴充功能及其相關元件會為 PostgreSQL 新增數千個函數。若這對您的使用案例有意義，請考慮在其自己的結構描述中建立 PostGIS 擴充功能。下列範例會顯示如何在其自己的資料庫中安裝擴充功能，但這並非必要。

**Topics**
+ [步驟 1：建立使用者 (角色) 來管理 PostGIS 擴充功能](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.Connect)
+ [步驟 2：載入 PostGIS 擴充功能](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.LoadExtensions)
+ [步驟 3：轉移延伸模組結構描述的擁有權](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.TransferOwnership)
+ [步驟 4：轉移 PostGIS 物件的擁有權](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.TransferObjects)
+ [步驟 5：測試擴充功能](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.Test)
+ [步驟 6：升級 PostGIS 擴充功能](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.Update)
+ [PostGIS 擴充功能版本](#CHAP_PostgreSQL.Extensions.PostGIS)
+ [將 PostGIS 2 升級到 PostGIS 3](#PostgreSQL.Extensions.PostGIS.versions.upgrading.2-to-3)

## 步驟 1：建立使用者 (角色) 來管理 PostGIS 擴充功能
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.Connect"></a>

首先，以具有 `rds_superuser` 權限的使用者身分連線至您的 RDS for PostgreSQL 資料庫執行個體。若您在設定執行個體時保留預設名稱，則以 `postgres` 身分連線：

```
psql --host=111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password
```

建立一個單獨的角色 (使用者) 來管理 PostGIS 擴充功能。

```
postgres=>  CREATE ROLE gis_admin LOGIN PASSWORD 'change_me';
CREATE ROLE
```

授予此角色 `rds_superuser` 權限，允許角色安裝擴充功能。

```
postgres=> GRANT rds_superuser TO gis_admin;
GRANT
```

建立用於 PostGIS 成品的資料庫：此為選擇性步驟。或者，您可以在 PostGIS 擴充功能的使用者資料庫中建立結構描述，但這也並非必要。

```
postgres=> CREATE DATABASE lab_gis;
CREATE DATABASE
```

授予 `gis_admin` 在 `lab_gis` 資料庫上的所有權限。

```
postgres=> GRANT ALL PRIVILEGES ON DATABASE lab_gis TO gis_admin;
GRANT
```

退出工作階段，並以 `gis_admin` 身分重新連線至您的 RDS for PostgreSQL 資料庫執行個體。

```
postgres=> psql --host=111122223333.aws-region.rds.amazonaws.com --port=5432 --username=gis_admin --password --dbname=lab_gis
Password for user gis_admin:...
lab_gis=>
```

按照後續步驟中的詳細說明，繼續設定擴充功能。

## 步驟 2：載入 PostGIS 擴充功能
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.LoadExtensions"></a>

PostGIS 擴充功能包含數個共同運作的相關擴充功能，以提供地理空間的功能。根據您的使用案例，可能不需要在此步驟中建立的所有擴充功能。

使用 `CREATE EXTENSION` 陳述式載入 PostGIS 擴充。

```
CREATE EXTENSION postgis;
CREATE EXTENSION
CREATE EXTENSION postgis_raster;
CREATE EXTENSION
CREATE EXTENSION fuzzystrmatch;
CREATE EXTENSION
CREATE EXTENSION postgis_tiger_geocoder;
CREATE EXTENSION
CREATE EXTENSION postgis_topology;
CREATE EXTENSION
CREATE EXTENSION address_standardizer_data_us;
CREATE EXTENSION
```

您可以執行下例中顯示的 SQL 查詢來確認結果，其中列出擴充功能及其擁有者。

```
SELECT n.nspname AS "Name",
  pg_catalog.pg_get_userbyid(n.nspowner) AS "Owner"
  FROM pg_catalog.pg_namespace n
  WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'
  ORDER BY 1;
List of schemas
     Name     |   Owner
--------------+-----------
 public       | postgres
 tiger        | rdsadmin
 tiger_data   | rdsadmin
 topology     | rdsadmin
(4 rows)
```

## 步驟 3：轉移延伸模組結構描述的擁有權
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.TransferOwnership"></a>

使用 ALTER SCHEMA 陳述式將結構描述的擁有權移轉至 `gis_admin` 角色。

```
ALTER SCHEMA tiger OWNER TO gis_admin;
ALTER SCHEMA
ALTER SCHEMA tiger_data OWNER TO gis_admin; 
ALTER SCHEMA
ALTER SCHEMA topology OWNER TO gis_admin;
ALTER SCHEMA
```

您可執行下列 SQL 查詢，來確認所有權變更。您也可以使用 `\dn` 中繼命令和 psql 命令列。

```
SELECT n.nspname AS "Name",
  pg_catalog.pg_get_userbyid(n.nspowner) AS "Owner"
  FROM pg_catalog.pg_namespace n
  WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'
  ORDER BY 1;

       List of schemas
     Name     |     Owner
--------------+---------------
 public       | postgres
 tiger        | gis_admin
 tiger_data   | gis_admin
 topology     | gis_admin
(4 rows)
```

## 步驟 4：轉移 PostGIS 物件的擁有權
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.TransferObjects"></a>

**注意**  
請勿變更 PostGIS 函數的擁有權。PostGIS 的適當操作和未來升級需要這些函數來保留原始擁有權。如需 PostGIS 許可的詳細資訊，請參閱 [PostgreSQL 安全性](https://postgis.net/workshops/postgis-intro/security.html)。

使用下列函式將 PostGIS 資料表的擁有權移轉至 `gis_admin` 角色。從 psql 提示字元執行下列陳述式來建立函式。

```
CREATE FUNCTION exec(text) returns text language plpgsql volatile AS $f$ BEGIN EXECUTE $1; RETURN $1; END; $f$;
CREATE FUNCTION
```

接下來，執行下列查詢來執行 `exec` 函數，該函數會執行陳述式及變更權限。

```
SELECT exec('ALTER TABLE ' || quote_ident(s.nspname) || '.' || quote_ident(s.relname) || ' OWNER TO gis_admin;')
  FROM (
    SELECT nspname, relname
    FROM pg_class c JOIN pg_namespace n ON (c.relnamespace = n.oid) 
    WHERE nspname in ('tiger','topology') AND
    relkind IN ('r','S','v') ORDER BY relkind = 'S')
s;
```

## 步驟 5：測試擴充功能
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.Test"></a>

為避免需要指定結構描述名稱，請使用下列命令將 `tiger` 結構描述新增至您的搜尋路徑。

```
SET search_path=public,tiger;
SET
```

使用下列 SELECT 陳述式來測試 `tiger` 結構描述。

```
SELECT address, streetname, streettypeabbrev, zip
 FROM normalize_address('1 Devonshire Place, Boston, MA 02109') AS na;
address | streetname | streettypeabbrev |  zip
---------+------------+------------------+-------
       1 | Devonshire | Pl               | 02109
(1 row)
```

要進一步了解此擴充功能，請參閱 PostGIS 文件中的 [Tiger Geocoder](https://postgis.net/docs/Extras.html#Tiger_Geocoder) (Tiger 地理編碼器)。

使用下列 `SELECT` 陳述式來測試存取 `topology` 結構描述。這樣會呼叫 `createtopology` 函數，以使用指定的空間參考識別碼 (26986) 和預設公差 (0.5) 註冊新拓撲物件 (my\$1new\$1topo)。如需進一步了解，請參閱 PostgreGIS 文件中的[建立拓撲](https://postgis.net/docs/CreateTopology.html)。

```
SELECT topology.createtopology('my_new_topo',26986,0.5);
 createtopology
----------------
              1
(1 row)
```

## 步驟 6：升級 PostGIS 擴充功能
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.Update"></a>

每個新版本的 PostgreSQL 都支援一個或多個與該版本相容的 PostGIS 擴充功能版本。將 PostgreSQL 引擎升級到新版本並不會自動升級 PostGIS 擴充功能。升級 PostgreSQL 引擎之前，您通常會將 PostGIS 升級到目前 PostgreSQL 版本的最新可用版本。如需詳細資訊，請參閱[PostGIS 擴充功能版本](#CHAP_PostgreSQL.Extensions.PostGIS)。

PostgreSQL 引擎升級之後，接著再次將 PostGIS 擴充功能升級為支援新升級之 PostgreSQL 引擎版本的版本。如需升級 PostgreSQL 資料庫引擎的詳細資訊，請參閱 [如何執行 RDS for PostgreSQL 的主要版本升級](USER_UpgradeDBInstance.PostgreSQL.MajorVersion.Process.md)。

您可以隨時在 RDS for PostgreSQL 資料庫執行個體上檢查可用的 PostGIS 擴充功能版本更新。若要這麼做，請執行下列命令。PostGIS 2.5.0 和更新版本可使用此功能。

```
SELECT postGIS_extensions_upgrade();
```

如果您的應用程式不支援最新的 PostGIS 版本，您仍然可以安裝主要版本中可用的舊版 PostGIS，如下所示。

```
CREATE EXTENSION postgis VERSION "2.5.5";
```

如果您想要從舊版本升級到特定的 PostGIS 版本，也可以使用以下命令。

```
ALTER EXTENSION postgis UPDATE TO "2.5.5";
```

視您要從哪個版本升級而定，您可能需要再次執行此函數。第一次執行函數的結果會決定是否需要額外的升級函數。例如，這是從 PostGIS 2 升級到 PostGIS 3 的情況。如需詳細資訊，請參閱[將 PostGIS 2 升級到 PostGIS 3](#PostgreSQL.Extensions.PostGIS.versions.upgrading.2-to-3)。

如果您升級此擴充功能以準備 PostgreSQL 引擎的主要版本升級，您可以繼續執行其他初步工作。如需詳細資訊，請參閱 [如何執行 RDS for PostgreSQL 的主要版本升級](USER_UpgradeDBInstance.PostgreSQL.MajorVersion.Process.md)。

## PostGIS 擴充功能版本
<a name="CHAP_PostgreSQL.Extensions.PostGIS"></a>

我們建議您安裝所有擴充功能的版本，例如在《*Amazon RDS for PostgreSQL 版本備註*》中的 [Amazon RDS for PostgreSQL 擴充功能版本](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html)所列出的 PostGIS。若要取得您的發行版本中有哪些可用版本，請使用下列命令。

```
SELECT * FROM pg_available_extension_versions WHERE name='postgis';
```

您也可以在 *Amazon RDS for PostgreSQL 版本備註*的以下各節找到版本資訊：
+ [Amazon RDS 上支援的 PostgreSQL 16 版擴充功能](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-16x)
+ [Amazon RDS 上支援的 PostgreSQL 15 版擴充功能](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-15x)
+ [Amazon RDS 上支援的 PostgreSQL 14 版擴充功能](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-14x)
+ [Amazon RDS 上支援的 PostgreSQL 13 版擴充功能](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-13x)
+ [Amazon RDS 上支援的 PostgreSQL 12 版擴充功能](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-12x)
+ [Amazon RDS 上支援的 PostgreSQL 11 版擴充功能](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-11x)
+ [Amazon RDS 上支援的 PostgreSQL 10 版擴充功能](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-101x)
+ [Amazon RDS 上支援的 PostgreSQL 9.6.x 版擴充功能](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-96x)

## 將 PostGIS 2 升級到 PostGIS 3
<a name="PostgreSQL.Extensions.PostGIS.versions.upgrading.2-to-3"></a>

從 3.0 版開始，PostGIS 點陣函數現在是一個單獨的擴充功能，`postgis_raster`。此擴充功能具有自己的安裝和升級路徑。如此一來，可以從核心 `postgis` 擴充功能移除點陣影像處理所需的數十種函數、資料類型和其他成品。這意味著，如果您的使用案例不需要點陣處理，則不需要安裝 `postgis_raster` 擴充功能。

在以下升級範例中，第一個升級命令會將點陣函數擷取至 `postgis_raster` 擴充功能。接著便需要第二個升級命令將 `postgis_raster` 升級到新版本。

**從 PostGIS 2 升級到 PostGIS 3**

1. 識別可用於 PostgreSQL 版本的 PostGIS 預設版本，而其中 PostgreSQL 位於您的 RDS for PostgreSQL 資料庫執行個體。若要這麼做，請執行下列查詢。

   ```
   SELECT * FROM pg_available_extensions
       WHERE default_version > installed_version;
     name   | default_version | installed_version |                          comment
   ---------+-----------------+-------------------+------------------------------------------------------------
    postgis | 3.1.4           | 2.3.7             | PostGIS geometry and geography spatial types and functions
   (1 row)
   ```

1. 識別您的 RDS for PostgreSQL 資料庫執行個體上，每個資料庫中安裝的 PostGIS 版本。換句話說，查詢每個使用者資料庫，如下所示。

   ```
   SELECT
       e.extname AS "Name",
       e.extversion AS "Version",
       n.nspname AS "Schema",
       c.description AS "Description"
   FROM
       pg_catalog.pg_extension e
       LEFT JOIN pg_catalog.pg_namespace n ON n.oid = e.extnamespace
       LEFT JOIN pg_catalog.pg_description c ON c.objoid = e.oid
       AND c.classoid = 'pg_catalog.pg_extension'::pg_catalog.regclass
   WHERE
       e.extname LIKE '%postgis%'
   ORDER BY
       1;
     Name   | Version | Schema |                             Description
   ---------+---------+--------+---------------------------------------------------------------------
    postgis | 2.3.7   | public | PostGIS geometry, geography, and raster spatial types and functions
   (1 row)
   ```

   預設版本 (PostGIS 3.1.4) 與安裝的版本 (PostGIS 2.3.7) 之間不符，代表您需要升級 PostGIS 擴充功能。

   ```
   ALTER EXTENSION postgis UPDATE;
   ALTER EXTENSION
   WARNING: unpackaging raster
   WARNING: PostGIS Raster functionality has been unpackaged
   ```

1. 執行下列查詢，以確認點陣函數現在位於其自己的套件中。

   ```
   SELECT
       probin,
       count(*)
   FROM
       pg_proc
   WHERE
       probin LIKE '%postgis%'
   GROUP BY
       probin;
             probin          | count
   --------------------------+-------
    $libdir/rtpostgis-2.3    | 107
    $libdir/postgis-3        | 487
   (2 rows)
   ```

   輸出結果顯示版本之間仍然存在差異。PostGIS 函數是第 3 版 (postgis-3)，而點陣函數 (rtpostgis) 是第 2 版 (rtpostgis-2.3)。若要完成升級，請再次執行升級命令，如下所示。

   ```
   postgres=> SELECT postgis_extensions_upgrade();
   ```

   您可以放心忽略警告訊息。再次執行下列查詢以確認升級是否已完成。當 PostGIS 和所有相關的擴充功能均未標記為需要升級時，則升級完成。

   ```
   SELECT postgis_full_version();
   ```

1. 使用下列查詢來查看已完成的升級程序和個別套裝的擴充功能，並確認其版本是否相符。

   ```
   SELECT
       e.extname AS "Name",
       e.extversion AS "Version",
       n.nspname AS "Schema",
       c.description AS "Description"
   FROM
       pg_catalog.pg_extension e
       LEFT JOIN pg_catalog.pg_namespace n ON n.oid = e.extnamespace
       LEFT JOIN pg_catalog.pg_description c ON c.objoid = e.oid
           AND c.classoid = 'pg_catalog.pg_extension'::pg_catalog.regclass
   WHERE
       e.extname LIKE '%postgis%'
   ORDER BY
       1;
         Name      | Version | Schema |                             Description
   ----------------+---------+--------+---------------------------------------------------------------------
    postgis        | 3.1.5   | public | PostGIS geometry, geography, and raster spatial types and functions
    postgis_raster | 3.1.5   | public | PostGIS raster types and functions
   (2 rows)
   ```

   輸出結果顯示 PostGIS 2 擴充功能已升級到 PostGIS 3，並且 `postgis` 和現在的個別 `postgis_raster` 擴充功能則為 3.1.5 版。

升級完成後，如果您不打算使用點陣函數，您可以按以下方式卸除擴充功能。

```
DROP EXTENSION postgis_raster;
```

# 使用 Amazon RDS for PostgreSQL 支援的外部資料包裝函式
<a name="Appendix.PostgreSQL.CommonDBATasks.Extensions.foreign-data-wrappers"></a>

外部資料包裝函式 (FDW) 是一種特定類型的擴充功能，可提供對外部資料的存取。例如，`oracle_fdw` 擴充功能可讓您的 RDS for PostgreSQL 資料庫叢集 使用 Oracle 資料庫。另一個範例是，您可以使用 PostgreSQL 原生 `postgres_fdw` 擴充功能，存取存放在 RDS for PostgreSQL 資料庫執行個體外部的 PostgreSQL 資料庫執行個體中的資料。

在下文中，您可以了解幾個受支援的 PostgreSQL 外部資料包裝函式的資訊。

**Topics**
+ [使用 log\$1fdw 擴充功能存取使用 SQL 的資料庫日誌](CHAP_PostgreSQL.Extensions.log_fdw.md)
+ [使用 postgres\$1fdw 擴充功能存取外部資料](postgresql-commondbatasks-fdw.md)
+ [使用 mysql\$1fdw 擴充功能處理 MySQL 資料庫](postgresql-mysql-fdw.md)
+ [使用 oracle\$1fdw 擴充功能處理 Oracle 資料庫](postgresql-oracle-fdw.md)
+ [使用 tds\$1fdw 擴充功能處理 SQL 資料庫](postgresql-tds-fdw.md)

# 使用 log\$1fdw 擴充功能存取使用 SQL 的資料庫日誌
<a name="CHAP_PostgreSQL.Extensions.log_fdw"></a>

RDS for PostgreSQL 資料庫執行個體支援 `log_fdw` 擴充功能，讓您可以使用 SQL 介面存取資料庫引擎日誌。`log_fdw` 擴充功能推出兩個新函數，可讓您輕鬆為資料庫日誌建立外部資料表：
+ `list_postgres_log_files` – 列出資料庫日誌目錄中的檔案和檔案大小 (以位元組為單位)。
+ `create_foreign_table_for_log_file(table_name text, server_name text, log_file_name text)` – 在目前資料庫中為指定的檔案建立外部資料表。

`log_fdw` 建立的所有函數皆為 `rds_superuser` 所擁有。`rds_superuser` 角色的成員可以將這些函數的存取權授予其他資料庫使用者。

依預設，日誌檔案由 Amazon RDS 以 `stderr` (標準錯誤) 格式產生，如 `log_destination` 參數中所指定。此參數只有兩個選項：`stderr` 和 `csvlog` (逗號分隔值，CSV)。若將 `csvlog` 選項新增至參數，Amazon RDS 將同時產生 `stderr` 和 `csvlog` 日誌。這可能會影響資料庫叢集的儲存容量，因此您需要了解影響日誌處理的其他參數。如需詳細資訊，請參閱[設定日誌目標 (`stderr`、`csvlog`)](USER_LogAccess.Concepts.PostgreSQL.overview.parameter-groups.md#USER_LogAccess.Concepts.PostgreSQL.Log_Format)。

產生 `csvlog` 日誌的一個好處為 `log_fdw` 延伸允許您建置外部資料表，並將資料整齊分割成數個資料欄。為此，您的執行個體需要與自訂資料庫參數群組關聯，則您可變更 `log_destination` 的設定。如需如何執行作業的資訊，請參閱 [在 RDS for PostgreSQL 資料庫執行個體上搭配使用參數](Appendix.PostgreSQL.CommonDBATasks.Parameters.md)。

下列範例假設 `log_destination` 參數包括 `cvslog`。

**使用 log\$1fdw 擴充功能**

1. 安裝 `log_fdw` 擴充功能。

   ```
   postgres=> CREATE EXTENSION log_fdw;
   CREATE EXTENSION
   ```

1. 建立日誌伺服器做為外部資料包裝函數。

   ```
   postgres=> CREATE SERVER log_server FOREIGN DATA WRAPPER log_fdw;
   CREATE SERVER
   ```

1. 叢日誌檔案清單全選。

   ```
   postgres=> SELECT * FROM list_postgres_log_files() ORDER BY 1;
   ```

   範例回應如下所示。

   ```
             file_name           | file_size_bytes
   ------------------------------+-----------------
    postgresql.log.2023-08-09-22.csv |            1111
    postgresql.log.2023-08-09-23.csv |            1172
    postgresql.log.2023-08-10-00.csv |            1744
    postgresql.log.2023-08-10-01.csv |            1102
   (4 rows)
   ```

1. 針對選取的檔案，建立只有單一 'log\$1entry' 資料欄的資料表。

   ```
   postgres=> SELECT create_foreign_table_for_log_file('my_postgres_error_log',
        'log_server', 'postgresql.log.2023-08-09-22.csv');
   ```

   除了目前存在的資料表之外，回應不提供任何其他詳細資訊。

   ```
   -----------------------------------
   (1 row)
   ```

1. 選取日誌檔案的範例。以下程式碼會擷取日誌時間和錯誤訊息描述。

   ```
   postgres=> SELECT log_time, message FROM my_postgres_error_log ORDER BY 1;
   ```

   範例回應如下所示。

   ```
                log_time             |                                  message
   ----------------------------------+---------------------------------------------------------------------------
   Tue Aug 09 15:45:18.172 2023 PDT | ending log output to stderr
   Tue Aug 09 15:45:18.175 2023 PDT | database system was interrupted; last known up at 2023-08-09 22:43:34 UTC
   Tue Aug 09 15:45:18.223 2023 PDT | checkpoint record is at 0/90002E0
   Tue Aug 09 15:45:18.223 2023 PDT | redo record is at 0/90002A8; shutdown FALSE
   Tue Aug 09 15:45:18.223 2023 PDT | next transaction ID: 0/1879; next OID: 24578
   Tue Aug 09 15:45:18.223 2023 PDT | next MultiXactId: 1; next MultiXactOffset: 0
   Tue Aug 09 15:45:18.223 2023 PDT | oldest unfrozen transaction ID: 1822, in database 1
   (7 rows)
   ```

# 使用 postgres\$1fdw 擴充功能存取外部資料
<a name="postgresql-commondbatasks-fdw"></a>

您可以使用 [postgres\$1fdw](https://www.postgresql.org/docs/current/static/postgres-fdw.html) 擴充功能，存取遠端資料庫伺服器上資料表中的資料。如果您設定來自 PostgreSQL 資料庫執行個體的遠端連線，則也可以存取您的僅供讀取複本。

**若要使用 postgres\$1fdw 來存取遠端資料庫伺服器**

1. 安裝 postgres\$1fdw 擴充功能。

   ```
   CREATE EXTENSION postgres_fdw;
   ```

1. 使用 CREATE SERVER 建立外部資料伺服器。

   ```
   CREATE SERVER foreign_server
   FOREIGN DATA WRAPPER postgres_fdw
   OPTIONS (host 'xxx.xx.xxx.xx', port '5432', dbname 'foreign_db');
   ```

1. 建立使用者對應，找出要使用於遠端伺服器的角色。
**重要**  
若要修訂密碼使其不會在日誌中顯示，請在工作階段層級設定 `log_statement=none`。在參數層級進行設定不會修訂密碼。

   ```
   CREATE USER MAPPING FOR local_user
   SERVER foreign_server
   OPTIONS (user 'foreign_user', password 'password');
   ```

1. 建立一個資料表，其對應至遠端伺服器上的資料表。

   ```
   CREATE FOREIGN TABLE foreign_table (
           id integer NOT NULL,
           data text)
   SERVER foreign_server
   OPTIONS (schema_name 'some_schema', table_name 'some_table');
   ```

# 使用 mysql\$1fdw 擴充功能處理 MySQL 資料庫
<a name="postgresql-mysql-fdw"></a>

若要從 RDS for PostgreSQL 資料庫執行個體存取相容於 MySQL 的資料庫，您可以安裝並使用 `mysql_fdw` 擴充功能。此外部資料包裝函數可讓您使用 MySQL、Aurora MySQL、MariaDB 和其他相容於 MySQL 的資料庫的 RDS。從 RDS for PostgreSQL 資料庫執行個體到 MySQL 資料庫的連線是在最大努力的基礎上加密的，具體取決於用戶端和伺服器的組態。但是，如有需要，您可以強制執行加密。如需詳細資訊，請參閱[搭配此擴充功能使用傳輸中加密](#postgresql-mysql-fdw.encryption-in-transit)。

Amazon RDS for PostgreSQL 版本 14.2、13.6 及更高版本支援 `mysql_fdw` 擴充功能。它支援從 RDS for PostgreSQL DB 對相容於 MySQL 的資料庫執行個體上的資料表進行選擇、插入、更新和刪除。

**Topics**
+ [設定 RDS for PostgreSQL 資料庫以使用 mysql\$1fdw 擴充功能](#postgresql-mysql-fdw.setting-up)
+ [範例：使用 RDS for PostgreSQL 中的 RDS for MySQL 資料庫](#postgresql-mysql-fdw.using-mysql_fdw)
+ [搭配此擴充功能使用傳輸中加密](#postgresql-mysql-fdw.encryption-in-transit)

## 設定 RDS for PostgreSQL 資料庫以使用 mysql\$1fdw 擴充功能
<a name="postgresql-mysql-fdw.setting-up"></a>

在您的 RDS for PostgreSQL 資料庫執行個體上設定 `mysql_fdw` 擴充功能包括在資料庫執行個體中載入擴充功能，然後建立與 MySQL資料庫執行個體的連線點。針對此任務，您必須有以下關於 MySQL 資料庫執行個體的詳細內容：
+ 主機名稱或端點。如果是 RDS for PostgreSQL 資料庫執行個體，您可以使用主控台尋找端點。選擇 Connectivity & security (連線和安全) 索引標籤，然後查看「端點和連線埠」區段。
+ 連線埠號碼。MySQL 的預設連線埠號為 3306。
+ 資料庫的名稱。資料庫識別符。

您也必須提供 MySQL 連線埠 3306 的安全群組或存取控制清單 (ACL) 的存取權限。 RDS for PostgreSQL 資料庫執行個體和 RDS for MySQL 資料庫執行個體都需要存取連接埠 3306。如果未正確設定存取權限，當您嘗試連線至相容於 MySQL 的資料表時，會看到類似以下的錯誤訊息：

```
ERROR: failed to connect to MySQL: Can't connect to MySQL server on 'hostname.aws-region.rds.amazonaws.com:3306' (110)
```

在以下程序中，您 (作為 `rds_superuser` 帳戶) 建立外部伺服器。然後，您將外部伺服器的存取權限授予特定使用者。然後，這些使用者建立自己的映射到適合的 MySQL 使用者帳戶以使用 MySQL 資料庫執行個體。

**使用 mysql\$1fdw 存取 MySQL 資料庫伺服器**

1. 使用有 `rds_superuser` 角色的帳戶連線到您的 PostgreSQL 資料庫執行個體。如果您在建立 RDS for PostgreSQL 資料庫執行個體時接受了預設值，則使用者名稱為 `postgres`，而且您可以使用 `psql` 命令列工具進行連線，如下所示：

   ```
   psql --host=your-DB-instance.aws-region.rds.amazonaws.com --port=5432 --username=postgres –-password
   ```

1. 安裝 `mysql_fdw` 擴充功能，如下所示：

   ```
   postgres=> CREATE EXTENSION mysql_fdw;
   CREATE EXTENSION
   ```

在 RDS for PostgreSQL 資料庫執行個體上安裝擴充功能後，您可以設定提供連線至 MySQL 資料庫的外部伺服器。

**建立外部伺服器**

在 RDS for PostgreSQL 資料庫執行個體上執行這些任務。這些步驟假設您以具有 `rds_superuser` 權限 (例如 `postgres`) 的使用者進行連線。

1. 在 RDS for PostgreSQL 資料庫執行個體中建立外部伺服器：

   ```
   postgres=> CREATE SERVER mysql-db FOREIGN DATA WRAPPER mysql_fdw OPTIONS (host 'db-name.111122223333.aws-region.rds.amazonaws.com', port '3306');
   CREATE SERVER
   ```

1. 將適當的使用者存取權限授予外部伺服器。這些使用者應該是非管理員使用者，亦即沒有 `rds_superuser` 角色。

   ```
   postgres=> GRANT USAGE ON FOREIGN SERVER mysql-db to user1;
   GRANT
   ```

PostgreSQL 使用者透過外部伺服器建立和管理自己的 MySQL 資料庫連線。

## 範例：使用 RDS for PostgreSQL 中的 RDS for MySQL 資料庫
<a name="postgresql-mysql-fdw.using-mysql_fdw"></a>

假設您在 RDS for PostgreSQL 資料庫執行個體上有一個簡單資料表。您的 RDS for PostgreSQL 使用者想要查詢 (`SELECT`)、`INSERT`、`UPDATE` 和 `DELETE` 該資料表上的項目。假設 `mysql_fdw` 擴充功能已在 RDS for PostgreSQL 資料庫執行個體上建立，詳情如上述程序所述。作為具有 `rds_superuser` 權限的使用者，在您連線到 RDS 的 PostgreSQL 資料庫執行個體後，可繼續執行以下步驟。

1. 在 RDS for PostgreSQL 資料庫執行個體中建立外部伺服器：

   ```
   test=> CREATE SERVER mysqldb FOREIGN DATA WRAPPER mysql_fdw OPTIONS (host 'your-DB.aws-region.rds.amazonaws.com', port '3306');
   CREATE SERVER
   ```

1. 授與使用量給沒有 `rds_superuser` 許可的使用者，例如 `user1`：

   ```
   test=> GRANT USAGE ON FOREIGN SERVER mysqldb TO user1;
   GRANT
   ```

1. 以 *user1* 身分連線，然後建立一個 MySQL 使用者的映射：

   ```
   test=> CREATE USER MAPPING FOR user1 SERVER mysqldb OPTIONS (username 'myuser', password 'mypassword');
   CREATE USER MAPPING
   ```

1. 建立 MySQL 資料表的外部資料表連結。

   ```
   test=> CREATE FOREIGN TABLE mytab (a int, b text) SERVER mysqldb OPTIONS (dbname 'test', table_name '');
   CREATE FOREIGN TABLE
   ```

1. 對外部資料表執行簡單查詢：

   ```
   test=> SELECT * FROM mytab;
   a |   b
   ---+-------
   1 | apple
   (1 row)
   ```

1. 您可以從 MySQL 資料表新增、變更和移除資料。例如：

   ```
   test=> INSERT INTO mytab values (2, 'mango');
   INSERT 0 1
   ```

   再次執行 `SELECT` 查詢以查看結果：

   ```
   test=> SELECT * FROM mytab ORDER BY 1;
    a |   b
   ---+-------
   1 | apple
   2 | mango
   (2 rows)
   ```

## 搭配此擴充功能使用傳輸中加密
<a name="postgresql-mysql-fdw.encryption-in-transit"></a>

預設情況下，從 RDS for PostgreSQL 到 MySQL 的連線會使用傳輸中加密 (TLS/SSL)。但是，當用戶端和伺服器組態不同時，連線會回退到未加密。您可以在 RDS for MySQL 使用者帳戶上指定 `REQUIRE SSL` 選項，強制加密所有的對外連線。此方法也適用於 MariaDB 和 Aurora MySQL 使用者帳戶。

當 MySQL 使用者帳戶設定為 `REQUIRE SSL`，如果無法建立安全連線，連線嘗試將會失敗。

若要強制加密現有 MySQL 資料庫使用者帳戶，可使用 `ALTER USER` 命令。語法依據 MySQL 版本而異，如下表所示。如需詳細資訊，請參閱《*MySQL 參考手冊*》中的 [ALTER USER](https://dev.mysql.com/doc/refman/8.0/en/alter-user.html)。


| MySQL 5.7、MySQL 8.0 | MySQL 5.6 | 
| --- | --- | 
|  `ALTER USER 'user'@'%' REQUIRE SSL;`  |  `GRANT USAGE ON *.* to 'user'@'%' REQUIRE SSL;`  | 

如需 `mysql_fdw` 擴充功能的詳細資訊，請參閱 [mysql\$1fdw](https://github.com/EnterpriseDB/mysql_fdw) 文件。

# 使用 oracle\$1fdw 擴充功能處理 Oracle 資料庫
<a name="postgresql-oracle-fdw"></a>

若要從您的 RDS for PostgreSQL 資料庫執行個體 存取 Oracle 資料庫，您可以安裝並使用 `oracle_fdw` 擴充功能。此擴充功能是 Oracle 資料庫的外部資料包裝函式。若要進一步了解此擴充功能，請參閱 [oracle\$1fdw](https://github.com/laurenz/oracle_fdw) 文件。

RDS for PostgreSQL 12.7、13.3 版及更高版本支援此 `oracle_fdw` 擴充功能。

**Topics**
+ [開啟 oracle\$1fdw 擴充功能](#postgresql-oracle-fdw.enabling)
+ [範例：使用 Amazon RDS for Oracle Database 的外部伺服器連結](#postgresql-oracle-fdw.example)
+ [在傳輸中使用加密](#postgresql-oracle-fdw.encryption)
+ [了解 pg\$1user\$1mappings 檢視和許可權限](#postgresql-oracle-fdw.permissions)

## 開啟 oracle\$1fdw 擴充功能
<a name="postgresql-oracle-fdw.enabling"></a>

如要使用 oracle\$1fdw 擴充功能，請執行下列程序。

**如要開啟 oracle\$1fdw 擴充功能**
+ 使用具有 `rds_superuser` 許可的帳戶執行下列命令。

  ```
  CREATE EXTENSION oracle_fdw;
  ```

## 範例：使用 Amazon RDS for Oracle Database 的外部伺服器連結
<a name="postgresql-oracle-fdw.example"></a>

下列範例顯示使用連結至 Amazon RDS for Oracle 資料庫的外部伺服器。

**若要建立連結至 RDS for Oracle 資料庫的外部伺服器**

1. 請注意以下 RDS for Oracle 資料庫執行個體的事項：
   + 端點
   + 連線埠
   + 資料庫名稱

1. 建立外部伺服器。

   ```
   test=> CREATE SERVER oradb FOREIGN DATA WRAPPER oracle_fdw OPTIONS (dbserver '//endpoint:port/DB_name');
   CREATE SERVER
   ```

1. 授予使用權限給沒有 `rds_superuser` 權限的使用者，例如 `user1`。

   ```
   test=> GRANT USAGE ON FOREIGN SERVER oradb TO user1;
   GRANT
   ```

1. 連線為 `user1` 並建立一個對應至 Oracle 使用者的映射。

   ```
   test=> CREATE USER MAPPING FOR user1 SERVER oradb OPTIONS (user 'oracleuser', password 'mypassword');
   CREATE USER MAPPING
   ```

1. 建立連結至 Oracle 資料表的外部資料表。

   ```
   test=> CREATE FOREIGN TABLE mytab (a int) SERVER oradb OPTIONS (table 'MYTABLE');
   CREATE FOREIGN TABLE
   ```

1. 查詢外部資料表。

   ```
   test=>  SELECT * FROM mytab;
   a
   ---
   1
   (1 row)
   ```

如果查詢報告下列錯誤，請檢查您的安全群組和存取控制清單 (ACL)，以確定這兩個執行個體可以通訊。

```
ERROR: connection for foreign table "mytab" cannot be established
DETAIL: ORA-12170: TNS:Connect timeout occurred
```

## 在傳輸中使用加密
<a name="postgresql-oracle-fdw.encryption"></a>

傳輸中的 PostgreSQL-to-Oracle 加密是以從用戶端和伺服器組態參數的組合為依據。如需使用 Oracle 21c 的範例，請參閱 Oracle 文件中的[關於溝通加密和完整性的值](https://docs.oracle.com/en/database/oracle/oracle-database/21/dbseg/configuring-network-data-encryption-and-integrity.html#GUID-3A2AF4AA-AE3E-446B-8F64-31C48F27A2B5)。在 Amazon RDS 上用於 oracle\$1fdw 的用戶端已設定為 `ACCEPTED`，表示加密取決於 Oracle 資料庫伺服器組態，其會使用 Oracle 安全性程式庫 (libnnz) 進行加密。

如果資料庫位於 RDS for Oracle，請參閱 [Oracle 原生網路加密](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.Oracle.Options.NetworkEncryption.html)以設定加密。

## 了解 pg\$1user\$1mappings 檢視和許可權限
<a name="postgresql-oracle-fdw.permissions"></a>

PostgreSQL 目錄 `pg_user_mapping` 儲存從 RDS-PostgreSQL 使用者新增至外部資料 (遠端) 伺服器上使用者的映射。存取目錄受到限制，但您使用 `pg_user_mappings` 檢視查看映射。接下來，您可找到一個範例，其顯示許可權限如何套用於範例 Oracle 資料庫，但此資訊通常適用於任何外部資料包裝函式。

在以下輸出中，您可以找到映射至三個不同範例使用者的角色和權限。使用者 `rdssu1` 和 `rdssu2` 是 `rds_superuser` 角色的成員，`user1` 則不是。此範例使用 `psql` 中繼命令 `\du` 來列出現有角色。

```
test=>  \du
                                                               List of roles
    Role name    |                         Attributes                         |                          Member of
-----------------+------------------------------------------------------------+-------------------------------------------------------------
 rdssu1          |                                                            | {rds_superuser}
 rdssu2          |                                                            | {rds_superuser}
 user1           |                                                            | {}
```

所有使用者，包括具有 `rds_superuser` 權限的使用者，可在 `pg_user_mappings` 資料表中查看自己的使用者映射 (`umoptions`)。如以下範例所示，當 `rdssu1` 嘗試獲取所有使用者映射，即使有 `rdssu1``rds_superuser` 權限，仍會引起錯誤：

```
test=> SELECT * FROM pg_user_mapping;
ERROR: permission denied for table pg_user_mapping
```

下列是一些範例。

```
test=> SET SESSION AUTHORIZATION rdssu1;
SET
test=> SELECT * FROM pg_user_mappings;
 umid  | srvid | srvname | umuser | usename    |            umoptions
-------+-------+---------+--------+------------+----------------------------------
 16414 | 16411 | oradb   |  16412 | user1      |
 16423 | 16411 | oradb   |  16421 | rdssu1     | {user=oracleuser,password=mypwd}
 16424 | 16411 | oradb   |  16422 | rdssu2     |
 (3 rows)

test=> SET SESSION AUTHORIZATION rdssu2;
SET
test=> SELECT * FROM pg_user_mappings;
 umid  | srvid | srvname | umuser | usename    |            umoptions
-------+-------+---------+--------+------------+----------------------------------
 16414 | 16411 | oradb   |  16412 | user1      |
 16423 | 16411 | oradb   |  16421 | rdssu1     |
 16424 | 16411 | oradb   |  16422 | rdssu2     | {user=oracleuser,password=mypwd}
 (3 rows)

test=> SET SESSION AUTHORIZATION user1;
SET
test=> SELECT * FROM pg_user_mappings;
 umid  | srvid | srvname | umuser | usename    |           umoptions
-------+-------+---------+--------+------------+--------------------------------
 16414 | 16411 | oradb   |  16412 | user1      | {user=oracleuser,password=mypwd}
 16423 | 16411 | oradb   |  16421 | rdssu1     |
 16424 | 16411 | oradb   |  16422 | rdssu2     |
 (3 rows)
```

由於實作 `information_schema._pg_user_mappings` 和 `pg_catalog.pg_user_mappings` 存在差異，手動建立的 `rds_superuser` 需要額外的許可才能在 `pg_catalog.pg_user_mappings` 上檢視密碼。

`rds_superuser` 不需要額外許可才能在 `information_schema._pg_user_mappings` 中檢視密碼。

沒有 `rds_superuser` 角色的使用者僅能在以下情況下在 `pg_user_mappings` 中檢視密碼：
+ 目前使用者是被映射的使用者，且擁有伺服器或擁有伺服器上 `USAGE` 的權限。
+ 目前使用者是伺服器擁有者，且映射適用於 `PUBLIC`。

# 使用 tds\$1fdw 擴充功能處理 SQL 資料庫
<a name="postgresql-tds-fdw"></a>

您可以使用 PostgreSQL `tds_fdw` 擴充功能來存取支援表格式資料串流 (TDS) 協議的資料庫，如 Sybase 和 Microsoft SQL Server 資料庫。此外部資料包裝函式可讓您從 RDS for PostgreSQL 資料庫執行個體 連線到使用 TDS 協議的資料庫，包括 Amazon RDS for Microsoft SQL Server。如需詳細資訊，請參閱 GitHub 上的 [tds-fdw/tds\$1fdw](https://github.com/tds-fdw/tds_fdw) 文件。

Amazon RDS for PostgreSQL 版本 14.2、13.6 及更新版本支援此 `tds_fdw` 擴充功能。

## 設定 Aurora PostgreSQL 資料庫以使用 tds\$1fdw 擴充功能
<a name="postgresql-tds-fdw-setting-up"></a>

在以下程序中，您可以找到設定及使用 `tds_fdw` 與 RDS for PostgreSQL 資料庫執行個體 的範例。您必須取得執行個體的以下詳細內容，然後才能使用 `tds_fdw` 連線到 SQL Server 資料庫：
+ 主機名稱或端點。如果是 RDS for SQL Server 資料庫執行個體，您可以使用主控台找到端點。選擇 Connectivity & security (連線和安全) 索引標籤，然後查看「端點和連線埠」區段。
+ 連線埠號碼。Microsoft SQL 伺服器的預設連線埠號是 1433。
+ 資料庫的名稱。資料庫識別符。

您也必須提供 SQL 連線埠 1433 的安全群組或存取控制清單 (ACL) 的存取權限。 RDS for PostgreSQL 資料庫執行個體和 RDS for SQL 資料庫執行個體都需要存取連線埠 1433。如果存取權限未正確設定，當您嘗試查詢 Microsoft SQL Server 時，您會看到以下錯誤訊息：

```
ERROR: DB-Library error: DB #: 20009, DB Msg: Unable to connect:
Adaptive Server is unavailable or does not exist (mssql2019.aws-region.rds.amazonaws.com), OS #: 0, OS Msg: Success, Level: 9
```

**使用 tds\$1fdw 連線到 SQL Server 資料庫**

1. 使用有 `rds_superuser` 角色的帳戶連線到您的 PostgreSQL 資料庫執行個體 ：

   ```
   psql --host=your-DB-instance.aws-region.rds.amazonaws.com --port=5432 --username=test –-password
   ```

1. 安裝 `tds_fdw` 擴充功能：

   ```
   test=> CREATE EXTENSION tds_fdw;
   CREATE EXTENSION
   ```

擴充功能安裝到您的 RDS for PostgreSQL 資料庫執行個體之後，您就可以設定外部伺服器。

**建立外部伺服器**

使用有 `rds_superuser` 權限的帳戶，在 RDS for PostgreSQL 資料庫執行個體上執行這些任務。

1. 在 RDS for PostgreSQL 資料庫執行個體中建立外部伺服器：

   ```
   test=> CREATE SERVER sqlserverdb FOREIGN DATA WRAPPER tds_fdw OPTIONS (servername 'mssql2019.aws-region.rds.amazonaws.com', port '1433', database 'tds_fdw_testing');
   CREATE SERVER
   ```

   如要存取 SQLServer 端上的非 ASCII 資料，請使用 RDS for PostgreSQL 資料庫執行個體中的 character\$1set 選項建立伺服器連結：

   ```
   test=> CREATE SERVER sqlserverdb FOREIGN DATA WRAPPER tds_fdw OPTIONS (servername 'mssql2019.aws-region.rds.amazonaws.com', port '1433', database 'tds_fdw_testing', character_set 'UTF-8');
   CREATE SERVER
   ```

1. 將權限授予沒有 `rds_superuser` 角色權限的使用者，例如 `user1`：

   ```
   test=> GRANT USAGE ON FOREIGN SERVER sqlserverdb TO user1;
   ```

1. 以 user1 身分連線，然後建立一個 SQL Server 使用者的映射：

   ```
   test=> CREATE USER MAPPING FOR user1 SERVER sqlserverdb OPTIONS (username 'sqlserveruser', password 'password');
   CREATE USER MAPPING
   ```

1. 建立連結至 SQL Server 資料表的外部資料表：

   ```
   test=> CREATE FOREIGN TABLE mytab (a int) SERVER sqlserverdb OPTIONS (table 'MYTABLE');
   CREATE FOREIGN TABLE
   ```

1. 查詢外部資料表：

   ```
   test=> SELECT * FROM mytab;
    a
   ---
    1
   (1 row)
   ```

### 對連線使用傳輸中加密
<a name="postgresql-tds-fdw-ssl-tls-encryption"></a>

從 RDS for PostgreSQL 到 SQL Server 的連線使用傳輸中加密 (TLS/SSL)，具體取決於 SQL Server 資料庫組態。如果 SQL 伺服器未設定為加密，則 RDS for PostgreSQL 用戶端對 SQL Server 資料庫發出的請求將回退為未加密。

您可以透過設定 `rds.force_ssl` 參數，強制加密 RDS for SQL Server 資料庫執行個體的連線。若要了解作法，請參閱[強制使用 SSL 連線至資料庫執行個體](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/SQLServer.Concepts.General.SSL.Using.html#SQLServer.Concepts.General.SSL.Forcing)。如需有關 RDS for SQL Server 的 SSL/TLS 組態的詳細資訊，請參閱[對 Microsoft SQL Server 資料庫執行個體使用 SSL](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/SQLServer.Concepts.General.SSL.Using.html)。

# 使用適用於 PostgreSQL 的受信任語言延伸模組
<a name="PostgreSQL_trusted_language_extension"></a>

PostgreSQL 的受信任語言延伸模組是用於建置 PostgreSQL 延伸模組的開放原始碼開發套件。它可讓您建置高效能 PostgreSQL 延伸模組，並在 RDS for PostgreSQL 資料庫執行個體上安全地執行它們 透過使用適用於 PostgreSQL 的受信任語言延伸模組 (TLE)，您可以建立 PostgreSQL 延伸模組，遵循記載的方法來擴充 PostgreSQL 功能。如需詳細資訊，請參閱 PostgreSQL 文件中的[將相關物件封裝為延伸模組](https://www.postgresql.org/docs/current/extend-extensions.html)。

TLE 的一個主要優點，就是您可以在未於 PostgreSQL 執行個體之下提供檔案系統存取權的環境中使用它。先前，安裝新的延伸模組需要存取檔案系統。TLE 移除了此條件約束。它提供一個開發環境，可讓您針對任何 PostgreSQL 資料庫 (包括在 RDS for PostgreSQL 資料庫執行個體上執行的資料庫) 建立新的延伸模組。

TLE 的設計旨在防止存取對您使用 TLE 建立的延伸模組而言不安全的資源。其執行時間環境會限制任何延伸模組瑕疵對單一資料庫連線的影響。TLE 還可讓資料庫管理員對可以安裝延伸模組的人員進行精細控制，並提供用於執行延伸模組的許可模型。

下列 RDS for PostgreSQL 版本支援 TLE：
+  18.1 版和更新的 18 版 
+  17.1 版和更新的 17 版 
+  16.1 版和更新的 16 版 
+  15.2 版和更新的第 15 版 
+  14.5 版和更新的第 14 版 
+  13.12 版和更新的第 13 版 

受信任語言延伸模組開發環境和執行時間會封裝成 `pg_tle` PostgreSQL 延伸模組 1.0.1 版。它支援以 JavaScript、Perl、Tcl、PL/PGSQL 和 SQL 建立延伸模組。您可以採取您安裝其他 PostgreSQL 延伸模組的同一方式，在 RDS for PostgreSQL 資料庫執行個體中安裝 `pg_tle` 延伸模組。在設定了 `pg_tle` 之後，開發人員可以使用它，建立新的 PostgreSQL 延伸模組，稱為 *TLE 延伸模組*。

 

在下列主題中，您可以找到如何設定受信任語言延伸模組，以及如何開始建立您自己的 TLE 延伸模組的相關資訊。

**Topics**
+ [術語](PostgreSQL_trusted_language_extension-terminology.md)
+ [使用適用於 PostgreSQL 的受信任語言延伸模組的需求](PostgreSQL_trusted_language_extension-requirements.md)
+ [在您的 RDS for PostgreSQL 資料庫執行個體中設定受信任語言延伸模組](PostgreSQL_trusted_language_extension-setting-up.md)
+ [適用於 PostgreSQL 的受信任語言延伸模組概觀](PostgreSQL_trusted_language_extension.overview.md)
+ [針對 RDS for PostgreSQL 建立 TLE 延伸模組](PostgreSQL_trusted_language_extension-creating-TLE-extensions.md)
+ [從資料庫中捨棄您的 TLE 延伸模組](PostgreSQL_trusted_language_extension-creating-TLE-extensions.dropping-TLEs.md)
+ [解除安裝適用於 PostgreSQL 的受信任語言延伸模組](PostgreSQL_trusted_language_extension-uninstalling-pg_tle-devkit.md)
+ [搭配您的延伸模組使用 PostgreSQL 掛鉤](PostgreSQL_trusted_language_extension.overview.tles-and-hooks.md)
+ [在 TLE 中使用自訂資料類型](PostgreSQL_trusted_language_extension-custom-data-type.md)
+ [適用於 PostgreSQL 的受信任語言延伸模組的函數參考](PostgreSQL_trusted_language_extension-functions-reference.md)
+ [適用於 PostgreSQL 的受信任語言延伸模組的掛鉤參考](PostgreSQL_trusted_language_extension-hooks-reference.md)

# 術語
<a name="PostgreSQL_trusted_language_extension-terminology"></a>

為了協助您更好地了解受信任語言延伸模組，請檢視下列詞彙表以取得本主題中使用的術語。

**適用於 PostgreSQL 的受信任語言延伸模組**  
*適用於 PostgreSQL 的受信任語言延伸模組*是封裝為 `pg_tle` 延伸模組之開放原始碼開發套件的正式名稱。它可以在任何 PostgreSQL 系統上使用。如需詳細資訊，請參閱 GitHub 上的 [aws/pg\$1tle](https://github.com/aws/pg_tle)。

**受信任語言延伸模組**  
*受信任語言延伸模組*是適用於 PostgreSQL 的受信任語言延伸模組的簡稱。此簡稱及其縮寫 (TLE) 也會在本文件中使用。

**受信任語言**  
*受信任語言*是具有特定安全性屬性的程式設計或指令碼語言。例如，受信任語言通常會限制對檔案系統的存取，而且也會限制使用指定的聯網屬性。TLE 開發套件專為支援受信任語言而設計。PostgreSQL 支援數種不同的語言，這些語言用來建立受信任或不受信任的延伸模組。如需範例，請參閱 PostgreSQL 文件中的[受信任和不受信任的 PL/Perl](https://www.postgresql.org/docs/current/plperl-trusted.html)。當您使用受信任語言延伸模組建立延伸模組時，延伸模組本質上會使用受信任語言機制。

**TLE 延伸模組**  
*TLE 延伸模組*是已使用受信任語言延伸模組 (TLE) 開發套件所建立的 PostgreSQL 延伸模組。

# 使用適用於 PostgreSQL 的受信任語言延伸模組的需求
<a name="PostgreSQL_trusted_language_extension-requirements"></a>

以下是設定和使用 TLE 開發套件時的需求。
+ ** RDS for PostgreSQL 版本** - 僅在 RDS for PostgreSQL 13.12 版和更新的第 13 版、14.5 版和更新的第 14 版，以及 15.2 版及更新版本上支援受信任語言延伸模組。
  + 如果您需要升級 RDS for PostgreSQL 執行個體， 請參閱 [RDS for PostgreSQL 資料庫引擎的升級](USER_UpgradeDBInstance.PostgreSQL.md)。
  + 如果您還沒有執行 PostgreSQL 的 Amazon RDS 資料庫執行個體，則可以建立一個。如需詳細資訊，請參閱 RDS for PostgreSQL 資料庫執行個體，請參閱 [建立並連線至 PostgreSQL 資料庫執行個體](CHAP_GettingStarted.CreatingConnecting.PostgreSQL.md)。
+ **需要 `rds_superuser` 權限** - 若要設定 `pg_tle` 延伸模組，您的資料庫使用者角色必須具有 `rds_superuser` 角色的許可。根據預設，會將此角色授予建立 的 `postgres` 使用者。RDS for PostgreSQL 資料庫執行個體。
+ **需要自訂資料庫參數群組** – 您的 RDS for PostgreSQL 資料庫執行個體必須搭配自訂資料庫參數群組進行設定。
  + 如果您的 RDS for PostgreSQL 資料庫執行個體未搭配自訂資料庫參數群組進行設定，您應該建立一個，並將其與 RDS for PostgreSQL 資料庫執行個體建立關聯。如需步驟的簡短摘要，請參閱 [建立並套用自訂資料庫參數群組](#PostgreSQL_trusted_language_extension-requirements-create-custom-params)。
  + 如果您的 RDS for PostgreSQL 資料庫執行個體已使用自訂資料庫參數群組進行設定，您可以設定受信任語言延伸模組。如需詳細資訊，請參閱[在您的 RDS for PostgreSQL 資料庫執行個體中設定受信任語言延伸模組](PostgreSQL_trusted_language_extension-setting-up.md)。

## 建立並套用自訂資料庫參數群組
<a name="PostgreSQL_trusted_language_extension-requirements-create-custom-params"></a>

請使用下列步驟建立自訂資料庫參數群組，並設定您的 RDS for PostgreSQL 資料庫執行個體來使用該群組。

### 主控台
<a name="PostgreSQL_trusted_language_extension-requirements-custom-parameters.CON"></a>

**建立自訂資料庫參數群組，並將其與 RDS for PostgreSQL 資料庫執行個體搭配使用**

1. 登入 AWS 管理主控台 ，並在 [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/)：// 開啟 Amazon RDS 主控台。

1. 從 Amazon RDS 功能表中，選擇 Parameter groups (參數群組)。

1. 選擇 **Create parameter group (建立參數群組)**。

1. 在 **Parameter group details** (參數群組詳細資訊) 頁面中，輸入下列資訊：
   + 針對 **Parameter group family** (參數群組系列)，選擇 postgres14。。
   + 針對 **Type** (類型)，選擇 DB Parameter Group (資料庫參數群組)。
   + 針對 **Group name** (群組名稱)，在操作內容中給與您的參數群組一個有意義的名稱。
   + 針對 **Description** (描述)，輸入有用的描述，以便您團隊中的其他成員可以輕鬆找到它。

1. 選擇**建立**。您的自訂資料庫參數群組是在 AWS 區域中建立。您現在可以遵循下列步驟修改 RDS for PostgreSQL 資料庫執行個體以使用它。

1. 從 Amazon RDS 功能表中選擇 **Databases** (資料庫)。

1. 從列出的 RDS for PostgreSQL 資料庫執行個體中選擇您想要哪一個與 TLE 搭配使用，然後選擇 **Modify** (修改)。

1. 在 Modify DB instance settings (修改資料庫執行個體設定) 頁面中，於 Additional configuration (其他組態) 區段中尋找 **Database options** (資料庫選項)，然後從選取器中選擇您的自訂資料庫參數群組。

1. 選擇 **Continue** (繼續) 以儲存變更。

1. 選擇 **Apply immediately** (立即套用)，以便您可以繼續設定 RDS for PostgreSQL 資料庫執行個體以使用 TLE。

若要繼續針對受信任語言延伸模組設定您的系統，請參閱 [在您的 RDS for PostgreSQL 資料庫執行個體中設定受信任語言延伸模組](PostgreSQL_trusted_language_extension-setting-up.md)。

如需深入了解如何使用資料庫參數群組，請參閱 [Amazon RDS 資料庫執行個體的資料庫參數群組](USER_WorkingWithDBInstanceParamGroups.md)。

### AWS CLI
<a name="PostgreSQL_trusted_language_extension-requirements-custom-parameters-CLI"></a>

您可以避免在使用 CLI 命令時指定 `--region` 引數，方法是使用您的預設 AWS 區域來設定您的 AWS CLI 。如需詳細資訊，請參閱《AWS Command Line Interface 使用者指南》**中的[組態基礎概念](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-config)。

**建立自訂資料庫參數群組，並將其與 RDS for PostgreSQL 資料庫執行個體搭配使用**

1. 使用 [create-db-parameter-group](https://docs.aws.amazon.com/cli/latest/reference/rds/create-db-parameter-group.html) AWS CLI 命令，根據 postgres14 為您的 建立自訂資料庫參數群組 AWS 區域。

   對於 Linux、macOS 或 Unix：

   ```
   aws rds create-db-parameter-group \
     --region aws-region \
     --db-parameter-group-name custom-params-for-pg-tle \
     --db-parameter-group-family postgres14 \
     --description "My custom DB parameter group for Trusted Language Extensions"
   ```

   在 Windows 中：

   ```
   aws rds create-db-parameter-group ^
     --region aws-region ^
     --db-parameter-group-name custom-params-for-pg-tle ^
     --db-parameter-group-family postgres14 ^
     --description "My custom DB parameter group for Trusted Language Extensions"
   ```

   您的自訂資料庫參數群組可在 AWS 區域中使用，因此您可以修改  RDS for PostgreSQL 資料庫叢集以使用它。

1. 使用 [modify-db-instance](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-instance.html) AWS CLI 命令，將您的自訂資料庫參數群組套用至 您的 RDS for PostgreSQL 資料庫執行個體。此命令會立即重新啟動作用中執行個體。

   對於 Linux、macOS 或 Unix：

   ```
   aws rds modify-db-instance \
     --region aws-region \
     --db-instance-identifier your-instance-name \
     --db-parameter-group-name custom-params-for-pg-tle \
     --apply-immediately
   ```

   在 Windows 中：

   ```
   aws rds modify-db-instance ^
     --region aws-region ^
     --db-instance-identifier your-instance-name ^
     --db-parameter-group-name custom-params-for-pg-tle ^
     --apply-immediately
   ```

若要繼續針對受信任語言延伸模組設定您的系統，請參閱 [在您的 RDS for PostgreSQL 資料庫執行個體中設定受信任語言延伸模組](PostgreSQL_trusted_language_extension-setting-up.md)。

如需更多詳細資訊，請參閱 [Amazon RDS 的參數群組](USER_WorkingWithParamGroups.md)。

# 在您的 RDS for PostgreSQL 資料庫執行個體中設定受信任語言延伸模組
<a name="PostgreSQL_trusted_language_extension-setting-up"></a>

下列步驟假設您的 RDS for PostgreSQL 資料庫執行個體與自訂資料庫參數群組相關聯。您可以針對這些步驟使用 AWS 管理主控台 或 AWS CLI。

當您在 RDS for PostgreSQL 資料庫執行個體中設定受信任語言延伸模組時，可以將其安裝在特定資料庫中，供具有該資料庫許可的資料庫使用者使用。

## 主控台
<a name="PostgreSQL_trusted_language_extension-setting-up.CON"></a>

**設定受信任語言延伸模組**

使用屬於 `rds_superuser` 群組 (角色) 成員的帳戶執行下列步驟。

1. 登入 AWS 管理主控台，開啟位於 [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/) 的 Amazon RDS 主控台。

1. 在導覽窗格中，選擇您的 RDS for PostgreSQL 資料庫執行個體。

1. 針對您的 開啟 **Configuration** (組態) 索引標籤。RDS for PostgreSQL 資料庫執行個體。在執行個體詳細資訊之間，尋找 **Parameter group** (參數群組) 連結。

1. 選擇連結以開啟與 相關聯的自訂參數。RDS for PostgreSQL 資料庫執行個體。

1. 在 **Parameters** (參數) 搜尋欄位中，輸入 `shared_pre` 以尋找 `shared_preload_libraries` 參數。

1. 選擇 **Edit parameters** (編輯參數) 以存取屬性值。

1. 在 **Values** (值) 欄位中，將 `pg_tle` 新增至清單。使用逗號區隔值清單中的項目。  
![\[已新增 pg_tle 之 shared_preload_libraries 參數的影像。\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/images/apg_rpg_shared_preload_pg_tle.png)

1. 重新啟動 RDS for PostgreSQL 資料庫執行個體，以便您對 `shared_preload_libraries` 參數所做的變更生效。

1. 當執行個體可用時，請驗證 `pg_tle` 是否已初始化。使用 `psql` 連線至 RDS for PostgreSQL 資料庫執行個體，然後執行下列命令。

   ```
   SHOW shared_preload_libraries;
   shared_preload_libraries 
   --------------------------
   rdsutils,pg_tle
   (1 row)
   ```

1. 在初始化 `pg_tle` 延伸模組之後，您現在可以建立延伸模組。

   ```
   CREATE EXTENSION pg_tle;
   ```

   您可以使用下列 `psql` 中繼命令，驗證是否已安裝延伸模組。

   ```
   labdb=> \dx
                            List of installed extensions
     Name   | Version |   Schema   |                Description
   ---------+---------+------------+--------------------------------------------
    pg_tle  | 1.0.1   | pgtle      | Trusted-Language Extensions for PostgreSQL
    plpgsql | 1.0     | pg_catalog | PL/pgSQL procedural language
   ```

1. 在設定時，將 `pgtle_admin` 角色授予您已針對 RDS for PostgreSQL 資料庫執行個體建立的主要使用者名稱。如果您接受預設值，其為 `postgres`。

   ```
   labdb=> GRANT pgtle_admin TO postgres;
   GRANT ROLE
   ```

   您可以使用 `psql` 中繼命令來驗證授予是否已發生，如下列範例所示。只有 `pgtle_admin` 和 `postgres` 角色會顯示在輸出中。如需詳細資訊，請參閱 [了解 rds\$1superuser 角色](Appendix.PostgreSQL.CommonDBATasks.Roles.rds_superuser.md)。

   ```
   labdb=> \du
                             List of roles
       Role name    |           Attributes            |               Member of
   -----------------+---------------------------------+-----------------------------------
   pgtle_admin     | Cannot login                     | {}
   postgres        | Create role, Create DB          +| {rds_superuser,pgtle_admin}
                   | Password valid until infinity    |...
   ```

1. 使用 `\q` 中繼命令關閉 `psql` 工作階段。

   ```
   \q
   ```

若要開始建立 TLE 延伸模組，請參閱 [範例：使用 SQL 建立受信任語言延伸模組](PostgreSQL_trusted_language_extension-creating-TLE-extensions.md#PostgreSQL_trusted_language_extension-simple-example)。

## AWS CLI
<a name="PostgreSQL_trusted_language_extension-setting-up-CLI"></a>

您可以避免在使用 CLI 命令時指定 `--region` 引數，方法是使用您的預設 AWS 區域來設定您的 AWS CLI。如需詳細資訊，請參閱《AWS Command Line Interface 使用者指南》**中的[組態基礎概念](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-config)。

**設定受信任語言延伸模組**

1. 使用 [modify-db-parameter-group](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-parameter-group.html) AWS CLI 命令，將 `pg_tle` 新增至 `shared_preload_libraries` 參數。

   ```
   aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=shared_preload_libraries,ParameterValue=pg_tle,ApplyMethod=pending-reboot" \
      --region aws-region
   ```

1. 使用 [reboot-db-instance](https://docs.aws.amazon.com/cli/latest/reference/rds/reboot-db-instance) AWS CLI 命令重新啟動 RDS for PostgreSQL 資料庫執行個體，並初始化 `pg_tle` 程式庫。

   ```
   aws rds reboot-db-instance \
       --db-instance-identifier your-instance \
       --region aws-region
   ```

1. 當執行個體可用時，您可以驗證 `pg_tle` 是否已初始化。使用 `psql` 連線至 RDS for PostgreSQL 資料庫執行個體，然後執行下列命令。

   ```
   SHOW shared_preload_libraries;
   shared_preload_libraries 
   --------------------------
   rdsutils,pg_tle
   (1 row)
   ```

   在初始化 `pg_tle` 之後，您現在可以建立延伸模組。

   ```
   CREATE EXTENSION pg_tle;
   ```

1. 在設定時，將 `pgtle_admin` 角色授予您已針對 RDS for PostgreSQL 資料庫執行個體建立的主要使用者名稱。如果您接受預設值，其為 `postgres`。

   ```
   GRANT pgtle_admin TO postgres;
   GRANT ROLE
   ```

1. 關閉 `psql` 工作階段，如下所示。

   ```
   labdb=> \q
   ```

若要開始建立 TLE 延伸模組，請參閱 [範例：使用 SQL 建立受信任語言延伸模組](PostgreSQL_trusted_language_extension-creating-TLE-extensions.md#PostgreSQL_trusted_language_extension-simple-example)。

# 適用於 PostgreSQL 的受信任語言延伸模組概觀
<a name="PostgreSQL_trusted_language_extension.overview"></a>

適用於 PostgreSQL 的受信任語言延伸模組是一種 PostgreSQL 延伸模組，而您使用您設定其他 PostgreSQL 延伸模組的同一方式，將其安裝在 RDS for PostgreSQLR 資料庫執行個體中。在 pgAdmin 用戶端工具中範例資料庫的下列影像中，您可以檢視構成 `pg_tle` 延伸模組的一些元件。

![\[此圖顯示構成 TLE 開發套件的一些元件。\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/UserGuide/images/apg-pg_tle-installed-view-in-pgAdmin.png)


您可以查看下列詳細資訊。

1. 適用於 PostgreSQL 的受信任語言延伸模組 (TLE) 開發套件會封裝為 `pg_tle` 延伸模組。因此，`pg_tle` 會新增至其安裝所在資料庫的可用延伸模組。

1. TLE 有其自己的結構描述 (`pgtle`)。此結構描述包含協助程式函數 (3)，用於安裝和管理您建立的延伸模組。

1. TLE 提供了十幾個協助程式函數，用於安裝、註冊和管理您的延伸模組。若要進一步了解這些函數，請參閱[適用於 PostgreSQL 的受信任語言延伸模組的函數參考](PostgreSQL_trusted_language_extension-functions-reference.md)。

`pg_tle` 延伸套件的其他元件包含下列項目：
+ **`pgtle_admin` 角色** – 安裝 `pg_tle` 延伸模組時會建立 `pgtle_admin` 角色。此角色具有特殊權限，且應如此對待。強烈建議您在將 `pgtle_admin` 角色授予資料庫使用者時遵循*最低權限*原則。換句話說，只將 `pgtle_admin` 角色授予資料庫使用者，允許其建立、安裝和管理新的 TLE 延伸模組，例如 `postgres`。
+ **`pgtle.feature_info` 資料表** – `pgtle.feature_info` 資料表是受保護的資料表，其中包含 TLE、掛鉤，以及其使用的自訂預存程序和函數的相關資訊。如果具有 `pgtle_admin` 權限，則您可以使用下列受信任語言延伸模組函數，在資料表中新增和更新該資訊。
  + [pgtle.register\$1feature](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.register_feature)
  + [pgtle.register\$1feature\$1if\$1not\$1exists](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.register_feature_if_not_exists)
  + [pgtle.unregister\$1feature](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.unregister_feature)
  + [pgtle.unregister\$1feature\$1if\$1exists](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.unregister_feature_if_exists)

# 針對 RDS for PostgreSQL 建立 TLE 延伸模組
<a name="PostgreSQL_trusted_language_extension-creating-TLE-extensions"></a>

您可以在任何已安裝延伸模組的 RDS for PostgreSQL 資料庫執行個體中安裝使用 TLE 建立的任何 `pg_tle` 延伸模組。`pg_tle` 延伸模組的範圍會限定在其安裝所在的 PostgreSQL 資料庫。您使用 TLE 建立的延伸模組，其範圍會限定在相同的資料庫。

使用各種 `pgtle` 函數來安裝構成 TLE 延伸模組的程式碼。下列受信任語言延伸模組函數全都需要 `pgtle_admin` 角色。
+ [pgtle.install\$1extension](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.install_extension)
+ [pgtle.install\$1update\$1path](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.install_update_path)
+ [pgtle.register\$1feature](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.register_feature)
+ [pgtle.register\$1feature\$1if\$1not\$1exists](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.register_feature_if_not_exists)
+ [pgtle.set\$1default\$1version](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.set_default_version)
+ [pgtle.uninstall\$1extension(name)](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.uninstall_extension-name)
+ [pgtle.uninstall\$1extension(name, version)](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.uninstall_extension-name-version)
+ [pgtle.uninstall\$1extension\$1if\$1exists](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.uninstall_extension_if_exists)
+ [pgtle.uninstall\$1update\$1path](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.uninstall_update_path)
+ [pgtle.uninstall\$1update\$1path\$1if\$1exists](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.uninstall_update_path_if_exists)
+ [pgtle.unregister\$1feature](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.unregister_feature)
+ [pgtle.unregister\$1feature\$1if\$1exists](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.unregister_feature_if_exists)

## 範例：使用 SQL 建立受信任語言延伸模組
<a name="PostgreSQL_trusted_language_extension-simple-example"></a>

下列範例說明如何建立名為 `pg_distance` 的 TLE 延伸模組，其中包含一些 SQL 函數，用於使用不同的公式計算距離。在清單中，您可以找到用於計算曼哈頓距離的函數，以及計算歐幾里得距離的函數。如需這些公式之間差異的詳細資訊，請參閱 Wikipedia 中的[出租車幾何](https://en.wikipedia.org/wiki/Taxicab_geometry)和[歐幾里得幾何](https://en.wikipedia.org/wiki/Euclidean_geometry)。

如果您已按照[在您的 RDS for PostgreSQL 資料庫執行個體中設定受信任語言延伸模組](PostgreSQL_trusted_language_extension-setting-up.md)中所述設定 `pg_tle` 延伸模組，則可以在自己的 RDS for PostgreSQL 資料庫執行個體中使用此範例。

**注意**  
您必須具有 `pgtle_admin` 角色的權限才能遵循此程序。

**建立範例 TLE 延伸模組**

下列步驟會使用名為 `labdb` 的範例資料庫。此資料庫是由 `postgres` 主要使用者所擁有。`postgres` 角色也具有 `pgtle_admin` 角色的權限。

1. 使用 `psql` 連線到 RDS for PostgreSQL 資料庫執行個體。

   ```
   psql --host=db-instance-123456789012.aws-region.rds.amazonaws.com
   --port=5432 --username=postgres --password --dbname=labdb
   ```

1. 複製下列程式碼並將其貼入 `psql` 工作階段主控台中，來建立名為 `pg_distance` 的 TLE 延伸模組。

   ```
   SELECT pgtle.install_extension
   (
    'pg_distance',
    '0.1',
     'Distance functions for two points',
   $_pg_tle_$
       CREATE FUNCTION dist(x1 float8, y1 float8, x2 float8, y2 float8, norm int)
       RETURNS float8
       AS $$
         SELECT (abs(x2 - x1) ^ norm + abs(y2 - y1) ^ norm) ^ (1::float8 / norm);
       $$ LANGUAGE SQL;
   
       CREATE FUNCTION manhattan_dist(x1 float8, y1 float8, x2 float8, y2 float8)
       RETURNS float8
       AS $$
         SELECT dist(x1, y1, x2, y2, 1);
       $$ LANGUAGE SQL;
   
       CREATE FUNCTION euclidean_dist(x1 float8, y1 float8, x2 float8, y2 float8)
       RETURNS float8
       AS $$
         SELECT dist(x1, y1, x2, y2, 2);
       $$ LANGUAGE SQL;
   $_pg_tle_$
   );
   ```

   您會看到如下輸出。

   ```
   install_extension
   ---------------
    t
   (1 row)
   ```

   構成 `pg_distance` 延伸模組的成品現在已安裝在您的資料庫中。這些成品包括延伸模組的控制檔和程式碼，這些是必須存在的項目，如此才能使用 `CREATE EXTENSION` 命令建立延伸模組。換句話說，您仍然需要建立延伸模組，以使其函數可供資料庫使用者使用。

1. 若要建立延伸模組，請使用 `CREATE EXTENSION` 命令，如您對任何其他延伸模組所做一樣。與其他延伸模組一樣，資料庫使用者需要在資料庫中具有 `CREATE` 權限。

   ```
   CREATE EXTENSION pg_distance;
   ```

1. 若要測試 `pg_distance` TLE 延伸模組，您可以使用它，計算四點之間的[曼哈頓距離](https://en.wikipedia.org/wiki/Taxicab_geometry)。

   ```
   labdb=> SELECT manhattan_dist(1, 1, 5, 5);
   8
   ```

   若要計算同一組點之間的[歐幾里得距離](https://en.wikipedia.org/wiki/Euclidean_geometry)，您可以使用下列命令。

   ```
   labdb=> SELECT euclidean_dist(1, 1, 5, 5);
   5.656854249492381
   ```

`pg_distance` 延伸模組會在資料庫中載入函數，並使其可供具有資料庫權限的任何使用者使用。

## 修改 TLE 延伸模組
<a name="PostgreSQL_trusted_language_extension-simple-example.modify"></a>

若要改善此 TLE 延伸模組中封裝之函數的查詢效能，請將下列兩個 PostgreSQL 屬性新增至其規格。
+ `IMMUTABLE` – `IMMUTABLE` 屬性確保查詢最佳化工具可以使用最佳化來改善查詢回應時間。如需詳細資訊，請參閱 PostgreSQL 文件中的[函數波動類別](https://www.postgresql.org/docs/current/xfunc-volatility.html)。
+ `PARALLEL SAFE` – `PARALLEL SAFE` 屬性是允許 PostgreSQL 以平行模式執行函數的另一個屬性。如需詳細資訊，請參閱 PostgreSQL 文件中的 [CREATE FUNCTION](https://www.postgresql.org/docs/current/sql-createfunction.html)。

在下列範例中，您可以看到如何使用 `pgtle.install_update_path` 函數將這些屬性新增到每個函數，以建立 `pg_distance` TLE 延伸模組的版本 `0.2`。如需此函數狀態的詳細資訊，請參閱 [pgtle.install\$1update\$1path](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.install_update_path)。您必須具有 `pgtle_admin` 角色才能執行此任務。

**更新現有 TLE 延伸模組並指定預設版本**

1. 使用 `psql` 或其他用戶端工具 (例如 pgAdmin)，連線至 RDS for PostgreSQL 資料庫執行個體。

   ```
   psql --host=db-instance-123456789012.aws-region.rds.amazonaws.com
   --port=5432 --username=postgres --password --dbname=labdb
   ```

1. 複製下列程式碼並將其貼入 `psql` 工作階段主控台中，來修改現有的 TLE 延伸模組。

   ```
   SELECT pgtle.install_update_path
   (
    'pg_distance',
    '0.1',
    '0.2',
   $_pg_tle_$
       CREATE OR REPLACE FUNCTION dist(x1 float8, y1 float8, x2 float8, y2 float8, norm int)
       RETURNS float8
       AS $$
         SELECT (abs(x2 - x1) ^ norm + abs(y2 - y1) ^ norm) ^ (1::float8 / norm);
       $$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE;
   
       CREATE OR REPLACE FUNCTION manhattan_dist(x1 float8, y1 float8, x2 float8, y2 float8)
       RETURNS float8
       AS $$
         SELECT dist(x1, y1, x2, y2, 1);
       $$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE;
   
       CREATE OR REPLACE FUNCTION euclidean_dist(x1 float8, y1 float8, x2 float8, y2 float8)
       RETURNS float8
       AS $$
         SELECT dist(x1, y1, x2, y2, 2);
       $$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE;
   $_pg_tle_$
   );
   ```

   您會看到如下回應：

   ```
   install_update_path
   ---------------------
    t
   (1 row)
   ```

   您可以將此版本的延伸模組設為預設版本，這樣資料庫使用者就不必在資料庫中建立或更新延伸模組時指定版本。

1. 若要指定 TLE 延伸模組的修改版本 (版本 0.2) 為預設版本，請使用 `pgtle.set_default_version` 函數，如下列範例所示。

   ```
   SELECT pgtle.set_default_version('pg_distance', '0.2');
   ```

   如需此函數狀態的詳細資訊，請參閱 [pgtle.set\$1default\$1version](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.set_default_version)。

1. 在程式碼就位之後，您可以使用 `ALTER EXTENSION ... UPDATE` 命令，以尋常方式更新已安裝的 TLE 延伸模組，如這裡所示：

   ```
   ALTER EXTENSION pg_distance UPDATE;
   ```

# 從資料庫中捨棄您的 TLE 延伸模組
<a name="PostgreSQL_trusted_language_extension-creating-TLE-extensions.dropping-TLEs"></a>

您可以採取您對其他 PostgreSQL 延伸模組所用的同一方式，使用 `DROP EXTENSION` 命令來捨棄 TLE 延伸模組。捨棄延伸模組並不會移除構成延伸模組的安裝檔案，因而允許使用者重新建立延伸模組。若要移除延伸模組及其安裝檔案，請執行下列兩步驟程序。

**捨棄 TLE 延伸模組並移除其安裝檔案**

1. 使用 `psql` 或其他用戶端工具，連線至 RDS for PostgreSQL 資料庫執行個體。

   ```
   psql --host=.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=dbname
   ```

1. 捨棄延伸模組，如同您對任何 PostgreSQL 延伸模組所做一般。

   ```
   DROP EXTENSION your-TLE-extension
   ```

   例如，如果您如[範例：使用 SQL 建立受信任語言延伸模組](PostgreSQL_trusted_language_extension-creating-TLE-extensions.md#PostgreSQL_trusted_language_extension-simple-example)所述建立 `pg_distance` 延伸模組，則可以捨棄延伸模組，如下所示。

   ```
   DROP EXTENSION pg_distance;
   ```

   您會看到輸出，確認已捨棄延伸模組，如下所示。

   ```
   DROP EXTENSION
   ```

   此時，延伸模組在資料庫中不再處於作用中狀態。不過，其安裝檔案和控制檔案仍然可在資料庫中使用，因此資料庫使用者可以再次建立延伸模組 (如果想要的話)。
   + 如果想要延伸模組檔案保持不變，以便資料庫使用者可以建立您的 TLE 延伸模組，您可以在此停止。
   + 如果想要移除所有構成延伸模組的檔案，請繼續下一個步驟。

1. 若要移除延伸模組的所有安裝檔案，請使用 `pgtle.uninstall_extension` 函數。此函數會移除延伸模組的所有程式碼和控制檔。

   ```
   SELECT pgtle.uninstall_extension('your-tle-extension-name');
   ```

   例如，若要移除所有 `pg_distance` 安裝檔案，請使用下列命令。

   ```
   SELECT pgtle.uninstall_extension('pg_distance');
    uninstall_extension
   ---------------------
    t
   (1 row)
   ```

# 解除安裝適用於 PostgreSQL 的受信任語言延伸模組
<a name="PostgreSQL_trusted_language_extension-uninstalling-pg_tle-devkit"></a>

如果您再也不要使用 TLE 建立自己的 TLE 延伸模組，則可以捨棄 `pg_tle` 延伸模組並移除所有成品。此動作包括捨棄資料庫中的任何 TLE 延伸模組，以及捨棄 `pgtle` 結構描述。

**從資料庫中捨棄 `pg_tle` 延伸模組及其結構描述**

1. 使用 `psql` 或其他用戶端工具，連線至 RDS for PostgreSQL 資料庫執行個體。

   ```
   psql --host=.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=dbname
   ```

1. 從資料庫中捨棄 `pg_tle` 延伸模組。如果您自己的 TLE 延伸模組仍在資料庫中執行，您也需要捨棄這些延伸模組。若要這樣做，您可以使用 `CASCADE` 關鍵字，如下所示。

   ```
   DROP EXTENSION pg_tle CASCADE;
   ```

   如果 `pg_tle` 延伸模組在資料庫中仍未作用中，則您不需要使用 `CASCADE` 關鍵字。

1. 捨棄 `pgtle` 結構描述。此動作會移除資料庫中的所有管理函數。

   ```
   DROP SCHEMA pgtle CASCADE;
   ```

   此命令會在程序完成時傳回下列內容。

   ```
   DROP SCHEMA
   ```

   `pg_tle` 延伸模組、其結構描述和函數，以及所有成品都會遭到移除。若要使用 TLE 建立新的延伸模組，請再次完成設定程序。如需更多詳細資訊，請參閱 [在您的 RDS for PostgreSQL 資料庫執行個體中設定受信任語言延伸模組](PostgreSQL_trusted_language_extension-setting-up.md)。

# 搭配您的延伸模組使用 PostgreSQL 掛鉤
<a name="PostgreSQL_trusted_language_extension.overview.tles-and-hooks"></a>

*掛鉤*是 PostgreSQL 中提供的回呼機制，允許開發人員在一般資料庫操作期間呼叫自訂函數或其他常式。TLE 開發套件支援 PostgreSQL 掛鉤，以便您可以在執行時整合自訂函數與 PostgreSQL 行為。例如，您可以使用掛鉤，將身分驗證程序與您自己的自訂程式碼建立關聯，或因應您的特定需求修改查詢規劃和執行程序。

您的 TLE 延伸模組可以使用掛鉤。如果掛鉤在範圍內是全域的，則其在所有資料庫之中都適用。因此，如果您的 TLE 延伸模組使用全域掛鉤，則您需要在使用者可以存取的所有資料庫中建立 TLE 延伸模組。

當使用 `pg_tle` 延伸模組來建置您自己的受信任語言延伸模組時，您可以使用 SQL API 中可用的掛鉤來建置延伸模組的函數。您應該使用 `pg_tle` 註冊任何掛鉤。對於某些掛鉤，您可能還需要設定各種組態參數。例如，`passcode` 檢查掛鉤可以設為開啟、關閉或需要。如需可用 `pg_tle` 掛鉤之特定需求的詳細資訊，請參閱 [適用於 PostgreSQL 的受信任語言延伸模組的掛鉤參考](PostgreSQL_trusted_language_extension-hooks-reference.md)。

## 範例：建立使用 PostgreSQL 掛鉤的延伸模組
<a name="PostgreSQL_trusted_language_extension-example-hook"></a>

本節中討論的範例使用 PostgreSQL 掛鉤，來檢查在特定 SQL 操作期間提供的密碼，並防止資料庫使用者將其密碼設為 `password_check.bad_passwords` 資料表中包含的任何密碼。該資料表包含前十大最常用但容易破解的密碼選擇。

若要在您的 RDS for PostgreSQL 資料庫執行個體中設定此範例，您必須已安裝受信任語言延伸模組。如需詳細資訊，請參閱 [在您的 RDS for PostgreSQL 資料庫執行個體中設定受信任語言延伸模組](PostgreSQL_trusted_language_extension-setting-up.md)。

**設定密碼檢查掛鉤範例**

1. 使用 `psql` 連線到 RDS for PostgreSQL 資料庫執行個體。

   ```
   psql --host=db-instance-123456789012.aws-region.rds.amazonaws.com
   --port=5432 --username=postgres --password --dbname=labdb
   ```

1. 從 [密碼檢查掛鉤程式碼清單](#PostgreSQL_trusted_language_extension-example-hook_code_listing) 中複製程式碼，並將其貼入您的資料庫中。

   ```
   SELECT pgtle.install_extension (
     'my_password_check_rules',
     '1.0',
     'Do not let users use the 10 most commonly used passwords',
   $_pgtle_$
     CREATE SCHEMA password_check;
     REVOKE ALL ON SCHEMA password_check FROM PUBLIC;
     GRANT USAGE ON SCHEMA password_check TO PUBLIC;
   
     CREATE TABLE password_check.bad_passwords (plaintext) AS
     VALUES
       ('123456'),
       ('password'),
       ('12345678'),
       ('qwerty'),
       ('123456789'),
       ('12345'),
       ('1234'),
       ('111111'),
       ('1234567'),
       ('dragon');
     CREATE UNIQUE INDEX ON password_check.bad_passwords (plaintext);
   
     CREATE FUNCTION password_check.passcheck_hook(username text, password text, password_type pgtle.password_types, valid_until timestamptz, valid_null boolean)
     RETURNS void AS $$
       DECLARE
         invalid bool := false;
       BEGIN
         IF password_type = 'PASSWORD_TYPE_MD5' THEN
           SELECT EXISTS(
             SELECT 1
             FROM password_check.bad_passwords bp
             WHERE ('md5' || md5(bp.plaintext || username)) = password
           ) INTO invalid;
           IF invalid THEN
             RAISE EXCEPTION 'Cannot use passwords from the common password dictionary';
           END IF;
         ELSIF password_type = 'PASSWORD_TYPE_PLAINTEXT' THEN
           SELECT EXISTS(
             SELECT 1
             FROM password_check.bad_passwords bp
             WHERE bp.plaintext = password
           ) INTO invalid;
           IF invalid THEN
             RAISE EXCEPTION 'Cannot use passwords from the common password dictionary';
           END IF;
         END IF;
       END
     $$ LANGUAGE plpgsql SECURITY DEFINER;
   
     GRANT EXECUTE ON FUNCTION password_check.passcheck_hook TO PUBLIC;
   
     SELECT pgtle.register_feature('password_check.passcheck_hook', 'passcheck');
   $_pgtle_$
   );
   ```

   將延伸模組載入資料庫後，您會看到如下輸出。

   ```
    install_extension
   -------------------
    t
   (1 row)
   ```

1. 在仍然連線到資料庫時，您現在可以建立延伸模組。

   ```
   CREATE EXTENSION my_password_check_rules;
   ```

1. 您可以使用下列 `psql` 中繼命令，確認已在資料庫中建立延伸模組。

   ```
   \dx
                           List of installed extensions
             Name           | Version |   Schema   |                         Description
   -------------------------+---------+------------+-------------------------------------------------------------
    my_password_check_rules | 1.0     | public     | Prevent use of any of the top-ten most common bad passwords
    pg_tle                  | 1.0.1   | pgtle      | Trusted-Language Extensions for PostgreSQL
    plpgsql                 | 1.0     | pg_catalog | PL/pgSQL procedural language
   (3 rows)
   ```

1. 開啟另一個要使用 AWS CLI 的終端機工作階段。您需要修改自訂資料庫參數群組，以開啟密碼檢查掛鉤。若要這麼做，請使用 [modify-db-parameter-group](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-parameter-group.html) 命令，如下列範例所示。

   ```
   aws rds modify-db-parameter-group \
       --region aws-region \
       --db-parameter-group-name your-custom-parameter-group \
       --parameters "ParameterName=pgtle.enable_password_check,ParameterValue=on,ApplyMethod=immediate"
   ```

   在成功開啟參數時，您會看到如下輸出。

   ```
   (
       "DBParameterGroupName": "docs-lab-parameters-for-tle"
   }
   ```

   可能需要幾分鐘，對參數群組設定所做的變更才會生效。不過，此參數是動態參數，因此您不需要重新啟動 RDS for PostgreSQL 資料庫執行個體，設定即可生效。

1. 開啟 `psql` 工作階段並查詢資料庫，以驗證密碼檢查掛鉤是否已開啟。

   ```
   labdb=> SHOW pgtle.enable_password_check;
   pgtle.enable_password_check
   -----------------------------
   on
   (1 row)
   ```

密碼檢查掛鉤現在處於作用中狀態。您可以建立新角色並使用其中一個錯誤密碼來對它進行測試，如下列範例所示。

```
CREATE ROLE test_role PASSWORD 'password';
ERROR:  Cannot use passwords from the common password dictionary
CONTEXT:  PL/pgSQL function password_check.passcheck_hook(text,text,pgtle.password_types,timestamp with time zone,boolean) line 21 at RAISE
SQL statement "SELECT password_check.passcheck_hook(
    $1::pg_catalog.text, 
    $2::pg_catalog.text, 
    $3::pgtle.password_types, 
    $4::pg_catalog.timestamptz, 
    $5::pg_catalog.bool)"
```

為了方便閱讀，輸出已經過格式化處理。

下列範例顯示 `pgsql` 互動式中繼命令 `\password` 行為也受密碼檢查掛鉤的影響。

```
postgres=> SET password_encryption TO 'md5';
SET
postgres=> \password
Enter new password for user "postgres":*****
Enter it again:*****
ERROR:  Cannot use passwords from the common password dictionary
CONTEXT:  PL/pgSQL function password_check.passcheck_hook(text,text,pgtle.password_types,timestamp with time zone,boolean) line 12 at RAISE
SQL statement "SELECT password_check.passcheck_hook($1::pg_catalog.text, $2::pg_catalog.text, $3::pgtle.password_types, $4::pg_catalog.timestamptz, $5::pg_catalog.bool)"
```

如果需要，您可以捨棄此 TLE 延伸模組並解除安裝其來源檔案。如需更多詳細資訊，請參閱 [從資料庫中捨棄您的 TLE 延伸模組從資料庫中捨棄您的 TLE 延伸模組](PostgreSQL_trusted_language_extension-creating-TLE-extensions.dropping-TLEs.md)。

### 密碼檢查掛鉤程式碼清單
<a name="PostgreSQL_trusted_language_extension-example-hook_code_listing"></a>

此處顯示的範例程式碼定義了 `my_password_check_rules` TLE 延伸模組的規格。當您複製此程式碼並將其貼入資料庫中時，`my_password_check_rules` 延伸模組的程式碼會載入至資料庫，而且 `password_check` 掛鉤會進行註冊以供該延伸模組使用。

```
SELECT pgtle.install_extension (
  'my_password_check_rules',
  '1.0',
  'Do not let users use the 10 most commonly used passwords',
$_pgtle_$
  CREATE SCHEMA password_check;
  REVOKE ALL ON SCHEMA password_check FROM PUBLIC;
  GRANT USAGE ON SCHEMA password_check TO PUBLIC;

  CREATE TABLE password_check.bad_passwords (plaintext) AS
  VALUES
    ('123456'),
    ('password'),
    ('12345678'),
    ('qwerty'),
    ('123456789'),
    ('12345'),
    ('1234'),
    ('111111'),
    ('1234567'),
    ('dragon');
  CREATE UNIQUE INDEX ON password_check.bad_passwords (plaintext);

  CREATE FUNCTION password_check.passcheck_hook(username text, password text, password_type pgtle.password_types, valid_until timestamptz, valid_null boolean)
  RETURNS void AS $$
    DECLARE
      invalid bool := false;
    BEGIN
      IF password_type = 'PASSWORD_TYPE_MD5' THEN
        SELECT EXISTS(
          SELECT 1
          FROM password_check.bad_passwords bp
          WHERE ('md5' || md5(bp.plaintext || username)) = password
        ) INTO invalid;
        IF invalid THEN
          RAISE EXCEPTION 'Cannot use passwords from the common password dictionary';
        END IF;
      ELSIF password_type = 'PASSWORD_TYPE_PLAINTEXT' THEN
        SELECT EXISTS(
          SELECT 1
          FROM password_check.bad_passwords bp
          WHERE bp.plaintext = password
        ) INTO invalid;
        IF invalid THEN
          RAISE EXCEPTION 'Cannot use passwords from the common password dictionary';
        END IF;
      END IF;
    END
  $$ LANGUAGE plpgsql SECURITY DEFINER;

  GRANT EXECUTE ON FUNCTION password_check.passcheck_hook TO PUBLIC;

  SELECT pgtle.register_feature('password_check.passcheck_hook', 'passcheck');
$_pgtle_$
);
```

# 在 TLE 中使用自訂資料類型
<a name="PostgreSQL_trusted_language_extension-custom-data-type"></a>

PostgreSQL 支援註冊新基底類型 (也稱為純量類型) 的命令，以便有效處理資料庫中複雜的資料結構。基底類型可讓您自訂在內部儲存資料的方式，以及如何將資料與外部文字表示法相互轉換。這些自訂資料類型在擴充 PostgreSQL 以支援功能定義域時很實用，因為這些定義域的內建類型 (如數字或文字) 無法提供足夠的搜尋語意。

RDS for PostgreSQL 可讓您在信任的語言延伸模組中建立自訂資料類型，並定義功能來支援這些新資料類型的 SQL 和索引操作。以下版本提供自訂資料類型：
+ RDS for PostgreSQL 15.4 及更高的 15 版
+ RDS for PostgreSQL 14.9 及更高的 14 版
+ RDS for PostgreSQL 13.12 及更高的 13 版

如需詳細資訊，請參閱[信任的語言基底類型](https://github.com/aws/pg_tle/blob/main/docs/09_datatypes.md)。

# 適用於 PostgreSQL 的受信任語言延伸模組的函數參考
<a name="PostgreSQL_trusted_language_extension-functions-reference"></a>

檢視下列有關適用於 PostgreSQL 的受信任語言延伸模組中提供之函數的參考文件。使用這些函數來安裝、註冊、更新和管理您的 *TLE 延伸模組*，亦即您使用受信任語言延伸模組開發套件所開發的 PostgreSQL 延伸模組。

**Topics**
+ [pgtle.available\$1extensions](#pgtle.available_extensions)
+ [pgtle.available\$1extension\$1versions](#pgtle.available_extension_versions)
+ [pgtle.extension\$1update\$1paths](#pgtle.extension_update_paths)
+ [pgtle.install\$1extension](#pgtle.install_extension)
+ [pgtle.install\$1update\$1path](#pgtle.install_update_path)
+ [pgtle.register\$1feature](#pgtle.register_feature)
+ [pgtle.register\$1feature\$1if\$1not\$1exists](#pgtle.register_feature_if_not_exists)
+ [pgtle.set\$1default\$1version](#pgtle.set_default_version)
+ [pgtle.uninstall\$1extension(name)](#pgtle.uninstall_extension-name)
+ [pgtle.uninstall\$1extension(name, version)](#pgtle.uninstall_extension-name-version)
+ [pgtle.uninstall\$1extension\$1if\$1exists](#pgtle.uninstall_extension_if_exists)
+ [pgtle.uninstall\$1update\$1path](#pgtle.uninstall_update_path)
+ [pgtle.uninstall\$1update\$1path\$1if\$1exists](#pgtle.uninstall_update_path_if_exists)
+ [pgtle.unregister\$1feature](#pgtle.unregister_feature)
+ [pgtle.unregister\$1feature\$1if\$1exists](#pgtle.unregister_feature_if_exists)

## pgtle.available\$1extensions
<a name="pgtle.available_extensions"></a>

`pgtle.available_extensions` 函數是一個設定-傳回函數。它會傳回資料庫中所有可用的 TLE 延伸模組。每一傳回的列都包含單一 TLE 延伸模組的相關資訊。

### 函數原型
<a name="pgtle.available_extensions-prototype"></a>

```
pgtle.available_extensions()
```

### 角色
<a name="pgtle.available_extensions-role"></a>

無。

### 引數
<a name="pgtle.available_extensions-arguments"></a>

無。

### 輸出
<a name="pgtle.available_extensions-output"></a>
+ `name` – TLE 延伸模組的名稱。
+ `default_version` – 在未指定版本的情況下呼叫 `CREATE EXTENSION` 時使用的 TLE 延伸模組版本。
+ `description` – 有關 TLE 延伸模組的詳細描述。

### 使用範例
<a name="pgtle.available_extensions-usage-example"></a>

```
SELECT * FROM pgtle.available_extensions();
```

## pgtle.available\$1extension\$1versions
<a name="pgtle.available_extension_versions"></a>

`available_extension_versions` 函數是一個設定-傳回函數。其會傳回一份清單，列出所有可用的 TLE 延伸模組及其版本。每一列都包含指定 TLE 延伸模組之特定版本的相關資訊，包括其是否需要特定角色。

### 函數原型
<a name="pgtle.available_extension_versions-prototype"></a>

```
pgtle.available_extension_versions()
```

### 角色
<a name="pgtle.available_extension_versions-role"></a>

無。

### 引數
<a name="pgtle.available_extension_versions-arguments"></a>

無。

### 輸出
<a name="pgtle.available_extension_versions-output"></a>
+ `name` – TLE 延伸模組的名稱。
+ `version` – TLE 延伸模組的版本。
+ `superuser` – 對於 TLE 延伸模組，此值一律為 `false`。建立 TLE 延伸模組或更新它所需的許可，與在指定資料庫中建立其他物件所需的許可相同。
+ `trusted` – 對於 TLE 延伸模組，此值一律為 `false`。
+ `relocatable` – 對於 TLE 延伸模組，此值一律為 `false`。
+ `schema` – 指定其中安裝 TLE 延伸模組的結構描述名稱。
+ `requires` – 一種陣列，其中包含此 TLE 延伸模組所需之其他延伸模組的名稱。
+ `description` – TLE 延伸模組的詳細描述。

如需輸出值的詳細資訊，請參閱 PostgreSQL 文件中的[將相關物件封裝為延伸模組 > 延伸模組檔案](https://www.postgresql.org/docs/current/extend-extensions.html#id-1.8.3.20.11)。

### 使用範例
<a name="pgtle.available_extension_versions-example"></a>

```
SELECT * FROM pgtle.available_extension_versions();
```

## pgtle.extension\$1update\$1paths
<a name="pgtle.extension_update_paths"></a>

`extension_update_paths` 函數是一個設定-傳回函數。其會傳回一份清單，列出 TLE 延伸模組的所有可能更新路徑。每一列都包含該 TLE 延伸模組的可用升級或降級。

### 函數原型
<a name="pgtle.extension_update_paths-prototype"></a>

```
pgtle.extension_update_paths(name)
```

### 角色
<a name="pgtle.extension_update_paths-role"></a>

無。

### 引數
<a name="pgtle.extension_update_paths-arguments"></a>

`name` – 要從中取得升級路徑的 TLE 延伸模組名稱。

### 輸出
<a name="pgtle.extension_update_paths-output"></a>
+ `source` – 更新的來源版本。
+ `target` – 更新的目標版本。
+ `path` – 用來將 TLE 延伸模組從 `source` 版本更新至 `target` 版本的升級路徑，例如 `0.1--0.2`。

### 使用範例
<a name="pgtle.extension_update_paths-example"></a>

```
SELECT * FROM pgtle.extension_update_paths('your-TLE');
```

## pgtle.install\$1extension
<a name="pgtle.install_extension"></a>

`install_extension` 函數可讓您在資料庫中安裝構成 TLE 延伸模組的成品，然後您可以使用 `CREATE EXTENSION` 命令來建立它。

### 函數原型
<a name="pgtle.install_extension-prototype"></a>

```
pgtle.install_extension(name text, version text, description text, ext text, requires text[] DEFAULT NULL::text[])
```

### 角色
<a name="pgtle.install_extension-role"></a>

無。

### 引數
<a name="pgtle.install_extension-arguments"></a>
+ `name` – TLE 延伸模組的名稱。呼叫 `CREATE EXTENSION` 時會使用此值。
+ `version` – TLE 延伸模組的版本。
+ `description` – 有關 TLE 延伸模組的詳細描述。此描述顯示在 `pgtle.available_extensions()` 的 `comment` 欄位中。
+ `ext` – TLE 延伸模組的內容。此值包含函數之類的物件。
+ `requires` – 針對此 TLE 延伸模組指定相依性的選用參數。`pg_tle` 延伸模組會自動新增為相依性。

其中許多引數與延伸模組控制檔中包含的引數相同，用於在 PostgreSQL 執行個體的檔案系統上安裝 PostgreSQL 延伸模組。如需詳細資訊，請參閱 PostgreSQL 文件中[將相關物件封裝為延伸模組](https://www.postgresql.org/docs/current/extend-extensions.html)中的[延伸模組檔案](http://www.postgresql.org/docs/current/extend-extensions.html#id-1.8.3.20.11)。

### 輸出
<a name="pgtle.install_extension-output"></a>

此函數會在成功時傳回 `OK`，以及在發生錯誤時傳回 `NULL`。
+ `OK` – TLE 延伸模組已成功安裝在資料庫中。
+ `NULL` – TLE 延伸模組未成功安裝在資料庫中。

### 使用範例
<a name="pgtle.install_extension-example"></a>

```
SELECT pgtle.install_extension(
 'pg_tle_test',
 '0.1',
 'My first pg_tle extension',
$_pgtle_$
  CREATE FUNCTION my_test()
  RETURNS INT
  AS $$
    SELECT 42;
  $$ LANGUAGE SQL IMMUTABLE;
$_pgtle_$
);
```

## pgtle.install\$1update\$1path
<a name="pgtle.install_update_path"></a>

`install_update_path` 函數會提供 TLE 延伸模組的兩個不同版本之間的更新路徑。此函數允許 TLE 延伸模組的使用者透過使用 `ALTER EXTENSION ... UPDATE` 語法更新其版本。

### 函數原型
<a name="pgtle.install_update_path-prototype"></a>

```
pgtle.install_update_path(name text, fromvers text, tovers text, ext text)
```

### 角色
<a name="pgtle.install_update_path-role"></a>

`pgtle_admin`

### 引數
<a name="pgtle.install_update_path-arguments"></a>
+ `name` – TLE 延伸模組的名稱。呼叫 `CREATE EXTENSION` 時會使用此值。
+ `fromvers` – 用於升級之 TLE 延伸模組的來源版本。
+ `tovers` – 用於升級之 TLE 延伸模組的目標版本。
+ `ext` – 更新的內容。此值包含函數之類的物件。

### 輸出
<a name="pgtle.install_update_path-output"></a>

無。

### 使用範例
<a name="pgtle.install_update_path-example"></a>

```
SELECT pgtle.install_update_path('pg_tle_test', '0.1', '0.2',
  $_pgtle_$
    CREATE OR REPLACE FUNCTION my_test()
    RETURNS INT
    AS $$
      SELECT 21;
    $$ LANGUAGE SQL IMMUTABLE;
  $_pgtle_$
);
```

## pgtle.register\$1feature
<a name="pgtle.register_feature"></a>

函數 `register_feature` 會將指定的內部 PostgreSQL 功能新增至 `pgtle.feature_info` 資料表。PostgreSQL 掛鉤是內部 PostgreSQL 功能的範例。受信任語言延伸模組開發套件支援使用 PostgreSQL 掛鉤。目前，此函數支援下列功能。
+ `passcheck` – 使用自訂 PostgreSQL 密碼檢查行為的程序或函數註冊密碼檢查掛鉤。

### 函數原型
<a name="pgtle.register_feature-prototype"></a>

```
pgtle.register_feature(proc regproc, feature pg_tle_feature)
```

### 角色
<a name="pgtle.register_feature-role"></a>

`pgtle_admin` 

### 引數
<a name="pgtle.register_feature-arguments"></a>
+ `proc` – 要用於功能的預存程序或函數名稱。
+ `feature` – 要向函數註冊的 `pg_tle` 功能 (例如 `passcheck`) 名稱。

### 輸出
<a name="pgtle.register_feature-output"></a>

無。

### 使用範例
<a name="pgtle.register_feature-example"></a>

```
SELECT pgtle.register_feature('pw_hook', 'passcheck');
```

## pgtle.register\$1feature\$1if\$1not\$1exists
<a name="pgtle.register_feature_if_not_exists"></a>

`pgtle.register_feature_if_not_exists` 函數會將指定的 PostgreSQL 功能新增至 `pgtle.feature_info` 資料表，並識別 TLE 延伸模組或其他使用該功能的程序或函數。如需掛鉤和受信任語言延伸模組的詳細資訊，請參閱 [搭配您的延伸模組使用 PostgreSQL 掛鉤](PostgreSQL_trusted_language_extension.overview.tles-and-hooks.md)。

### 函數原型
<a name="pgtle.register_feature_if_not_exists-prototype"></a>

```
pgtle.register_feature_if_not_exists(proc regproc, feature pg_tle_feature)
```

### 角色
<a name="pgtle.register_feature_if_not_exists-role"></a>

`pgtle_admin` 

### 引數
<a name="pgtle.register_feature_if_not_exists-arguments"></a>
+ `proc` – 預存程序或函數的名稱，此預存程序或函數包含可用作 TLE 延伸功能之功能的邏輯 (程式碼)。例如，`pw_hook` 程式碼。
+ `feature` – 要針對 TLE 函數註冊的 PostgreSQL 功能名稱。目前，唯一可用的功能為 `passcheck` 掛鉤。如需詳細資訊，請參閱 [密碼檢查掛鉤 (passcheck)](PostgreSQL_trusted_language_extension-hooks-reference.md#passcheck_hook)。

### 輸出
<a name="pgtle.register_feature_if_not_exists-output"></a>

在針對指定的延伸模組註冊功能之後傳回 `true`。如果此功能已註冊，則會傳回 `false`。

### 使用範例
<a name="pgtle.register_feature_if_not_exists-example"></a>

```
SELECT pgtle.register_feature_if_not_exists('pw_hook', 'passcheck');
```

## pgtle.set\$1default\$1version
<a name="pgtle.set_default_version"></a>

`set_default_version` 函數可讓您針對 TLE 延伸模組指定 `default_version`。您可以使用此函數來定義升級路徑，並將該版本指定為 TLE 延伸模組的預設版本。當資料庫使用者在 `CREATE EXTENSION` 和 `ALTER EXTENSION ... UPDATE` 命令中指定您的 TLE 延伸模組時，該版本的 TLE 延伸模組就會在該使用者的資料庫中建立。

成功時此函數會傳回 `true`。如果 `name` 引數中指定的 TLE 延伸模組不存在，函數會傳回錯誤。同樣地，如果 TLE 延伸模組的 `version` 不存在，則其會傳回錯誤。

### 函數原型
<a name="pgtle.set_default_version-prototype"></a>

```
pgtle.set_default_version(name text, version text)
```

### 角色
<a name="pgtle.set_default_version-role"></a>

`pgtle_admin`

### 引數
<a name="pgtle.set_default_version-arguments"></a>
+ `name` – TLE 延伸模組的名稱。呼叫 `CREATE EXTENSION` 時會使用此值。
+ `version` – 要設定預設值的 TLE 延伸模組版本。

### 輸出
<a name="pgtle.set_default_version-output"></a>
+ `true` – 設定預設版本成功時，函數會傳回 `true`。
+ `ERROR` – 如果具有指定名稱或版本的 TLE 延伸模組不存在，則會傳回錯誤訊息。

### 使用範例
<a name="pgtle.set_default_version-example"></a>

```
SELECT * FROM pgtle.set_default_version('my-extension', '1.1');
```

## pgtle.uninstall\$1extension(name)
<a name="pgtle.uninstall_extension-name"></a>

`uninstall_extension` 函數會從資料庫中移除 TLE 延伸模組的所有版本。此函數可防止未來呼叫 `CREATE EXTENSION` 時安裝 TLE 延伸模組。如果 TLE 延伸模組不存在於資料庫中，則會引發錯誤。

`uninstall_extension` 函數不會捨棄資料庫中目前作用中的 TLE 延伸模組。若要移除目前作用中的 TLE 延伸模組，您必須明確地呼叫 `DROP EXTENSION` 才能將其移除。

### 函數原型
<a name="pgtle.uninstall_extension-name-prototype"></a>

```
pgtle.uninstall_extension(extname text)
```

### 角色
<a name="pgtle.uninstall_extension-name-role"></a>

`pgtle_admin`

### 引數
<a name="pgtle.uninstall_extension-name-arguments"></a>
+ `extname` – 要解除安裝的 TLE 延伸模組名稱。此名稱與搭配 `CREATE EXTENSION` 用來載入 TLE 延伸模組，以用於指定資料庫的名稱相同。

### 輸出
<a name="pgtle.uninstall_extension-name-output"></a>

無。

### 使用範例
<a name="pgtle.uninstall_extension-name-example"></a>

```
SELECT * FROM pgtle.uninstall_extension('pg_tle_test');
```

## pgtle.uninstall\$1extension(name, version)
<a name="pgtle.uninstall_extension-name-version"></a>

`uninstall_extension(name, version)` 函數會從資料庫中移除 TLE 延伸模組的指定版本。此函數可防止 `CREATE EXTENSION` 和 `ALTER EXTENSION` 將 TLE 延伸模組安裝或更新為指定版本。此函數也會移除 TLE 延伸模組指定版本的所有更新路徑。如果 TLE 延伸模組目前在資料庫中作用中，則此函數無法將其解除安裝。您必須明確地呼叫 `DROP EXTENSION` 才能移除 TLE 延伸模組。若要解除安裝 TLE 延伸模組的所有版本，請參閱 [pgtle.uninstall\$1extension(name)](#pgtle.uninstall_extension-name)。

### 函數原型
<a name="pgtle.uninstall_extension-name-version-prototype"></a>

```
pgtle.uninstall_extension(extname text, version text)
```

### 角色
<a name="pgtle.uninstall_extension-name-version-role"></a>

`pgtle_admin`

### 引數
<a name="pgtle.uninstall_extension-name-version-arguments"></a>
+ `extname` – TLE 延伸模組的名稱。呼叫 `CREATE EXTENSION` 時會使用此值。
+ `version` – 要從資料庫中解除安裝的 TLE 延伸模組版本。

### 輸出
<a name="pgtle.uninstall_extension-name-version-output"></a>

無。

### 使用範例
<a name="pgtle.uninstall_extension-name-version-example"></a>

```
SELECT * FROM pgtle.uninstall_extension('pg_tle_test', '0.2');
```

## pgtle.uninstall\$1extension\$1if\$1exists
<a name="pgtle.uninstall_extension_if_exists"></a>

`uninstall_extension_if_exists` 函數會從指定資料庫中移除 TLE 延伸模組的所有版本。如果 TLE 延伸模組不存在，則函數會以無訊息方式返回 (不會引發任何錯誤訊息)。如果指定的延伸模組目前在資料庫內作用中，則此函數不會捨棄它。您必須明確地呼叫 `DROP EXTENSION` 來移除 TLE 延伸模組，然後再使用此函數來解除安裝其成品。

### 函數原型
<a name="pgtle.uninstall_extension_if_exists-prototype"></a>

```
pgtle.uninstall_extension_if_exists(extname text)
```

### 角色
<a name="pgtle.uninstall_extension_if_exists-role"></a>

`pgtle_admin`

### 引數
<a name="pgtle.uninstall_extension_if_exists-arguments"></a>
+ `extname` – TLE 延伸模組的名稱。呼叫 `CREATE EXTENSION` 時會使用此值。

### 輸出
<a name="pgtle.uninstall_extension_if_exists-output"></a>

在解除安裝指定的延伸模組之後，`uninstall_extension_if_exists` 函數會傳回 `true`。如果指定的延伸模組不存在，函數會傳回 `false`。
+ `true` – 在解除安裝 TLE 延伸模組之後傳回 `true`。
+ `false` – 當 TLE 延伸模組不存在於資料庫中時傳回 `false`。

### 使用範例
<a name="pgtle.uninstall_extension_if_exists-example"></a>

```
SELECT * FROM pgtle.uninstall_extension_if_exists('pg_tle_test');
```

## pgtle.uninstall\$1update\$1path
<a name="pgtle.uninstall_update_path"></a>

`uninstall_update_path` 函數會從 TLE 延伸模組中移除特定的更新路徑。這樣可以防止 `ALTER EXTENSION ... UPDATE TO` 將其用作更新路徑。

如果 TLE 延伸模組目前正由這個更新路徑上的其中一個版本使用，則其仍會保留在資料庫中。

如果指定的更新路徑不存在，此函數會引發錯誤。

### 函數原型
<a name="pgtle.uninstall_update_path-prototype"></a>

```
pgtle.uninstall_update_path(extname text, fromvers text, tovers text)
```

### 角色
<a name="pgtle.uninstall_update_path-role"></a>

`pgtle_admin`

### 引數
<a name="pgtle.uninstall_update_path-arguments"></a>
+ `extname` – TLE 延伸模組的名稱。呼叫 `CREATE EXTENSION` 時會使用此值。
+ `fromvers` – 更新路徑上使用之 TLE 延伸模組的來源版本。
+  `tovers` – 更新路徑上使用之 TLE 延伸模組的目標版本。

### 輸出
<a name="pgtle.uninstall_update_path-output"></a>

無。

### 使用範例
<a name="pgtle.uninstall_update_path-example"></a>

```
SELECT * FROM pgtle.uninstall_update_path('pg_tle_test', '0.1', '0.2');
```

## pgtle.uninstall\$1update\$1path\$1if\$1exists
<a name="pgtle.uninstall_update_path_if_exists"></a>

`uninstall_update_path_if_exists` 函數類似於 `uninstall_update_path`，在這裡其會從 TLE 延伸模組中移除指定的更新路徑。不過，如果更新路徑不存在，則此函數不會引發錯誤訊息。反之，此函數會傳回 `false`。

### 函數原型
<a name="pgtle.uninstall_update_path_if_exists-prototype"></a>

```
pgtle.uninstall_update_path_if_exists(extname text, fromvers text, tovers text)
```

### 角色
<a name="pgtle.uninstall_update_path_if_exists-role"></a>

`pgtle_admin`

### 引數
<a name="pgtle.uninstall_update_path_if_exists-arguments"></a>
+ `extname` – TLE 延伸模組的名稱。呼叫 `CREATE EXTENSION` 時會使用此值。
+ `fromvers` – 更新路徑上使用之 TLE 延伸模組的來源版本。
+ `tovers` – 更新路徑上使用之 TLE 延伸模組的目標版本。

### 輸出
<a name="pgtle.uninstall_update_path_if_exists-output"></a>
+ `true` – 函數已成功更新 TLE 延伸模組的路徑。
+ `false` – 函數無法更新 TLE 延伸模組的路徑。

### 使用範例
<a name="pgtle.uninstall_update_path_if_exists-example"></a>

```
SELECT * FROM pgtle.uninstall_update_path_if_exists('pg_tle_test', '0.1', '0.2');
```

## pgtle.unregister\$1feature
<a name="pgtle.unregister_feature"></a>

`unregister_feature` 函數會提供一種方法，來刪除已註冊為使用 `pg_tle` 功能 (例如掛鉤) 的函數。如需註冊功能的相關資訊，請參閱 [pgtle.register\$1feature](#pgtle.register_feature)。

### 函數原型
<a name="pgtle.unregister_feature-prototype"></a>

```
pgtle.unregister_feature(proc regproc, feature pg_tle_features)
```

### 角色
<a name="pgtle.unregister_feature-role"></a>

`pgtle_admin`

### 引數
<a name="pgtle.unregister_feature-arguments"></a>
+ `proc` – 要向 `pg_tle` 功能註冊的預存函數名稱。
+ `feature` – 要向函數註冊的 `pg_tle` 功能名稱。例如，`passcheck` 是一種功能，可以將其註冊以供您開發的受信任語言延伸模組使用。如需詳細資訊，請參閱 [密碼檢查掛鉤 (passcheck)](PostgreSQL_trusted_language_extension-hooks-reference.md#passcheck_hook)。

### 輸出
<a name="pgtle.unregister_feature-output"></a>

無。

### 使用範例
<a name="pgtle.unregister_feature-example"></a>

```
SELECT * FROM pgtle.unregister_feature('pw_hook', 'passcheck');
```

## pgtle.unregister\$1feature\$1if\$1exists
<a name="pgtle.unregister_feature_if_exists"></a>

`unregister_feature` 函數會提供一種方法，來刪除已註冊為使用 `pg_tle` 功能 (例如掛鉤) 的函數。如需詳細資訊，請參閱 [搭配您的延伸模組使用 PostgreSQL 掛鉤](PostgreSQL_trusted_language_extension.overview.tles-and-hooks.md)。在成功取消註冊功能之後傳回 `true`。如果功能未註冊，則會傳回 `false`。

如需為 TLE 延伸模組註冊 `pg_tle` 功能的相關資訊，請參閱 [pgtle.register\$1feature](#pgtle.register_feature)。

### 函數原型
<a name="pgtle.unregister_feature_if_exists-prototype"></a>

```
pgtle.unregister_feature_if_exists('proc regproc', 'feature pg_tle_features')
```

### 角色
<a name="pgtle.unregister_feature_if_exists-role"></a>

`pgtle_admin`

### 引數
<a name="pgtle.unregister_feature_if_exists-arguments"></a>
+ `proc` – 已註冊來包含 `pg_tle` 功能的預存函數名稱。
+ `feature` – 已向受信任語言延伸模組註冊的 `pg_tle` 功能名稱。

### 輸出
<a name="pgtle.unregister_feature_if_exists-output"></a>

傳回 `true` 或 `false`，如下所示。
+ `true` – 函數已成功從延伸模組中取消註冊功能。
+ `false` – 函數無法從 TLE 延伸模組中取消註冊功能。

### 使用範例
<a name="pgtle.unregister_feature_if_exists-example"></a>

```
SELECT * FROM pgtle.unregister_feature_if_exists('pw_hook', 'passcheck');
```

# 適用於 PostgreSQL 的受信任語言延伸模組的掛鉤參考
<a name="PostgreSQL_trusted_language_extension-hooks-reference"></a>

適用於 PostgreSQL 的受信任語言延伸模組支援 PostgreSQL 掛鉤。*掛鉤*是開發人員可用於擴充 PostgreSQL 核心功能的內部回呼機制。透過使用掛鉤，開發人員可以實作自己的函數或程序，以在各種資料庫操作期間使用，從而以某種方式修改 PostgreSQL 的行為。例如，您可以使用 `passcheck` 掛鉤，來自訂 PostgreSQL 在為使用者 (角色) 建立或變更密碼時如何處理所提供的密碼。

檢視下列文件，以了解 TLE 延伸模組可用的 passcheck 勾點。若要進一步了解可用的勾點，包括用戶端驗證勾點，請參閱[受信任語言延伸模組勾點](https://github.com/aws/pg_tle/blob/main/docs/04_hooks.md)。

## 密碼檢查掛鉤 (passcheck)
<a name="passcheck_hook"></a>

`passcheck` 掛鉤用來針對下列 SQL 命令和 `psql` 中繼命令自訂密碼檢查過程中的 PostgreSQL 行為。
+ `CREATE ROLE username ...PASSWORD` – 如需詳細資訊，請參閱 PostgreSQL 文件中的 [CREATE ROLE](https://www.postgresql.org/docs/current/sql-createrole.html)。
+ `ALTER ROLE username...PASSWORD` – 如需詳細資訊，請參閱 PostgreSQL 文件中的 [ALTER ROLE](https://www.postgresql.org/docs/current/sql-alterrole.html)。
+ `\password username` – 此互動式 `psql` 中繼命令透過在透明地使用 `ALTER ROLE ... PASSWORD` 語法之前對密碼進行雜湊處理，來安全地變更所指定使用者的密碼。中繼命令是 `ALTER ROLE ... PASSWORD` 命令的安全包裝函式，因此掛鉤適用於 `psql` 中繼命令的行為。

如需範例，請參閱 [密碼檢查掛鉤程式碼清單](PostgreSQL_trusted_language_extension.overview.tles-and-hooks.md#PostgreSQL_trusted_language_extension-example-hook_code_listing)。

**Contents**
+ [函數原型](#passcheck_hook-prototype)
+ [引數](#passcheck_hook-arguments)
+ [Configuration](#passcheck_hook-configuration)
+ [使用須知](#passcheck_hook-usage)

### 函數原型
<a name="passcheck_hook-prototype"></a>

```
passcheck_hook(username text, password text, password_type pgtle.password_types, valid_until timestamptz, valid_null boolean)
```

### 引數
<a name="passcheck_hook-arguments"></a>

`passcheck` 掛鉤函數採用下列引數：
+ `username` – 設定密碼之角色 (使用者名稱) 的名稱 (以文字形式表示)。
+ `password` – 純文字或雜湊密碼。輸入的密碼應符合 `password_type` 中指定的類型。
+ `password_type` – 指定密碼的 `pgtle.password_type` 格式。此 格式可以是下列其中一個選項：
  + `PASSWORD_TYPE_PLAINTEXT` – 純文字密碼。
  + `PASSWORD_TYPE_MD5` – 使用 MD5 (訊息摘要 5) 演算法進行雜湊處理的密碼。
  + `PASSWORD_TYPE_SCRAM_SHA_256` – 使用 SCRAM-SHA-256 演算法進行雜湊處理的密碼。
+ `valid_until` – 指定密碼變成無效的時間。此為選用引數。如果使用此引數，請將時間指定為 `timestamptz` 值。
+ `valid_null` – 如果將此布林值設為 `true`，則 `valid_until` 選項會設為 `NULL`。

### Configuration
<a name="passcheck_hook-configuration"></a>

此函數 `pgtle.enable_password_check` 可控制 passcheck 掛鉤是否作用中。passcheck 掛鉤有三種可能的設定。
+ `off` – 關閉 `passcheck` 密碼檢查掛鉤。這是預設值。
+ `on` – 開啟 `passcode` 密碼檢查掛鉤，以便針對資料表檢查密碼。
+ `require` – 需要定義密碼檢查掛鉤。

### 使用須知
<a name="passcheck_hook-usage"></a>

若要開啟或關閉 `passcheck` 掛鉤，您需要針對 RDS for PostgreSQL 資料庫執行個體修改自訂資料庫參數群組。

對於 Linux、macOS 或 Unix：

```
aws rds modify-db-parameter-group \
    --region aws-region \
    --db-parameter-group-name your-custom-parameter-group \
    --parameters "ParameterName=pgtle.enable_password_check,ParameterValue=on,ApplyMethod=immediate"
```

在 Windows 中：

```
aws rds modify-db-parameter-group ^
    --region aws-region ^
    --db-parameter-group-name your-custom-parameter-group ^
    --parameters "ParameterName=pgtle.enable_password_check,ParameterValue=on,ApplyMethod=immediate"
```