Lock:transactionid
Lock:transactionid
イベントは、トランザクションが行レベルのロックを待っているときに発生します。
サポート対象エンジンバージョン
この待機イベント情報は、Aurora PostgreSQL のすべてのバージョンでサポートされています。
Context
イベントLock:transactionid
は、トランザクションが、同時に実行されているトランザクションにすでに付与された行レベルのロックを取得しようとすると発生します。を示すセッションは、Lock:transactionid
待機イベントがこのロックのためにブロックされていることを示します。COMMIT
またはROLLBACK
ステートメントでブロックされているトランザクションの完了後、ブロックされたトランザクションを続行できます。
Aurora PostgreSQL のマルチバージョン同時実行制御セマンティクスは、リーダーがライターを、ライターがリーダーをブロックしないことを保証します。行レベルの競合が発生するには、ブロックおよびブロックされたトランザクションで、次のタイプの競合するステートメントを発行する必要があります。
-
UPDATE
-
SELECT … FOR UPDATE
-
SELECT … FOR KEY SHARE
ステートメントSELECT … FOR KEY SHARE
は特殊なケースです。データベースは、レファレンスの整合性のパフォーマンスを最適化するために、FOR KEY
SHARE
節を使用します。行に対する行レベルロックは、行を参照している他のテーブルのINSERT
、UPDATE
、DELETE
コマンドをブロックできます。
待機時間が増加する原因の可能性
このイベントが通常よりも頻繁に発生する場合、通常はUPDATE
、SELECT …
FOR UPDATE
、またはSELECT … FOR KEY SHARE
ステートメントが以下の条件と組み合わさることが原因です。
同時実行数が多い
Aurora 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
からの出力を検証します。
トランザクションの実行時間が長い
実行時間が長いトランザクションは、長時間ロックされます。これらの長時間のロックは、他のトランザクションの実行をブロックすることがあります。
アクション
行ロックはUPDATE
、SELECT … FOR
UPDATE
、またはSELECT … FOR KEY SHARE
ステートメント間の競合です。解決策を試す前に、これらのステートメントが同じ行で実行されているかどうかを調べます。この情報をもとに、次のセクションで説明する戦略を選択してください。
同時実行数の多さに対応
同時実行数が問題になる場合は、以下から 1 つの方法を試行します。
-
アプリケーションの同時実行数を減らします。例えば、アクティブなセッションの数を減らします。
-
接続プールを実装します。RDS プロキシを使用して接続をプールする方法については、「Amazon RDS Proxy for Aurora の使用」を参照してください。
-
アプリケーションまたはデータモデルを設計し、
UPDATE
およびSELECT … FOR UPDATE
ステートメントの競合を避けてください。また、SELECT … FOR KEY SHARE
ステートメントにアクセスされる外部キーの数を減らすこともできます。
アイドル状態のトランザクションに対応する
pg_stat_activity.state
がidle in transaction
を示している場合は、以下の方法を使用します。
-
可能な限り、オートコミットをオンにします。この方法では、
COMMIT
またはROLLBACK
を待っている間に、トランザクションが他のトランザクションをブロックすることを防ぎます。 -
COMMIT
、ROLLBACK
、またはEND
が不足しているコードパスを検索します。 -
アプリケーションの例外処理ロジックに、常に有効な
end of transaction
へのパスが設定されていることを確認してください。 -
COMMIT
またはROLLBACK
でトランザクションを完了した後、アプリケーションがクエリの結果を処理することを確認します。
長時間実行されるトランザクションへの対応
長時間実行されるトランザクションがLock:transactionid
の発生を頻繁に引き起こす場合、以下の方法を試します。
-
長時間実行されるトランザクションが行をロックしないようにします。
-
可能であれば、オートコミットを実装してクエリの長さを制限します。