[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 メーリングリストの案内