すべてのプロダクト
Search
ドキュメントセンター

PolarDB:pg_locks

最終更新日:Jun 04, 2024

pg_locksビューは、データベースサーバー上のアクティブなプロセスが保持するロックに関する情報を提供します。

概要

pg_locksビューには、アクティブなロック可能オブジェクト、要求されたロックモード、および関連するプロセスごとに1行が表示されます。 したがって、複数のプロセスがロックを保持または待機している場合、同じロック可能オブジェクトが複数回表示される可能性があります。 ただし、現在ロックされていないオブジェクトは表示されません。

ロック可能なオブジェクトにはいくつかの異なるタイプがあります。リレーション全体 (テーブルなど) 、リレーションの個々のページ、リレーションの個々のタプル、トランザクションID (仮想IDと永続IDの両方) 、および一般的なデータベースオブジェクト (クラスOIDとオブジェクトOIDによって識別されます。pg_descriptionまたはpg_dependと同じように) 。 また、リレーションを拡張する権利とpg_database.datfrozenxidを更新する権利は、個別のロック可能オブジェクトと見なされます。 また、アドバイザリロックは、ユーザー定義の意味を持つ番号で取得できます。

pg_locksビューには、次の列が含まれます。

列名

データ型

説明

ロックタイプ

text

ロック可能なオブジェクトの型。 有効な値: relationextendfrozenidpagetupletransactionidvirtualxidspectokenobjectuserlockadvisory

削除

oid

ロックターゲットが存在するデータベースのOID。 ターゲットが共有オブジェクトの場合、値は0です。 ターゲットがトランザクションIDの場合、値は空です。

関係

oid

ロックの対象となるリレーションのOID。 ターゲットがリレーションまたはリレーションの一部でない場合、値は空です。

page

int4

リレーション内のロックの対象となるページ番号。 ターゲットが関係ページまたはタプルでない場合、値は空です。

タプル

int2

ページ内のロックの対象となるタプル番号。 ターゲットがタプルでない場合、値は空です。

virtualxid

text

ロックの対象となるトランザクションの仮想ID。 ターゲットが仮想トランザクションIDでない場合、値は空です。

transactionid

xid

ロックの対象となるトランザクションのID。 ターゲットがトランザクションIDでない場合、値は空です。

クラシッド

oid

ロックターゲットを含むシステムカタログのOID。 ターゲットが一般的なデータベースオブジェクトでない場合、値は空です。

objid

oid

システムカタログ内のロックターゲットのOID。 ターゲットが一般的なデータベースオブジェクトでない場合、値は空です。

objsubid

int2

ロックの対象となる列番号 (classidobjidはテーブル自体を参照します) 。 ターゲットが他の通常のデータベースオブジェクトである場合、値は0です。 ターゲットが通常のデータベースオブジェクトでない場合、このオブジェクトは空です。

virtualtransaction

text

ロックを保持している、またはロックを待っているトランザクションの仮想ID。

ピッド

int4

ロックを保持または待機しているサーバープロセスのPID。 この値は、ロックが準備済みトランザクションによって保持されている場合は空です。

モード

text

このプロセスで保持または必要なロックモードの名前

付与された

bool

ロックが保持されている場合、値はtrueです。 ロックが待機している場合、値はfalseです。

fastpath

bool

高速パスを介してロックが取得された場合、値はtrueです。 ロックがメインロックテーブルを介して取得された場合、値はfalseです。

行の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つずつ収集されます。 その結果、情報が収集されている間にロックを解除することが可能である。 ただし、これらのロックは、現在配置されている他のロックと競合しません。 すべてのバックエンドが高速パスロックについて照会された後、通常のロックマネージャの残りの部分はユニットとしてロックされ、残りのすべてのロックの一貫したスナップショットがアトミックアクションとして収集されます。 通常のロックマネージャをアンロックした後、述語ロックマネージャは同様にロックされ、すべての述語ロックがアトミックなアクションとして収集されます。 したがって、高速経路ロックを除いて、各ロックマネージャは、一貫した結果のセットを提供する。しかし、両方のロックマネージャを同時にロックしないので、通常のロックマネージャに問い合わせた後、述語ロックマネージャに問い合わせた後に、ロックを取得または解放することが可能である。

このビューが非常に頻繁にアクセスされる場合、通常のロック管理または述語ロックマネージャ、またはその両方をロックすると、データベースのパフォーマンスに影響を与える可能性があります。 ロックは、ロックマネージャからデータを取得するのに必要な最小限の時間だけ保持されますが、これはパフォーマンスへの影響の可能性を完全に排除するものではありません。