‘Multiple Repositories’

pgBackrestリリースの主な機能は、マルチプルのリポジトリのサポートです。これにより、さまざまなバックアップリポジトリにさまざまな動作を定義できます。例として、(スペースを節約するための)保持期間が短い高速復元用のローカルリポジトリと、コールドストレージ用に大きいリモートリポジトリを使用できます。

この機能では、コマンドを適用するリポジトリを設定するために使用できる新しい --repo オプションが導入されました。複数のリポジトリを構成できるように、すべてのrepo*- オプションにはインデックスが付けられています。

このセクションでは、 デモ クラスターを(CentOS 7で EDBPostgresAdvancedServer バージョン13を使用して)セットアップして、この新機能が各pgBackRestコマンドにどのように影響するかを示します。

構成

このデモでは、データベースホストに2つのローカルリポジトリをセットアップすることに注意してください。実稼働目的では、各リポジトリを個別のストレージに保存し、少なくとも1つのリモートリポジトリを構成することをお勧めします。

[global]
#  repository details

repo1-path=/var/lib/edb/as13/backups/repo1
repo1-retention-full=1
repo2-path=/var/lib/edb/as13/backups/repo2
repo2-retention-full=1

#  general options

process-max=2
log-level-console=info
log-level-file=debug
start-fast=y
delta=y

[demo]
pg1-path=/var/lib/edb/as13/data
pg1-user=enterprisedb
pg1-port=5444

安全上の理由から、 --repo オプションは構成ファイルで定義できません。定義すると、警告がトリガーされます:WARN: configuration file contains command-line only option 'repo' 。複数のリポジトリが構成されており、コマンドに--repo オプションが指定されていない場合、優先順位が最も高いリポジトリ(たとえば、 repo1 次に repo2 )が選択されます。

repo1 のみが下位互換性を維持するように構成されている場合、 --repo オプションは必要ありません。ただし、単一のリポジトリが構成されている場合、構成で repo1 を使用することをお勧めします。

初期化

スタンザ作成コマンド

stanza-create コマンドは、構成されているすべてのリポジトリで自動的に動作します。

$ pgbackrest --stanza=demo stanza-create
P00   INFO: stanza-create for stanza demo on repo1
P00   INFO: stanza-create for stanza demo on repo2

チェックコマンド

check コマンドは、新しいWALセグメントのアーカイブをトリガーし、定義されたすべてのリポジトリにプッシュしようとします。

$ pgbackrest --stanza=demo check
P00   INFO: check repo1 configuration (primary)
P00   INFO: check repo2 configuration (primary)
P00   INFO: check repo1 archive for WAL (primary)
P00   INFO: WAL segment ... successfully archived to ... on repo1
P00   INFO: check repo2 archive for WAL (primary)
P00   INFO: WAL segment ... successfully archived to ... on repo2

アーカイブプッシュコマンド

archive-push コマンドは、構成されたすべてのリポジトリにWALを常にアーカイブします。バックアップは、リポジトリごとに個別にスケジュールする必要があります。バックアップの種類と保持はリポジトリごとに異なる可能性があるため、ほとんどの場合、これが望ましいです。

archive_command は引き続き通常どおりに定義できます。

$ psql -d postgres -c "show archive_command;"
             archive_command
- -----------------------------------------
 pgbackrest --stanza=demo archive-push %p
(1 row)

これは、 archive-push アクティビティを示すPostgreSQLログのDEBUG 抽出です。

...
P00  DEBUG:     storage/storage::storageNewWrite: => {
    type: posix, name: {"/var/lib/edb/as13/backups/repo1/archive/demo/13-1/0000000100000000/
                            000000010000000000000005-be9a61a800934879842fa647b0d50385f44e0228.gz"},
    modeFile: 0640, modePath: 0750, createPath: true, syncFile: true, syncPath: true, atomic: true}
...
P00  DEBUG:     storage/storage::storageNewWrite: => {
    type: posix, name: {"/var/lib/edb/as13/backups/repo2/archive/demo/13-1/0000000100000000/
                            000000010000000000000005-be9a61a800934879842fa647b0d50385f44e0228.gz"},
    modeFile: 0640, modePath: 0750, createPath: true, syncFile: true, syncPath: true, atomic: true}
...
P00   INFO: pushed WAL file 000000010000000000000005 to the archive

archive-push コマンドは、WALアーカイブを到達可能なすべてのリポジトリにプッシュしようとします。考え方は、WALファイルが削除されないようにPostgreSQLにエラーをスローする必要がある場合でも、できるだけ多くのリポジトリにアーカイブすることです。

P00   INFO: archive-push command begin: [pg_wal/000000010000000000000006] ...
...
P00   INFO: archive-push command begin: [pg_wal/000000010000000000000007] ...
ERROR: [104]: archive-push command encountered error(s):
       repo2: [PathOpenError] unable to list file info for path ...: [13] Permission denied
P00   INFO: archive-push command end: aborted with exception [104]
DETAIL:  The failed archive command was: pgbackrest --stanza=demo archive-push pg_wal/000000010000000000000007
WARNING:  archiving write-ahead log file "000000010000000000000007" failed too many times, will try again later

PostgreSQL archiver プロセスはエラーを報告するはずです。

$ ps -o pid,cmd fx |grep archiver
 4440  \_ postgres: archiver failed on 000000010000000000000007

次のWALセグメントはアーカイブしないでください。

$ psql -d postgres -c "SELECT pg_create_restore_point(generate some activity); SELECT pg_switch_wal();"
 pg_switch_wal
- --------------
 0/80001C8
(1 row)

$ ls as13/data/pg_wal/archive_status/ |grep ".ready"
000000010000000000000007.ready
000000010000000000000008.ready

pgBackRest自分自身内で非同期アーカイブプロセスを使用するためにarchive-async=y を構成に追加すると、これは非常に便利になります。 PostgreSQL archiver プロセスがまだスタックしている場合でも、アーカイブは作業リポジトリに到達します。

$ $ ls /var/lib/edb/as13/backups/repo1/archive/demo/13-1/0000000100000000/
000000010000000000000005-be9a61a800934879842fa647b0d50385f44e0228.gz
000000010000000000000006-7108296955e1208c93447dcfc5712ce59af97907.gz
000000010000000000000007-f1b6fcdd23e96a19a7a89dc92613674c2316aa49.gz
000000010000000000000008-791c44d39ef772d58e51d64c8e3589231d3916a4.gz
000000010000000000000009-47241214eb3fd5e693eed778caa7b304a778ecc2.gz

$ ls /var/lib/edb/as13/backups/repo2/archive/demo/13-1/0000000100000000/
000000010000000000000005-be9a61a800934879842fa647b0d50385f44e0228.gz
000000010000000000000006-7108296955e1208c93447dcfc5712ce59af97907.gz

さらに進む前に、 archiver プロセスのブロックを解除(および非同期アーカイブを削除)しましょう。

$ $ ps -o pid,cmd fx |grep archiver
 4440  \_ postgres: archiver last was 00000001000000000000000

バックアップ

バックアップコマンド

いくつかのバックアップを取りましょう。

$ pgbackrest backup --stanza=demo --type=full
P00   INFO: backup command begin ...
P00   INFO: repo option not specified, defaulting to repo1
P00   INFO: execute non-exclusive pg_start_backup(): backup begins after the requested immediate checkpoint completes
P00   INFO: backup start archive = 00000001000000000000000C, lsn = 0/C000060
P00   INFO: full backup size = 50.4MB
P00   INFO: execute non-exclusive pg_stop_backup() and wait for all WAL segments to archive
P00   INFO: backup stop archive = 00000001000000000000000C, lsn = 0/C000138
P00   INFO: check archive for segment(s) 00000001000000000000000C:00000001000000000000000C
P00   INFO: new backup label = 20210419-142212F
P00   INFO: backup command end: completed successfully

$ pgbackrest backup --stanza=demo --type=full --repo=2
P00   INFO: backup command begin ...
P00   INFO: execute non-exclusive pg_start_backup(): backup begins after the requested immediate checkpoint completes
P00   INFO: backup start archive = 00000001000000000000000E, lsn = 0/E000028
P00   INFO: full backup size = 50.5MB
P00   INFO: execute non-exclusive pg_stop_backup() and wait for all WAL segments to archive
P00   INFO: backup stop archive = 00000001000000000000000E, lsn = 0/E000138
P00   INFO: check archive for segment(s) 00000001000000000000000E:00000001000000000000000E
P00   INFO: new backup label = 20210419-142414F
P00   INFO: backup command end: completed successfully

$ pgbackrest backup --stanza=demo --type=incr --repo=1
P00   INFO: backup command begin ...
P00   INFO: last backup label = 20210419-142212F, version = ...
P00   INFO: execute non-exclusive pg_start_backup(): backup begins after the requested immediate checkpoint completes
P00   INFO: backup start archive = 000000010000000000000010, lsn = 0/10000028
P00   INFO: incr backup size = 50.5MB
P00   INFO: execute non-exclusive pg_stop_backup() and wait for all WAL segments to archive
P00   INFO: backup stop archive = 000000010000000000000010, lsn = 0/10000100
P00   INFO: check archive for segment(s) 000000010000000000000010:000000010000000000000010
P00   INFO: new backup label = 20210419-142212F_20210419-142502I
P00   INFO: backup command end: completed successfully

$ pgbackrest backup --stanza=demo --type=incr --repo=2
P00   INFO: backup command begin ...
P00   INFO: last backup label = 20210419-142414F, version = ...
P00   INFO: execute non-exclusive pg_start_backup(): backup begins after the requested immediate checkpoint completes
P00   INFO: backup start archive = 000000010000000000000012, lsn = 0/12000028
P00   INFO: incr backup size = 50.6MB
P00   INFO: execute non-exclusive pg_stop_backup() and wait for all WAL segments to archive
P00   INFO: backup stop archive = 000000010000000000000012, lsn = 0/12000100
P00   INFO: check archive for segment(s) 000000010000000000000012:000000010000000000000012
P00   INFO: new backup label = 20210419-142414F_20210419-142556I
P00   INFO: backup command end: completed successfully

ここでは、各リポジトリでfull とincr のバックアップを交互に使用しました。

情報コマンド

$ pgbackrest info --stanza=demo
stanza: demo
    status: ok
    cipher: none

    db (current)
        wal archive min/max (13): 000000010000000000000002/000000010000000000000012

        full backup: 20210419-142212F
            timestamp start/stop: 2021-04-19 14:22:12 / 2021-04-19 14:22:26
            wal start/stop: 00000001000000000000000C / 00000001000000000000000C
            database size: 50.4MB, database backup size: 50.4MB
            repo1: backup set size: 8MB, backup size: 8MB

        full backup: 20210419-142414F
            timestamp start/stop: 2021-04-19 14:24:14 / 2021-04-19 14:24:26
            wal start/stop: 00000001000000000000000E / 00000001000000000000000E
            database size: 50.5MB, database backup size: 50.5MB
            repo2: backup set size: 8MB, backup size: 8MB

        incr backup: 20210419-142212F_20210419-142502I
            timestamp start/stop: 2021-04-19 14:25:02 / 2021-04-19 14:25:04
            wal start/stop: 000000010000000000000010 / 000000010000000000000010
            database size: 50.5MB, database backup size: 613.4KB
            repo1: backup set size: 8MB, backup size: 26.3KB
            backup reference list: 20210419-142212F

        incr backup: 20210419-142414F_20210419-142556I
            timestamp start/stop: 2021-04-19 14:25:56 / 2021-04-19 14:25:57
            wal start/stop: 000000010000000000000012 / 000000010000000000000012
            database size: 50.6MB, database backup size: 661.5KB
            repo2: backup set size: 8MB, backup size: 28KB
            backup reference list: 20210419-142414F

デフォルトの順序では、リポジトリが混在する日付でバックアップがソートされます。相互に依存するバックアップを見つけるのは難しい場合があります。

次に、このビューをリポジトリごとに分割できます。

$ pgbackrest info --stanza=demo --repo=1
stanza: demo
    status: ok
    cipher: none

    db (current)
        wal archive min/max (13): 00000001000000000000000C/000000010000000000000012

        full backup: 20210419-142212F
            timestamp start/stop: 2021-04-19 14:22:12 / 2021-04-19 14:22:26
            wal start/stop: 00000001000000000000000C / 00000001000000000000000C
            database size: 50.4MB, database backup size: 50.4MB
            repo1: backup set size: 8MB, backup size: 8MB

        incr backup: 20210419-142212F_20210419-142502I
            timestamp start/stop: 2021-04-19 14:25:02 / 2021-04-19 14:25:04
            wal start/stop: 000000010000000000000010 / 000000010000000000000010
            database size: 50.5MB, database backup size: 613.4KB
            repo1: backup set size: 8MB, backup size: 26.3KB
            backup reference list: 20210419-142212F

$ pgbackrest info --stanza=demo --repo=2
stanza: demo
    status: ok
    cipher: none

    db (current)
        wal archive min/max (13): 00000001000000000000000E/000000010000000000000012

        full backup: 20210419-142414F
            timestamp start/stop: 2021-04-19 14:24:14 / 2021-04-19 14:24:26
            wal start/stop: 00000001000000000000000E / 00000001000000000000000E
            database size: 50.5MB, database backup size: 50.5MB
            repo2: backup set size: 8MB, backup size: 8MB

        incr backup: 20210419-142414F_20210419-142556I
            timestamp start/stop: 2021-04-19 14:25:56 / 2021-04-19 14:25:57
            wal start/stop: 000000010000000000000012 / 000000010000000000000012
            database size: 50.6MB, database backup size: 661.5KB
            repo2: backup set size: 8MB, backup size: 28KB
            backup reference list: 20210419-142414F

‘walarchivemin/max’ は、現在アーカイブに保存されているWALの最小値と最大値を示し、マルチプルのリポジトリの場合、 --repo オプションが設定されていない限り、すべてのリポジトリで報告されます。アーカイブの保持ポリシーまたはその他の理由により、ギャップが生じる場合があります。

そのコンテンツを削除して、最初のリポジトリを壊しましょう。

$ pgbackrest --stanza=demo stanza-delete --repo=1 --force
P00   INFO: stanza-delete command end: completed successfully

$ pgbackrest --stanza=demo stanza-create
P00   INFO: stanza-create for stanza demo on repo1
P00   INFO: stanza-create for stanza demo on repo2
P00   INFO: stanza demo already exists on repo2 and is valid
P00   INFO: stanza-create command end: completed successfully

複数のリポジトリーが構成されている場合、ステータス mixed は、1つ以上のリポジトリーでスタンザが正常な状態でないことを示します。この場合、スタンザの状態はリポジトリーごとに追加の行で詳細に説明されます。

$ pgbackrest info --stanza=demo
stanza: demo
    status: mixed
        repo1: error (no valid backups)
        repo2: ok
    cipher: none

    db (current)
        wal archive min/max (13): 00000001000000000000000E/000000010000000000000012

        full backup: 20210419-142414F
            timestamp start/stop: 2021-04-19 14:24:14 / 2021-04-19 14:24:26
            wal start/stop: 00000001000000000000000E / 00000001000000000000000E
            database size: 50.5MB, database backup size: 50.5MB
            repo2: backup set size: 8MB, backup size: 8MB

        incr backup: 20210419-142414F_20210419-142556I
            timestamp start/stop: 2021-04-19 14:25:56 / 2021-04-19 14:25:57
            wal start/stop: 000000010000000000000012 / 000000010000000000000012
            database size: 50.6MB, database backup size: 661.5KB
            repo2: backup set size: 8MB, backup size: 28KB
            backup reference list: 20210419-142414F

この状態は、新しいバックアップを作成することで解決できます。

$ pgbackrest backup --stanza=demo --type=full --repo=1
P00   INFO: backup command begin ...
P00   INFO: execute non-exclusive pg_start_backup(): backup begins after the requested immediate checkpoint completes
P00   INFO: backup start archive = 000000010000000000000014, lsn = 0/14000028
P00   INFO: full backup size = 50.6MB
P00   INFO: execute non-exclusive pg_stop_backup() and wait for all WAL segments to archive
P00   INFO: backup stop archive = 000000010000000000000014, lsn = 0/14000138
P00   INFO: check archive for segment(s) 000000010000000000000014:000000010000000000000014
P00   INFO: new backup label = 20210419-143400F
P00   INFO: backup command end: completed successfully

復元

いくつかのデータ、バックアップ、および復元ポイントで状況を開始しましょう。

$ createdb test
$ psql -d test -c "CREATE TABLE t1(id int);"
CREATE TABLE
$ psql -d test -c "INSERT INTO t1 VALUES (1);"
INSERT 0 1

$ pgbackrest backup --stanza=demo --type=full --repo=1
P00   INFO: backup command begin ...
P00   INFO: execute non-exclusive pg_start_backup(): backup begins after the requested immediate checkpoint completes
P00   INFO: backup start archive = 000000010000000000000016, lsn = 0/16000028
P00   INFO: full backup size = 63.0MB
P00   INFO: execute non-exclusive pg_stop_backup() and wait for all WAL segments to archive
P00   INFO: backup stop archive = 000000010000000000000016, lsn = 0/16000138
P00   INFO: check archive for segment(s) 000000010000000000000016:000000010000000000000016
P00   INFO: new backup label = 20210419-143643F
P00   INFO: backup command end: completed successfully
P00   INFO: expire command begin ...
P00   INFO: repo1: expire full backup 20210419-143400F
P00   INFO: repo1: remove expired backup 20210419-143400F
P00   INFO: expire command end: completed successfully

$ psql -d test -c "INSERT INTO t1 VALUES (2);"
INSERT 0 1
$ pgbackrest backup --stanza=demo --type=full --repo=2
P00   INFO: backup command begin ...
P00   INFO: execute non-exclusive pg_start_backup(): backup begins after the requested immediate checkpoint completes
P00   INFO: backup start archive = 000000010000000000000018, lsn = 0/18000028
P00   INFO: full backup size = 63MB
P00   INFO: execute non-exclusive pg_stop_backup() and wait for all WAL segments to archive
P00   INFO: backup stop archive = 000000010000000000000018, lsn = 0/18000138
P00   INFO: check archive for segment(s) 000000010000000000000018:000000010000000000000018
P00   INFO: new backup label = 20210419-143749F
P00   INFO: backup command end: completed successfully
P00   INFO: expire command begin ...
P00   INFO: repo2: expire full backup set 20210419-142414F, 20210419-142414F_20210419-142556I
P00   INFO: repo2: remove expired backup 20210419-142414F_20210419-142556I
P00   INFO: repo2: remove expired backup 20210419-142414F
P00   INFO: expire command end: completed successfully

$ psql -d postgres -c "select pg_create_restore_point(RP1);"
 pg_create_restore_point
- ------------------------
 0/190000C8
(1 row)

$ psql -d postgres -Atc "select current_timestamp,current_setting(datestyle),txid_current();"
19-APR-21 14:38:55.313716 +00:00|Redwood, SHOW_TIME|1183

$ psql -d test -c "INSERT INTO t1 VALUES (3); SELECT pg_switch_wal();"
 pg_switch_wal
- --------------
 0/19000238
(1 row)

$ pgbackrest info --stanza=demo
stanza: demo
    status: ok
    cipher: none

    db (current)
        wal archive min/max (13): 000000010000000000000016/000000010000000000000019

        full backup: 20210419-143643F
            timestamp start/stop: 2021-04-19 14:36:43 / 2021-04-19 14:37:01
            wal start/stop: 000000010000000000000016 / 000000010000000000000016
            database size: 63.0MB, database backup size: 63.0MB
            repo1: backup set size: 10MB, backup size: 10MB

        full backup: 20210419-143749F
            timestamp start/stop: 2021-04-19 14:37:49 / 2021-04-19 14:38:03
            wal start/stop: 000000010000000000000018 / 000000010000000000000018
            database size: 63MB, database backup size: 63MB
            repo2: backup set size: 10MB, backup size: 10MB

上記の例でわかるように、 backup コマンドは、バックアップを作成したときにリポジトリでexpire コマンドを自動的にトリガーしました。このコマンドは1つのリポジトリでのみ動作するため、そのリポジトリに対して backup または expire コマンドが実行されるまで、他のリポジトリの有効期限はありません。

デフォルトの保持ポリシーは多数のバックアップに基づいているため、新しいバックアップのみがバックアップとアーカイブに影響を与えることが予想されます。

復元コマンド

restoreコマンドは、デフォルトで、バックアップが存在する最初のリポジトリから最新のバックアップを選択します。リポジトリがチェックされる順序は、 pgbackrest.conf で構成されたリポジトリの順序によって指示されます(たとえば、repo1はrepo2の前にチェックされます)。特定のリポジトリから復元するには、 --repo オプションを使用できます。

--type=time を指定し、 --target でターゲットタイムを指定することでPITRを行うことができます。 --set オプションでバックアップが指定されていない場合、構成されたリポジトリで、要求された時間が含まれているかどうかがチェックされます。バックアップが見つからない場合、バックアップを含む最初のリポジトリからの最新のバックアップが使用されます。

$ mkdir /tmp/restored_data
$ pgbackrest restore --stanza=demo --target="RP1" --type=name --no-delta --pg1-path=/tmp/restored_data
P00   INFO: repo1: restore backup set 20210419-143643F

$ rm -rf /tmp/restored_data/*
$ pgbackrest restore --stanza=demo --target="2021-04-19 14:38:55.313716+00:00" --type=time --no-delta --pg1-path=/tmp/restored_data
HINT: time format must be YYYY-MM-DD HH:MM:SS with optional msec and optional timezone (+/- HH or HHMM or HH:MM)
    - if timezone is omitted, local time is assumed (for UTC use +00)
P00   INFO: repo1: restore backup set 20210419-143643F

$ rm -rf /tmp/restored_data/*
$ pgbackrest restore --stanza=demo --target="RP1" --type=name --no-delta --pg1-path=/tmp/restored_data --repo=2
P00   INFO: repo2: restore backup set 20210419-143749F

repo2 のバックアップの方が新しい場合でも、最初に見つかった一致が保持されます。 repo1 で新しいバックアップを作成して、pgBackRestが repo2 のバックアップを自動選択するかどうかを確認しましょう。

$ pgbackrest backup --stanza=demo --type=full --repo=1
P00   INFO: backup command begin ...
P00   INFO: execute non-exclusive pg_start_backup(): backup begins after the requested immediate checkpoint completes
P00   INFO: backup start archive = 00000001000000000000001B, lsn = 0/1B000028
P00   INFO: full backup size = 63MB
P00   INFO: execute non-exclusive pg_stop_backup() and wait for all WAL segments to archive
P00   INFO: backup stop archive = 00000001000000000000001B, lsn = 0/1B000138
P00   INFO: check archive for segment(s) 00000001000000000000001B:00000001000000000000001B
P00   INFO: new backup label = 20210419-144656F
P00   INFO: backup command end: completed successfully
P00   INFO: expire command begin ...
P00   INFO: repo1: expire full backup 20210419-143643F
P00   INFO: repo1: remove expired backup 20210419-143643F
P00   INFO: expire command end: completed successfully

$ pgbackrest info --stanza=demo
stanza: demo
    status: ok
    cipher: none

    db (current)
        wal archive min/max (13): 000000010000000000000018/00000001000000000000001B

        full backup: 20210419-143749F
            timestamp start/stop: 2021-04-19 14:37:49 / 2021-04-19 14:38:03
            wal start/stop: 000000010000000000000018 / 000000010000000000000018
            database size: 63MB, database backup size: 63MB
            repo2: backup set size: 10MB, backup size: 10MB

        full backup: 20210419-144656F
            timestamp start/stop: 2021-04-19 14:46:56 / 2021-04-19 14:47:10
            wal start/stop: 00000001000000000000001B / 00000001000000000000001B
            database size: 63MB, database backup size: 63MB
            repo1: backup set size: 10MB, backup size: 10MB

$ rm -rf /tmp/restored_data/*
$ pgbackrest restore --stanza=demo --target="2021-04-19 14:38:55.313716+00:00" --type=time --no-delta --pg1-path=/tmp/restored_data
P00   INFO: repo2: restore backup set 20210419-143749F

リカバリープロセスはターゲットによっては複雑で注意が必要な場合があるため、 info コマンドは、復元するリポジトリーを決定するのに役立ちます。

アーカイブ取得コマンド

複数のリポジトリが設定されている場合、WALはリポジトリから優先順位に従ってフェッチされます(例、 repo1 、repo2 など)。一般に、より高速なストレージの優先度が高い方が良いでしょう。このコマンドは、 --repo オプションで指定することにより、単一のリポジトリーを操作できます。

root# systemctl stop edb-as-13.service
$ mv /var/lib/edb/as13/data /var/lib/edb/as13/data.orig
$ mkdir -m 700 /var/lib/edb/as13/data

$ pgbackrest restore --stanza=demo --target="2021-04-19 14:38:55.313716+00:00" --type=time --no-delta --target-action=promote
P00   INFO: restore command begin ...
P00   INFO: write updated /var/lib/edb/as13/data/postgresql.auto.conf
P00   INFO: restore global/pg_control (performed last to ensure aborted restores cannot be started)
P00   INFO: restore command end: completed successfully

$ cat /var/lib/edb/as13/data/postgresql.auto.conf|grep restore_command
restore_command = pgbackrest --stanza=demo archive-get %f "%p"

root# systemctl start edb-as-13.service
$ cat /var/lib/edb/as13/data/log/edb-2021-04-19_145147.log
...
LOG:  starting point-in-time recovery to 2021-04-19 14:38:55.313716+00
P00   INFO: found 000000010000000000000018 in the repo2: 13-1 archive
P00   INFO: found 000000010000000000000019 in the repo2: 13-1 archive
LOG:  recovery stopping before commit of transaction 1183, time 2021-04-19 14:38:55.314118+00
LOG:  redo done at 0/19000100
P00   INFO: unable to find 00000002.history in the archive
LOG:  selected new timeline ID: 2
LOG:  archive recovery complete
P00   INFO: pushed WAL file 00000002.history to the archive

$ ls /var/lib/edb/as13/backups/repo*/archive/demo/13-1/00000002.history
/var/lib/edb/as13/backups/repo1/archive/demo/13-1/00000002.history
/var/lib/edb/as13/backups/repo2/archive/demo/13-1/00000002.history

PostgreSQLは、回復に必要なWALを repo2 で検出し、新しいタイムラインを選択して、履歴ファイルをリポジトリにプッシュしました。

新しいタイムラインが作成されるたびに、PostgreSQLは、いつどのタイムラインから分岐したかを示すタイムライン履歴ファイルを作成します。これらの履歴ファイルは、複数のタイムラインを含むバックアップから回復するときに、システムが適切なWALセグメントファイルを選択できるようにするために必要です。

root# systemctl stop edb-as-13.service
$ rm -rf /var/lib/edb/as13/data/*
$ rm -rf /var/lib/edb/as13/backups/repo1/archive/demo/13-1/00000002.history
$ pgbackrest restore --stanza=demo --target="2021-04-19 14:38:55.313716+00:00" --type=time --target-timeline=current --no-delta --target-action=promote
P00   INFO: restore command begin ...
P00   INFO: repo2: restore backup set 20210419-143749F
P00   INFO: write updated /var/lib/edb/as13/data/postgresql.auto.conf
P00   INFO: restore global/pg_control (performed last to ensure aborted restores cannot be started)
P00   INFO: restore command end: completed successfully

root# systemctl start edb-as-13.service
$ cat /var/lib/edb/as13/data/log/edb-2021-04-19_145721.log
P00   INFO: found 00000002.history in the repo2: 13-1 archive
P00   INFO: unable to find 00000003.history in the archive
LOG:  selected new timeline ID: 3
P00   INFO: pushed WAL file 00000003.history to the archive

上記のように、履歴ファイルは復元されたバックアップセットと同じリポジトリ内に保存されるため、PostgreSQLは新しい正確なタイムラインを選択できます。

履歴ファイルを repo1 に移動してから、リトライしてみましょう。

root# systemctl stop edb-as-13.service
$ rm -rf /var/lib/edb/as13/data/*
$ mv /var/lib/edb/as13/backups/repo2/archive/demo/13-1/00000002.history /var/lib/edb/as13/backups/repo1/archive/demo/13-1/00000002.history
$ pgbackrest restore --stanza=demo --target="2021-04-19 14:38:55.313716+00:00" --type=time --target-timeline=current --no-delta --target-action=promote
root# systemctl start edb-as-13.service
$ cat /var/lib/edb/as13/data/log/edb-2021-04-19_150037.log
P00   INFO: found 00000002.history in the repo1: 13-1 archive
P00   INFO: found 00000003.history in the repo1: 13-1 archive
P00   INFO: unable to find 00000004.history in the archive
LOG:  selected new timeline ID: 4
P00   INFO: pushed WAL file 00000004.history to the archive

ご覧のとおり、 00000002.history と00000003.history の両方が repo1 で見つかったため、復元されたバックアップセットが repo2 からのものであっても、PostgreSQLは次のタイムラインを正しく選択できました。

複数のリポジトリを使用する場合、 archive-get コマンドは、主に他のリポジトリで不足しているファイルを見つけることができるため、1つのリポジトリでのギャップ(ディスク領域の不足など)を許容します。