

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

`LWLock:MultiXactMemberBuffer`、`LWLock:MultiXactOffsetBuffer`、`LWLock:MultiXactMemberSLRU`、および `LWLock:MultiXactOffsetSLRU` の各待機イベントは、特定のテーブル内の同じ行を修正するトランザクションのリストをセッションが取得するのを待っていることを示します。
+ `LWLock:MultiXactMemberBuffer` – プロセスは、multixact メンバーのシンプルな最も長い時間使われていない (SLRU) バッファの I/O を待っています。
+ `LWLock:MultiXactMemberSLRU` – プロセスは、multixact メンバーのシンプルな最も長い時間使われていない (SLRU) キャッシュへのアクセスを待っています。
+ `LWLock:MultiXactOffsetBuffer` – プロセスは、multixact オフセットのシンプルな最も長い時間使われていない (SLRU) バッファの I/O を待っています。
+ `LWLock:MultiXactOffsetSLRU` – プロセスは、multixact オフセットのシンプルな最も長い時間使われていない (SLRU) キャッシュへのアクセスを待っています。

**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) のリストを格納するデータ構造です。1 つのトランザクションでテーブル内の行が参照されると、トランザクション 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)」を参照してください。
+ **PL/pgSQL EXCEPTION 句からのサブトランザクション** – PL/pgSQL 関数またはプロシージャに書き込む各 `EXCEPTION` 句は、内部で `SAVEPOINT` を作成します。
+ **外部キー** – 複数のトランザクションが親の行で共有ロックを取得する場合。

特定の行が複数のトランザクションオペレーションに含まれる場合、その行を処理するには、`multixact` リストからトランザクション ID を取得する必要があります。ルックアップによりメモリキャッシュから multixact を取得できない場合は、データ構造を Aurora ストレージレイヤーから読み取る必要があります。このストレージからの I/O により、SQL クエリに時間がかかることがあります。メモリキャッシュミスは、複数のトランザクションの数が多く、使用率が高くなると発生し始める可能性があります。これらのすべての要因が、この待機イベントの増加の原因となっています。

## アクション
<a name="apg-waits.lwlockmultixact.actions"></a>

待機イベントの原因に応じたさまざまなアクションをお勧めします。これらのアクションの一部は、待機イベントを即座に削減するのに役立ちます。ただし、アクションによっては、ワークロードをスケールするために調査と修正が必要な場合があります。

**Topics**
+ [この待機イベントがあるテーブルでバキュームフリーズを実行する](#apg-waits.lwlockmultixact.actions.vacuumfreeze)
+ [この待機イベントがあるテーブルで autovacuum の頻度を上げる](#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)」を参照してください。

### この待機イベントがあるテーブルで autovacuum の頻度を上げる
<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 DB クラスターの VACUUM が最適に設定されていることを確認します。

影響を受けたテーブルまたはテーブルパーティションで VACUUM FREEZE を使用して待機イベントの問題を解決する場合は、インスタンスレベルで autovacuum を調整する代わりに、`pg_cron` などのスケジューラを使用して VACUUM を実行することをお勧めします。

autovacuum をより頻繁に実行するため、影響を受けるテーブルの `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 では、コミュニティ PostgreSQL 17 に合わせてパラメータ名が `multixact_offsets_cache_size` から `multixact_offset_buffers` へ、および `multixact_members_cache_size` から `multixact_member_buffers` へ変更されました。

これらのパラメータをクラスターレベルで設定することで、クラスター内のすべてのインスタンスの整合性を維持できます。特定のワークロード要件とインスタンスクラスに最も適した値をテストして調整することをお勧めします。パラメータの変更を有効にするには、ライターインスタンスを再起動する必要があります。

パラメータは 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 (データ定義言語) を分析する必要があります。テーブル構造とインデックスが適切に設計されていることを確認します。
+ 影響を受けるテーブルに外部キーがある場合、それらが必要かどうか、または参照整合性を強制する別の方法があるかどうかを確認します。
+ テーブルに未使用のインデックスが大量にある場合、autovacuum がワークロードに適合せず、実行がブロックされる可能性があります。これを回避するには、未使用のインデックスをチェックし、それらを完全に削除します。詳細については、「[大量のインデックスでの autovacuum の管理](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.LargeIndexes.html)」を参照してください。
+ トランザクションでのセーブポイントの使用を減らします。