LWLock:lock_manager
このイベントは、Aurora PostgreSQL エンジンが、高速パスロックが不可能な場合に共有ロックのメモリ領域を維持し、ロックの割り当て、チェック、および解放を行うときに発生します。
サポート対象エンジンバージョン
この待機イベント情報は、Aurora PostgreSQL バージョン 9.6 以降に関連します。
Context
SQL ステートメントを発行すると、Aurora PostgreSQL は同時オペレーション中にデータベースの構造、データ、および整合性を保護するためにロックを記録します。エンジンは、高速パスロックまたは高速ではないパスロックを使用して、この目標を達成できます。高速ではないパスロックは、高速パスロックよりも高価で、オーバーヘッドも多く発生します。
高速パスロック
バックエンドプロセスでは、頻繁にロックされロック解除されるがめったに競合しないロックのオーバーヘッドを減らすために、高速パスロックを使用できます。データベースでは、以下の基準を満たすロックにこのメカニズムを使用します。
-
DEFAULT ロック方式を使用します。
-
これらは、共有関係ではなく、データベースリレーションに対するロックを表します。
-
これらは競合する可能性が低い弱いロックです。
-
エンジンは、競合するロックが存在する可能性がないことをすばやく確認できます。
エンジンは、以下のいずれかの条件が true の場合、高速パスロックを使用できません。
-
ロックが上記の条件を満たしていません。
-
バックエンドプロセスに使用できるスロットはこれ以上ありません。
高速パスロックの詳細については、「PostgreSQL ロックマネージャ README」 のfast path
ロックマネージャのスケーリング問題の例
この例では、purchases
という名前のテーブルが 5 年分のデータを日ごとにパーティション化して保存しています。各パーティションには 2 つのインデックスがあります。次の一連のイベントが発生します。
-
何日分ものデータをクエリすると、データベースは多くのパーティションを読み取る必要があります。
-
データベースは、各パーティションに対してロックエントリを作成します。パーティションインデックスがオプティマイザアクセスパスの一部である場合、データベースはそれらのロックエントリも作成します。
-
同じバックエンドプロセスでリクエストされたロックエントリの数が
FP_LOCK_SLOTS_PER_BACKEND
の値である16より大きい場合、ロックマネージャは非高速パスロック方式を使用します。
最新のアプリケーションには何百ものセッションがあることがあります。同時セッションが適切なパーティションプルーニングを行わずに親を照会している場合、データベースは数百または数千の非高速パスロックを作成することがあります。通常、この同時実行が vCPUs の数よりも多いと、LWLock:lock_manager
待機イベントが表示されます。
注記
LWLock:lock_manager
待機イベントは、データベーススキーマのパーティションまたはインデックスの数とは関係ありません。代わりに、データベースが制御する必要がある非高速パスロックの数と関係しています。
待機時間が増加する原因の可能性
LWLock:lock_manager
待機イベントが通常より頻繁に発生する場合は、おそらくパフォーマンスの問題を示しており、突然のスパイクが発生する原因として最も可能性が高いものは次のとおりです。
-
同時アクティブセッションは、高速パスロックを使用しないクエリを実行しています。また、これらのセッション数が最大 vCPU を超えています。
-
多数の同時アクティブセッションが、大きくパーティション化されたテーブルにアクセスしています。各パーティションには複数のインデックスがあります。
-
データベースで接続ストームが発生しています。デフォルトでは、一部のアプリケーションと接続プールソフトウェアは、データベースが遅い場合により多くの接続を作成します。これは問題を悪化させます。接続ストームが発生しないように接続プールソフトウェアをチューニングします。
-
多数のセッションが、パーティションをプルーニングせずに親テーブルをクエリします。
-
データ定義言語 (DDL)、データ操作言語 (DML)、またはメンテナンスコマンドは、頻繁にアクセスまたは変更されるビジーリレーションあるいはタプルのいずれかを排他的にロックします。
アクション
待機イベントの原因に応じたさまざまなアクションをお勧めします。
トピック
パーティションプルーニングを使用する
パーティションプルーニングとは、不要なパーティションをテーブルスキャンから除外し、パフォーマンスを向上させるクエリ最適化戦略です。パーティションプルーニングは、デフォルトで有効になっています。オフになっている場合は、次のようにオンにします。
SET enable_partition_pruning = on;
クエリのWHERE
節にパーティショニングに使用される列が含まれる場合は、パーティションのプルーニングを利用できます。詳細については、PostgreSQL のドキュメントの「パーティションプルーニング
不要なインデックスを削除する
データベースには、未使用またはほとんど使用されないインデックスが含まれている可能性があります。その場合は、それらの削除を検討します。次のいずれかを実行します。
-
不要なインデックスを見つける方法については、PostgreSQL wikiの「未使用のインデックス
」を参照してください。 -
PG コレクタを実行します。この SQL スクリプトは、データベース情報を収集し、統合 HTML レポートに表示します。「未使用のインデックス」セクションをチェックします。詳細については、AWSLabs GitHub リポジトリの「PG コレクター
」を参照してください。
高速パスロック用にクエリをチューニングする
クエリで高速パスロックが使用されているかどうかを調べるには、pg_locks
テーブルのfastpath
列にクエリを実行します。クエリで高速パスロックを使用していない場合は、クエリあたりのリレーション数を 16 未満に減らしてください。
他の待機イベントに合わせてチューニングする
LWLock:lock_manager
が上位待機のリストの第1位または 2 番目である場合、次の待機イベントもリストに表示されるかどうかを確認します。
-
Lock:Relation
-
Lock:transactionid
-
Lock:tuple
上記のイベントがリスト内で上位に表示される場合は、まずこれらの待機イベントのチューニングを検討してください。これらのイベントは、LWLock:lock_manager
のドライバーになり得ます。
ハードウェアのボトルネックを減らす
CPU の枯渇や Amazon EBS 帯域幅の最大使用率など、ハードウェアのボトルネックが発生する可能性があります。このような場合は、ハードウェアのボトルネックを減らすことを検討してください。以下のアクションの場合を検討します。
-
インスタンスクラスをスケールアップします。
-
大量の CPU とメモリを消費するクエリを最適化します。
-
アプリケーションロジックを変更します。
-
データをアーカイブします。
CPU、メモリ、および EBS ネットワーク帯域幅の詳細については、Amazon RDS インスタンスタイプ
接続プーラーを使用する
アクティブな接続の総数が最大 vCPU を超えると、インスタンスタイプがサポートできるより多くの OS プロセスが CPU を必要とします。このような場合は、接続プールの使用またはチューニングを検討してください。インスタンスタイプの vCPUs の詳細については、「Amazon RDS インスタンスタイプ
接続プールの詳細については、次のリソースを参照してください。
-
PostgreSQL ドキュメントの接続プールとデータソース
Aurora PostgreSQL のバージョンをアップグレードする
現在使用している Aurora PostgreSQL のバージョンが 12 より前のものであれば、バージョン 12 以上にアップグレードします。PostgreSQL バージョン 12 と 13 では、パーティションメカニズムが改良されています。バージョン12の詳細については、PostgreSQL 12.0 リリースノート