[pgsql-jp: 41767] レプリケーション構成でスタンバイ系に反映されるまで時間がかかる

suzutsuki0220 . suzutsuki0220 @ gmail.com
2015年 2月 5日 (木) 18:41:01 JST


お世話になります。涼月と申します

PostgreSQL 9.2.6 (Linux) 8台でマスタ1台、スタンバイ7台のレプリケーション
構成を行っています。ここ最近、データの登録件数が増えてくると(総数60万件程)、
レプリケーションが追いつかず、1分程待っても反映されない状況になり困ってお
ります

■構成
・RHEL 5.8 x86_64
・PostgreSQL version 9.2.6

マスタは更新クエリ専用として、問合せはすべてスタンバイ系で実施
クエリはWebサーバ(apache)内にlibpqを使ったモジュール(自作)を経由しています
Webサーバは各7台のスタンバイ系にあり、Webサーバが必要に応じて更新クエリを
マスタに送っています

8台とも同じLANで同じスイッチにあるため、ネットワークの遅延はほどんどあり
ません

postgresql.confの内容 (デフォルトから変更した箇所のみ)
**********
listen_addresses = '*'
max_connections = 1024
maintenance_work_mem = 32MB
vacuum_cost_delay = 10ms
hot_standby = on  # Standby系ではoff
synchronous_commit = remote_write
wal_level = hot_standby
max_wal_senders = 32
wal_keep_segments = 128
restart_after_crash = off
replication_timeout = 20s
wal_receiver_status_interval = 5s
hot_standby_feedback = on
max_standby_streaming_delay = -1
max_standby_archive_delay = -1
**********


■状況確認

1. レプリケーションの状態確認
SQL [SELECT * FROM pg_stat_replication] を実行するとstatusがstreamingと
なっていることからレプリケーションの状態は正常であると判断しました

しかしながら、マスタと各スタンバイの登録件数をCOUNT関数で確認すると、
件数が異なってしまい、数10~100件程少ない状態です

マスタ/スタンバイともログにエラーメッセージはありません

更新クエリは多いときで1分間に200件程で、多かれ少なかれ、登録は常にある
状態です

2. 問合せクエリの停止でレプリケーションが追いつくことを確認
スタンバイサーバで一時的にWebサーバを停止させて、問合せクエリが届かな
い状態にすると数秒で更新が追いつく(件数がマスタと同じになる)ことは確
認できました

このことから、スタンバイ側の問合せが負荷となり、レプリケーション遅延に
つながっていると判断しました

3. 設定変更
スタンバイ系はいずれもload averageは上がっていないようで、設定を見直し
たところ max_standby_archive_delay と max_standby_streaming_delay が
"-1"となっていたため、これらの行をコメントアウトしました

これによって登録件数の差異はなくなったのですが、以下のメッセージが出力
されるようになりました
======
ERROR: canceling statement due to conflict with recovery
DETAIL:  User was holding a relation lock for too long.
======

今までdelay値が-1でキャンセルを行わないようにしていたのが、設定を変更
したことによりキャンセルされるようになったようです

4. キャンセルされるクエリの確認
キャンセルされたクエリはログから特定できたので、psqlプロンプトから実行して
みましたが数100ミリ秒程度で完了し、タイムアウトするような状況ではありません
でした

Webサーバの問合せ動作のログでも、実行時間はあまり変わらず、
SELECT文の実行から150ミリ秒程度でエラーになっているようでした

max_standby_archive_delay、max_standby_streaming_delay の初期値は共に
30秒であると認識しているのですが、30秒もかかっていないのに問合せが
キャンセルされて、上記のメッセージが出ているようです

キャンセルの頻度は数は出せていませんが、全体の数%程度でそれ程多くは
ありません


■確認したいこと

1. max_standby_archive_delayならびに、max_standby_streaming_delay
   はスタンバイ系でSELECT文の実行時間が長くなってマスタ側の更新が
   反映できなくなってしまった時に、その実行をキャンセルするための
   時間ではないのでしょうか?

2. 問合せに対してキャンセルされてしまうとデータが0件になってしまいますので、
  DB側で再試行するような仕組みはあるのでしょうか?

なお、実際のクエリの内容やDBの構成等については、申し訳ありませんが
出すことはできかねます。これまでで何かお気づきの点がありましたら、
ご教示のほど、よろしくお願いいたします

-----
suzutsuki0220 @ gmail.com


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