[pgpool-general-jp: 1087] Re: postgresql9.1.5 + pgpool-II3.2.0 ストリーミングレプリケーション ロードバランスの時にエラーとなる

Tatsuo Ishii ishii @ sraoss.co.jp
2012年 9月 9日 (日) 07:59:05 JST


石井です。

結論から言うと、pgpoolは想定通りの動きをしています。

> 藤倉と申します。
> ストリーミングレプリケーションしているpostgresql(master/slave)にpgpoolを接続させロードバランスさせると以下のようなエラーが出力され、
> アプリケーションにはエラーが返ってくる状態です。
> 
> 
> ■実行したコマンド
> $ createdb -e -p 5432 -h db -U postgres -E UTF8 -T template0 --lc-collate
> 'C' --lc-ctype 'ja_JP.UTF8' <database_name>
> $ psql -h db -U postgres < /tmp/schema.sql
> ※ schema.sqlは中身が何でもエラーになります
> ※ createdbとpsqlの間にsleepをはさむとエラーが出なくなります
> 
> 
> ◯pgpool.log
> 2012-09-06 17:50:45 ERROR: pid 5278: pool_read_kind: kind does not match
> between master(53) slot[1] (45)
> 2012-09-06 17:50:45 LOG:   pid 5278: pool_read_kind: error message from 1
> th backend:database "<database_name>" does not exist
> 2012-09-06 17:50:45 ERROR: pid 5278: pool_do_auth: failed to read kind
> before BackendKeyData
> 
> 
> 
> スレーブ側のpostgresでは以下のようなログが出力されていました。
> ◯postgresql
> Sep  6 17:50:45 slave-server postgres[5468]: [2-1] [unknown]  [5468]:0
> ()LOG:  connection received: host=localhost.localdomain port=41516
> Sep  6 17:50:45 slave-server postgres[5468]: [3-1] <database_name>
> localhost.localdomain(41516) [5468]:0 (authentication)LOG:  connection
> authorized: user=postgres database=<database_name>
> Sep  6 17:50:45 slave-server postgres[5468]: [4-1] <database_name>
> localhost.localdomain(41516) [5468]:0 (startup)FATAL:  database
> "<database_name>" does not exist
> 
> 
> 
> ■環境
>  CentOS 5.x (64bit)
>  - pgpool-ii 3.2.0
> port = 5432
> master_slave_mode = on
> master_slave_sub_mode = 'stream'
> connection_cache = on
> load_balance_mode = on
> replication_mode = off
> replicate_select = off
> 
> ※ pgpoolのバージョン3.1.3-2/3.0.5にしても同様の問題は発生しました
>  - PostgreSQL 9.1.5
> ※ ローカルにマスター/スレーブを立ててストリーミングレプリケーションしています
> master port = 5442
> slave  port = 5443
> 
> postgres=# SHOW pool_nodes;
>  node_id | hostname  | port | status | lb_weight |  role
> ---------+-----------+------+--------+-----------+---------
>  0       | 127.0.0.1 | 5442 | 2      | 0.500000  | primary
>  1       | 127.0.0.1 | 5443 | 2      | 0.500000  | standby
> ※ lb_weightを1/0 1/1 0/1に変更して同様の問題は再現しました
> node_id 1をdetachしている状態では問題は再現しませんでした(現象は発生しない)
> 
> 
> postgres=# psql -x  -U postgres -h localhost -c "SELECT * FROM
> pg_stat_replication"
> -[ RECORD 1 ]----+------------------------------
> procpid          | 18398
> usesysid         | 10
> usename          | postgres
> application_name | walreceiver
> client_addr      | 127.0.0.1
> client_hostname  |
> client_port      | 59479
> backend_start    | 2012-09-06 17:26:15.112519+09
> state            | streaming
> sent_location    | 6/CF00ED50
> write_location   | 6/CF00ED50
> flush_location   | 6/CF00ED50
> replay_location  | 6/CF00ED50
> sync_priority    | 0
> sync_state       | async

pgpoolは、クライアントからの接続を受付けてから、すべてのバックエンドに
対して指定したユーザ、データベースで接続を試みます。このケースでは、レ
プリケーションの遅延のためにスタンバイ側でまだデータベースが作成されて
いないためにエラーになっています。

> ※ sync_stateをsyncにしても同様の問題は再現しました

PostgreSQLの「同期」レプリケーションは、レプリケーション遅延を0にするも
のではないので、そうなります。
> 
> PostgreSQLストリーミングレプリケーションではsyncであってもスレーブ側への遅延がある程度許容されていると考えておりますが、
> pgpool側ではmaster_slave_sub_mode = 'stream'であっても少しの遅延も許容されない状態になっているように見えます。

「許容されている」の意味がちょっとわかりませんが、pgpoolがエラーになる
のは最初に述べた理由からです。pgpoolを使わなくても、

psqlでプライマリに接続、データベースを作成
すかさず別のpsqlでスタンバイに接続

とやってもエラーになります。

> delay_threshold の値を0もしくは数GBを設定しても改善が見られませんでした。

delay_thresholdを0にするとチェックが行われません。また、
delay_thresholdはSELECTがスタンバイに行くかどうかを制御するものですので、
このケースでは無関係です。

> 以上のような状況なのですが、どなたか回避策などご存知でしたらご教示お願い致します。

回避策としては、pgpoolの(同期)レプリケーションを使うことになります。

> よろしくお願い申しあげます。
> 
> 藤倉
--
Tatsuo Ishii
SRA OSS, Inc. Japan
English: http://www.sraoss.co.jp/index_en.php
Japanese: http://www.sraoss.co.jp


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