

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

# LWLock:MultiXact
<a name="apg-waits.lwlockmultixact"></a>

`LWLock:MultiXactMemberBuffer`、`LWLock:MultiXactOffsetBuffer`、`LWLock:MultiXactMemberSLRU`、和 `LWLock:MultiXactOffsetSLRU` 等待事件表示工作階段正在等待擷取所指定資料表中修改相同資料列的交易清單。
+ `LWLock:MultiXactMemberBuffer` – 程序正在等待簡單的最近最少使用 (SLRU) 緩衝區上的輸入/輸出，以取得 multixact 成員。
+ `LWLock:MultiXactMemberSLRU` – 程序正在等待存取簡單的最近最少使用 (SLRU) 快取，以取得 multixact 成員。
+ `LWLock:MultiXactOffsetBuffer` – 程序正在等待簡單的最近最少使用 (SLRU) 緩衝區上的輸入/輸出，以取得 multixact 位移。
+ `LWLock:MultiXactOffsetSLRU` – 程序正在等待存取簡單的最近最少使用 (SLRU) 快取上，以取得 multixact 位移。

**Topics**
+ [支援的引擎版本](#apg-waits.xactsync.context.supported)
+ [Context](#apg-waits.lwlockmultixact.context)
+ [等待時間增加的可能原因](#apg-waits.lwlockmultixact.causes)
+ [動作](#apg-waits.lwlockmultixact.actions)

## 支援的引擎版本
<a name="apg-waits.xactsync.context.supported"></a>

所有版本的 Aurora PostgreSQL 都支援此等待事件資訊。

## Context
<a name="apg-waits.lwlockmultixact.context"></a>

*multixact* 是資料結構，其中存放一份清單，列出修改相同資料表資料列的交易 ID (XID)。當單一交易參考資料表中的資料列時，交易 ID 會存放在資料表標題列中。當多個交易參考資料表中的同一資料列時，交易 ID 清單會存放在 multixact 資料結構中。multixact 等待事件表示工作階段正在從資料結構中擷取參照資料表中指定資料列的交易清單。

## 等待時間增加的可能原因
<a name="apg-waits.lwlockmultixact.causes"></a>

使用 multixact 的三個常見原因如下：
+ **來自明確儲存點的子交易** – 在交易中明確建立儲存點會為相同資料列產生新的交易。例如，依序使用 `SELECT FOR UPDATE`、`SAVEPOINT`、`UPDATE`。

  某些驅動程式、物件關聯式映射器 (ORM) 和抽象層具有組態選項，用於使用儲存點自動包裝所有操作。這可能會在某些工作負載中產生許多 multixact 等待事件。PostgreSQL JDBC 驅動程式的 `autosave` 選項就是此情況的範例。如需詳細資訊，請參閱 PostgreSQL JDBC 文件中的 [pgJDBC](https://jdbc.postgresql.org/)。另一個範例是 PostgreSQL ODBC 驅動程式及其 `protocol` 選項。如需詳細資訊，請參閱 PostgreSQL ODBC 驅動程式文件中的 [psqlODBC Configuration Options](https://odbc.postgresql.org/docs/config.html) (psqlODBC 組態選項)。
+ **來自 PL/pgSQL EXCEPTION 子句的子交易** – 您在 PL/pgSQL 函數或程序中寫入的每個 `EXCEPTION` 子句都會在 `SAVEPOINT` 內部建立 。
+ **外部索引鍵** – 多個交易在上層記錄上取得共用鎖定。

當指定資料列包含在多重交易操作中時，處理資料列需要從 `multixact` 清單中擷取交易 ID。如果查詢無法從記憶體快取中取得 multixact，則必須從 Aurora 儲存層讀取資料結構。這個來自儲存體的 I/O 表示查詢可能需要較長的時間。由於大量的多重交易，記憶體快取遺漏可能會在大量使用情況下開始發生。所有這些因素都會導致此等待事件的增加。

## 動作
<a name="apg-waits.lwlockmultixact.actions"></a>

根據等待事件的原因，我們會建議不同的動作。其中一些動作有助於立即減少等待事件。但是，其他人可能需要調查和修正才能擴展工作負載。

**Topics**
+ [使用此等待事件對資料表執行清空凍結](#apg-waits.lwlockmultixact.actions.vacuumfreeze)
+ [使用此等待事件增加資料表的自動清空頻率](#apg-waits.lwlockmultixact.actions.autovacuum)
+ [增加記憶體參數](#apg-waits.lwlockmultixact.actions.memoryparam)
+ [減少長時間執行的交易](#apg-waits.lwlockmultixact.actions.longtransactions)
+ [長期動作](#apg-waits.lwlockmultixact.actions.longactions)

### 使用此等待事件對資料表執行清空凍結
<a name="apg-waits.lwlockmultixact.actions.vacuumfreeze"></a>

如果此等待事件突然激增並影響您的生產環境，您可以使用下列任何暫時方法來減少其計數。
+ 在受影響的資料表或資料表分割區上使用 *VACUUM FREEZE*，以立即解決問題。如需詳細資訊，請參閱 [VACUUM](https://www.postgresql.org/docs/current/sql-vacuum.html)。
+ 使用 VACUUM (FREEZE、INDEX\$1CLEANUP FALSE) 子句略過索引來執行快速清空。如需詳細資訊，請參閱[盡快清空資料表](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.LargeIndexes.html#Appendix.PostgreSQL.CommonDBATasks.Autovacuum.LargeIndexes.Executing)。

### 使用此等待事件增加資料表的自動清空頻率
<a name="apg-waits.lwlockmultixact.actions.autovacuum"></a>

掃描所有資料庫中的所有資料表後，VACUUM 最終會移除 multixact，而其最舊的 multixact 值會向前。如需詳細資訊，請參閱 [Multixacts 和 Wraparound](https://www.postgresql.org/docs/current/routine-vacuuming.html#VACUUM-FOR-MULTIXACT-WRAPAROUND)。若要將 LWLock：MultiXact 等待事件維持在其最小值，您必須視需要執行 VACUUM。若要這麼做，請確定 Aurora PostgreSQL 資料庫叢集中的 VACUUM 已進行最佳設定。

如果在受影響的資料表或資料表分割區上使用 VACUUM FREEZE 解決等待事件問題，我們建議您使用排程器，例如 `pg_cron` 來執行 VACUUM，而不是在執行個體層級調整自動清空。

若要讓自動清空更頻繁地發生，您可以減少受影響資料表中儲存參數 `autovacuum_multixact_freeze_max_age` 的值。如需詳細資訊，請參閱 [autovacuum\$1multixact\$1freeze\$1max\$1age](https://www.postgresql.org/docs/current/runtime-config-autovacuum.html#GUC-AUTOVACUUM-MULTIXACT-FREEZE-MAX-AGE)。

### 增加記憶體參數
<a name="apg-waits.lwlockmultixact.actions.memoryparam"></a>

您可以調整下列參數，以最佳化 multixact 快取的記憶體用量。這些設定會控制為這些快取預留多少記憶體，這有助於減少工作負載中的 multixact 等待事件。我們建議您從下列值開始：

對於 Aurora PostgreSQL 17 和更新版本：  
+ `multixact_offset_buffers` = 128
+ `multixact_member_buffers` = 256

對於 Aurora PostgreSQL 16 和更早版本：  
+ `multixact_offsets_cache_size` = 128
+ `multixact_members_cache_size` = 256

**注意**  
在 Aurora PostgreSQL 17 中，參數名稱從 `multixact_offsets_cache_size` 變更為 `multixact_offset_buffers`，以及從 `multixact_members_cache_size` 變更為 `multixact_member_buffers`，以符合社群 PostgreSQL 17。

您可以在叢集層級設定這些參數，讓叢集中的所有執行個體保持一致。我們建議您測試和調整這些值，以達到最適合您的特定工作負載需求和執行個體類別。為了使參數變更生效，您必須重新啟動寫入器執行個體。

這些參數會以 multixact 快取項目表示。每個快取項目會使用 `8 KB` 記憶體。若要計算保留的總記憶體，請將每個參數值乘以 `8 KB`。例如，如果您將參數設定為 128，則預留記憶體總數將為 `128 * 8 KB = 1 MB`。

### 減少長時間執行的交易
<a name="apg-waits.lwlockmultixact.actions.longtransactions"></a>

長時間執行的交易會導致清空程序保留其資訊，直到認可交易或關閉唯讀交易為止。建議您主動監控和管理長時間執行的交易。如需更多詳細資訊，請參閱 [資料庫在交易連線中長時間閒置](PostgreSQL.Tuning_proactive_insights.md#proactive-insights.idle-txn)。請嘗試修改您的應用程式，以避免使用或儘量不使用長時間執行的交易。

### 長期動作
<a name="apg-waits.lwlockmultixact.actions.longactions"></a>

檢查您的工作負載，以探索 multixact 溢出的原因。您必須修正問題，才能擴展工作負載並減少等待事件。
+ 您必須分析用來建立資料表的 DDL (資料定義語言)。請確定資料表結構和索引的設計良好。
+ 當受影響的資料表具有外部索引鍵時，請判斷是否需要這些索引鍵，或是否有其他方式可強制執行參考完整性。
+ 當資料表有大型未使用的索引時，可能會導致自動清空不符合您的工作負載，並可能使其無法執行。若要避免這種情況，請檢查未使用的索引並將其完全移除。如需詳細資訊，請參閱[使用大型索引管理自動清空](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.LargeIndexes.html)。
+ 減少在交易中使用儲存點。