Backup and recovery
===================

PGDは、分散された高可用システムであるように設計されています。クラスターの1つ以上のノードが失われた場合、それらを置き換える最良の方法は、残りのノードから直接新しいノードのクローンを作成することです。

PGDにおけるバックアップとリカバリーの役割は、次の状況などのディザスターリカバリーDRを提供することです。

-  クラスター内のすべてのノードの損失

-  データの破損、アプリケーションエラー、またはセキュリティ侵害の結果、マルチプルのノードにわたる重大な修正不可能なデータの破損

バックアップ
------------

pg_dump
^^^^^^^

pg_dumpは、 *論理バックアップ*
と呼ばれることもあります、通常はPGDで使用できます。

pg_dumpは、ローカルシーケンスとグローバルシーケンスの両方をローカルシーケンスであるかのようにダンプします。この動作は意図的なもので、PGDスキーマをダンプして他のPostgreSQLデータベースに移植できるようにします。これは、ダンプ時にシーケンス種類のメタデータが失われることを意味するため、リストアはすべてのシーケンス種類をリストア時に\ ``bdr.default_sequence_kind``
の値に効果的にリセットします。

シーケンスごとに正確なシーケンス種類をリセットする復元後スクリプトを作成するには、次のようなSQLスクリプトを使用することができます。

.. code:: sql

   SELECT SELECT bdr.alter_sequence_set_kind(||
           nspname||.||relname||,||seqkind||);
   FROM bdr.sequences
   WHERE seqkind != local;

``bdr.crdt_raw_value = on`` を使用してpg_dumpが実行されている場合、
``bdr.crdt_raw_value = on`` でのみダンプをリロードできます。

テクニカルサポートでは、
PGDのバックアップとリカバリーに物理的バックアップ技術を使用することをお勧めします。

物理的バックアップ
^^^^^^^^^^^^^^^^^^

 `Barman <https://www.enterprisedb.com/docs/supported-open-source/barman/>`_ などの標準のPostgreSQLソフトウェアを使用して、 EDB
Postgres分散クラスター内のノードの物理バックアップを取得できます。

PostgreSQLノードに適用されるのと同じ手順を使用して、PGDノードの物理バックアップを実行できます。
PGDノードは、 BDR拡張機能を実行する単なるPostgreSQLノードです。

PostgreSQLバックアップ技術をPGDに適用する際に、次の特定の点を考慮してください。

-  PGDは単一のデータベースのレベルで動作しますが、物理バックアップにはインスタンス内のすべてのデータベースが含まれます。データベースを簡単にバックアップおよび復元できるように計画します。

-  バックアップは、1つのノードのみのコピーを作成します。最も単純なケースでは、すべてのノードにすべてのデータのコピーがあるため、すべてのデータをキャプチャするには1つのノードのみをバックアップする必要があります。ただし、その単一のコピーを含むサイトがダウンした場合、PGDの目標は満たされないため、最小はサイトごとに少なくとも1つのノードバックアップ多数のコピーなど。

-  ただし、各ノードにはレプリケーションされていないローカルデータがある場合、またはレプリケーションセットの定義が複雑な場合があるため、すべてのノードがすべてのレプリケーションセットをサブスクライブしない場合があります。これらの場合、バックアップ計画には、レプリケートされていないローカルデータと、各レプリケーションセットをサブスクライブする少なくとも1つのノードのバックアップをバックアップする方法に関する計画も含める必要があります。

最終的な一貫性
^^^^^^^^^^^^^^

EDB Postgres分散クラスター内のノードは *結果的に一貫性* ですが、
*完全に一貫性*
ではありません。特定のノードの物理バックアップは、そのノードが実際に想定する状態に制限されたポイントインタイムリカバリ機能を提供します。

次の例は、同じEDB
Postgres分散クラスター内の2つのノードがどのようにして同じ状態のシーケンスを通過しないか、通常は通過しないかを示しています。

2つのノード\ ``N1`` および\ ``N2`` を含むクラスターで、最初は\ ``S``
状態であるとします。トランザクション\ ``W1`` がノード\ ``N1``
に適用され、同時に競合しないトランザクション\ ``W2`` がノード\ ``N2``
に適用される場合、ノード\ ``N1`` は次の状態を経ます。

::

   (N1)   S  -->  S + W1  -->  S + W1 + W2

ノード\ ``N2`` は、次の状態を経ます。

::

   (N2)   S  -->  S + W2  -->  S + W1 + W2

つまり、ノード\ ``N1`` は決して*状態\ ``S + W2``
を引き受けることはなく、ノード\ ``N2`` も同様に状態\ ``S + W1``
を引き受けることはありません。ただし、両方のノードは同じ状態\ ``S + W1 + W2``
になります。この状況を考慮すると、バックアップ戦略の決定方法に影響を与える可能性があります。

ポイントインタイムリカバリーPITR
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

前の例では、変更も時間的に一貫していないことを示しました。 ``W1``
と\ ``W2`` は両方とも\ ``T1`` で発生しますが、変更\ ``W1`` は\ ``T2``
まで\ ``N2`` に適用されません。

PostgreSQL
PITRは、単一のマスターからCOMMITオーダーで変更が到着するという想定に基づいて設計されています。したがって、PITRは、特定の時点PITに到達するまで変更をスキャンすることにより可能です。このスキームを使用すると、1つのノードをその観点から単一のポイントに復元できます\ ``T1``
など。ただし、その状態には、その時間近くにコミットしたがノードにまだ到着していない他のノードからの他のデータは含まれません。その結果、回復は部分的に一貫していない、または少なくとも1つのレプリケーションオリジンのみについて一貫していると考えられる場合があります。

これを要求するには、標準の構文を使用します。

::

   recovery_target_time = T1

PGDでは、マルチプルのマスターからの変更が可能で、すべては1つのノードのWALログに記録され、レプリケーションオリジン識別子を使用して個別に識別されます。

PGDは、すべてまたは一部のレプリケーションオリジンの特定の時点へのPITRを可能にし、ノードのすべてのサブセットにわたって完全に一貫した観点を提供します。

したがって、マルチオリジンの場合、WALストリームを、複数のストリームがすべて1つの大きなストリームに混合されたものとして表示できます。
PITはまだ1つだけですが、それは各原点の異なるポイントとして個別に到達されます。

WALストリームは、要求されたオリジンがPITを見つけるまで読み取られます。すべての変更は、その時点までに適用されますが、オリジンのPITに到達した後、トランザクションレコードはオリジンのコミットとしてマークされません。

WALには1つのLSN「停止ポイント」がありますが、シングルオリジンPITRの場合と同様に、単一のタイムスタンプが一貫して適用されます。

定義されたPITに到達すると、必要に応じてリカバリーを続行できるように新しいPITが設定される場合があります。

目的の停止ポイントに到達した後、復旧したサーバーが昇格する場合は、最初にシャットダウンします。
``pg_resetwal``
を使用して、このサーバーのタイムラインで使用されるよりも高いLSN値にLSNを移動します。このアプローチでは、論理デコードによって生成される重複LSNがないことが保証されます。

この特定の例では、\ ``N1`` は\ ``T1``
に復元されます。また、後まで\ ``N1`` に適用されなかった場合でも、 ``T1``
によってコミットされた他のノードからの変更も含まれます。

マルチオリジンPITRを要求するには、 ``postgresql.conf``
ファイルの標準の構文を使用します。

::

   recovery_target_time = T1

2つの方法のいずれかで\ ``T1``
に復元されるレプリケーションオリジンのリストを指定する必要があります。新しいパラメーター\ ``recovery_target_origins``
を介して別の\ ``multi_recovery.conf`` ファイルを使用できます。

::

   recovery_target_origins = *

または、オリジンのサブセットを\ ``recovery_target_origins``
のリストとして指定できます。

::

   recovery_target_origins = 1,3

指定された\ ``recovery_target_time``
へのローカルWALアクティビティのリカバリーは、常に暗黙的に実行されます。
``recovery_target_origins`` で指定されていないオリジンの場合、
``recovery_target_origins``
で記載されているリストの目標が達成される時期に応じて、任意の時点でリカバリーを停止できます。

``multi_recovery.conf``
ファイルが存在しない場合、リカバリーは、COMMITオーダーで単一のマスターから到着する変更を想定して設計された元のPostgreSQL
PITR動作がデフォルトになります。

..  Note::
   この機能は、 EDB Postgres Extendedでのみ使用できます。 Barmanは`multi_recovery.conf` ファイルを作成しません。

リストア
--------

標準のPostgreSQLノードと同じ手順で物理バックアップを取ることができますが、
PGDノードの物理バックアップを復元するのは少し複雑です。

EDB Postgres分散クラスター障害またはバックアップからの新しいクラスターのシード
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

物理バックアップを復元するための最も一般的なユースケースには、データセンターに障害が発生した場合など、クラスター内のすべてのPGDノードの障害または交換が含まれます。

また、この手順を実行して、 EDB
Postgres分散クラスターの現在のコンテンツのクローンを作成して、QAまたは開発インスタンスをシードすることもできます。

その場合、単一のPGDノードとオプションでWALアーカイブの物理バックアップに基づいて、PGD機能を復元できます。

-  いくつかのPGDノードがまだライブで実行されている場合は、
   PGDノードを復元したホストをフェンスオフして、残りのPGDノードに接続できないようにします。この実践により、新しいノードが既存のクラスターを混乱させないようになります。

-  PGDノードの1つの物理バックアップから単一のPostgreSQLノードを復元します。

-  バックアップに関連付けられているWALアーカイブがある場合は、適切な\ ``postgresql.conf``
   を作成し、リカバリーでPostgreSQLを起動して最新の状態まで再生します。必要に応じて、ここで代替の\ ``recovery_target``
   を指定できます。

-  復元されたノードを起動するか、スタンバイ復旧している場合は読み取り/書き込みに昇格させます。生き残ったノードからフェンスしてください。

-  物理バックアップに含まれる残りのPGDメタデータをクリーンアップします。

-  PostgreSQLインスタンスを完全に停止して再起動します。

-  ``bdr.join_node_group()``
   ファンクション呼び出しに基づいた標準プロシージャでPGDノードをさらに追加します。

PGDメタデータのクリーンアップ
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

残ったPGDメタデータをクリーンアップするには

1. :ref:`bdr.drop_node <bdr.drop_node>` を使用してPGDノードを削除します。

2. PostgreSQLを完全に停止して再起動します重要！

レプリケーション起点のクリーンアップ
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

レプリケーションオリジンはシステムカタログに永続的に記録されるため、別の手順で明示的に削除する必要があります。したがって、これらはバックアップと復元されたインスタンスに含まれます。これらは依存関係として明示的に記録されていないため、
BDR拡張機能をドロップするときに自動的に削除されません。

クラッシュセーフな方法で着信レプリケーションの進行状況を追跡するため、PGDはリモートマスターノードごとに1つのレプリケーションオリジンを作成します。したがって、以前のクラスターのノードごとに、これを1回実行します。

::

   SELECT pg_replication_origin_drop(bdr_dbname_grpname_nodename);

次のようにして、レプリケーションオリジンをリストできます。

::

   SELECT * FROM pg_replication_origin;

PGDによって作成されたものは、名前で簡単に認識されます。

レプリケーションスロットのクリーンアップ
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``pg_basebackup``
で物理バックアップが作成された場合、レプリケーションスロットはバックアップから省略されます。

他のバックアップ方法には、レプリケーションスロットが古いまたは無効な状態で保持される場合があります。バックアップを復元したら、これを使用してすべてのレプリケーションスロットをドロップします。

::

   SELECT pg_drop_replication_slot(slot_name)
   FROM pg_replication_slots;

一部のスロットを保持する理由がある場合は、
``WHERE slot_name LIKE 'bdr%'``
句を追加できますが、これはほとんど役に立ちません。

..  Warning::
   これは、ライブPGDノードでは決して実行しないでください。
