[pgcluster: 444] SELECT FOR UPDATE のデッドロックについて
Yusuke Ito
y-110 @ yumemi.co.jp
2004年 8月 4日 (水) 16:42:23 JST
お世話になります。
伊藤と申します。
pg_cluster1.0.7を利用しておりますが、select for update のロックの挙動について
気になる点がありましたので、投稿させていただきます。
# [pgcluster:439] と関連する内容と判断し、レスをつける形で投稿しました
[pgcluster:236] [pgcluster:439] と類似の報告となるかと思いますが、
select for update を含むトランザクションにて、デッドロックを発生させる
クエリを発行した際に、psql からの応答がなくなるという現象が発生しております。
【サーバ構成】
レプリケーションサーバ(R1,R2) 2台
クラスタサーバ (C1,C2,C3) 3台
PGCluster 1.0.7v10
レプリケーションサーバのスレーブが FreeBSD 5.2.1-RELEASE-p9,
その他4台のサーバが Debian GNU 3.0 の構成。
ロードバランサは使用しておらず、プログラムでランダムにC1〜C3に接続するようになっています。
接続は PHP の pconnect 関数を使用して接続。
【前提】
create table a(int id) を実行し、1〜10 までを insert しておく。
また、他のテーブルにランダムに SELECT を発行するようなプログラムを起動しておく。
【手順】
1. C1 に接続し、以下の select for update を実行。
test=> begin;
test=> select id from a where id = 8 for update;
id
----
8
(1 row)
2. C2 に接続し、以下の select for update を実行
test=> begin;
test=> select id from a where id = 7 for update;
id
----
7
(1 row)
3. デッドロックが起こるように、それぞれ相手のリソースを select for update.
C1 test=> select id from a where id = 7 for update;
C2 test=> select id from a where id = 8 for update;
ここでデッドロックが発生し、両方のターミナルからの応答がなくなる。
4. しばらく待つと C2 の入力がアクティブになる。C1は応答がないまま。
このタイミングで C1 の postmaster のログには以下のログがひたすら流れ続ける。
2004-08-03 20:59:02 [31505] LOG: pq_recvbuf: unexpected EOF on client connection
2004-08-03 20:59:02 [31505] LOG: pq_recvbuf: unexpected EOF on client connection
2004-08-03 20:59:02 [31505] LOG: pq_recvbuf: unexpected EOF on client connection
入力が戻った C2 で再度、以下の select for update を実行するとやはり応答が帰ってこないままだった。
C2=> select id from a where id = 8 for update;
【結果】
一度、この現象が発生すると、自動スクリプトが走っている間に pg_locks テーブルの要素が
どんどん増えていき、最終的にシステムが不安定になり、C1〜C3 に全くアクセスができなくなる。
pg_stat_activity.current_query には、BEGIN, ROLLBACK, idle, idle in transaction が大量にある。
# BEGIN と ROLLBACK は pconnect によるものでしょうか...
何度か同様の実験を試みたが、この状態から回復するには、C1〜C3, R1, R2 を止めて、再起動するしかなかった。
レプリケーションサーバ1台の構成(全てDebian 3.0構成)でも試してみましたが、結果は同様でした。
今回は、select for update で意図的にデッドロックを発生させましたが、
一度、select for update でデッドロックが発生すると、応答がない状況になってしまうのでしょうか?
尚、C1〜C3 の deadlock_timeout の設定はデフォルト(1000ms) のままになっております。
# 同様の実験をスタンドアロンの Postgres で行いましたが、即座にデッドロックが検出されました。
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
Yusuke Ito <y-110 @ yumemi.co.jp>
Work Phone: 090-4708-2445
Yumemi, Inc
________________________________i___
| | | | | | | _| | | _ |
|_ _| | | _| ||_||
|___| |___|_|___|_|___|_|___|_|:::|
|:::|
|___|
pgcluster メーリングリストの案内