Lock:transactionid - Amazon Relational Database Service

Lock:transactionid

Lock:transactionidイベントは、トランザクションが行レベルのロックを待っているときに発生します。

サポート対象エンジンバージョン

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

Context

イベントLock:transactionidは、トランザクションが、同時に実行されているトランザクションにすでに付与された行レベルのロックを取得しようとすると発生します。を示すセッションは、Lock:transactionid待機イベントがこのロックのためにブロックされていることを示します。COMMITまたはROLLBACKステートメントでブロックされているトランザクションの完了後、ブロックされたトランザクションを続行できます。

RDS for PostgreSQL のマルチバージョン同時実行制御セマンティクスは、リーダーがライターを、ライターがリーダーをブロックしないことを保証します。行レベルの競合が発生するには、ブロックおよびブロックされたトランザクションで、次のタイプの競合するステートメントを発行する必要があります。

  • UPDATE

  • SELECT … FOR UPDATE

  • SELECT … FOR KEY SHARE

ステートメントSELECT … FOR KEY SHAREは特殊なケースです。データベースは、レファレンスの整合性のパフォーマンスを最適化するために、FOR KEY SHARE節を使用します。行に対する行レベルロックは、行を参照している他のテーブルのINSERTUPDATEDELETEコマンドをブロックできます。

待機時間が増加する原因の可能性

このイベントが通常よりも頻繁に発生する場合、通常はUPDATESELECT … FOR UPDATE、またはSELECT … FOR KEY SHAREステートメントが以下の条件と組み合わさることが原因です。

同時実行数が多い

RDS for PostgreSQL は、きめ細かい行レベルのロックセマンティクスを使用できます。以下の条件が満たされると、行レベルの同時実行が発生する可能性が高くなります。

  • 同時性の高いワークロードは、同じ行で同時実行します。

  • 同時実行数が増加します。

トランザクションでのアイドル状態

時々、pg_stat_activity.state列にはidle in transaction値が表示されます。この値は、トランザクションをスタートしていても、まだCOMMITまたはROLLBACKを発行していないセッションに表示されます。pg_stat_activity.state値がactiveではない場合、pg_stat_activityに表示されるクエリは、実行を終了した最新のクエリになります。ブロックされているセッションは、開いているトランザクションがロックを保持しているため、クエリを積極的に処理しません。

アイドル状態のトランザクションが行レベルロックを取得した場合は、他のセッションがそのロックを取得するのを妨害する可能性があります。この状態は、待機イベントLock:transactionidの頻発につながります。問題を診断するには、pg_stat_activityそしてpg_locksからの出力を検証します。

トランザクションの実行時間が長い

実行時間が長いトランザクションは、長時間ロックされます。これらの長時間のロックは、他のトランザクションの実行をブロックすることがあります。

アクション

行ロックはUPDATESELECT … FOR UPDATE、またはSELECT … FOR KEY SHAREステートメント間の競合です。解決策を試す前に、これらのステートメントが同じ行で実行されているかどうかを調べます。この情報をもとに、次のセクションで説明する戦略を選択してください。

同時実行数の多さに対応

同時実行数が問題になる場合は、以下から 1 つの方法を試行します。

  • アプリケーションの同時実行数を減らします。例えば、アクティブなセッションの数を減らします。

  • 接続プールを実装します。RDS プロキシを使用して接続をプールする方法については、「Amazon RDS Proxy の使用」を参照してください。

  • アプリケーションまたはデータモデルを設計し、UPDATEおよびSELECT … FOR UPDATEステートメントの競合を避けてください。また、SELECT … FOR KEY SHAREステートメントにアクセスされる外部キーの数を減らすこともできます。

アイドル状態のトランザクションに対応する

pg_stat_activity.stateidle in transactionを示している場合は、以下の方法を使用します。

  • 可能な限り、オートコミットをオンにします。この方法では、COMMITまたはROLLBACKを待っている間に、トランザクションが他のトランザクションをブロックすることを防ぎます。

  • COMMITROLLBACK、またはENDが不足しているコードパスを検索します。

  • アプリケーションの例外処理ロジックに、常に有効なend of transactionへのパスが設定されていることを確認してください。

  • COMMITまたはROLLBACKでトランザクションを完了した後、アプリケーションがクエリの結果を処理することを確認します。

長時間実行されるトランザクションへの対応

長時間実行されるトランザクションがLock:transactionidの発生を頻繁に引き起こす場合、以下の方法を試します。

  • 長時間実行されるトランザクションが行をロックしないようにします。

  • 可能であれば、オートコミットを実装してクエリの長さを制限します。