[pgsql-jp: 34006] Re: pgpoolのmaster データベース停止時の動作について( pgpool-2.0.9)
Tatsuo Ishii
t-ishii @ sra.co.jp
2004年 9月 19日 (日) 22:03:11 JST
石井です.
> この度実際の業務システムでの使用を前提として、
> pgpoolを使用したレプリケーション機能の動作確認を行っております。
> 簡単な内容ではありますが、幾つかの障害ケースを人為的に発生させ、
> pgpool経由で接続している際にどのようなエラーが発生するのか
> パターンを洗い出しておりました。
> その際に、pgpoolがSQL文やpsqlコマンドに対して無反応になってしまう
> 現象が発生したため、そのことをご報告致します。
>
> 本MLの過去のメールの中で、今年7月上旬の[pgsql-jp: 33449]から始まる
> 一連のスレッドにおいてケビン シュワンツ氏が報告された件と
> 現象がほぼ同じようです。
>
> 以下、私の手元の環境構成と再現手順を列記します。
詳細な再現手順,ありがとうございます.
> ◎master側サーバー構成
> Red Hat Enterprise Linux 3.0 ES
> PostgreSQL 7.4.5 (本家RPM公開版)
> pgpool 2.0.9 (tarball)
>
> ◎secondary側サーバー構成
> Red Hat Linux 9
> PostgreSQL 7.4.5 (本家RPM公開版)
>
> ◎主な設定変更点
> ・pgpoolからmaster側PostgreSQLへはUNIXドメインソケット経由で、
> secondary側PostgreSQLへはTCP/IP経由で接続しています。
> ・master/secondaryともにPostgreSQLのポート番号を5433へ変更しています。
>
> ◎pgpool.conf
> pgpool.conf.sampleから変更している設定項目は以下のとおりです。
> ------------------------------------------------------------
> allow_inet_domain_socket = true
> port = 5432
> backend_port = 5433
> secondary_backend_host_name = 'nnn.nnn.nnn.nnn'
> secondary_backend_port = 5433
> replication_mode = true
> ------------------------------------------------------------
>
> ◎再現手順
> 1. masterおよびsecondaryのPostgreSQLを起動する。
> # service postgresql start
>
> 2. pgpoolを起動する。
> $ pgpool -d -n
>
> 3. psqlからpgpool経由でPostgreSQLに接続する。
> $ psql -U hogehoge
>
> 4. psqlより一回以上SQL文やpsqlコマンドを実行する。
>
> 5. psqlを終了する。
>
> 6. master側のPostgreSQLを停止する。
> # service postgresql stop
>
> 7. 再度psqlからpgpool経由でPostgreSQLに接続する。
> この時点ではpgpoolはまだmaster側の停止を検知しておらず(?)
> エラーが発生しないため、psqlのプロンプトまで正常に表示されます。
はい.コネクションプールを再利用する場合,7.4以降では接続時にバックエ
ンドとまったく通信する必要がないため,プロンプトが正常に表示されます.
> 8. psqlよりSQL文やpsqlコマンドを実行する。
> ※pgpoolからの応答がなくなり、Ctrl+Cによるキャンセルもできなくなる。
> show pool_statusコマンドの場合も応答がありません。
> 他から別にpsqlで接続を行うと、応答なしの状態が解消され、
> 接続に関するエラーメッセージが表示されます。
おそらく起きているのは以下のような現象です.
1) マスタがシャットダウン時にpgpoolにnotice messageを投げる
2) pgpoolはそれを受けとったので,セカンダリからもnotice messageが来る
ものと思って待ち続ける
対策を色々考えたのですが,結局2)の時点でタイムアウトするしかないと思い
ました.しかし,ここで何も考えずにタイムアウトをかけると,時間のかかる
問い合わせを実行した際にもタイムアウトになってしまいます.そこで,問い
合わせを処理する際にマスタ側だけでなく,セカンダリの完了も待つことにし
ました.こうすると,正常ならば2)の時点では必ずセカンダリからすぐに応答
があるはずなので,タイムアウトするのは異常時だけと分かります.
というわけで,よろしくければ以下のパッチをお試し下さい.なお,このパッ
チは先日リリースしたばかりの2.1(ロードバランスの重み設定機能付)に対す
るものです.できれば2.1+パッチで試していただきたいのですが,どうしても
2.0.9でのテストが必要であれば教えてください.
--
Tatsuo Ishii
Index: pool_process_query.c
===================================================================
RCS file: /home/t-ishii/repository/pgpool/pool_process_query.c,v
retrieving revision 1.30
diff -c -r1.30 pool_process_query.c
*** pool_process_query.c 13 Sep 2004 00:05:10 -0000 1.30
--- pool_process_query.c 19 Sep 2004 12:45:49 -0000
***************
*** 283,289 ****
}
if (kind1 == 0)
{
! pool_read(SECONDARY(backend), &kind1, 1);
}
if (kind == '\0' || kind != kind1)
{
--- 283,306 ----
}
if (kind1 == 0)
{
! /* at this point the query has completed and it's safe to set timeout here */
! pool_debug("pool_process_query: waiting for secondary for data ready");
!
! /* temporary enable timeout */
! pool_enable_timeout();
!
! if (pool_check_fd(SECONDARY(backend), 0))
! {
! pool_error("pool_process_query: secondary data is not ready at syncronous point. abort this session");
!
! }
! else
! {
! pool_read(SECONDARY(backend), &kind1, 1);
! }
!
! pool_disable_timeout();
!
}
if (kind == '\0' || kind != kind1)
{
***************
*** 492,497 ****
--- 509,519 ----
{
return POOL_END;
}
+
+ /* in "strict mode" we need to wait for secondary completing the query */
+ if (pool_config.replication_strict || STRICT_MODE(string))
+ if (synchronize(SECONDARY(backend)))
+ return POOL_END;
}
return POOL_CONTINUE;
}
pgsql-jp メーリングリストの案内