[pgsql-jp: 29288] Re: Lockの状況確認の方法
Tatsuro Ishikawa
ishikawa-t @ comtecc.net
2003年 3月 6日 (木) 13:33:25 JST
石川です
杉田さん
返信が遅れて申し訳ありません
On Sat, 01 Mar 2003 10:31:09 +0900 (JST)
sugita @ sra.co.jp wrote:
>
> ロックされているテーブルについては、次のテーブルがあるとすると、
>
> =# \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 も同じならば、
> このバックエンドがロック状態とほぼ確定できます。
>
大変ありがとうございます。
今現在、確認は取れませんが問題発生時に使用させていただきます
pgsql-jp メーリングリストの案内