リカバリー

PostgreSQLの用語では、リカバリとは、既存のバックアップを使用してPostgreSQLインスタンスを起動するプロセスです。 PostgreSQLのリカバリメカニズムは非常に堅牢で豊富です。また、ポイントインタイムリカバリーPITRもサポートしており、カタログ内の最初に使用可能なバックアップから最後にアーカイブされたWALまで、特定のクラスターを任意の時点に復元できます。 (この場合、WALアーカイブは必須です。)

CloudNativePGでは、既存のクラスターでリカバリーインプレースを実行できません。リカバリーは、代わりに、使用可能な物理的バックアップから新しいPostgresクラスターをブートストラップする方法です。

注釈

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

recovery ブートストラップモードでは、既存の物理ベースバックアップからクラスターを作成できます。次に、アーカイブからREDOログを含むWALファイルを再適用します。

WALファイルは、定義された リカバリオブジェクトストア からプルされます。

ベースバックアップは、オブジェクトストアまたはボリュームスナップショットバージョン1.21以降を使用して取得できます。

警告

ボリュームスナップショットを使用したリカバリーの初期リリースは1.20.1でした。 1.21.0の機能の進歩の量のため、ボリュームスナップショットを使用するには、1.21以上の高度なリリースにアップグレードすることを強くお勧めします。

2つの方法で リカバリオブジェクトストア からのリカバリを実現できます。

  • リカバリオブジェクトストア、つまりBarman Cloudによって作成され、externalClusters セクションのbarmanObjectStore オプションを介して定義された別のクラスターのバックアップを使用することをお勧めします。

  • または、同じ名前空間内の既存のBackup オブジェクトを使用できます。

どちらの復旧方法も、完全な復旧最後に使用可能なWALまでまたは最大

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

までのいずれかが有効になります。完全なリカバリーを実行するときに、クラスターをレプリカモードで起動することもできます。 レプリカクラスター を参照してください。

重要

レプリカモードを使用する場合、復旧したクラスターのPostgreSQL構成`.spec.postgresql.parameters` が、物理レプリケーションの観点から元の構成と互換性があることを確認します。

ボリュームスナップショット を使用したリカバリの場合

  • すべてが同じバックアップに属し、同じcnpg.io/cluster およびcnpg.io/backupName ラベルで識別されるVolumeSnapshot オブジェクトの一貫したセットを使用します。次に、 :ref:VolumeSnapshot` オブジェクトからのリカバリー <`VolumeSnapshot` オブジェクトからのリカバリー>` の説明に従って、 ``.spec.bootstrap.recovery スタンザのvolumeSnapshots オプションを使用してリカバリします。

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

Barman Cloudによって作成され、サポートされているオブジェクトストアに保存されているバックアップから復元できます。 barmanObjectStore セクションで必要な構成をすべて含む外部クラスターを定義した後、 .spec.recovery.source オプションで参照する必要があります。

この例では、AzureのBLOBコンテナにリカバリオブジェクトストアを定義します。

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

  superuserSecret:
    name: superuser-secret

  bootstrap:
    recovery:
      source: clusterBackup

  externalClusters:
    - name: clusterBackup
      barmanObjectStore:
        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

重要

デフォルトでは、 recovery メソッドは、オブジェクトストア内のバックアップデータのメインフォルダーの名前として、 externalClusters セクションのクラスターの`name` を厳密に使用します。この名前は、通常、サーバーの名前用に予約されています。 barmanObjectStore.serverName プロパティを使用して、別のフォルダー名を指定できます。

注釈

この例では、並列WALリストア機能を利用し、最大8つのジョブを専用にして、アーカイブから必要なWALファイルを同時に取得します。この機能により、復旧時間を大幅に短縮できます。このシナリオを事前に計画し、ご使用の環境に合わせてこのパラメーターの値を正しく調整してください。必要なときに違いを生みますし、そうします。

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

警告

ボリュームスナップショットからプライマリインスタンスをリカバリした後にレプリカを作成する場合、オペレーターは`pg_basebackup` を使用して同期することになる場合があります。この動作により、データベースのサイズによっては、プロセスが遅くなります。この制限は、将来的にオンラインバックアップとPVCクローン作成のサポートが導入されると解除されます。

CloudNativePGは、 volume snapshot backupsの宣言APIを使用して取得された既存のCluster のPVCのVolumeSnapshot から新しいクラスターを作成できます。次の例のように、スナップショットの名前を指定する必要があります。

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

バックアップされたクラスターが別の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

警告

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

  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クラスターが別の名前を使用していた場合、 Configure the application databaseの文書に従ってそれらを指定できます。

追加の考慮事項

リカバリオブジェクトストア、ボリュームスナップショット、または既存のBackup リソースからリカバリするかどうかにかかわらず、次の考慮事項が適用されます。

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

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

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

重要

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

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

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

重要

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

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

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

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

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: clusterBackup
      recoveryTarget:
        # Time base target for the recovery
        targetTime: "2023-08-11 11:14:21.00000+02"

  externalClusters:
    - name: clusterBackup
      barmanObjectStore:
        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

この例では、タイムスタンプの形式でtargetTime のみを指定する必要がありました。リカバリーを開始するベースバックアップを指定する必要はありません。

backupID オプションは、リカバリプロセスを開始するベースバックアップを指定できるオプションです。デフォルトでは、この値は空です。

BarmanバックアップIDの形式で値を割り当てると、オペレーターはそのバックアップをリカバリのベースとして使用します。

重要

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

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

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

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

VolumeSnapshot オブジェクトからのPITR

次の例では、以下を使用します。

  • リカバリプロセスを開始するベースバックアップを含むPGDATA のKubernetesボリュームスナップショット。このスナップショットはrecovery.volumeSnapshots セクションで指定され、 test-snapshot-1 と呼ばれます。

  • WALアーカイブを含むMinIOのリカバリオブジェクトストア。オブジェクトストアは、外部クラスター定義の形式でrecovery.source オプションで指定されます。

リカバリターゲットは、要求されたタイムスタンプに基づいています。

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: cluster-example-snapshot
spec:
  # ...
  bootstrap:
    recovery:
      source: cluster-example-with-backup
      volumeSnapshots:
        storage:
          name: test-snapshot-1
          kind: VolumeSnapshot
          apiGroup: snapshot.storage.k8s.io
      recoveryTarget:
        targetTime: "2023-07-06T08:00:39"
  externalClusters:
    - name: cluster-example-with-backup
      barmanObjectStore:
        destinationPath: s3://backups/
        endpointURL: http://minio:9000
        s3Credentials:
          accessKeyId:
            name: minio
            key: ACCESS_KEY_ID
          secretAccessKey:
            name: minio
            key: ACCESS_SECRET_KEY

注釈

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

警告

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

リカバリーターゲット

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

targetTime

RFC 3339 形式で表現される、リカバリーが進行するタイムスタンプ。正確な停止ポイントは、

exclusive オプションの影響も受けます。

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

targetName リカバリが続行する名前付けのリストアポイント 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: clusterBackup
      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: clusterBackup
      recoveryTarget:
        backupID: 20220616T142236
        targetName: "maintenance-activity"
        exclusive: true

  externalClusters:
    - name: clusterBackup
      barmanObjectStore:
        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

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

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

空のクラスターをブートストラップする `initdb <空のクラスターをブートストラップする initdb>` を参照

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

この例では、所有者がapp 、提供されたシークレットがapp-secret を使用してアプリケーションデータベースapp を構成します。

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
[...]
spec:
  bootstrap:
    recovery:
      database: app
      owner: app
      secret:
        name: app-secret
      [...]

この構成では、復旧の完了後に次が発生します。

  1. データベース app が存在しない場合、新しいデータベース app が作成されます。

  2. ユーザーapp が存在しない場合、新しいユーザー app が作成されます。

  3. ユーザー app がデータベースの所有者でない場合、ユーザー app はデータベース app の所有者として付与されます。

  4. username の値がシークレットのowner の値と一致する場合、アプリケーションデータベースのパスワードはシークレットのpassword の値に変更されます。

重要

レプリカモードが有効になっているレプリカクラスターの場合、オペレーターはPostgreSQLインスタンスにデータベースもユーザーも作成しません。これらは、元のクラスターから復元されます。

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

オブジェクトストレージにアップロードされたデータを使用して、既存のバックアップから新しいクラスターを ブートストラップ できます。オペレーターは、 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を実行できます。指定しない場合、リカバリは上の最新の使用可能なWALまで継続されます。デフォルトのターゲットタイムラインlatest

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

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

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

クラスターリストアのマニフェストには、backup セクションが含まれる場合があります。これは、復旧後に、新しいクラスターがWALのアーカイブと、構成されている場合にバックアップの取得を開始することを意味します。

たとえば、このセクションは、クラスターcluster-example-backup からブートストラップするクラスターのマニフェストの一部です。ストレージバケットに、recoveredCluster という名前のフォルダーを作成します。ここに、復旧したクラスターのベースバックアップとWALが保存されます。

backup:
  barmanObjectStore:
    destinationPath: s3://backups/
    endpointURL: http://minio:9000
    serverName: "recoveredCluster"
    s3Credentials:
      accessKeyId:
        name: minio
        key: ACCESS_KEY_ID
      secretAccessKey:
        name: minio
        key: ACCESS_SECRET_KEY
  retentionPolicy: "30d"

externalClusters:
- name: cluster-example-backup
  barmanObjectStore:
    destinationPath: s3://backups/
    endpointURL: http://minio:9000
    s3Credentials:

異なるクラスターで同じbarmanObjectStore 構成を再利用しないでください。ストレージバケットの既存の情報が新しいクラスターによって上書きされる場合があります。

警告

オペレーターには、クラスターが情報を含むストレージバケットを上書きしないことを確認する安全チェックが含まれます。既存のストレージを上書きするクラスターは、ポッドがエラー状態の`Setting up primary` 状態のままです。ポッドログには`ERROR: WAL archive check failed for server recoveredCluster: Expected empty archive` が表示されます。

重要

復旧したクラスターで`cnpg.io/skipEmptyWalArchiveCheck` アノテーションを`enabled` に設定すると、安全性チェックをスキップできます。一般的な使用ケースでは、チェックは正常に機能するため、チェックをスキップすることはお勧めしません。重大なデータの損失が発生する可能性があるため、PostgreSQLリカバリシステムに精通している場合にのみこのチェックをスキップしてください。