pg_locks
ビューは、データベースサーバー上のアクティブなプロセスが保持するロックに関する情報を提供します。
概要
pg_locks
ビューには、アクティブなロック可能オブジェクト、要求されたロックモード、および関連するプロセスごとに1行が表示されます。 したがって、複数のプロセスがロックを保持または待機している場合、同じロック可能オブジェクトが複数回表示される可能性があります。 ただし、現在ロックされていないオブジェクトは表示されません。
ロック可能なオブジェクトにはいくつかの異なるタイプがあります。リレーション全体 (テーブルなど) 、リレーションの個々のページ、リレーションの個々のタプル、トランザクションID (仮想IDと永続IDの両方) 、および一般的なデータベースオブジェクト (クラスOIDとオブジェクトOIDによって識別されます。pg_description
またはpg_depend
と同じように) 。 また、リレーションを拡張する権利とpg_database.datfrozenxid
を更新する権利は、個別のロック可能オブジェクトと見なされます。 また、アドバイザリロックは、ユーザー定義の意味を持つ番号で取得できます。
pg_locks
ビューには、次の列が含まれます。
列名 | データ型 | 説明 |
ロックタイプ | text | ロック可能なオブジェクトの型。 有効な値: |
削除 | oid | ロックターゲットが存在するデータベースのOID。 ターゲットが共有オブジェクトの場合、値は0です。 ターゲットがトランザクションIDの場合、値は空です。 |
関係 | oid | ロックの対象となるリレーションのOID。 ターゲットがリレーションまたはリレーションの一部でない場合、値は空です。 |
page | int4 | リレーション内のロックの対象となるページ番号。 ターゲットが関係ページまたはタプルでない場合、値は空です。 |
タプル | int2 | ページ内のロックの対象となるタプル番号。 ターゲットがタプルでない場合、値は空です。 |
virtualxid | text | ロックの対象となるトランザクションの仮想ID。 ターゲットが仮想トランザクションIDでない場合、値は空です。 |
transactionid | xid | ロックの対象となるトランザクションのID。 ターゲットがトランザクションIDでない場合、値は空です。 |
クラシッド | oid | ロックターゲットを含むシステムカタログのOID。 ターゲットが一般的なデータベースオブジェクトでない場合、値は空です。 |
objid | oid | システムカタログ内のロックターゲットのOID。 ターゲットが一般的なデータベースオブジェクトでない場合、値は空です。 |
objsubid | int2 | ロックの対象となる列番号 ( |
virtualtransaction | text | ロックを保持している、またはロックを待っているトランザクションの仮想ID。 |
ピッド | int4 | ロックを保持または待機しているサーバープロセスのPID。 この値は、ロックが準備済みトランザクションによって保持されている場合は空です。 |
モード | text | このプロセスで保持または必要なロックモードの名前 |
付与された | bool | ロックが保持されている場合、値は |
fastpath | bool | 高速パスを介してロックが取得された場合、値は |
行のgranted
の値がtrue
の場合、ロックは指定されたプロセスによって保持されます。 値が偽
の場合、指示されたプロセスは現在このロックを取得するのを待っています。これは、少なくとも1つの他のプロセスが、同じロック可能オブジェクト上で競合するロックモードを保持または待機していることを意味します。 待機プロセスは、他のロックが解放されるか、またはデッドロック状況が検出されるまでスリープする。 単一のプロセスは、一度に多くとも1つのロックを取得するのを待つことができる。
トランザクションの実行中、サーバプロセスは、トランザクションの仮想トランザクションIDに対する排他ロックを保持する。 トランザクションに永続IDが割り当てられている場合 (通常、トランザクションがデータベースの状態を変更した場合にのみ発生します) 、トランザクションが終了するまで、トランザクションの永続トランザクションIDの排他ロックも保持します。 トランザクションが別のトランザクションを待つ必要がある場合、トランザクションは、他のトランザクションID (それが仮想IDであろうと永久IDであろうと) の共有ロックも取得しようとする。 これは、他のトランザクションが終了してロックを解放した場合にのみ成功します。
タプルはロック可能なタイプのオブジェクトですが、行レベルのロックに関する情報はメモリではなくディスクに保存されるため、通常、このビューには行レベルのロックは表示されません。 プロセスが行レベルのロックを待機している場合、通常、その行ロックの現在の所有者の永続トランザクションIDを待機しているとしてビューに表示されます。
アドバイザリロックは、単一のbigint
値または2つの整数値からなるキーで取得できます。 bigint
キーは、上位半分がclassid
列に、下位半分がobjid
列に、objsubid
が1に等しい状態で表示されます。 元のbigint
値は、式 (classid::bigint << 32) | objid::bigint
で再構築できます。 整数キーは、classid
列の最初のキー、objid
列の2番目のキー、および2に等しいobjsubid
で表示されます。 キーの実際の意味は、ユーザによって決定される。 アドバイザリロックは各データベースに対してローカルであるため、データベース
列はアドバイザリロックには意味がありません。
pg_locks
は、現在のデータベースに関連するロックだけでなく、データベースクラスター内のすべてのロックのグローバルビューを提供します。 relation
列はpg_class
に結合できます。oid
を使用してロックされたリレーションを識別する場合、これは現在のデータベース (データベース
列が現在のデータベースのOIDまたはゼロのいずれかであるリレーション) に対してのみ正しく機能します。
pid
列をpg_stat_activity
ビューのpid
列に結合して、各ロックを保持または待機しているセッションに関する情報を取得できます。 サンプルコード:
SELECT * FROM pg_locks pl LEFT JOIN pg_stat_activity psa
ON pl.pid = psa.pid;
準備済みトランザクションを使用している場合、virtualtransaction
列をpg_prepared_xacts
ビューのtransaction
列に結合して、ロックを保持する準備済みトランザクションに関する情報を取得できます。 準備されたトランザクションはロックを待つことはできませんが、実行中に取得したロックを保持し続けます。 サンプルコード:
SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
ON pl.virtualtransaction = '-1/' | | ppx.transaction;
pg_locks
をそれ自体に結合することによって、どのプロセスが他のどのプロセスをブロックするかに関する情報を取得することは可能ですが、詳細を取得することは非常に困難です。 このようなクエリは、どのロックモードが他のロックモードと競合するかについての情報を返さない。 pg_locks
ビューでは、どのプロセスがロック待ちキュー内の他のプロセスより先にあるかについての情報や、どのプロセスが他のクライアントセッションの代わりに実行されている並列ワーカーであるかについての情報は公開されません。 より良いアプローチは、pg_blocking_pids()
関数を使用して、待機中のプロセスをブロックしているプロセスを識別することです。
pg_locks
ビューには、別々のシステムである通常のロックマネージャと述語ロックマネージャの両方からのデータが表示されます。 さらに、通常ロックマネージャは、そのロックを通常および高速パスロックに細分する。 このデータが完全に一致することは保証されません。 ビューが照会されると、高速パスロック (fastpath
=true
) のデータは、ロックマネージャ全体の状態を凍結することなく、各バックエンドから一度に1つずつ収集されます。 その結果、情報が収集されている間にロックを解除することが可能である。 ただし、これらのロックは、現在配置されている他のロックと競合しません。 すべてのバックエンドが高速パスロックについて照会された後、通常のロックマネージャの残りの部分はユニットとしてロックされ、残りのすべてのロックの一貫したスナップショットがアトミックアクションとして収集されます。 通常のロックマネージャをアンロックした後、述語ロックマネージャは同様にロックされ、すべての述語ロックがアトミックなアクションとして収集されます。 したがって、高速経路ロックを除いて、各ロックマネージャは、一貫した結果のセットを提供する。しかし、両方のロックマネージャを同時にロックしないので、通常のロックマネージャに問い合わせた後、述語ロックマネージャに問い合わせた後に、ロックを取得または解放することが可能である。
このビューが非常に頻繁にアクセスされる場合、通常のロック管理または述語ロックマネージャ、またはその両方をロックすると、データベースのパフォーマンスに影響を与える可能性があります。 ロックは、ロックマネージャからデータを取得するのに必要な最小限の時間だけ保持されますが、これはパフォーマンスへの影響の可能性を完全に排除するものではありません。