

# RDSfor PostgreSQL の一般的な PostgreSQL パフォーマンス問題の初期トラブルシューティング
<a name="PostgreSQL.InitialTroubleshooting"></a>

このガイドでは、RDS for PostgreSQL データベースに影響する 4 つの最も一般的なパフォーマンスの問題について説明します。テーブルとインデックスの肥大化、並列クエリのリソースの枯渇、接続と認証の負荷増大、autovacuum の調整です。パフォーマンスの低下が発生した場合、より詳細な調査を開始する前に、このガイドを初期診断チェックリストとして活用してください。

各セクションでは、観察される可能性のある症状について説明し、根本原因を確認するための診断クエリを提供し、特定の修復手順を推奨します。

**「何も変更していない」場合のパフォーマンスのリグレッションについて**  
PostgreSQL ワークロードは、数週間または数か月間問題なく実行された後、アプリケーションコードとクエリパターンに変更がないにもかかわらず、突然パフォーマンスが低下することがよくあります。これは、データベース環境が真に静的ではないために発生します。いくつかの目に見えない要因が時間の経過とともに変化し、計画の変更やリソースの競合を引き起こす可能性があります。  
**肥大の蓄積はワークロードの変化を意味します。**PostgreSQL のマルチバージョン同時実行制御 (MVCC) は、autovacuum がそれらを再利用するまで古い行バージョンを保持します。デッドタプルが autovacuum が処理できるよりも速く蓄積されると、テーブルとインデックスが物理的に大きくなります。その後、クエリプランナーは、テーブルサイズが大きくなるにつれてコスト見積もりがシフトするため、効率的なインデックススキャンからシーケンシャルスキャンに切り替える可能性があります。SQL は変更されていませんが、プランナーが参照するデータが変更されています。
**新しいパラメータ値は、ワークロードの変更を意味します。**ある範囲の値に対して優れたパフォーマンスを発揮するパラメータ化されたクエリでも、アプリケーションが別の範囲の使用を開始すると、パフォーマンスが低下する可能性があります。PostgreSQL は、新しい範囲内のデータスキューを考慮しない汎用実行プランを再利用したり、プランナーの統計がそれらの値の分布を正確に反映しない場合があります。肥大化も存在する場合、影響は複雑になります。最適ではない計画では、より多くのデッドデータをスキャンすることになります。
**autovacuum が実行されても、統計は古くなる可能性があります。**autovacuum は、データ分散が実質的に変更されたかどうかではなく、挿入または更新された行数に基づいて `ANALYZE` をトリガーします。アプリケーションが別の値範囲または時間枠のクエリに移行した場合、autovacuum が最近実行された場合でも、プランナーのコスト見積もりが不正確になる可能性があります。
**データベース全体の成長は、ワークロードの変化を意味します。**テーブルが時間の経過とともに増加すると、クエリがスキャンする必要があるデータページの量が増えます。小さいテーブルで正常に実行されたクエリは、クエリロジックとインデックスが変更されていない場合でも、テーブルサイズが大きくなるにつれてレイテンシーが発生する可能性があります。`FreeStorageSpace` をモニタリングして、ストレージの増加傾向を追跡します。
「何も変更していない」場合のパフォーマンスリグレッションを調査する際には、肥大の蓄積、新しいパラメータ値の範囲、データベース全体の成長、古くなった統計などを根本原因として最も可能性の高いものとして考慮します。このガイドの診断手順を使用して、どの要素が適用されるかを確認します。  
詳細については次を参照してください:  
[Amazon RDS および Amazon Aurora での PostgreSQL データベースのメンテナンスアクティビティ](https://docs.aws.amazon.com/prescriptive-guidance/latest/postgresql-maintenance-rds-aurora/introduction.html) (AWS 規範ガイダンス)
[PostgreSQL クエリのパフォーマンスの最適化](https://docs.aws.amazon.com/prescriptive-guidance/latest/postgresql-query-tuning/introduction.html) (AWS 規範ガイダンス)
[Amazon RDS および Amazon Aurora での PostgreSQL パラメータの調整](https://docs.aws.amazon.com/prescriptive-guidance/latest/tuning-postgresql-parameters/introduction.html)
[Amazon RDS インスタンスレベルのメトリクス](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-metrics.html#rds-cw-metrics-instance) (ストレージの増加傾向について `FreeStorageSpace` をモニタリング)

## クイック診断チェックリスト
<a name="PostgreSQL.InitialTroubleshooting.Checklist"></a>

パフォーマンスの問題を最初に調査するときは、次の順序付けられたトリアージステップを使用します。

1. ** をチェックします。。`pg_stat_activity`**接続数、アイドル状態のトランザクションセッション、長時間実行されるクエリを確認します。詳細については、「[RDS for PostgreSQL チューニングの基本概念](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/PostgreSQL.Tuning.concepts.html)」を参照してください。

1. **肥大化がないか確認します。**`n_dead_tup` で高い `pg_stat_user_tables` を探し、正確な測定に `pgstattuple` を使用することを検討してください。詳細については、「[pg\_repack を使用したテーブルからの肥大化の削除](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pg_repack.html)」を参照してください。

1. ** をチェックします。。`pg_stat_user_tables`**`n_dead_tup` の値が高いもの、および `last_autovacuum` のタイムスタンプが古いものを探します。詳細については、「[Amazon RDS での PostgreSQL autovacuum の使用](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.html)」を参照してください。

1. **スロークエリの `EXPLAIN ANALYZE` を確認します。**並列プランや大きなテーブルに対するシーケンシャルスキャンを探します。詳細については、「[RDS for PostgreSQL での並列クエリのベストプラクティス](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/PostgreSQL.ParallelQueries.html)」を参照してください。

1. **CloudWatch と Performance Insights のメトリクスを確認します。**CPU 使用率、接続数、IOPS、解放可能なメモリを確認します。詳細については、「[Amazon RDS のモニタリング](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/MonitoringOverview.html)」を参照してください。一般的な待機イベントと修正アクションについては、「[RDS for PostgreSQL 待機イベント](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/PostgreSQL.Tuning.concepts.summary.html)」を参照してください。

1. **DB パラメータグループを確認します。**`max_parallel_workers_per_gather` および autovacuum の設定を確認します。詳細については、「[Amazon RDS および Amazon Aurora での PostgreSQL パラメータの調整](https://docs.aws.amazon.com/prescriptive-guidance/latest/tuning-postgresql-parameters/introduction.html)」を参照してください。

## テーブルとインデックスの肥大化
<a name="PostgreSQL.InitialTroubleshooting.Bloat"></a>

テーブルとインデックスの肥大化は、autovacuum がテーブルを再利用できるよりも速いペースで、デッドタプルがテーブルに蓄積されたときに発生します。これにより、時間の経過とともに、クエリのパフォーマンスが徐々に低下し、ストレージ使用量が増加し、最適ではないクエリプランが発生します。

### 症状
<a name="PostgreSQL.InitialTroubleshooting.Bloat.Symptoms"></a>
+ 数週間または数か月にわたる段階的なクエリパフォーマンスの低下
+ データ量は安定しているもののストレージ使用量が増加する
+ クエリプランナーが、古い統計のため、インデックススキャンよりもシーケンシャルスキャンを選択する
+ テーブル統計における `dead_tuple_count` の値が高い

### 診断
<a name="PostgreSQL.InitialTroubleshooting.Bloat.Diagnosis"></a>

システムカタログをクエリすることで、すべてのテーブルにおける肥大化を推定できます。このアプローチでは、拡張機能は必要ありません。

```
SELECT schemaname, relname,
       n_dead_tup,
       n_live_tup,
       ROUND(n_dead_tup::numeric / GREATEST(n_live_tup, 1) * 100, 2) AS dead_pct,
       last_autovacuum,
       last_autoanalyze
FROM pg_stat_user_tables
WHERE n_dead_tup > 10000
ORDER BY n_dead_tup DESC
LIMIT 20;
```

肥大化に対処するには、`pg_repack` 拡張機能を使用して、最小限のロックでテーブルとインデックスを再編成できます。詳細については、「[pg\_repack を使用したテーブルからの肥大化の削除](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pg_repack.html)」および「[pg\_repack を使用した Amazon Aurora および RDS for PostgreSQL からの肥大化の削除](https://aws.amazon.com/blogs/database/remove-bloat-from-amazon-aurora-and-rds-for-postgresql-with-pg_repack/)」を参照してください。

**重要**  
手動メンテナンスに依存するのではなく、autovacuum が有効で、ワークロードに合わせて適切に調整されていることを確認してください。チューニングの推奨事項については、「[autovacuum 調整](#PostgreSQL.InitialTroubleshooting.Autovacuum)」を参照してください。

## 並列クエリのリソースの枯渇
<a name="PostgreSQL.InitialTroubleshooting.ParallelQuery"></a>

PostgreSQL はクエリを並行して実行し、大規模なシーケンシャルスキャンと集約のパフォーマンスを向上させることができます。ただし、各並列ワーカーは、`max_worker_processes` (およびサブ制限 `max_parallel_workers`) に対してカウントされ、独自の `work_mem` を割り当てる完全なバックエンドプロセスです。4 つの並列ワーカーを含む 1 つのクエリは、数百メガバイトのメモリと大量の CPU を消費する可能性があります。同時実行性が高い場合、過剰な並列処理により CPU とメモリが急速に枯渇する可能性があります。

一般的な症状には、突然の CPU スパイク、クエリあたりのメモリ使用量の増加、アプリケーションの変更がないにもかかわらず CloudWatch で `DatabaseConnections` が上昇することなどがあります。また、`IPC:BgWorkerStartup`、`IPC:ExecuteGather`、`IPC:ParallelFinish` などの待機イベントが発生することもあります。これらの待機イベントの詳細については、「[IPC:parallel 待機イベント](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rpg-ipc-parallel.html)」を参照してください。

ほとんどの OLTP および高同時実行の本稼働ワークロードでは、DB パラメータグループで `max_parallel_workers_per_gather = 0` に設定して自動並列処理を無効にします。その後、セッションごとまたはロールごとにパラメータを設定することで、特定の分析セッションまたはレポートセッションの並列処理を選択的に有効にできます。

並列クエリの動作の診断と制御に関する詳細なガイダンスについては、「[RDS for PostgreSQL での並列クエリのベストプラクティス](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/PostgreSQL.ParallelQueries.html)」を参照してください。

## 接続および認証の高負荷
<a name="PostgreSQL.InitialTroubleshooting.ConnectionPressure"></a>

接続チャーン (プーリングを行わずにデータベース接続を頻繁に開閉すること) は、認証オーバーヘッドを発生させ、使用可能な接続スロットを枯渇させる可能性があります。アイドル状態のまま開いたままになっている接続も、有用な作業を実行せずにスロットを消費します。

### 症状
<a name="PostgreSQL.InitialTroubleshooting.ConnectionPressure.Symptoms"></a>
+ Performance Insights モニタリングで `total_auth_attempts` の値が増加しています。詳細については、「[RDS for PostgreSQL の非ネイティブカウンター](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_PerfInsights_Counters.html#USER_PerfInsights_Counters.PostgreSQL.NonNative)」を参照してください。
+ 接続確立時間が遅い
+ `FATAL: too many connections for role` または `remaining connection slots are reserved` エラー
+ 接続チャーンと相関する CPU スパイク

### 診断
<a name="PostgreSQL.InitialTroubleshooting.ConnectionPressure.Diagnosis"></a>

次のクエリを実行して、現在の接続状態を確認します。

```
SELECT
  setting::int AS max_connections,
  (SELECT count(*) FROM pg_stat_activity) AS current_connections,
  (SELECT count(*) FROM pg_stat_activity WHERE state = 'idle') AS idle_connections,
  (SELECT count(*) FROM pg_stat_activity WHERE state = 'idle in transaction') AS idle_in_txn
FROM pg_settings
WHERE name = 'max_connections';
```

`max_connections` に対する `idle` または `idle in transaction` 接続の数が多い場合は、接続が適切に解放されていないことを示しています。アイドル状態のトランザクション接続は、ロックを保持し、autovacuum によるデッドタプルの再利用を妨げるため、特に問題があります。

### 修正
<a name="PostgreSQL.InitialTroubleshooting.ConnectionPressure.Remediation"></a>
+ **接続プーリングをデプロイします。**PgBouncer または Amazon RDS Proxy を使用して、データベースへの直接接続の数を減らします。接続プーリングは、リクエストごとに新しい接続を作成するのではなく、既存の接続を再利用します。
+ ** を設定します。。`idle_in_transaction_session_timeout`**このパラメータは、指定された期間を超えてトランザクションでアイドル状態のままになっているセッションを自動的に終了させます。これにより、長時間実行されるアイドル状態のトランザクションがロックを保持し、autovacuum をブロックすることを防ぎます。
+ **アプリケーションの接続処理を確認します。**アプリケーションが接続をすぐに閉じ、トランザクションを必要以上に長く開いたままにしないようにします。

**注記**  
並列クエリワーカーは CPU とメモリを消費します。並列クエリアクティビティと同時にリソースの枯渇が見られる場合は、「[並列クエリのリソースの枯渇](#PostgreSQL.InitialTroubleshooting.ParallelQuery)」を参照して、並列ワーカーの使用を制御するためのガイダンスを確認してください。

## Performance Insights の待機イベントを使用したトラブルシューティング
<a name="PostgreSQL.InitialTroubleshooting.WaitEvents"></a>

Performance Insights は、データベースが時間を費やしている場所を示す待機イベントをキャプチャします。パフォーマンスの問題を調査する場合、待機イベントは、ボトルネックが CPU、I/O、ロック、ネットワーク、またはプロセス間通信のいずれであるかを特定するのに役立ちます。このガイドで説明されている問題発生時の一般的な待機イベントカテゴリは次のとおりです。
+ **CPU** - セッションは CPU でアクティブであるか、CPU を待機中です。CPU 待機イベントの増加は、過剰な並列処理や、肥大化したテーブルをスキャンする非効率的なクエリプランと関連していることがよくあります。
+ **IPC (プロセス間通信)** - `IPC:BgWorkerStartup`、`IPC:ExecuteGather`、`IPC:ParallelFinish` などの待機イベントは、並列クエリ調整のオーバーヘッドを示します。
+ **IO** - `IO:DataFileRead` などの待機イベントは、必要なページが共有メモリにないため、クエリがストレージからデータを読み取っていることを示します。これは、肥大化したテーブルがバッファキャッシュを超えた場合に一般的です。
+ **ロック** - `Lock:transactionid` や `Lock:tuple` などの待機イベントはセッション間の競合を示します。アイドル状態のトランザクション接続は、他のクエリや autovacuum をブロックするロックを保持している可能性があります。
+ **クライアント** - データベースがアプリケーションがデータを送信するのを待っていることを示す `Client:ClientRead` などの待機イベント。クライアント待機イベントが多い場合は、接続チャーンまたはネットワークレイテンシーを示している可能性があります。

パフォーマンスの問題を示す一般的な待機イベントとその推奨される是正措置の完全なリファレンスについては、「[RDS for PostgreSQL 待機イベント](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/PostgreSQL.Tuning.concepts.summary.html)」を参照してください。

## autovacuum 調整
<a name="PostgreSQL.InitialTroubleshooting.Autovacuum"></a>

autovacuum は、デッドタプルの再利用、テーブルとインデックスの肥大化の防止、プランナー統計の更新、トランザクション ID の循環に対する保護を行うバックグラウンドプロセスです。デフォルトの autovacuum 設定は保守的で、小規模なデータベース用に設計されています。書き込みの多い本稼働ワークロードでは、ほとんどの場合、チューニングが必要です。

autovacuum が書き込みワークロードに対応できない場合、肥大化し、プランナー統計が古くなり、トランザクション ID の循環のリスクが高まります。`age(relfrozenxid)` が 20 億に近づくと、データベースはデータ破損を防ぐためにシャットダウンします。

autovacuum のパラメータの調整、バキュームアクティビティのモニタリング、テーブルごとのオーバーライドの設定に関する詳細なガイダンスについては、「[Amazon RDS での PostgreSQL autovacuum の使用](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.html)」を参照してください。

## 関連情報
<a name="PostgreSQL.InitialTroubleshooting.RelatedInfo"></a>
+ [RDS for PostgreSQL での並列クエリのベストプラクティス](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/PostgreSQL.ParallelQueries.html)
+ [PostgreSQL でのデッド接続の処理](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.html)
+ [Amazon RDS での PostgreSQL Autovacuum の使用](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.html)
+ [RDS for PostgreSQL の一般的な DBA タスク](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.html)
+ [Amazon RDS での PostgreSQL Autovacuum の使用](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.html)
+ [Amazon RDS for PostgreSQL 環境における自動バキュームについて](https://aws.amazon.com/blogs/database/understanding-autovacuum-in-amazon-rds-for-postgresql-environments/)