[pgcluster: 1046] クラスタDBのロック解除に関する異常について
吉泉 昭
izu @ pgc.sakuraweb.com
2011年 2月 3日 (木) 19:34:09 JST
はじめまして、泉と申します。
Linuxサーバでpgclusterを使用させていただいております。
Tomcatからjdbc経由でクラスタDBに接続してUPDATE処理を行っていたのですが、
途中でロック解除待ち状態となり停止してしまい、
原因調査の段階で手詰まりとなったため、質問をさせていただきたく思い、
投稿致しました。
クラスタDBサーバを確認したところ、
以下のように対象のDBとの接続プロセスでPARSE waitingが発生しておりました。
ps x
zzzzz ? Ss hh:mm postgres: postgres xxx_db 192.168.xx.x(xxxxx)
PARSE waiting
xxxxx ? Ss hh:mm postgres: postgres xxx_db 192.168.xx.x(xxxxx)
PARSE waiting
xxxxx ? Ss hh:mm postgres: postgres xxx_db 192.168.xx.x(xxxxx)
PARSE waiting
……
問題となっているDBに接続し、実行中のクエリを確認したところ、以下のデータ
が返されました。
【実行中のクエリ確認】
SELECT
procpid,
start,
now() - start AS lap
FROM
(
SELECT
backendid,
pg_stat_get_backend_pid(S.backendid) AS procpid,
pg_stat_get_backend_activity_start(S.backendid) AS start,
pg_stat_get_backend_activity(S.backendid) AS current_query
FROM
(
SELECT pg_stat_get_backend_idset() AS backendid
) AS S
) AS S
WHERE
current_query <> '<IDLE>' ORDER BY lap DESC;
【出力結果】
procpid | start | lap
---------+-------------------------------+-------------------------
zzzzz | 2011-01-11 18:38:07.857211+09 | 20 days 15:13:51.193143
上記プロセス内で実行しているクエリは2月1日に実行されているのですが
(Tomcat側のログで確認)、
クエリの開始時刻は20日以上前となっていました。
また、ロック解除待ちで最初に停止したのもこちらのプロセスとなります。
【ロック状態確認】
select locktype, database, relation, virtualxid, virtualtransaction,
pid, mode, granted from pg_locks;(抜粋)
locktype | database | relation | virtualxid | virtualtransaction |
pid | mode | granted
------------+----------+----------+------------+--------------------+-------+-----------------------+---------
relation | 16420 | 20328 | | 195/14 |
xxxxx | ShareRowExclusiveLock | f
virtualxid | | | 200/14 | 195/14 |
xxxxx | ExclusiveLock | t
relation | 16420 | 20328 | | 200/14 |
xxxxx | ShareRowExclusiveLock | f
virtualxid | | | 200/14 | 200/14 |
xxxxx | ExclusiveLock | t
relation | 16420 | 20328 | | 49/736846 |
zzzzz | ShareRowExclusiveLock | t
virtualxid | | | 49/736846 | 49/736846 |
zzzzz | ExclusiveLock | t
※他のプロセスはzzzzzプロセスが終了しないため、ロック解除待ちとなっている
状態でした。
※ここで取り上げていないカラムはすべて空となっておりました。
取り急ぎ上記zzzzzプロセスを終了させることで『ロック解除待ち』の状態から
は脱しましたが、
なぜ『ロック解除待ち』の状態になってしまったのかの調査で手詰まりとなって
おります。
まず、zzzzzプロセス終了前にデッドロックの可能性を考え調査しましたが、
zzzzzプロセスとの組み合わせでデッドロックを起こし得るトランザクションは
見つかりませんでした。
事後調査を行ったところ、問題のzzzzzプロセスとは別のプロセスで妙なものが
見つかりました。
select datid, datname, procpid, usename, current_query, waiting,
query_start, backend_start from pg_stat_activity where waiting='t';(抜粋)
datid | datname | procpid | usename | current_query | waiting |
query_start | backend_start
-------+---------+---------+----------+---------------+---------+-------------------------------+-------------------------------
16420 | xxx_db | xxxxx | postgres | <IDLE> | t |
2011-01-11 18:38:08.399642+09 | 2011-01-11 18:38:05.557201+09
IDLE状態かつロック解除待ち(waiting=true)となっているため、こういったプロ
セスがTomcatとの通信で再度割り当てられた場合、
『ロック解除待ち』の状態になってしまうのではないかと見ております。
(現在稼働中の環境のため、この推測を裏付けるための確認試験はできておりま
せんが……)
なお、こういったプロセスが実際にできるのかテスト環境で再現を試みました
が、いずれも失敗に終わっております。
ここで質問させていただきたいのですが、
・pgclusterの処理によって、TomcatとクラスタDBの通信プロセスがIDLEかつ
ロック解除待ちの状態になる可能性はありますでしょうか?
(トランザクション処理が特定の条件で終了することでプロセスがIDLE&ロック
解除待ちになってしまう、等)
環境は以下の通りになります。
【使用バージョン】
Pgcluster 1.9.0rc5
【構成】
マシンA:クラスタDB1(稼働中)、レプリケーションサーバ(別の障害により状態)
マシンB:クラスタDB2(停止)
※元々アプリケーション(Tomcat)からの通信はクラスタDB1で行っており、
クラスタDB2は予備機として稼働しておりました。
ただ、昨年レプリケーションサーバに問題が起きたため、
現在は実質クラスタDB1のみが動いている状態です。
OS CentOS4.4
kernel 2.6.9-42
なお、Tomcat側のモジュールでコネクションをクローズし損ねていないかチェッ
クを行いましたが、
モジュール内での『クローズ漏れ』はありませんでした。
また、ロック解除待ちが発生した時刻(2月1日)、問題のプロセスが発生した時刻
(1月11日)共に、
エラーログは出力されておらず、Tomcatが正常に稼働し続けていたことを確認し
ております。
お手数おかけしますが、ご回答いただければと思います。
pgcluster メーリングリストの案内