[pgsql-jp: 33986] Re: pgpool でデッドロック?
Mana Takebe
takebemana @ yahoo.co.jp
2004年 9月 15日 (水) 11:08:16 JST
武部です。申し訳ありません、基本的な情報を記述していませ
んでした。
PostgreSQLのバージョンは7.4.5
pgpoolのバージョンは2.0.9
pgpoolの設定ファイルの中身
→最後に添付します。
さて、実行していうSQLですが、PostgreのLOGベースで
以下にご説明します。
(すべてそのままを公開することはできないので、加工してい
ます)
まず、前提としてINSERT対象のテーブルには以下の特徴があり
ます。
・INSERT対象のTABLE_AにはINSERT,UPDATEのトリガーがついて
います。内容は行のあるフィールドをインクリメントするもの
です。
・TABLE_Aのother_table_idフィールドには外部参照キーが
張られており、other_tableのpk_other_tableを参照していま
す。
トランザクションがうまくいった場合は以下のような流れで
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;
ロックが発生しているプロセスでは(1)の行までしか実行ログが
図れません。idleしているプロセスでは(1)の後に「LOG:
duration: 3.156 ms
」が出力されます。
外部参照のロックのあたりでなにか問題が発生しているような
気がします。
再現性は、こちらの環境ではアプリのほうの同時接続数が5を
越えると100%です。
以下にpgpoolの設定ファイルの内容を添付します。
# pgpool configuration file sample
# $Header:
/home/t-ishii/repository/pgpool/pgpool.conf.sample,v 1.10
2004/07/09 05:51:13 t-ishii Exp $
# if 1, connection using INET domain socket is allowed
allow_inet_domain_socket = true
# port number for pgpool
port = 5432
# Unix domain socket path. Debian package default to
/var/run/postgresql!
socket_dir = '/tmp'
# host name where PostgreSQL server is running on. ''
means localhost using UNIX
# domain socket
#backend_host_name = ''
backend_host_name = '192.168.1.108'
# port number PostgreSQL server is running on.
backend_port = 5433
# Unix domain socket path for the backend. Debian package
default to /var/run/postgresql!
backend_socket_dir = '/tmp'
# host name where secondary PostgreSQL server is running
on. '' means localhost using UNIX
# domain socket
secondary_backend_host_name = '192.168.1.109'
# port number secondary PostgreSQL server is running on.
# 0 means no secondrary PostgreSQL
secondary_backend_port = 5432
# number of pre-forked child process
#num_init_children = 32
num_init_children = 4
# numer of connection pool allowed for a child process.
#max_pool = 4
max_pool = 1
# if idle for this seconds, child exits. 0 means no
timeout. this
# featue is not implemented yet.
child_life_time = 0
# if idle for this seconds, connection to PostgreSQL
closes. 0 means
# no timeout
connection_life_time = 0
# logging directory
logdir = '/tmp'
# replication mode
replication_mode = true
# set this to true if you want to avoid deadlock situation
when
# replication enabled.
# there will be noticable performance degration, however.
# a work around is set this to false and insert /*STRICT*/
comment
# at the beginning of the SQL command.
replication_strict = true
# when replication_strict is set to true, there will be a
chance for
# deadlocks. set this to non 0 (in milli seconds) to
detect this
# situation and resolve the deadlock aborting current
session.
#replication_timeout = 5000
replication_timeout = 10000
# load balancing mode. i.e. all SELECT except in a
transaction block
# are load balanced. This is useless if replication_mode
is false.
load_balance_mode = false
# if there's a data mismatch between master and secondary
# start degenration to stop replication mode
replication_stop_on_mismatch = false
================================
takebemana @ yahoo.co.jp
--- Tatsuo Ishii <t-ishii @ sra.co.jp> からのメッセージ:
> 石井です.
>
> 実行したSQL文
> PostgreSQLのバージョン
> pgpoolのバージョン
> pgpoolの設定ファイルの中身
>
> がわかって,かつ再現性があれば何か分かるかも知れません
.
>
> こちらでpgbenchでテストした程度では再現しないようなの
で...
> --
> Tatsuo Ishii
>
> > 武部と申します。
> >
> >
> Tomcat+PostgreSQLでアプリケーションを構築しており、
> >
> 主にレプリケートの目的で、pgpoolを利用しようと考えてい
ま
> > すが、
> > アプリケーションの負荷試験を行ったところ、
> >
> pgpoolでレプリケートしていると、デッドロックのような
> > 現象が発生し、更新処理が止まってしまいます。
> > (replication_strictはtrueに設定しています。)
> >
> > ロック状態を確認したところ以下のようになっており、
> > slave側ではp2の方がSQLの実行としては後
> > (postgreのlog_statement
> > の出力から)
> > なのですがトランザクションID
> 5417630ロックを先に取得して
> > しまって
> > いるように見えます。
> >
> (p1,p2というのは同じSQLを実行するmasterとslaveのペアに
同
> > じ名前をつけています。)
> >
> > master側---------------------------------
> > p1(psで見るとidle in tranzaction状態)
> > | | 5417667 |
> 25384 |
> > ExclusiveLock | t
> > other_table | db1 | |
> 25384 |
> > AccessShareLock | t
> > other_table | db1 | |
> 25384 |
> > RowShareLock | t
> > TABLE_A | db1 | |
> 25384 |
> > AccessShareLock | t
> > TABLE_A | db1 | |
> 25384 |
> > RowExclusiveLock | t
> >
> >
> > p2 (psで見るとINSERT waiting状態)
> > pk_other_table | db1 | |
> 25382 |
> > AccessShareLock | t
> > TABLE_A | db1 | |
> 25382 |
> > AccessShareLock | t
> > TABLE_A | db1 | |
> 25382 |
> > RowExclusiveLock | t
> > | | 5417667 |
> 25382 |
> > ShareLock | f
> > | | 5417693 |
> 25382 |
> > ExclusiveLock | t
> > other_table | db1 | |
> 25382 |
> > AccessShareLock | t
> > other_table | db1 | |
> 25382 |
> > RowShareLock | t
> >
> >
> > slave側---------------------------------
> > p1 (psで見るとINSERT waiting 状態)
> > pk_other_table | db1 | |
> 3389 |
> > AccessShareLock | t
> > other_table | db1 | |
> 3389 |
> > AccessShareLock | t
> > other_table | db1 | |
> 3389 |
> > RowShareLock | t
> > | | 5417630 |
> 3389 |
> > ShareLock | f
> > TABLE_A | db1 | |
> 3389 |
> > AccessShareLock | t
> > TABLE_A | db1 | |
> 3389 |
> > RowExclusiveLock | t
> > | | 5417605 |
> 3389 |
> > ExclusiveLock | t
> >
> > p2 idle (psで見るとidle in tranzaciton状態)
> > other_table | db1 | |
> 3387 |
> > AccessShareLock | t
> > other_table | db1 | |
> 3387 |
> > RowShareLock | t
> > TABLE_A | db1 | |
> 3387 |
> > AccessShareLock | t
> > TABLE_A | db1 | |
> 3387 |
> > RowExclusiveLock | t
> > | | 5417630 |
> 3387 |
> > ExclusiveLock | t
> >
> >
> > 現状、replication_strictがtrueですが、
> > master側のSQLがロック待ちになっている状態でも
> >
> salve側にSQLが実行されているという状況に見えるのですが
、
> > これは正しい状態なのでしょうか?
> > 設定がうまくいっていないのでしょうか?
> >
> > なにかアドバイスをいただければ幸いです。
__________________________________
Do You Yahoo!?
http://bb.yahoo.co.jp/
pgsql-jp メーリングリストの案内