web-dev-qa-db-ja.com

マスターに対応できないPostgreSQL 9.3スレーブを修正するにはどうすればよいですか?

次のようなマスタースレーブレプリケーション構成があります。

マスター:

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チャネルで分析とヘルプを行った後、スレーブがマスターに追いつけないという結論に達しました。私の提案する解決策は次のとおりです。

マスター:

  1. セットする max_wal_senders=5
  2. セットする wal_keep_segments=4000。はい、非常に高いことはわかっていますが、状況を監視して何が起こるかを確認したいと思います。マスターに余裕があります。

スレーブ上:

  1. データディレクトリに構成ファイルを保存します(つまり、pg_hba.conf pg_ident.conf postgresql.conf recovery.conf
  2. データディレクトリをクリアします(rm -rf /var/lib/pgsql/9.3/data/*)。これはpg_basebackup
  3. 次のコマンドを実行します:pg_basebackup -h master -D /var/lib/pgsql/9.3/data --username=replication --password

何か不足していますか?すべてのデータをリロードしなくてもスレーブを最新の状態にするためのより良い方法はありますか?

どんな助けでも大歓迎です。

16
Oleg Dulin

[〜#〜] 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 から再度開始することです。

25
Ben Grimm

実際に回復するには、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。手順の最後にスレーブを戻す

私はこれを本番で行いました、それは私にとって完璧に機能します。スレーブとマスターは同期しており、データの損失はありません。

1
linehrr

そのようなスロットで言及されたレプリカの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がコメントで提案したように、これはスレーブが追いつくことができるようにセグメントを可能な限り最大の値に設定することを確認する問題です。

0
Oleg Dulin

keep_wal_segmentsの設定が低すぎると、このエラーが発生します。 keep_wal_segmentsの値を設定するときは、「pg_basebackupの所要時間」を考慮してください。

セグメントは約5分ごとに生成されるため、バックアップに1時間かかる場合は、少なくとも12個のセグメントを保存する必要があります。 2時間で24が必要、など。バックアップの1時間あたり約12.2セグメントに値を設定します。

0