Retention
Generally it is best to retain as many backups as possible to provide a greater window for Point-in-Time Recovery, but practical concerns such as disk space must also be considered. Retention options remove older backups once they are no longer needed.
Full Backup Retention
Set repo1-retention-full
to the number of full backups required. New backups must be completed before expiration will occur — that means if repo1-retention-full=2 then there will be three full backups stored before the oldest one is expired.
# pg-primary:/etc/pgbackrest/pgbackrest.conf ⇒ Configure repo1-retention-full
[demo]
pg1-path=/var/lib/postgresql/9.4/demo
[global]
repo1-cipher-pass=zWaf6XtpjIVZC5444yXB+cgFDFl7MxGlgkZSaoPvTGirhPygu4jOKOXf9LO4vjfO
repo1-cipher-type=aes-256-cbc
repo1-path=/var/lib/pgbackrest
repo1-retention-full=2
start-fast=y
stop-auto=y
[global:archive-push]
compress-level=3
Backup repo1-retention-full=2
but currently there is only one full backup so the next full backup to run will not expire any full backups.
# pg-primary ⇒ Perform a full backup
sudo -u postgres pgbackrest --stanza=demo --type=full \
--log-level-console=detail backup
[filtered 763 lines of output]
P00 INFO: backup command end: completed successfully
P00 INFO: expire command begin
P00 DETAIL: archive retention on backup 20180506-151611F, archiveId = 9.4-1, start = 000000010000000000000002
P00 DETAIL: no archive to remove, archiveId = 9.4-1
P00 INFO: expire command end: completed successfully
Archive is expired because WAL segments were generated before the oldest backup. These are not useful for recovery — only WAL segments generated after a backup can be used to recover that backup.
# pg-primary ⇒ Perform a full backup
sudo -u postgres pgbackrest --stanza=demo --type=full \
--log-level-console=info backup
[filtered 763 lines of output]
P00 INFO: backup command end: completed successfully
P00 INFO: expire command begin
P00 INFO: expire full backup set: 20180506-151611F, 20180506-151611F_20180506-151616D, 20180506-151611F_20180506-151632I, 20180506-151611F_20180506-151637I, 20180506-151611F_20180506-151645I
P00 INFO: remove expired backup 20180506-151611F_20180506-151645I
P00 INFO: remove expired backup 20180506-151611F_20180506-151637I
[filtered 3 lines of output]
The 20180506-151611F
full backup is expired and archive retention is based on the 20180506-151655F
which is now the oldest full backup.
Differential Backup Retention
Set repo1-retention-diff
to the number of differential backups required. Differentials only rely on the prior full backup so it is possible to create a rolling set of differentials for the last day or more. This allows quick restores to recent points-in-time but reduces overall space consumption.
# pg-primary:/etc/pgbackrest/pgbackrest.conf ⇒ Configure repo1-retention-diff
[demo]
pg1-path=/var/lib/postgresql/9.4/demo
[global]
repo1-cipher-pass=zWaf6XtpjIVZC5444yXB+cgFDFl7MxGlgkZSaoPvTGirhPygu4jOKOXf9LO4vjfO
repo1-cipher-type=aes-256-cbc
repo1-path=/var/lib/pgbackrest
repo1-retention-diff=1
repo1-retention-full=2
start-fast=y
stop-auto=y
[global:archive-push]
compress-level=3
Backup repo1-retention-diff=1
so two differentials will need to be performed before one is expired. An incremental backup is added to demonstrate incremental expiration. Incremental backups cannot be expired independently — they are always expired with their related full or differential backup.
# pg-primary ⇒ Perform differential and incremental backups
sudo -u postgres pgbackrest --stanza=demo --type=diff backup
sudo -u postgres pgbackrest --stanza=demo --type=incr backup
Now performing a differential backup will expire the previous differential and incremental backups leaving only one differential backup.
# pg-primary ⇒ Perform a differential backup
sudo -u postgres pgbackrest --stanza=demo --type=diff \
--log-level-console=info backup
[filtered 10 lines of output]
P00 INFO: backup command end: completed successfully
P00 INFO: expire command begin
P00 INFO: expire diff backup set: 20180506-151702F_20180506-151709D, 20180506-151702F_20180506-151714I
P00 INFO: remove expired backup 20180506-151702F_20180506-151714I
P00 INFO: remove expired backup 20180506-151702F_20180506-151709D
Archive Retention
Although pgBackRest automatically removes archived WAL segments when expiring backups (the default expires WAL for full backups based on the repo1-retention-full option), it may be useful to expire archive more aggressively to save disk space. Note that full backups are treated as differential backups for the purpose of differential archive retention.
Expiring archive will never remove WAL segments that are required to make a backup consistent. However, since Point-in-Time-Recovery (PITR) only works on a continuous WAL stream, care should be taken when aggressively expiring archive outside of the normal backup expiration process.
# pg-primary:/etc/pgbackrest/pgbackrest.conf ⇒ Configure repo1-retention-diff
[demo]
pg1-path=/var/lib/postgresql/9.4/demo
[global]
repo1-cipher-pass=zWaf6XtpjIVZC5444yXB+cgFDFl7MxGlgkZSaoPvTGirhPygu4jOKOXf9LO4vjfO
repo1-cipher-type=aes-256-cbc
repo1-path=/var/lib/pgbackrest
repo1-retention-diff=2
repo1-retention-full=2
start-fast=y
stop-auto=y
[global:archive-push]
compress-level=3
# pg-primary ⇒ Perform differential backup
sudo -u postgres pgbackrest --stanza=demo --type=diff \
--log-level-console=info backup
[filtered 7 lines of output]
P00 INFO: execute exclusive pg_stop_backup() and wait for all WAL segments to archive
P00 INFO: backup stop archive = 000000020000000000000014, lsn = 0/140000F0
P00 INFO: new backup label = 20180506-151702F_20180506-151724D
P00 INFO: backup command end: completed successfully
P00 INFO: expire command begin
# pg-primary ⇒ Expire archive
sudo -u postgres pgbackrest --stanza=demo --log-level-console=detail \
--repo1-retention-archive-type=diff --repo1-retention-archive=1 expire
P00 INFO: expire command begin 2.02: --log-level-console=detail --log-level-stderr=off --no-log-timestamp --repo1-cipher-pass= --repo1-cipher-type=aes-256-cbc --repo1-path=/var/lib/pgbackrest --repo1-retention-archive=1 --repo1-retention-archive-type=diff --repo1-retention-diff=2 --repo1-retention-full=2 --stanza=demo
P00 DETAIL: archive retention on backup 20180506-151655F, archiveId = 9.4-1, start = 00000002000000000000000B, stop = 00000002000000000000000B
P00 DETAIL: archive retention on backup 20180506-151702F, archiveId = 9.4-1, start = 00000002000000000000000C, stop = 00000002000000000000000C
P00 DETAIL: archive retention on backup 20180506-151702F_20180506-151718D, archiveId = 9.4-1, start = 000000020000000000000010, stop = 000000020000000000000010
P00 DETAIL: archive retention on backup 20180506-151702F_20180506-151724D, archiveId = 9.4-1, start = 000000020000000000000014
P00 DETAIL: remove archive: archiveId = 9.4-1, start = 00000002000000000000000D, stop = 00000002000000000000000F
P00 DETAIL: remove archive: archiveId = 9.4-1, start = 000000020000000000000011, stop = 000000020000000000000013
P00 INFO: expire command end: completed successfully
The 20180506-151702F_20180506-151718D
differential backup has archived WAL segments that must be retained to make the older backups consistent even though they cannot be played any further forward with PITR. WAL segments generated after 20180506-151702F_20180506-151718D
but before 20180506-151702F_20180506-151724D
are removed. WAL segments generated after the new backup 20180506-151702F_20180506-151724D
remain and can be used for PITR.
Since full backups are considered differential backups for the purpose of differential archive retention, if a full backup is now performed with the same settings, only the archive for that full backup is retained for PITR.