[pgpool-general-jp: 1049] COMMITでエラー

稲村暢亮 inamuran36 @ mahikari.or.jp
2012年 4月 30日 (月) 13:48:48 JST


稲村と申します。お世話になっております。

以下の環境で2台のサーバで利用しています。
pgpool-II 3.1.3
postgresql9.1.3
debian6.0(64bit)
クライアントからはNpgsqlで.NETアプリから接続しています。

PostgreSQLのストリーミングレプリケーションを使用し、pgpoolでは負荷分散とコネクションプールだけを利用しています。
Pgpoolはマスタースレーブモードでstreamの設定で稼働しています。
(文末にpgpool.confの抜粋を記載)

Npgsqlにてトランザクション処理を実行しようと、Npgsqlのトランザクションメソットでトランザクションを実行し、INSERTを発行、メソットでコミットを実行すると、
コミットでエラーになり、アプリケーション側にも「オブジェクトに対するインスタンスがない」という旨のメッセージが返ってきます。

ログをみてみると
2012-04-30 12:04:05 LOG:   pid 19873: DB node id: 0 backend pid: 19884
statement: BEGIN
2012-04-30 12:04:05 LOG:   pid 19873: DB node id: 1 backend pid: 10979
statement: BEGIN
2012-04-30 12:04:05 LOG:   pid 19873: DB node id: 0 backend pid: 19884
statement: SET ssl_renegotiation_limit=0
2012-04-30 12:04:05 LOG:   pid 19873: DB node id: 1 backend pid: 10979
statement: SET ssl_renegotiation_limit=0
2012-04-30 12:04:05 LOG:   pid 19873: DB node id: 1 backend pid: 10979
statement: COMMIT
2012-04-30 12:04:05 LOG:   pid 19873: DB node id: 0 backend pid: 19884
statement: COMMIT
2012-04-30 12:04:05 LOG:   pid 19873: DB node id: 0 backend pid: 19884
statement: BEGIN
2012-04-30 12:04:05 LOG:   pid 19873: DB node id: 1 backend pid: 10979
statement: BEGIN
2012-04-30 12:04:05 LOG:   pid 19873: DB node id: 0 backend pid: 19884
statement: set search_path to table1
2012-04-30 12:04:05 LOG:   pid 19873: DB node id: 1 backend pid: 10979
statement: set search_path to table1
2012-04-30 12:04:05 LOG:   pid 19873: DB node id: 1 backend pid: 10979
statement: COMMIT
2012-04-30 12:04:05 LOG:   pid 19873: DB node id: 0 backend pid: 19884
statement: COMMIT
2012-04-30 12:04:05 LOG:   pid 19873: DB node id: 0 backend pid: 19884
statement: BEGIN; SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
2012-04-30 12:04:05 LOG:   pid 19873: DB node id: 0 backend pid: 19884
statement: INSERT INTO table1(SQL文略)
2012-04-30 12:04:05 LOG:   pid 19873: DB node id: 0 backend pid: 19884
statement: INSERT INTO table1(SQL文略)
2012-04-30 12:04:05 LOG:   pid 19873: DB node id: 1 backend pid: 10979
statement: COMMIT
2012-04-30 12:04:05 LOG:   pid 19873: pool_send_and_wait: Error or
notice message from backend: : DB node id: 1 backend pid: 10979
statement: COMMIT message: there is no transaction in progress
2012-04-30 12:04:05 LOG:   pid 19873: DB node id: 0 backend pid: 19884
statement: COMMIT
2012-04-30 12:04:05 ERROR: pid 19873: read_kind_from_backend: 1 th
kind N does not match with master or majority connection kind C
2012-04-30 12:04:05 ERROR: pid 19873: kind mismatch among backends.
Possible last query was: "COMMIT" kind details are: 0[C] 1[N: there is
no transaction in progress]
2012-04-30 12:04:05 LOG:   pid 19873: do_child: exits with status 1 due to error

ということで、NpgSQL使ったトランザクションはnode0のみに発行されているにも関わらず、
コミットに関しては参照専用であるnode1にも発行されており、それがエラーになっているようです。
COMMITがセカンダリにも発行されているということか、それともBEGINがプライマリにしか発行されていないということなのか・・・。
(それ以外にもBEGINとCOMMITが発行されているようで、プログラムの流れからこれらはおそらくSELECTの発行により実行されているものだと思いますが、
正しい動作なのでしょうか。)

で、具合が悪いのは、プライマリではCOMMITが有効になるようで、エラーが返ってきてもデータは更新されているという状態です。
(データベースのレプリケーションは正常に行われているようで、データの不整合は起きていません。)

設定がよくないのでしょうか・・・。どのように対応すればよいか困っております。
お知恵を拝借できればと思っております。

よろしくお願いいたします。


(以下pgpool.confの一部抜粋)
------------------------------------------------
listen_addresses = '*'
port = 5432

# - Backend Connection Settings -
backend_hostname0 = '192.168.0.198'
backend_port0 = 5433
backend_weight0 = 1
#backend_data_directory0 = '/data'
backend_flag0 = 'ALLOW_TO_FAILOVER'
backend_hostname1 = '192.168.0.197'
backend_port1 = 5433
backend_weight1 = 3
#backend_data_directory1 = '/data1'
backend_flag1 = 'ALLOW_TO_FAILOVER'

# - Authentication -
enable_pool_hba = on
authentication_timeout = 60

# - SSL Connections -
ssl = off

# - Pool size -
num_init_children = 150
max_pool = 10

# - Life time -
child_life_time = 300
child_max_connections = 0
connection_life_time = 0
client_idle_limit = 1800

# - Where to log -
log_destination = 'stderr'

# - What to log -
print_timestamp = on
log_connections = off
log_hostname = off
log_statement = off
log_per_node_statement = on
log_standby_delay = 'if_over_threshold'

# - Syslog specific -
syslog_facility = 'LOCAL0'
syslog_ident = 'pgpool'

# - Debug -
debug_level = 0

pid_file_name = '/var/run/pgpool/pgpool.pid'
logdir = '/tmp'


connection_cache = on
reset_query_list = 'ABORT; DISCARD ALL'
#reset_query_list = 'ABORT; RESET ALL; SET SESSION AUTHORIZATION DEFAULT'

replication_mode = off
replicate_select = off
insert_lock = off
lobj_lock_table = ''

# - Degenerate handling -
replication_stop_on_mismatch = off
failover_if_affected_tuples_mismatch = off

load_balance_mode = on
ignore_leading_white_space = on
white_function_list = ''
black_function_list = 'currval,lastval,nextval,setval'

master_slave_mode = on
master_slave_sub_mode = 'stream'

# - Streaming -
sr_check_period = 10
sr_check_user = 'replication_user'
sr_check_password = '*********'
delay_threshold = 10000000

# - Special commands -
follow_master_command = ''

parallel_mode = off
enable_query_cache = off
pgpool2_hostname = ''

health_check_period = 0
health_check_timeout = 20
health_check_user = 'postgres'
health_check_password = '*****'

relcache_expire = 0
------------------------------------------


pgpool-general-jp メーリングリストの案内