Recovery

PostgreSQLでは、 リカバリ は、既存の物理バックアップからインスタンスを起動するプロセスを指します。 PostgreSQLのリカバリシステムは堅牢で機能が豊富で、 ポイントインタイムリカバリーPITR をサポートしています。これは、使用可能な最も古いバックアップから最新のアーカイブされたWALファイルまで、クラスターを特定の瞬間に復元する機能です。

注釈

PITRを実行するには、有効なWALアーカイブが必要です。

CloudNativePGでは、復旧は既存のクラスターで インプレースで実行されません 。代わりに、物理バックアップから 新しいクラスター をブートストラップするために使用されます。

注釈

bootstrap スタンザの構成の詳細については、 Bootstrap を参照してください。

recovery ブートストラップモードでは、物理ベースバックアップからクラスターを初期化し、関連するWALファイルを再生して、システムを一貫したオプションでポイントインタイムの状態にすることができます。

CloudNativePGは、次の方法でのリカバリをサポートしています。

  • プラグ可能バックアップおよびリカバリーインターフェイスCNPG-IBarman Cloud Plugin などの外部ツールとの統合を可能にします。

  • ボリュームスナップショットからのネイティブリカバリ 、基になるKubernetesストレージインフラストラクチャでサポートされている場合。

  • Barman Cloud を介したオブジェクトストアからのネイティブリカバリー。これは、プラグインベースのアプローチを優先して、バージョン1.26の時点で 非推奨 です。

バージョン1.26でのネイティブBarman Cloudサポートの非推奨に伴い、このセクションでは、サポートされている2つのリカバリ方法に焦点を当てます。オブジェクトストアからのリカバリには Barman Cloud Plugin を使用し、ボリュームスナップショットからのリカバリには ネイティブインターフェイス を使用します。

注釈

古いドキュメントについては、 Appendix B – Recovery from an Object Store を参照してください。

Barman Cloudプラグインを使用したオブジェクトストアからのリカバリー

このセクションでは、推奨されるBarman Cloudプラグインを使用してオブジェクトストアからPostgreSQLクラスターを復旧する方法の概要を説明します。

注釈

オブジェクトストアには、CloudNativePG Cluster 非推奨のネイティブBarman Cloud統合**または Barman Cloud Plugin**のいずれかを使用して生成されたバックアップデータが含まれている必要があります。

注釈

詳細については、

“Recovery of a Postgres Cluster” section in the Barman Cloud Plugin documentation を参照してください。

最初に、ベースバックアップとWALファイルの両方を保持するオブジェクトストアを定義します。 Barman Cloudプラグインは、この目的にカスタムObjectStore リソースを使用します。次の例は、Azure Blob Storage用に構成する方法を示しています。

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 エントリーを定義します。

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 オブジェクトからのリカバリー

警告

VolumeSnapshot からプライマリインスタンスをリカバリした後にレプリカを作成する場合、オペレーターは`pg_basebackup` を使用して同期することにフォールバックする場合があります。このプロセスには、完全なベースバックアップが含まれるため、特に大規模なデータベースの場合、かなり遅くなる場合があります。この制限は、スケールアッププロセスでのオンラインバックアップとPVCクローンのサポートにより、将来的に解決される予定です。

CloudNativePGでは、既存のCluster に属するPersistentVolumeClaim PVCのVolumeSnapshot から新しいクラスターを作成できます。これらのスナップショットは、 ボリュームスナップショットバックアップを構成する方法 の宣言的APIを使用して作成されます。

リカバリプロセスを完了するには、新しいクラスターが、変更を再適用し、リカバリを最終化するために必要なWALアーカイブへのアクセスを提供する外部クラスターを参照する必要があります。

次の例は、ベースバックアップのVolumeSnapshot と、 Barman Cloudプラグインを介してアクセスされるWALアーカイブの両方を使用して、リカバリされるクラスターを示しています。

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: cluster-restore
spec:
  [...]

  bootstrap:
    recovery:
      source: origin
      volumeSnapshots:
        storage:
          name: <snapshot 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ファイルを保存していた場合、リカバリーにはそれも含める必要があります。

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: cluster-restore
spec:
  [...]

  bootstrap:
    recovery:
      volumeSnapshots:
        storage:
          name: <snapshot name>
          kind: VolumeSnapshot
          apiGroup: snapshot.storage.k8s.io

        walStorage:
          name: <snapshot name>
          kind: VolumeSnapshot
          apiGroup: snapshot.storage.k8s.io

前の例では、アプリケーションデータベースとその所有ユーザーの名前がデフォルトでapp であることを前提としています。リストアするPostgreSQLクラスターが別の名前を使用している場合、 アプリケーションデータベースの構成 に記載されているように、リカバリフェーズを終了する前にこれらの名前を指定する必要があります。

警告

スナップショットからレプリカモードクラスターをブートストラップして、プライマリだけでなくスタンバイインスタンスのスナップショットを活用する場合、次のことをお勧めします。

  1. 単一インスタンスのレプリカクラスターから開始します。プライマリインスタンスは、スナップショットとソースクラスタからの使用可能なWALを使用して復旧されます。 2. レプリカクラスター内のプライマリのスナップショットを取得します。 3. 必要に応じて、レプリカクラスター内のインスタンスの数を増やします。

Backup オブジェクトからのリカバリー

クラスターを作成する必要がある名前空間でBackup リソースが既に利用可能な場合、次の例のように.spec.bootstrap.recovery.backup.name を使用して名前を指定できます。

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クラスターが別の名前を使用している場合、 アプリケーションデータベースの構成 に文書されているように、リカバリフェーズを終了する前にこれらの名前を指定する必要があります。

追加の考慮事項

オブジェクトストア、ボリュームスナップショット、または既存のBackup リソースからリカバリーするかどうかにかかわらず、Cluster が完全にプライマリに昇格し、書き込み操作を受け入れるまで、カタログを含むデータベースを変更することはできません。この制限には、Cluster がプライマリに移行するまで遅延されるロールオーバーライドが含まれます。その結果、次の考慮事項が適用されます。

  • アプリケーションデータベース名とユーザーは、復元されるバックアップからコピーされます。これは、Kubernetesクラスターの通常のメンテナンスアクティビティの一部であるため、現在基になるシークレットのバックアップは行っていません。

  • 元のpostgresユーザーパスワードを保持するには、enableSuperuserAccess を構成し、superuserSecret を提供します。

デフォルトでは、リカバリはデフォルトのターゲットタイムライン latest で使用可能な最新のWALまで続行されます。オプションでrecoveryTarget を指定して、ポイントインタイムリカバリーを実行できます ポイント インタイム リカバリーPITR を参照してください。

注釈

barmanObjectStore.wal.maxParallel オプションを使用して、リカバリオブジェクトストアからトランザクションログを同時にダウンロードすることにより、アーカイブからのWAL取得を高速化することを検討します。

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

ベースバックアップを抽出した後、最新のWALまでのすべてのWALを再生する代わりに、任意の時点でWALの再生を停止するようにPostgreSQLに依頼できます。 PostgreSQLは、この技術を使用してPITRを達成します。 WALアーカイブの存在は必須です。

注釈

PITRでは、 リカバリーターゲット で説明したオプションを使用してリカバリターゲットを指定する必要があります。

リカバリターゲットが指定された場合、オペレーターは、この機能が動作するために必要な構成パラメーターを生成します。

オブジェクトストアからのPITR

この例では、 Barman Cloudプラグイン用に前に定義したAzureの同じリカバリオブジェクトストアを使用します。ベースバックアップとWALアーカイブの両方が含まれます。リカバリターゲットは、要求されたタイムスタンプに基づいています。

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の形式で値を割り当てると、オペレーターはそのバックアップをリカバリのベースとして使用します。

注釈

このようなバックアップが存在し、アクセス可能であることを確認する必要があります。

バックアップIDを指定しない場合、オペレーターは次のようにリカバリのベースバックアップを検出します。

  • targetTime またはtargetLSN を使用する場合、オペレーターは、そのターゲットより前に完了した最も近いバックアップを選択します。

  • それ以外の場合、オペレーターは最後の利用可能なバックアップを時系列で選択します。

VolumeSnapshot オブジェクトからのポイントインタイムリカバリーPITR

次の例は、以下を使用して ポイントインタイムリカバリーPITR を実行する方法を示しています。

  • ベースバックアップを提供するPGDATA ディレクトリのKubernetes VolumeSnapshot 。このスナップショットはrecovery.volumeSnapshots セクションで指定され、test-snapshot-1 名前付けです。

  • アーカイブされたWALファイルを含むリカバリオブジェクトストアこの場合、MinIO。オブジェクトストアは、 Barman Cloud Plugin ObjectStore リソースここには表示されていませんを介して定義され、外部クラスター構成をポイントするrecovery.source フィールドを使用して参照されます。

クラスターは、 recoveryTarget.targetTime オプションを使用して特定のポイントに復元されます。

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セグメントを適用して、目的のリカバリターゲットに到達できます。

注釈

バックアップクラスターで`walStorage` が有効になっていた場合、 Recovery from VolumeSnapshot objects で述べたように、 PGWAL ディレクトリを含むボリュームスナップショットも指定する必要があります。

警告

ボリュームスナップショットのベースバックアップの終了時刻がリカバリターゲットのタイムスタンプより前であることを確認するのは自分の責任です。

警告

最後のベースバックアップ以降にクラスター内の TablespaceConfiguration を追加または削除した場合、WALの再生は失敗します。テーブルスペースの変更からリカバリターゲットのタイムスタンプまでのベースバックアップが必要です。

リカバリーターゲット

次に、使用可能なリカバリターゲット基準を示します。

ターゲットタイム

リカバリーが進行するまでのタイムスタンプ。 RFC 3339 形式で表現されます。正確な停止ポイントは、 exclusive オプションの影響も受けます。

警告

PostgreSQLリカバリーは、指定された時間の後に発生する最初のトランザクションに遭遇すると停止します。ターゲット時間後にそのようなトランザクションが存在しない場合、リカバリプロセスは失敗します。

ターゲットXID

リカバリを続行するトランザクションID。正確な停止ポイントは、 exclusive オプションの影響も受けます。回復されるトランザクションは、指定されたトランザクションより前にコミットされたトランザクション、およびオプションで含まれるトランザクションです。

ターゲット名

リカバリーが続行する名前付けリストアポイント pg_create_restore_point() で作成されます。

targetLSN

リカバリが続行されるログ先行書き込みの場所のLSN。正確な停止ポイントは、 exclusive オプションの影響も受けます。

targetImmediate

リカバリーは、一貫した状態に到達するとすぐに、つまりできるだけ早く終了します。オンラインバックアップから復元する場合、これはバックアップの取得が終了したポイントを意味します。

注釈

targetTime または`targetLSN` のいずれかを指定すると、オペレーターは最も近いバックアップを取得できます。ただし、これは残りのターゲット`targetName` 、targetXID 、および`targetImmediate` では不可能です。このような場合、backupID の指定は必須です。

この例では、targetName ベースのリカバリターゲットを使用します。

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コンテナーに依存します。

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

アプリケーションデータベースの構成

復旧したクラスターの場合、追加の構成でアプリケーションデータベース名と資格情報を構成できます。アプリケーションデータベースの資格情報を更新するには、独自のパスワードを生成、シークレットとして保存し、シークレットを使用するようにデータベースを更新できます。または、オペレーターにランダムで安全なパスワードを使用してシークレットを生成させて使用することもできます。 空のクラスターをブートストラップする `initdb <空のクラスターをブートストラップする initdb>` を参照

シークレットの詳細については、

注釈

Cluster がリカバリモードである間、カタログを含むデータベースへの変更は許可されません。この制限には、Cluster がプライマリに移行するまで遅延されるロールオーバーライドが含まれます。このフェーズでは、ユーザーはソースクラスターで定義されたままになります。

次の例では、ライブクラスターからブートストラップに従って、所有者app と提供されたシークレットapp-secret に保存されたパスワードを使用してapp データベースを構成します。

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 値に更新されます。

リカバリーの内部的な仕組み

オブジェクトストレージにアップロードされたデータを使用して、既存のバックアップから新しいクラスターを ブートストラップ できます。オペレーターは、 barman-cloud-restore ツールベースバックアップ用とbarman-cloud-wal-restore ツールWALファイル用、要求に応じて並列サポートを含むを使用して、リカバリプロセスをオーケストレーションします。

recovery ブートストラップ方法の詳細と手順については、 バックアップからのブートストラップ `recovery <バックアップからのブートストラップ recovery>` を参照してください。

注釈

PostgreSQL PITR の方法に慣れていない場合

は動作しますが、 .spec.postgresql.parameters に関しては、リカバリクラスターを元のクラスターとして構成することをお勧めします。新しいクラスターが復元されたら、必要に応じて設定を変更できます。

その仕組みは、オペレーターが新しいクラスターの最初のインスタンスにinitコンテナを注入し、initコンテナがオブジェクトストレージからバックアップのリカバリを開始することです。

注釈

新しいPVCのベースバックアップコピーの期間は、バックアップのサイズ、およびネットワークとストレージの両方の速度によって異なります。

ベースバックアップ復旧プロセスが完了すると、オペレーターはPostgresインスタンスをリカバリモードで起動します。このフェーズでは、PostgreSQLは起動していますが、接続を受け入れることはできず、livenessプローブによれば、ポッドは正常です。 restore_command を介して、PostgreSQLはアーカイブからWALファイルの取得を開始します。 maxParallel オプションを設定し、並列WALリストア機能を有効にすることにより、このフェーズを高速化できます。

このフェーズは、PostgreSQLがターゲット、WALの終わりまたはPITRの場合は必要なターゲットに到達すると終了します。オプションでrecoveryTarget を指定して、PITRを実行できます。指定しない場合、リカバリはデフォルトのターゲットタイムライン latest で最新の使用可能なWALまで続行されます。

復旧が完了すると、オペレーターは必要なスーパーユーザーのパスワードをインスタンスに設定します。新しいプライマリインスタンスは通常どおり起動し、残りのインスタンスはレプリカとしてクラスターに参加します。

プロセスはユーザーに対して透過的であり、ポッドで実行されているインスタンスマネージャーによって管理されます。

バックアップセクションを使用したクラスターへの復元

クラスターを復元する場合、マニフェストには、 backup オブジェクトストアリソースを指すBarman Cloudプラグインを含むplugins セクションが含まれる場合があります。これにより、新しく作成されたクラスターは、バックアップポリシーが構成されている場合、復旧直後にWALファイルのアーカイブとバックアップの取得を開始できます。

同じクラスター内の backuprecovery の両方で同じObjectStore 構成を再利用しないでください。必要に応じて、各クラスターが一意のserverName を使用していることを確認して、バックアップまたはWALアーカイブデータの誤って上書きを防ぎます。

警告

CloudNativePGには、クラスターが共有ストレージバケットの既存のデータを上書きしないようにする安全チェックが含まれています。競合が検出された場合、クラスターは`Setting up primary` 状態のままで、関連付けられたポッドはエラーで失敗します。ポッドログには`ERROR: WAL archive check failed for server recoveredCluster: Expected empty archive` が表示されます。

注釈

復旧したクラスターで`cnpg.io/skipEmptyWalArchiveCheck` アノテーションを`enabled` に設定することにより、この安全性チェックをバイパスできます。ただし、PostgreSQLの復旧プロセスに精通していない限り、これは強くお勧めしません。チェックを誤ってスキップすると、重大なデータの損失が発生する可能性があります。専門的なシナリオでのみ注意して使用してください。