

# LWLock:pg\$1stat\$1statements
<a name="apg-rpg-lwlockpgstat"></a>

LWLock:pg\$1stat\$1statements 待機イベントは、`pg_stat_statements` 拡張機能が SQL ステートメントを追跡するハッシュテーブルで排他的ロックを取得したときに発生します。これは以下のようなシナリオで発生します。
+ 追跡されるステートメントの数が設定された `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>

 この待機イベント情報は、Aurora PostgreSQL のすべてのバージョンでサポートされています。

## Context
<a name="apg-rpg-lwlockpgstat.context"></a>

**pg\$1stat\$1statements 拡張機能を理解する** – pg\$1stat\$1statements 拡張機能は、ハッシュテーブル内の SQL ステートメントの実行統計を追跡します。拡張機能は、`pg_stat_statements.max` パラメータで定義された制限まで SQL ステートメントを追跡します。このパラメータは、pg\$1stat\$1statements ビューの最大行数に対応する、追跡できるステートメントの最大数を決定します。

**ステートメント統計の永続性** – 拡張機能は、以下によってインスタンスのすべての再起動でステートメント統計を保持します。
+ pg\$1stat\$1statements.stat という名前のファイルにデータを書き込む
+ pg\$1stat\$1statements.save パラメータを使用して永続性の動作を制御する

pg\$1stat\$1statements.save の設定と動作。
+ on (デフォルト): 統計はシャットダウン時に保存され、サーバー起動時に再ロードされる
+ off: 統計はシャットダウン時に保存されず、サーバー起動時に再ロードされない

**クエリテキストストレージ** – 拡張機能は、追跡されたクエリのテキストを `pgss_query_texts.stat` という名前のファイルに保存します。このファイルは、ガベージコレクションが発生する前に、追跡されるすべての SQL ステートメントの平均サイズの 2 倍に増加する可能性があります。拡張機能では、クリーンアップオペレーションと `pgss_query_texts.stat` ファイルの書き換え中にハッシュテーブルに排他的ロックが必要です。

**ステートメントの割り当て解除プロセス** – 追跡されたステートメントの数が `pg_stat_statements.max` の制限に達し、新しいステートメントを追跡する必要がある場合、拡張機能は以下の処理を行います。
+ ハッシュテーブルで排他的ロック (LWLock:pg\$1stat\$1statements) を取得します。
+ 既存のデータをローカルメモリにロードします。
+ 呼び出しの数に基づいてクイックソートを実行します。
+ 最小呼び出しステートメント (下位 5%) を削除します。
+ ハッシュテーブルに残りのエントリを再入力します。

**ステートメントの割り当て解除のモニタリング** – PostgreSQL 14 以降では、pg\$1stat\$1statements\$1info ビューを使用してステートメントの割り当て解除をモニタリングできます。このビューには、新しいステートメントのスペースを確保するためにステートメントが割り当て解除された回数を示す dealloc 列が含まれています。

ステートメントの割り当て解除が頻繁に発生すると、ディスク上の `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>

待機イベントの原因に応じたさまざまなアクションをお勧めします。`LWLock:pg_stat_statements` イベントは、Amazon RDS Performance Insights を使用するか、ビュー `pg_stat_activity` のクエリで特定することができます。

次の `pg_stat_statements` パラメータを調整して追跡動作を制御し、LWLock:pg\$1stat\$1statements の待機イベントを減らします。

**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` ビューをさらに分析して根本原因を特定する前に迅速な対応が必要な場合は、`pg_stat_statements.track` パラメータを `none` に設定することで無効にできます。これにより、ステートメント統計の収集が無効になります。

### 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` パラメータは即時反映されません。これらのパラメータの変更を適用するには、DB インスタンスを再起動する必要があります。

### 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 では、ユーティリティコマンドの追跡にいくつかの機能強化が導入されています。
+ セーブポイント名が定数として表示されるようになりました。
+ 2 フェーズコミットコマンドのグローバルトランザクション ID (GID) が定数として表示されるようになりました。
+ DEALLOCATE ステートメントの名前は定数として表示されます。
+ CALL パラメータが定数として表示されるようになりました。