レプリケーション
================

物理的レプリケーションはPostgreSQLの強みの1つであり、世界最大の組織の一部がビジネス継続性のコンテキストでのデータの管理にそれを選択した理由の1つです。物理レプリケーションは、主に高可用性を実現するために使用されますが、読み取り専用ワークロードのスケールアウトと、プライマリから一部の作業をオフロードすることもできます。

..  Important::
   このセクションは、同じKubernetesクラスターで管理される同じ`Cluster` リソース内のレプリケーションに関するものです。異なるKubernetesクラスター間でも、別のPostgres `Cluster` リソースを使用して複製する方法については、 :ref:`レプリカクラスター <レプリカクラスター>` を参照してください。

セクション。

アプリケーションレベルのレプリケーション
----------------------------------------

PostgreSQLのレプリケーション機能に長年貢献してきましたが、ネイティブ物理レプリケーションテクノロジーに基づいてCloudNativePGで高可用性を構築し、Kubernetes
APIに直接統合することにしました。

Kubernetesの用語では、これは
*ストレージレベルのレプリケーション*\ とは対照的に、\*\*
アプリケーションレベルのレプリケーション**と呼ばれます。

非常に成熟したテクノロジー
--------------------------

PostgreSQLには、プライマリインスタンスから1つ以上のレプリカにデータをレプリケートするための非常に堅牢で成熟したネイティブフレームワークがあり、WALライトアヘッドログに継続的に保存されるトランザクションの変更の概念を中心に構築されています。

クラッシュリカバリーとポイントインタイムリカバリーテクノロジーの進化として始まった物理的レプリケーションは、継続的リカバリーでのプライマリからウォームスタンバイへのWALシッピングを介してPostgreSQL
8.22006で最初に導入されました。

PostgreSQL 9.0 2010は、 *ホットスタンバイ*
を介した読み取り専用レプリカでそれを強化しましたが、 9.1
2011は、トランザクションレベルでの同期レプリケーションRPO=0クラスターの場合。カスケードレプリケーションは、PostgreSQL
9.22012でリリースされました。論理レプリケーションの基礎はPostgreSQL
9.4で築かれましたが、バージョン102017では、オリジンからデスティネーションにデータをレプリケートするパブリッシャー/サブスクライバーパターンのネイティブサポートを導入しました。

ストリーミングレプリケーションのサポート
----------------------------------------

現時点では、CloudNativePGは、 ``spec`` で提供された\ ``instances``
の数に基づいて、宣言的な方法でクラスター内の物理的ストリーミングレプリカをネイティブかつ透過的に管理します。

::

   replicas = instances - 1 (where  instances > 0)

クラスターの初期化の直後、オペレーターは次のように\ ``streaming_replica``
というユーザーを作成します。

.. code:: sql

   CREATE USER streaming_replica WITH REPLICATION;
      -- NOSUPERUSER INHERIT NOCREATEROLE NOCREATEDB NOBYPASSRLS

すぐに使える、オペレーターは、暗号化されたチャネルを介してクラスター内のストリーミングレプリケーションを自動的に設定し、\ ``streaming_replica``
ユーザーのTLSクライアント証明書認証を適用します。\ ``pg_hba.conf``
からの次の抜粋で強調表示されています。

::

   #  Require client certificate authentication for the streaming_replica user

   hostssl postgres streaming_replica all cert
   hostssl replication streaming_replica all cert

..  Seealso::
   CloudNativePGが証明書を管理する方法の詳細については、 :ref:`証明書 <証明書>` を参照してください。

ドキュメントで。

構成されている場合、オペレーターはHAクラスター内のすべてのレプリカのレプリケーションスロットを管理し、各スタンバイに必要なWALファイルが、フェールオーバーまたはスイッチオーバーの後でもプライマリのストレージに保持されるようにします。

..  Seealso::
   CloudNativePGが高可用性レプリカのレプリケーションスロットを自動的に管理する方法の詳細については、 :ref:`高可用性のためのレプリケーションスロット <高可用性のためのレプリケーションスロット>` を参照してください。

以下。

継続的なバックアップ統合
^^^^^^^^^^^^^^^^^^^^^^^^

クラスターで継続的バックアップが構成されている場合、CloudNativePGは、継続的リカバリー時に\ ``restore_command``
を利用するようにレプリカを透過的に構成します。その結果、PostgreSQLは、ストリーミングレプリケーションを介したWALのプルが失敗するときは常に、フォールバックオプションとしてWALアーカイブを使用できます。

同期レプリケーション
--------------------

CloudNativePGは、 ``minSyncReplicas`` および\ ``maxSyncReplicas``
と呼ばれる2つの構成オプションを介して
\**クォーラムベースの同期ストリーミングレプリケーション\*
の構成をサポートします。これらは、任意の時点で使用可能な同期スタンバイレプリカの予想される最小数と最大数です。自己修復の目的で、オペレーターは常にこれらの2つの値を使用可能なレプリカの数と比較して、クォーラムを決定します。

..  Important::
   デフォルトでは、同期レプリケーションは使用可能なすべてのレプリカを区別なく選択します。次のセクションで説明するように`syncReplicaElectionConstraint` オプションを介してノードラベルを操作することにより、同期レプリカをスケジュールできるノードを制限できます。

同期レプリケーションはデフォルトで無効になっています ``minSyncReplicas``
および\ ``maxSyncReplicas`` は定義されていません。 ``minSyncReplicas``
と\ ``maxSyncReplicas``
の両方が設定されている場合、CloudNativePGはPostgreSQLの\ ``synchronous_standby_names``
オプションを次の値に自動的に更新します。

::

   ANY q (pod1, pod2, ...)

そこで

-  ``q``
   は、演算子によって自動的に計算された整数です。\ ``1 <= minSyncReplicas <= q <= maxSyncReplicas <= readyReplicas``

-  ``pod1, pod2, ...``
   は、クラスター内のすべてのPostgreSQLポッドのリストです

..  Warning::
   自己修復機能を提供するために、オペレーターは`minSyncReplicas` そのような値が現在使用可能なレプリカの数より大きい場合は無視できます。 `readyReplicas` が`0` の場合、同期レプリケーションは自動的に無効になります。

 `PostgreSQL documentation <https://www.postgresql.org/docs/current/warm-standby.html#SYNCHRONOUS-REPLICATION>`_ で述べているように、 *メソッド ``ANY``
は、クォーラムベースの同期レプリケーションを指定し、WALレコードが少なくともリスト*
内の要求された数の同期スタンバイにレプリケートされるまで、トランザクションコミットを待機させます。

..  Important::
   オペレーターが同期レプリケーション設定の適用よりも自己修復を選択する場合でも、3つ以上のインスタンスがあるクラスター、より一般的には`maxSyncReplicas < (instances - 1)` の場合にのみ同期レプリケーションを計画することをお勧めします。

同期レプリケーションのノードを選択します
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

CloudNativePGを使用すると、PGDATAとPostgresポッドを保持するPVCが存在するノードラベルに基づいて、アンチアフィニティルールを介してクォーラムベースの同期レプリケーションセットに参加する資格のあるPostgreSQLインスタンスを選択できます。

..  Seealso::
   一般的なポッドアフィニティおよびアンチアフィニティルールの詳細については、 :ref:`スケジューリング <スケジューリング>`  を確認してください。

この機能のユースケースの例として
単一の同期レプリカを持つクラスターでは、同期レプリカがプライマリインスタンスとは別のアベイラビリティーゾーンにあることを確認できます。通常は
``topology.kubernetes.io/zone`` `label on a node <https://kubernetes.io/docs/reference/labels-annotations-taints/#topologykubernetesiozone>`_ 
で識別されます。これにより、単一のアベイラビリティーゾーンで停止が発生した場合のクラスターの堅牢性、特に目標復旧ポイントRPOの観点から向上します。

アンチアフィニティのアイデアは、クォーラムに参加する同期レプリカが、選択したラベルこの場合、アベイラビリティーゾーンラベルの異なる値を持つノードで実行されているポッドから選択されるようにすることです。プライマリが現在存在するノード実行中。このような基準に一致するノードがない場合、レプリカは同期レプリケーションの対象となります。

..  Important::
   自己修復の適用は、同期レプリカ選択の追加制約を定義しているときに引き続き適用されます :ref:`同期レプリケーションを介したゼロデータ損失クラスター <同期レプリケーションを介したゼロデータ損失クラスター>` を参照してください。

次の例は、\ ``spec.postgresql`` 内の\ ``syncReplicaElectionConstraint``
セクションを介してこれを行う方法を示しています。
``nodeLabelsAntiAffinity``
では、現在のプライマリと、アベイラビリティーゾーンラベルの値が異なるノードにあるレプリカの間で、オペレーターによって同期レプリケーションが動的に構成されることを確認するために、評価する必要があるノードラベルを指定できます。プライマリが存在するノード

.. code:: yaml

   spec:
     instances: 3
     postgresql:
       syncReplicaElectionConstraint:
         enabled: true
         nodeLabelsAntiAffinity:
         - topology.kubernetes.io/zone

ご想像のとおり、アベイラビリティーゾーンは一例にすぎませんが、ストレージ、CPU、メモリなど、ノードを説明する他のラベルに基づいてこの動作をカスタマイズできます。

高可用性のためのレプリケーションスロット
----------------------------------------

 `Replication slots <https://www.postgresql.org/docs/current/warm-standby.html#STREAMING-REPLICATION-SLOTS>`_ 

は、9.4で導入されたネイティブのPostgreSQL機能で、接続されているすべてのストリーミングレプリケーションクライアントがWALセグメントを受信するまで、プライマリがWALセグメントを削除しないこと、およびプライマリが次の場合でもリカバリ競合を発生させる可能性のある行を削除しないことを保証する自動方法を提供しますスタンバイは一時的に切断されます。

レプリケーションスロットは、それを作成したインスタンスにのみ存在し、PostgreSQLはスタンバイサーバーでレプリケートしません。その結果、フェールオーバーまたはスイッチオーバー後、新しいプライマリには、古いプライマリのレプリケーションスロットが含まれません。これにより、古いプライマリに接続され、スロットを失ったストリーミングレプリケーションクライアントに問題が発生する可能性があります。

CloudNativePGは、高可用性クラスターから始めて、クラスター管理レプリケーションスロットの概念を導入することにより、このギャップを埋めます。この機能は、プライマリとスタンバイの両方で、高可用性クラスター内の各ホットスタンバイレプリカの物理レプリケーションスロットを自動的に管理します。

CloudNativePGでは、次の用語を使用します。

-  **プライマリHAスロット**
   ライフサイクルがクラスターの現在のプライマリによって完全に管理され、目的がストリーミングレプリケーションで特定のスタンバイにマッピングすることである物理レプリケーションスロット。このようなスロットは、プライマリにのみ存在します。

-  **スタンバイHAスロット**
   スタンバイの物理レプリケーションスロット。そのライフサイクルは、プライマリの\ ``pg_replication_slots``
   ビューの内容に基づいて、クラスター内の別のスタンバイによって完全に管理され、\ ``pg_replication_slot_advance()``
   を使用して定期的に更新されます。

CloudNativePG
1.18で導入されたこの機能は、デフォルトで有効になり、構成から無効にできます。詳細については、
 :ref:`ReplicationSlotsConfiguration {postgresql-cnpg-io-v1-ReplicationSlotsConfiguration} <ReplicationSlotsConfiguration {postgresql-cnpg-io-v1-ReplicationSlotsConfiguration}>` を参照してください。以下に、メインオプションの簡単な説明を示します。

``.spec.replicationSlots.highAvailability.enabled``
trueの場合、機能は有効になります ``true`` は1.21以降のデフォルトです

``.spec.replicationSlots.highAvailability.slotPrefix``
この機能のオペレーターが管理するレプリケーションスロットを識別するプレフィックスデフォルト\ ``_cnpg_``

``.spec.replicationSlots.updateInterval``
スタンバイがレプリケーションスロットのローカルコピーの位置を現在のプライマリ上の位置と同期する頻度。秒単位で表現されますデフォルト30

..  Important::
   この機能は、 `pg_replication_slot_advance() <https://www.postgresql.org/docs/current/functions-admin.html>`_ に依存しているため、PostgreSQL 11以降が必要です。

レプリケーションスロットの位置を直接操作します。

..  Warning::
   PostgreSQL 11では、レプリケーションスロットを最初に無効にした場合に有効にしたり、最初に有効にした場合に無効にしたりすると、クラスターのローリング更新が必要になります起動時にのみ読み込まれる`recovery.conf` ファイルの存在のため。

お勧めしませんが、別の動作が必要な場合は、上記のオプションをカスタマイズできます。

たとえば、次のマニフェストは、レプリケーションスロットを無効にしたクラスターを作成します。

.. code:: yaml

   apiVersion: postgresql.cnpg.io/v1
   kind: Cluster
   metadata:
     name: cluster-example
   spec:
     instances: 3
     # Disable replication slots for HA in the cluster
     replicationSlots:
       highAvailability:
         enabled: false

     storage:
       size: 1Gi

この例のように、スタンバイがプライマリで\ ``pg_replication_slots``
ビューを照会し、レプリケーションスロットのローカルコピーを更新する頻度を制御することもできます。

.. code:: yaml

   apiVersion: postgresql.cnpg.io/v1
   kind: Cluster
   metadata:
     name: cluster-example
   spec:
     instances: 3
     # Reduce the frequency of standby HA slots updates to once every 5 minutes
     replicationSlots:
       highAvailability:
         enabled: true
       updateInterval: 300

     storage:
       size: 1Gi

インフラストラクチャでレプリケーションスロットは注意深く監視する必要があります。デフォルトでは、Prometheusエクスポーターの\ ``pg_replication_slots``
メトリックに、スロットの名前、タイプ、アクティブかどうか、プライマリからの遅延などの重要な情報を提供します。

..  Seealso::
   CloudNativePG展開をモニタする方法の詳細については、 :ref:`MonitoringConfiguration {postgresql-cnpg-io-v1-MonitoringConfiguration} <MonitoringConfiguration {postgresql-cnpg-io-v1-MonitoringConfiguration}>` を参照してください。

レプリケーションスロット用に保持されるWALサイズのキャップ
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

レプリケーションスロットが有効になっている場合、PostgreSQLがレプリケーションスロットによって要求されたWALファイルを保持しようとするため、ディスク領域が不足する場合があります。これは、スタンバイが一時的にダウンしている、遅延している、または単に孤立したレプリケーションスロットが原因で発生する可能性があります。

PostgreSQL 13以降、 :ref:`max_slot_wal_keep_size <レプリケーション>` を利用できます。

構成オプションは、レプリケーションスロットがチェックポイント時に\ ``pg_wal``
ディレクトリに保持できるWALファイルの最大サイズを制御します。デフォルトでは、PostgreSQLでは\ ``max_slot_wal_keep_size``
は\ ``-1``
に設定されています。これは、レプリケーションスロットが無制限の量のWALファイルを保持できることを意味します。その結果、レプリケーションスロットのサポートが有効になっているときに\ ``max_slot_wal_keep_size``
を明示的に設定することをお勧めします。例

.. code:: ini

     # ...
     postgresql:
       parameters:
         max_slot_wal_keep_size: "10GB"
     # ...
