Migrating Barman directory without loss of backups and WALs

Godson Tanyi
Godson Tanyi

This article explains how to move the Barman directory to a new mount point without loss of existing backups and WALs.

In the below test case, we are relocating the Barman directory for a server named primary. The Barman data for this server is initially located under /var/lib/barman/<SERVER_NAME>.

The steps below are required to change the Barman location for this server:

1- Disable the barman cron job

This is usually achieved by commenting out the contents of /etc/cron.d/barman, e.g.:

# /etc/cron.d/barman: crontab entries for the barman package
MAILTO=root
#* * * * * barman /etc/tpa/barman-home-ok && /usr/bin/barman -q cron

This is required so that the Barman receive-wal process is not automatically restarted by the cron job during the process.

2- Run barman check and confirm it's all OK

$ barman check primary
Server primary:
PostgreSQL: OK
superuser or standard user with backup privileges: OK
PostgreSQL streaming: OK
wal_level: OK
replication slot: OK
directories: OK
retention policy settings: OK
backup maximum age: OK (interval provided: 7 days, latest backup age: 2 hours, 3 minutes, 50 seconds)
backup minimum size: OK (1.1 KiB)
wal maximum age: OK (no last_wal_maximum_age provided)
wal size: OK (372.5 KiB)
compression settings: OK
failed backups: OK (there are 0 failed backups)
minimum redundancy requirements: OK (have 7 backups, expected at least 3)
ssh: OK (PostgreSQL server)
systemid coherence: OK
pg_receivexlog: OK
pg_receivexlog compatible: OK
receive-wal running: OK
archive_mode: OK
archive_command: OK
continuous archiving: OK
archiver errors: OK

3- Verify no backups are currently ongoing

One way of doing this is to use barman list-backup SERVER as this will show any ongoing backups as being in state STARTED, e.g.:

$ barman list-backup primary
primary 20230125T140633 - STARTED

If the command only shows completed backups then there should be no ongoing backups, e.g.:

$ barman list-backup primary
primary 20230125T140633 - Wed Jan 25 14:08:10 2023 - Size: 25.4 MiB - WAL Size: 0 B (tablespaces: tbs1:/opt/postgres/tablespaces/tbs1/tablespace_data)
primary 20230125T115711 - Wed Jan 25 11:58:31 2023 - Size: 19.2 MiB - WAL Size: 408.5 KiB (tablespaces: tbs1:/opt/postgres/tablespaces/tbs1/tablespace_data)
primary 20230125T115547 - Wed Jan 25 11:56:59 2023 - Size: 19.2 MiB - WAL Size: 36.1 KiB (tablespaces: tbs1:/opt/postgres/tablespaces/tbs1/tablespace_data)
primary 20230125T112956 - Wed Jan 25 11:31:00 2023 - Size: 20.8 MiB - WAL Size: 150.1 KiB (tablespaces: tbs1:/opt/postgres/tablespaces/tbs1/tablespace_data)

4- Set the server as inactive in the Barman configuration

$ grep /etc/barman.d/primary.conf
active = false

5- Stop barman receive-wal

$ barman receive-wal primary --stop
Stopped process receive-wal(39941)

This will work for a WAL streaming setup but would not work for a setup using archive_command. If archive_command is used, then it needs to be temporarily disabled by setting archive_command = '' in PostgreSQL configuration and reloading the PostgreSQL config with select pg_reload_conf();. Step 14 covers re-enabling it.

6- Create the new location and copy the old backup directory

Make sure ownership and permissions are set correctly:

$ mkdir $NEW_SERVER_DIR
$ chmod 700 $NEW_SERVER_DIR
$ chown barman $NEW_SERVER_DIR

Copy as the barman user so that ownership remains unaffected:

$ cp -r $OLD_SERVER_DIR/* $NEW_SERVER_DIR

7- Verify the copy

As a minimum there should be a .partial file in the streaming directory:

$ ls $NEW_SERVER_DIR/streaming
000000010000000000000022.partial

Note that this only comes into play if WAL streaming is used.

There should also be content in the wals directory:

$ ls -l $NEW_SERVER_DIR/wals
total 8
drwxr-xr-x 2 barman barman 4096 Jan 25 14:15 0000000100000000
-rw-rw-r-- 1 barman barman 1167 Jan 25 14:15 xlog.db

There should also be backups in the base directory:

$ ls -l $NEW_SERVER_DIR/base
total 16
drwxrwxr-x 3 barman barman 4096 Jan 25 14:15 20230125T112956
drwxrwxr-x 3 barman barman 4096 Jan 25 14:15 20230125T115547
drwxrwxr-x 3 barman barman 4096 Jan 25 14:15 20230125T115711
drwxrwxr-x 4 barman barman 4096 Jan 25 14:15 20230125T140633

8- Configure backup_directory to point to the new location

$ grep backup_directory /etc/barman.d/primary.conf
backup_directory = /var/lib/backups/primary

9- Run barman show-server primary and verify the configuration

The following variables should now point to directories under the new path, e.g.:

$ barman show-server primary
...
backup_directory: /var/lib/backups/primary
basebackups_directory: /var/lib/backups/primary/base
errors_directory: /var/lib/backups/primary/errors
incoming_wals_directory: /var/lib/backups/primary/incoming
streaming_wals_directory: /var/lib/backups/primary/streaming
wals_directory: /var/lib/backups/primary/wals
...

You can also pipe the barman show-server command through grep to show only the directories, e.g.: barman show-server main | grep directory.

10- Set the server as active in the Barman configuration

$ grep /etc/barman.d/primary.conf
active = true

11- Verify backups can be listed

Pay particular attention to the Size and WAL Size fields - the WAL Size should be non-zero with the possible exception of the most recent backup.

$ barman list-backups primary
primary 20230125T140633 - Wed Jan 25 14:08:10 2023 - Size: 25.4 MiB - WAL Size: 0 B (tablespaces: tbs1:/opt/postgres/tablespaces/tbs1/tablespace_data)
primary 20230125T115711 - Wed Jan 25 11:58:31 2023 - Size: 19.2 MiB - WAL Size: 408.5 KiB (tablespaces: tbs1:/opt/postgres/tablespaces/tbs1/tablespace_data)
primary 20230125T115547 - Wed Jan 25 11:56:59 2023 - Size: 19.2 MiB - WAL Size: 36.1 KiB (tablespaces: tbs1:/opt/postgres/tablespaces/tbs1/tablespace_data)
primary 20230125T112956 - Wed Jan 25 11:31:00 2023 - Size: 20.8 MiB - WAL Size: 150.1 KiB (tablespaces: tbs1:/opt/postgres/tablespaces/tbs1/tablespace_data)

If anything doesn't look right at this point it is safe to set the server back to inactive and check the previous steps as long as receive-wal has not yet been started.

12- Re-enable the barman cron job

This is usually achieved by un-commenting the contents of /etc/cron.d/barman, e.g.:

# /etc/cron.d/barman: crontab entries for the barman package
MAILTO=root
* * * * * barman /etc/tpa/barman-home-ok && /usr/bin/barman -q cron

13- Restart WAL streaming

barman receive-wal primary

14- Update archive_command in the PostgreSQL config

This step is not necessary if WAL streaming alone is being used. If archive_command is used, however, it will need to be updated so that WALs end up in $NEW_SERVER_DIR.

Once updated it is sufficient to run select pg_reload_conf(); in a PostgreSQL shell to load the new archive_command value.

15- Take new backup to verify changed backup location

$ barman backup primary
WARNING: No backup strategy set for server 'primary' (using default 'concurrent_backup').
Starting backup using rsync-concurrent method for server primary in /var/lib/custom_barman/base/20220629T231431
Backup start at LSN: 0/1B000060 (00000001000000000000001B, 00000060)
This is the first backup for server primary
WAL segments preceding the current backup have been found:
000000010000000000000019 from server primary has been removed
Starting backup copy via rsync/SSH for 20220629T231431 (10 jobs)
Copy done (time: 2 seconds)
This is the first backup for server primary
WAL segments preceding the current backup have been found:
00000001000000000000001A from server primary has been removed
Asking PostgreSQL server to finalize the backup.
Backup size: 52.7 MiB. Actual size on disk: 52.7 MiB (-0.00% deduplication ratio).
Backup end at LSN: 0/1B000138 (00000001000000000000001B, 00000138)
Backup completed (start time: 2022-06-29 22:25:02.293901, elapsed time: 5 seconds)
Processing xlog segments from streaming for primary
00000001000000000000001B

As a new backup has succeeded, then this finishes the configuration, where we moved the Barman directory to a new location.

Was this article helpful?

0 out of 0 found this helpful