★PostgreSQLカンファレンス2024 12月6日開催/チケット販売中★
他のバージョンの文書 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9.6 | 9.5 | 9.4 | 9.3 | 9.2 | 9.1 | 9.0 | 8.4 | 8.3 | 8.2 | 8.1 | 8.0 | 7.4 | 7.3 | 7.2

44.46. pg_locks

pg_locksビューはデータベースサーバ内で開かれているトランザクションのロックに関する情報へのアクセスを提供します。ロックに関するより詳細な説明は第13章を参照してください。

pg_locksにはロック対象となる進行中のオブジェクト、要求されたロックモード、および関連するトランザクションごとに1つの行を所有しています。ですから、もし複数のトランザクションがそのトランザクション上でロックを保持していたりロックを待機している場合には、同じロック対象オブジェクトが数多く出現することがあります。

ロック対象オブジェクトには異なる型がいくつか存在します。 全体のリレーション(例:テーブル)、リレーションの個別のページ、リレーションの個別の列、トランザクションID(仮想と永続の両方のID)、それから 一般的なデータベースオブジェクト(これはpg_descriptionpg_dependと同様にクラスOIDとオブジェクトOIDで識別されます) さらに、リレーションを拡張する権利は、分離したロック対象オブジェクトにより表現されます。

表 44-46. pg_locksの列

名前参照先説明
locktypetext  ロック対象オブジェクトの種類。 relationextendpagetupletransactionidvirtualxid, objectuserlockadvisory
databaseoidpg_database.oid オブジェクトが存在しているデータベースのOID、もしくはオブジェクトが共有されたオブジェクトの場合はゼロ、もしくはオブジェクトがトランザクションIDである場合はNULLとなります。
relationoidpg_class.oid リレーションのOID、もしくはオブジェクトがリレーションではない場合かリレーションの一部である場合はNULLとなります。
pageinteger  リレーション内のページ数、もしくはオブジェクトが列もしくはリレーションではない場合はNULLとなります。
tuplesmallint  ページ内の列数、もしくはオブジェクトが列ではない場合はNULLとなります。
virtualxidtext  トランザクションの仮想ID。オブジェクトが仮想トランザクションIDではない場合はNULL
transactionidxid  トランザクションのID、もしくはオブジェクトがトランザクションIDではない場合はNULLとなります。
classidoidpg_class.oid オブジェクトを含んだシステムカタログのOID、もしくはオブジェクトが一般的なデータベースオブジェクトではない場合はNULLとなります。
objidoidany OID column システムカタログ内のオブジェクトのOID、もしくはオブジェクトが一般的なデータベースオブジェクトでない場合はNULLとなります。
objsubidsmallint  テーブルの列に対しては、これは列数(classidobjidはテーブル自身を参照しています)です。 他の全てのオブジェクトの型に対しては、この列はゼロになります。オブジェクトが一般的なデータベースオブジェクトではない場合はNULLとなります。
virtualtransactionxid  ロックを保持、もしくは待っている仮想トランザクションのID
pidinteger  ロックを保持、もしくは待っているサーバプロセスのプロセスID。ロックが準備されているトランザクションにより保持されている場合はNULLとなります。
modetext Name of the lock mode held or desired by this process (see 項13.3.1)
grantedboolean ロックが保持されている場合は真、ロックが待ち状態の場合は偽

指定されたトランザクションにより所有されているロックを表す行内でgrantedは真です。偽の場合はこのロックを取得するため現在トランザクションが待機中であることを示しています。つまり、同じロック対象のオブジェクトに対して何らかの他のトランザクションが競合するロックを取得していることを意味します。待機中のトランザクションはその別のトランザクションがロックを解放するまで活動を控えます(もしくはデッドロック状態が検出されることになります)。単一トランザクションでは一度に多くても1つのロックを取得するために待機します。

全てのトランザクションはその全ての過程完了までその仮想トランザクションID上に排他的ロックをかけます。もしある永続IDがトランザクションに割り当てられる(普通はトランザクションがデータベースの状態を変化させるときのみに発生します)と、トランザクションは終了するまで永続トランザクションIDに対して排他ロックを保持します。あるトランザクションが他のトランザクションを特定して待機しなければならないと判断した場合、他とみなしたトランザクションのIDに対し共有ロックを取得するように試み、目的を達します。(仮想IDであるか永続IDであるかは、その状況によります)これは、他とみなしたトランザクションが完了し、そしてロックを解放した場合のみ成功します。

列がオブジェクトのロック可能な型であっても、行レベルロックについての情報はメモリではなく、ディスクに保存されます。よって行レベルロックは通常、このビューには現れません。もしトランザクションが行レベルロックの待ち状態である場合は、その行ロックを保持している永続トランザクションIDを待つ状態で、そのトランザクションはビューに現れます。

勧告的ロックは、単一のbigint値、または、2つの整数値をキーとして獲得することができます。 bigintの場合は、その上位半分がclassid列内に表示され、残りの下位半分はobjid列内に表示されます。また、objsubidは1となります。 整数値キーでは、最初のキーがclassid列に、2番目のキーがobjid列に表示され、objsubidは2となります。 キーの実際の意味はユーザに負かされています。 勧告的ロックはデータベースに対して局所的ですので、勧告的ロックではdatabase列が意味を持ちます。

pg_locksビューにアクセスがかかると内部ロック管理データ構造は一時的にロックされ、複製がビューとして表示用に作成されます。 このことにより通常のロック管理操作を必要以上に妨げないで、ビューは矛盾を含まない結果一式の生成が保証されます。 それにもかかわらずこのビューが頻繁にアクセスされるとするとデータベースのパフォーマンスに何らかの影響を及ぼすでしょう。

pg_locksは現行のデータベースに関連するロックのみならず、データベースクラスタ内の全てのロックの全体のビューを提供します。そのrelation列がpg_class.oidに対しロックされたリレーションであることを表明するために結合可能であっても、現行のデータベース内のリレーション(それに対するdatabase列が現行のデータベースのOIDもしくはゼロ)についてのみ正しく働きます。

ロック保持もしくは保持を待機しているセッションのさらなる情報を入手するためpg_stat_activityビューのprocpid列とpid列は結合できます。また、準備されたトランザクションを使用している場合には、transactionpg_prepared_xactsビューのtransaction列と結合でき、ロックを保持している準備されたトランザクションに関して、より多い情報を取得できます。(準備されたトランザクションはロックを待つことはありませんが、実行時に取得したロックを保持し続けます。)