次のようなマスタースレーブレプリケーション構成があります。
マスター:
postgresql.conf
のレプリケーションは次のように構成されています(コメント行は簡潔にするために省略されています)。
max_wal_senders = 1
wal_keep_segments = 8
スレーブ上:
同じpostgresql.conf
マスターと同様。 recovery.conf
は次のようになります。
standby_mode = 'on'
primary_conninfo = 'Host=master1 port=5432 user=replication password=replication'
trigger_file = '/tmp/postgresql.trigger.5432'
これが最初にセットアップされたときに、いくつかの簡単なテストを実行し、レプリケーションが機能していることを確認しました。ただし、初期データロードを実行すると、一部のデータのみがスレーブに到達しました。
スレーブのログは次のようなメッセージで満たされます。
< 2015-01-23 23:59:47.241 EST >LOG: started streaming WAL from primary at F/52000000 on timeline 1
< 2015-01-23 23:59:47.241 EST >FATAL: could not receive data from WAL stream: ERROR: requested WAL segment 000000010000000F00000052 has already been removed
< 2015-01-23 23:59:52.259 EST >LOG: started streaming WAL from primary at F/52000000 on timeline 1
< 2015-01-23 23:59:52.260 EST >FATAL: could not receive data from WAL stream: ERROR: requested WAL segment 000000010000000F00000052 has already been removed
< 2015-01-23 23:59:57.270 EST >LOG: started streaming WAL from primary at F/52000000 on timeline 1
< 2015-01-23 23:59:57.270 EST >FATAL: could not receive data from WAL stream: ERROR: requested WAL segment 000000010000000F00000052 has already been removed
#postgresql IRCチャネルで分析とヘルプを行った後、スレーブがマスターに追いつけないという結論に達しました。私の提案する解決策は次のとおりです。
マスター:
max_wal_senders=5
wal_keep_segments=4000
。はい、非常に高いことはわかっていますが、状況を監視して何が起こるかを確認したいと思います。マスターに余裕があります。スレーブ上:
pg_hba.conf pg_ident.conf postgresql.conf recovery.conf
)rm -rf /var/lib/pgsql/9.3/data/*
)。これはpg_basebackup
。pg_basebackup -h master -D /var/lib/pgsql/9.3/data --username=replication --password
何か不足していますか?すべてのデータをリロードしなくてもスレーブを最新の状態にするためのより良い方法はありますか?
どんな助けでも大歓迎です。
[〜#〜] wal [〜#〜] を扱うための2つの重要なオプション ストリーミングレプリケーション の場合:
wal_keep_segments
は、適度な遅延の後にスレーブが追いつくことができるように十分に高く設定する必要があります(たとえば、更新ボリュームが大きい、スレーブがオフラインになっている、など)。
archive_mode
は、wal_keep_segments
よりも古いファイルのリカバリに使用できるWALアーカイブを有効にします。スレーブサーバーは、WALセグメントを取得するメソッドを必要とします。 NFSが最も簡単な方法ですが、スクリプトを記述できる限り、scpからhttp、テープまで何でも機能します。
# on master
archive_mode = on
archive_command = 'cp %p /path_to/archive/%f'
# on slave
restore_command = 'cp /path_to/archive/%f "%p"'
スレーブがマスターから直接WALセグメントをプルできない場合、スレーブはrestore_command
を使用してそれをロードしようとします。 archive_cleanup_command
設定を使用して、セグメントを自動的に削除するようにスレーブを構成できます。
スレーブが必要とする次のWALセグメントがマスターとアーカイブの両方から失われる状況になった場合、データベースを一貫して回復する方法はありません。 onlyの合理的なオプションは、サーバーをスクラブして、新しい pg_basebackup
から再度開始することです。
実際に回復するには、DB全体を削除してゼロから始める必要はありません。マスターには最新のバイナリがあるため、以下を実行してスレーブを回復し、同期に戻すことができます。
psql -c "select pg_start_backup('initial_backup');"
rsync -cva --inplace --exclude=*pg_xlog* <data_dir> slave_IP_address:<data_dir>
psql -c "select pg_stop_backup();"
注意:
1。スレーブはservice stop
によって拒否される必要があります
2。クエリにより、マスターは読み取り専用になりますpg_start_backup
3。マスターは読み取り専用クエリの提供を継続できます
4。手順の最後にスレーブを戻す
私はこれを本番で行いました、それは私にとって完璧に機能します。スレーブとマスターは同期しており、データの損失はありません。
そのようなスロットで言及されたレプリカのWALセグメントを保持するために、ポストグレス用にreplication slots
を構成できます。
https://www.percona.com/blog/2018/11/30/postgresql-streaming-physical-replication-with-slots/ でさらにリード
マスターサーバーで実行
SELECT pg_create_physical_replication_slot('standby_slot');
スレーブサーバーで次の行をrecovery.conf
に追加します
primary_slot_name = 'standby_slot'
Ben Grimmがコメントで提案したように、これはスレーブが追いつくことができるようにセグメントを可能な限り最大の値に設定することを確認する問題です。
keep_wal_segments
の設定が低すぎると、このエラーが発生します。 keep_wal_segments
の値を設定するときは、「pg_basebackup
の所要時間」を考慮してください。
セグメントは約5分ごとに生成されるため、バックアップに1時間かかる場合は、少なくとも12個のセグメントを保存する必要があります。 2時間で24が必要、など。バックアップの1時間あたり約12.2セグメントに値を設定します。