[pgsql-jp: 29248] Re: Lockの状況確認の方法
sugita @ sra.co.jp
sugita @ sra.co.jp
2003年 3月 1日 (土) 10:31:09 JST
杉田です。
From: Tatsuro Ishikawa <ishikawa-t @ comtecc.net>
Subject: [pgsql-jp: 29242] Lockの状況確認の方法
Date: Thu, 27 Feb 2003 17:29:47 +0900
;;; 石川と申します
;;;
;;; 現在 以下の環境でPostgreSQLを使用して開発を行っています
;;;
;;; OS:RedHat Linux 8.0
;;; PosthreSQL: 7.3.2
;;;
;;; そこで、テーブル及びレコードのロック状況を確認する方法を教えていただけな
;;; いでしょうか?
;;; 確認したい項目は、
;;;
;;; ・ロックされているテーブル
;;; ・ロックしたSQL文
;;;
;;; ログにSQLを出力し、pg_locks のPIDで検索を行ってみましたが、解りませんで
;;; した。
ロックされているテーブルについては、次のテーブルがあるとすると、
=# \d
List of relations
Schema | Name | Type | Owner
--------+--------+-------+--------
sugita | class1 | table | sugita
(1 row)
=#
このテーブルをロックし、pg_locks を見ると、
=# select * from pg_locks;
relation | database | transaction | pid | mode | granted
----------+----------+-------------+------+---------------------+---------
| | 3646 | 1060 | ExclusiveLock | t
20036 | 16976 | | 1060 | AccessExclusiveLock | t
16757 | 16976 | | 1032 | AccessShareLock | t
| | 3647 | 1032 | ExclusiveLock | t
(4 rows)
となるので、pg_database と pg_class を調べるとどのデータベースのどのテーブルが
ロックされているか分かります。
=# select oid, datname from pg_database where oid in (16976);
oid | datname
-------+---------
16976 | sugita
(1 row)
=# select oid, relname from pg_class where oid in (20036, 16757);
oid | relname
-------+----------
16757 | pg_locks
20036 | class1
(2 rows)
=#
以上をまとめて、次のようにもできます。
=# select (select relname from pg_class c where c.oid = l.relation) as relation,
(select distinct datname from pg_database d where d.oid = l.database) as database,
l.transaction,
l.pid,
l.mode,
l.granted
from pg_locks l;
relation | database | transaction | pid | mode | granted
-------------+----------+-------------+------+-----------------+---------
| | 3672 | 1078 | ExclusiveLock | t
pg_database | | | 1078 | AccessShareLock | t
pg_class | sugita | | 1078 | AccessShareLock | t
class1 | sugita | | 1060 | AccessShareLock | t
class1 | sugita | | 1060 | RowShareLock | t
| | 3652 | 1060 | ExclusiveLock | t
pg_locks | sugita | | 1078 | AccessShareLock | t
(7 rows)
=#
ロックした SQL 文を得ることはできません。ロックしたということは、その SQL 文
の実行は終えてしまっているからです。逆に、ロックされているクエリーは、
stats_command_string を true に設定してあると次のようにして分かります。
=# select * from pg_stat_activity ;
datid | datname | procpid | usesysid | usename | current_query
-------+---------+---------+----------+---------+------------------------------------------------
16976 | sugita | 1141 | 1 | sugita | <IDLE> in transaction
16976 | sugita | 1143 | 1 | sugita | select * from class1 where id = 10 for update;
16976 | sugita | 1145 | 1 | sugita | <IDLE>
(3 rows)
これより pid が 1143 のバックエンドがロック状態らしいと分かります。
=# select (select relname from pg_class c where c.oid = l.relation) as relation,
(select distinct datname from pg_database d where d.oid = l.database) as database,
l.transaction,
l.pid,
l.mode,
l.granted
from pg_locks l;
relation | database | transaction | pid | mode | granted
-------------+----------+-------------+------+-----------------+---------
pg_locks | sugita | | 1147 | AccessShareLock | t
pg_database | | | 1147 | AccessShareLock | t
class1 | sugita | | 1141 | AccessShareLock | t
class1 | sugita | | 1141 | RowShareLock | t
| | 3687 | 1143 | ShareLock | f
| | 3691 | 1143 | ExclusiveLock | t
| | 3700 | 1147 | ExclusiveLock | t
class1 | sugita | | 1143 | AccessShareLock | t
class1 | sugita | | 1143 | RowShareLock | t
pg_class | sugita | | 1147 | AccessShareLock | t
| | 3687 | 1141 | ExclusiveLock | t
(11 rows)
=#
上の結果より、pid 1143 で granted が f のロックがあるので、pg_stat_activity で
の select ... for update が長い間表示されていて、transaction も同じならば、
このバックエンドがロック状態とほぼ確定できます。
Kenji Sugita
pgsql-jp メーリングリストの案内