[pgsql-jp: 33993] Re: pgpool でデッドロック?
Tatsuo Ishii
t-ishii @ sra.co.jp
2004年 9月 16日 (木) 23:50:37 JST
石井です.
> ・・そうですか。データのばらつきなどにも関係があるのかも
> 知れません。現状参照される側マスタのデータは3レコードで
> 、
> 登録・更新等はされず、トランザクションのインサート時には
> その3レコードのうちのどれかをランダムに選択するような仕
> 掛けにしています。
それでは言うとので,10レコードの中からランダムに参照キーが変わるように,
alter table history add constraint tellerref foreign key(tid)
references tellers;
と外部キーを追加してみたのですが,やっぱり再現しません.単純に外部キー
を付けただけでは駄目で,何かほかに条件があるようですね.
> とりあえずこちらの環境では、該当トランザクションテーブル
> の
> 外部参照キーをはずした状態では正常に動作することは確認し
> ましました。
>
>
> > 再現性のある人工的なテストデータを提供いただけませんで
> しょうか?
>
> す、すみません。何をどのような形でご提供すればよいのか、
> よくわかりません。
> pgpoolとDBの環境だけでこの現象を再現させる場合にどのよう
> な手段でテストすればよいのか、という点が不明です。
> もし具体的にお教えいただければ、こちらでその方法で再現す
> ることを確認した上でデータをご提供できると思います。
つまり現象を再現するための,公開可能なデータとプログラムのセットが欲し
いのです.Javaをお使いのようなので,たとえば
o スレッドを使って同時接続を再現するようなプログラム(できればServlet
などではなく単独のJavaアプリケーション)
o pg_dumpによるデータベースのダンプ
などがあればよろしいかと思います.
> ・・JDBCのコネクションプールを使って接続している点とかも
> なにか関係があるのでしょうか?
それは何とも言えません.ただ,問題の原因を絞り込むためには,JDBCのコネ
クションプールを使ったときと使わないときで違いが出るかどうか確認してみ
る必要はあると思います.同じように,トリガを外して様子を見る手もあると
思います.
ちなみに,以下の(3)は同一セッション内では最初の1回目しか表示されません.
pgpoolやJDBCでコネクションプールしていると,そうなる確率は高くなるはず
です.ログを解析するときの参考までに.
> トランザクションがうまくいった場合は以下のような流れで
> SQLが実行されます。実際アプリで発行しているSQLは(1)と(4)で
> (2)以下4行はトリガーの実行(3)は、外部参照によるother_table
> へのセレクト(FOR UPDATE)が内部的に発生しているのだと思
> います。
>
> (1) LOG: statement: INSERT INTO TABLE_A
> (id,other_table_id,data,create_date) VALUES
> (123,5,'aaaaaaaaaaaaaaaaaaaaa','2004-09-14 17:46:43.735');
> (2) LOG: statement: SELECT $1 = 'INSERT'
> CONTEXT: PL/pgSQL function "table_a_func" line 3 at if
> LOG: statement: SELECT 0
> CONTEXT: PL/pgSQL function "table_a_func" line 4 at
> assignment
> (3) LOG: statement: SELECT 1 FROM ONLY
> "public"."other_table" x WHERE "pk_other_table" = $1 FOR
> UPDATE OF x
> LOG: duration: 56.185 ms
> (4) LOG: statement: SELECT * FROM TABLE_A WHERE id=123
> LOG: duration: 3.156 ms
> LOG: statement: commit;begin;
> LOG: duration: 7.497 ms
> LOG: statement: rollback; begin;
>
--
Tatsuo Ishii
pgsql-jp メーリングリストの案内