Recovery
========
.. raw:: html
PostgreSQLでは、 **リカバリ**
は、既存の物理バックアップからインスタンスを起動するプロセスを指します。
PostgreSQLのリカバリシステムは堅牢で機能が豊富で、
**ポイントインタイムリカバリーPITR**
をサポートしています。これは、使用可能な最も古いバックアップから最新のアーカイブされたWALファイルまで、クラスターを特定の瞬間に復元する機能です。
.. Note::
PITRを実行するには、有効なWALアーカイブが必要です。
CloudNativePGでは、復旧は既存のクラスターで
**インプレースで実行されません** 。代わりに、物理バックアップから
**新しいクラスター** をブートストラップするために使用されます。
.. Note::
`bootstrap` スタンザの構成の詳細については、 :ref:`Bootstrap ` を参照してください。
``recovery``
ブートストラップモードでは、物理ベースバックアップからクラスターを初期化し、関連するWALファイルを再生して、システムを一貫したオプションでポイントインタイムの状態にすることができます。
CloudNativePGは、次の方法でのリカバリをサポートしています。
- **プラグ可能バックアップおよびリカバリーインターフェイスCNPG-I** 、
`Barman Cloud Plugin `_ などの外部ツールとの統合を可能にします。
- **ボリュームスナップショットからのネイティブリカバリ**
、基になるKubernetesストレージインフラストラクチャでサポートされている場合。
- **Barman Cloud**
を介したオブジェクトストアからのネイティブリカバリー。これは、プラグインベースのアプローチを優先して、バージョン1.26の時点で
**非推奨** です。
バージョン1.26でのネイティブBarman
Cloudサポートの非推奨に伴い、このセクションでは、サポートされている2つのリカバリ方法に焦点を当てます。オブジェクトストアからのリカバリには
**Barman Cloud Plugin**
を使用し、ボリュームスナップショットからのリカバリには
**ネイティブインターフェイス** を使用します。
.. Note::
古いドキュメントについては、 :ref:`Appendix B – Recovery from an Object Store ` を参照してください。
Barman Cloudプラグインを使用したオブジェクトストアからのリカバリー
------------------------------------------------------------------
このセクションでは、推奨されるBarman
Cloudプラグインを使用してオブジェクトストアからPostgreSQLクラスターを復旧する方法の概要を説明します。
.. Note::
オブジェクトストアには、CloudNativePG `Cluster` **非推奨のネイティブBarman Cloud統合**または** Barman Cloud Plugin**のいずれかを使用して生成されたバックアップデータが含まれている必要があります。
.. Note::
詳細については、
`“Recovery of a Postgres Cluster” section in the Barman Cloud Plugin documentation `_ を参照してください。
最初に、ベースバックアップとWALファイルの両方を保持するオブジェクトストアを定義します。
Barman Cloudプラグインは、この目的にカスタム\ ``ObjectStore``
リソースを使用します。次の例は、Azure Blob
Storage用に構成する方法を示しています。
.. code:: yaml
apiVersion: barmancloud.cnpg.io/v1
kind: ObjectStore
metadata:
name: cluster-example-backup
spec:
configuration:
destinationPath: https://STORAGEACCOUNTNAME.blob.core.windows.net/CONTAINERNAME/
azureCredentials:
storageAccount:
name: recovery-object-store-secret
key: storage_account_name
storageKey:
name: recovery-object-store-secret
key: storage_account_key
wal:
maxParallel: 8
次に、定義した\ ``ObjectStore`` を使用するように\ ``Cluster``
リソースを構成します。 ``bootstrap``
セクションで、リカバリソースを指定し、プラグインを参照する\ ``externalCluster``
エントリーを定義します。
.. code:: yaml
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: cluster-restore
spec:
[...]
superuserSecret:
name: superuser-secret
bootstrap:
recovery:
source: origin
externalClusters:
- name: origin
plugin:
name: barman-cloud.cloudnative-pg.io
parameters:
barmanObjectName: cluster-example-backup
serverName: cluster-example
``VolumeSnapshot`` オブジェクトからのリカバリー
-----------------------------------------------
.. Warning::
`VolumeSnapshot` からプライマリインスタンスをリカバリした後にレプリカを作成する場合、オペレーターは`pg_basebackup` を使用して同期することにフォールバックする場合があります。このプロセスには、完全なベースバックアップが含まれるため、特に大規模なデータベースの場合、かなり遅くなる場合があります。この制限は、スケールアッププロセスでのオンラインバックアップとPVCクローンのサポートにより、将来的に解決される予定です。
CloudNativePGでは、既存の\ ``Cluster``
に属する\ ``PersistentVolumeClaim`` PVCの\ ``VolumeSnapshot``
から新しいクラスターを作成できます。これらのスナップショットは、
:ref:`ボリュームスナップショットバックアップを構成する方法 <ボリュームスナップショットバックアップを構成する方法>` の宣言的APIを使用して作成されます。
リカバリプロセスを完了するには、新しいクラスターが、変更を再適用し、リカバリを最終化するために必要なWALアーカイブへのアクセスを提供する外部クラスターを参照する必要があります。
次の例は、ベースバックアップの\ ``VolumeSnapshot`` と、 Barman
Cloudプラグインを介してアクセスされるWALアーカイブの両方を使用して、リカバリされるクラスターを示しています。
.. code:: yaml
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: cluster-restore
spec:
[...]
bootstrap:
recovery:
source: origin
volumeSnapshots:
storage:
name:
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
externalClusters:
- name: origin
plugin:
name: barman-cloud.cloudnative-pg.io
parameters:
barmanObjectName: cluster-example-backup
serverName: cluster-example
バックアップされたクラスターが別のPVCを使用してWALファイルを保存していた場合、リカバリーにはそれも含める必要があります。
.. code:: yaml
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: cluster-restore
spec:
[...]
bootstrap:
recovery:
volumeSnapshots:
storage:
name:
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
walStorage:
name:
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
前の例では、アプリケーションデータベースとその所有ユーザーの名前がデフォルトで\ ``app``
であることを前提としています。リストアするPostgreSQLクラスターが別の名前を使用している場合、
:ref:`アプリケーションデータベースの構成 <アプリケーションデータベースの構成>` に記載されているように、リカバリフェーズを終了する前にこれらの名前を指定する必要があります。
.. Warning::
スナップショットからレプリカモードクラスターをブートストラップして、プライマリだけでなくスタンバイインスタンスのスナップショットを活用する場合、次のことをお勧めします。
1. 単一インスタンスのレプリカクラスターから開始します。プライマリインスタンスは、スナップショットとソースクラスタからの使用可能なWALを使用して復旧されます。
2. レプリカクラスター内のプライマリのスナップショットを取得します。
3. 必要に応じて、レプリカクラスター内のインスタンスの数を増やします。
``Backup`` オブジェクトからのリカバリー
---------------------------------------
クラスターを作成する必要がある名前空間で\ ``Backup``
リソースが既に利用可能な場合、次の例のように\ ``.spec.bootstrap.recovery.backup.name``
を使用して名前を指定できます。
.. code:: yaml
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: cluster-example-initdb
spec:
instances: 3
bootstrap:
recovery:
backup:
name: backup-example
storage:
size: 1Gi
このブートストラップ方法では、復元する必要があるバックアップへの参照のみを指定できます。
前の例では、アプリケーションデータベースとその所有ユーザーの名前がデフォルトで\ ``app``
であることを前提としています。リストアするPostgreSQLクラスターが別の名前を使用している場合、
:ref:`アプリケーションデータベースの構成 <アプリケーションデータベースの構成>` に文書されているように、リカバリフェーズを終了する前にこれらの名前を指定する必要があります。
追加の考慮事項
--------------
オブジェクトストア、ボリュームスナップショット、または既存の\ ``Backup``
リソースからリカバリーするかどうかにかかわらず、\ ``Cluster``
が完全にプライマリに昇格し、書き込み操作を受け入れるまで、カタログを含むデータベースを変更することはできません。この制限には、\ ``Cluster``
がプライマリに移行するまで遅延されるロールオーバーライドが含まれます。その結果、次の考慮事項が適用されます。
- アプリケーションデータベース名とユーザーは、復元されるバックアップからコピーされます。これは、Kubernetesクラスターの通常のメンテナンスアクティビティの一部であるため、現在基になるシークレットのバックアップは行っていません。
- 元のpostgresユーザーパスワードを保持するには、\ ``enableSuperuserAccess``
を構成し、\ ``superuserSecret`` を提供します。
デフォルトでは、リカバリはデフォルトのターゲットタイムライン ``latest``
で使用可能な最新のWALまで続行されます。オプションで\ ``recoveryTarget``
を指定して、ポイントインタイムリカバリーを実行できます
:ref:`ポイント インタイム リカバリーPITR <ポイント インタイム リカバリーPITR>` を参照してください。
.. Note::
`barmanObjectStore.wal.maxParallel` オプションを使用して、リカバリオブジェクトストアからトランザクションログを同時にダウンロードすることにより、アーカイブからのWAL取得を高速化することを検討します。
ポイント インタイム リカバリーPITR
----------------------------------
ベースバックアップを抽出した後、最新のWALまでのすべてのWALを再生する代わりに、任意の時点でWALの再生を停止するようにPostgreSQLに依頼できます。
PostgreSQLは、この技術を使用してPITRを達成します。
WALアーカイブの存在は必須です。
.. Note::
PITRでは、 :ref:`リカバリーターゲット <リカバリーターゲット>` で説明したオプションを使用してリカバリターゲットを指定する必要があります。
リカバリターゲットが指定された場合、オペレーターは、この機能が動作するために必要な構成パラメーターを生成します。
オブジェクトストアからのPITR
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
この例では、 Barman
Cloudプラグイン用に前に定義したAzureの同じリカバリオブジェクトストアを使用します。ベースバックアップとWALアーカイブの両方が含まれます。リカバリターゲットは、要求されたタイムスタンプに基づいています。
.. code:: yaml
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: cluster-restore-pitr
spec:
instances: 3
storage:
size: 5Gi
bootstrap:
recovery:
# Recovery object store containing WAL archive and base backups
source: origin
recoveryTarget:
# Time base target for the recovery
targetTime: "2023-08-11 11:14:21.00000+02"
externalClusters:
- name: origin
plugin:
name: barman-cloud.cloudnative-pg.io
parameters:
barmanObjectName: cluster-example-backup
serverName: cluster-example
この例では、タイムスタンプの形式で\ ``targetTime``
のみを指定する必要がありました。リカバリーを開始するベースバックアップを指定する必要はありません。
``backupID``
オプションは、リカバリプロセスを開始するベースバックアップを指定できるオプションです。デフォルトでは、この値は空です。
BarmanバックアップIDの形式で値を割り当てると、オペレーターはそのバックアップをリカバリのベースとして使用します。
.. Note::
このようなバックアップが存在し、アクセス可能であることを確認する必要があります。
バックアップIDを指定しない場合、オペレーターは次のようにリカバリのベースバックアップを検出します。
- ``targetTime`` または\ ``targetLSN``
を使用する場合、オペレーターは、そのターゲットより前に完了した最も近いバックアップを選択します。
- それ以外の場合、オペレーターは最後の利用可能なバックアップを時系列で選択します。
``VolumeSnapshot`` オブジェクトからのポイントインタイムリカバリーPITR
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
次の例は、以下を使用して **ポイントインタイムリカバリーPITR**
を実行する方法を示しています。
- ベースバックアップを提供する\ ``PGDATA`` ディレクトリのKubernetes
``VolumeSnapshot``
。このスナップショットは\ ``recovery.volumeSnapshots``
セクションで指定され、\ ``test-snapshot-1`` 名前付けです。
- アーカイブされたWALファイルを含むリカバリオブジェクトストアこの場合、MinIO。オブジェクトストアは、
Barman Cloud Plugin ``ObjectStore``
リソースここには表示されていませんを介して定義され、外部クラスター構成をポイントする\ ``recovery.source``
フィールドを使用して参照されます。
クラスターは、 ``recoveryTarget.targetTime``
オプションを使用して特定のポイントに復元されます。
.. code:: yaml
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: cluster-example-snapshot
spec:
# ...
bootstrap:
recovery:
source: origin
volumeSnapshots:
storage:
name: test-snapshot-1
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
recoveryTarget:
targetTime: "2023-07-06T08:00:39"
externalClusters:
- name: origin
plugin:
name: barman-cloud.cloudnative-pg.io
parameters:
barmanObjectName: minio-backup
serverName: cluster-example
この設定により、CloudNativePGはボリュームスナップショットからベースデータを復元し、オブジェクトストアからWALセグメントを適用して、目的のリカバリターゲットに到達できます。
.. Note::
バックアップクラスターで`walStorage` が有効になっていた場合、 :ref:`Recovery from VolumeSnapshot objects ` で述べたように、 `PGWAL` ディレクトリを含むボリュームスナップショットも指定する必要があります。
.. Warning::
ボリュームスナップショットのベースバックアップの終了時刻がリカバリターゲットのタイムスタンプより前であることを確認するのは自分の責任です。
.. Warning::
最後のベースバックアップ以降にクラスター内の :ref:`TablespaceConfiguration ` を追加または削除した場合、WALの再生は失敗します。テーブルスペースの変更からリカバリターゲットのタイムスタンプまでのベースバックアップが必要です。
リカバリーターゲット
^^^^^^^^^^^^^^^^^^^^
次に、使用可能なリカバリターゲット基準を示します。
ターゲットタイム
リカバリーが進行するまでのタイムスタンプ。 `RFC 3339 `_ 形式で表現されます。正確な停止ポイントは、
``exclusive`` オプションの影響も受けます。
.. Warning::
PostgreSQLリカバリーは、指定された時間の後に発生する最初のトランザクションに遭遇すると停止します。ターゲット時間後にそのようなトランザクションが存在しない場合、リカバリプロセスは失敗します。
ターゲットXID
リカバリを続行するトランザクションID。正確な停止ポイントは、
``exclusive``
オプションの影響も受けます。回復されるトランザクションは、指定されたトランザクションより前にコミットされたトランザクション、およびオプションで含まれるトランザクションです。
ターゲット名
リカバリーが続行する名前付けリストアポイント
``pg_create_restore_point()`` で作成されます。
targetLSN
リカバリが続行されるログ先行書き込みの場所のLSN。正確な停止ポイントは、
``exclusive`` オプションの影響も受けます。
targetImmediate
リカバリーは、一貫した状態に到達するとすぐに、つまりできるだけ早く終了します。オンラインバックアップから復元する場合、これはバックアップの取得が終了したポイントを意味します。
.. Note::
`targetTime` または`targetLSN` のいずれかを指定すると、オペレーターは最も近いバックアップを取得できます。ただし、これは残りのターゲット`targetName` 、`targetXID` 、および`targetImmediate` では不可能です。このような場合、`backupID` の指定は必須です。
この例では、\ ``targetName`` ベースのリカバリターゲットを使用します。
.. code:: yaml
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
[...]
bootstrap:
recovery:
source: origin
recoveryTarget:
backupID: 20220616T142236
targetName: restore_point_1
[...]
各\ ``recoveryTarget`` 構成のターゲットから1つだけを選択できます。
さらに、 ``targetTLI``
を指定して、特定のタイムラインに強制的にリカバリーできます。
デフォルトでは、以前のパラメーターは包括的であるとみなされ、リカバリターゲットの直後で停止し、
`the behavior in PostgreSQL `_ と一致します。
``exclusive`` パラメーターを\ ``true``
に設定することにより、リカバリターゲットの直前で停止する排他的動作を要求できます。次の例は、この動作を示しており、ベースバックアップとWALアーカイブの両方にAzureのBLOBコンテナーに依存します。
.. code:: yaml
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: cluster-restore-pitr
spec:
instances: 3
storage:
size: 5Gi
bootstrap:
recovery:
source: origin
recoveryTarget:
backupID: 20220616T142236
targetName: "maintenance-activity"
exclusive: true
externalClusters:
- name: origin
plugin:
name: barman-cloud.cloudnative-pg.io
parameters:
barmanObjectName: cluster-example-backup
serverName: cluster-example
アプリケーションデータベースの構成
----------------------------------
復旧したクラスターの場合、追加の構成でアプリケーションデータベース名と資格情報を構成できます。アプリケーションデータベースの資格情報を更新するには、独自のパスワードを生成、シークレットとして保存し、シークレットを使用するようにデータベースを更新できます。または、オペレーターにランダムで安全なパスワードを使用してシークレットを生成させて使用することもできます。
:ref:`空のクラスターをブートストラップする `initdb` <空のクラスターをブートストラップする `initdb`>` を参照
シークレットの詳細については、
.. Note::
`Cluster` がリカバリモードである間、カタログを含むデータベースへの変更は許可されません。この制限には、`Cluster` がプライマリに移行するまで遅延されるロールオーバーライドが含まれます。このフェーズでは、ユーザーはソースクラスターで定義されたままになります。
次の例では、ライブクラスターからブートストラップに従って、所有者\ ``app``
と提供されたシークレット\ ``app-secret``
に保存されたパスワードを使用して\ ``app`` データベースを構成します。
.. code:: yaml
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
[...]
spec:
bootstrap:
recovery:
database: app
owner: app
secret:
name: app-secret
[...]
上記の構成では、次は **復旧が完了した後** にのみ発生します。
1. ``app`` データベースが存在しない場合、作成されます。
2. ``app`` ユーザーが存在しない場合、作成されます。
3. ``app`` ユーザーが\ ``app``
データベースの所有者でない場合、所有権は\ ``app``
ユーザーに付与されます。
4. ``owner`` 値がシークレットの\ ``username``
値と一致する場合、アプリケーションユーザーこの場合は\ ``app``
ユーザーのパスワードはシークレットの\ ``password`` 値に更新されます。
リカバリーの内部的な仕組み
--------------------------
.. raw:: html
.. raw:: html
オブジェクトストレージにアップロードされたデータを使用して、既存のバックアップから新しいクラスターを
*ブートストラップ* できます。オペレーターは、 ``barman-cloud-restore``
ツールベースバックアップ用と\ ``barman-cloud-wal-restore``
ツールWALファイル用、要求に応じて並列サポートを含むを使用して、リカバリプロセスをオーケストレーションします。
``recovery`` ブートストラップ方法の詳細と手順については、
:ref:`バックアップからのブートストラップ `recovery` <バックアップからのブートストラップ `recovery`>` を参照してください。
.. Note::
`PostgreSQL PITR `_ の方法に慣れていない場合
は動作しますが、 ``.spec.postgresql.parameters``
に関しては、リカバリクラスターを元のクラスターとして構成することをお勧めします。新しいクラスターが復元されたら、必要に応じて設定を変更できます。
その仕組みは、オペレーターが新しいクラスターの最初のインスタンスにinitコンテナを注入し、initコンテナがオブジェクトストレージからバックアップのリカバリを開始することです。
.. Note::
新しいPVCのベースバックアップコピーの期間は、バックアップのサイズ、およびネットワークとストレージの両方の速度によって異なります。
ベースバックアップ復旧プロセスが完了すると、オペレーターはPostgresインスタンスをリカバリモードで起動します。このフェーズでは、PostgreSQLは起動していますが、接続を受け入れることはできず、livenessプローブによれば、ポッドは正常です。
``restore_command``
を介して、PostgreSQLはアーカイブからWALファイルの取得を開始します。
``maxParallel``
オプションを設定し、並列WALリストア機能を有効にすることにより、このフェーズを高速化できます。
このフェーズは、PostgreSQLがターゲット、WALの終わりまたはPITRの場合は必要なターゲットに到達すると終了します。オプションで\ ``recoveryTarget``
を指定して、PITRを実行できます。指定しない場合、リカバリはデフォルトのターゲットタイムライン
``latest`` で最新の使用可能なWALまで続行されます。
復旧が完了すると、オペレーターは必要なスーパーユーザーのパスワードをインスタンスに設定します。新しいプライマリインスタンスは通常どおり起動し、残りのインスタンスはレプリカとしてクラスターに参加します。
プロセスはユーザーに対して透過的であり、ポッドで実行されているインスタンスマネージャーによって管理されます。
バックアップセクションを使用したクラスターへの復元
--------------------------------------------------
クラスターを復元する場合、マニフェストには、 *backup*
オブジェクトストアリソースを指すBarman
Cloudプラグインを含む\ ``plugins``
セクションが含まれる場合があります。これにより、新しく作成されたクラスターは、バックアップポリシーが構成されている場合、復旧直後にWALファイルのアーカイブとバックアップの取得を開始できます。
同じクラスター内の *backup* と *recovery* の両方で同じ\ ``ObjectStore``
構成を再利用しないでください。必要に応じて、各クラスターが一意の\ ``serverName``
を使用していることを確認して、バックアップまたはWALアーカイブデータの誤って上書きを防ぎます。
.. Warning::
CloudNativePGには、クラスターが共有ストレージバケットの既存のデータを上書きしないようにする安全チェックが含まれています。競合が検出された場合、クラスターは`Setting up primary` 状態のままで、関連付けられたポッドはエラーで失敗します。ポッドログには`ERROR: WAL archive check failed for server recoveredCluster: Expected empty archive` が表示されます。
.. Note::
復旧したクラスターで`cnpg.io/skipEmptyWalArchiveCheck` アノテーションを`enabled` に設定することにより、この安全性チェックをバイパスできます。ただし、PostgreSQLの復旧プロセスに精通していない限り、これは強くお勧めしません。チェックを誤ってスキップすると、重大なデータの損失が発生する可能性があります。専門的なシナリオでのみ注意して使用してください。