スタンバイクラスター
Patroniは、「スタンバイクラスター」と呼ばれる機能を使用して、リモートのデータセンター(リージョン)へのカスケードレプリケーションも実行できます。この種類のクラスターには、次の要素があります。
- 「スタンバイリーダー」。リモートのノードからレプリケーションを行う点を除き、通常のクラスターリーダーとほぼ同じように動作します。
- スタンバイリーダーからレプリケーションを行うカスケードレプリカ。
スタンバイリーダーはDCS内のリーダーロックを保持し、更新します。リーダーロックが期限切れになると、カスケードレプリカは選出を行い、スタンバイの中から別のリーダーを選びます。
スタンバイクラスターと、そのレプリケーション元のプライマリークラスターの間には、これ以外の関係はありません。特に、同じDCSを使用する場合、同じDCSスコープを共有してはなりません。互いに知っているのはレプリケーション情報だけです。また、プライマリークラスターで実行したpatronictl_list やpatronictl_topology の出力に、スタンバイクラスターは表示されません。
柔軟性を確保するため、standby_cluster
セクションにcreate_replica_methods
キーを指定することで、クラスターが「スタンバイモード」のときにレプリカを作成し、WALレコードをリカバリーする方法を指定できます。これは、クラスターを切り離して通常のクラスターとして動作させるときのレプリカ作成とは別のものです。通常のクラスターでの作成は、postgresqlセクションのcreate_replica_methodsで制御します。「スタンバイ」と「通常」の両方のcreate_replica_methodsは、postgresqlセクション内のキーを参照します。
このようなクラスターを構成するには、Patroniの構成にstandby_cluster セクションを指定する必要があります。
これらのオプションはクラスターのブートストラップ時に一度だけ適用され、その後はDCSを通じてのみ変更できることに注意してください。
PatroniはリモートのプライマリーのPGDATA内にpostgresql.confまたはpostgresql.conf.backupがあることを想定しており、ベースバックアップ後に見つからなければ起動しません。リモートのプライマリーが別の場所にpostgresql.confを保存している場合、PGDATAへのコピーは利用者の責任で行ってください。
スタンバイクラスターでレプリケーションスロットを使用する場合は、プライマリークラスターにも対応するレプリケーションスロットを作成しなければなりません。スタンバイクラスターの実装では、自動的には作成されません。プライマリークラスターでPatroniの永続レプリケーションスロット機能を使用すると、primary_slot_nameと同じ名前、またはprimary_slot_nameが指定されていない場合はそのデフォルト値の名前を持つレプリケーションスロットを維持できます。
リモートサイトにプライマリーへ接続する単一のエンドポイントがない場合は、standby_cluster.hostセクションにソースクラスターの全ホストを列挙できます。standby_cluster.hostにカンマ区切りで複数のホストが含まれる場合、Patroniは次の処理を行います。
- スタンバイリーダーノードの
primary_conninfoにtarget_session_attrs=read-writeを追加します。 pg_rewindを実行する必要があるかどうかを判断するときや、スタンバイクラスターの全ノードでpg_rewindを実行するときに、target_session_attrs=read-writeを使用します。pg_rewindを正常に動作させるには、data page checksums(initdbの--data-checksumsオプション)を有効にしてクラスターを初期化するか、wal_log_hintsをonに設定する、あるいはその両方を行わなければならないことに注意してください。そうでなければ、pg_rewindは正しく動作しません。
別のスタンバイクラスターや、プライマリークラスターのスタンバイメンバーからスタンバイクラスターへレプリケーションすることも可能です。その場合は、standby_cluster.hostセクションに単一のホストを定義する必要があります。ただし、この場合はスタンバイクラスターでpg_rewindの実行に失敗することに注意してください。
メンバー名(各ノードのPatroni構成のnameフィールド)は、プライマリークラスターと、それに接続するすべてのスタンバイクラスターにわたって一意でなければなりません。
Patroniはメンバー名を使用してプライマリー上のsynchronous_standby_namesを設定します。メンバー名は、pg_stat_replication内の各レプリケーション接続のapplication_nameにもなります。スタンバイクラスターのノードとプライマリークラスターのメンバーが同じ名前を持つ場合、PostgreSQLには同一のapplication_name値を持つ接続が二つ見えることになります。この曖昧さにより、PostgreSQLが本来意図したプライマリークラスターのメンバーではなく、スタンバイクラスターの接続を使用して同期レプリケーションの要件を満たす可能性があります。その結果、正しいスタンバイにトランザクションが永続化されていないにもかかわらず、PostgreSQLが同期コミット済みとして早まって応答してしまいます。
これは検出されない障害です。レプリケーションは継続し、エラーもログに記録されませんが、実際には有効な同期スタンバイがない状態でクラスターが動作しているため、プライマリーが障害を起こすとデータを失う可能性があります。