Skip to content

Commit

Permalink
Recreate pg_wal if required in barman-cloud-restore
Browse files Browse the repository at this point in the history
If you run barman-cloud-backup on a data directory where pg_wal is a
symlink, it doesn't include pg_wal in the uploaded tar files, and the
pg_wal directory will not be created if you restore the backup.

We fix this by creating pg_wal (or pg_xlog, depending on the version) in
the destination directory if it does not exist at the end of the backup.

Closes #327
  • Loading branch information
amenonsen committed Jul 24, 2021
1 parent 089491b commit 5915961
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 2 deletions.
12 changes: 10 additions & 2 deletions barman/clients/cloud_restore.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,8 @@ def download_backup(self, backup_id, destination_dir):
"""
Download a backup from cloud storage
:param str wal_name: Name of the WAL file
:param str wal_dest: Full path of the destination WAL file
:param str backup_id: The backup id to restore
:param str destination_dir: Path to the destination directory
"""

backup_info = self.catalog.get_backup_info(backup_id)
Expand Down Expand Up @@ -227,6 +227,14 @@ def download_backup(self, backup_id, destination_dir):
)
self.cloud_interface.extract_tar(file_info.path, target_dir)

# If we did not restore the pg_wal directory from one of the uploaded
# backup files, we must recreate it here. (If pg_wal was originally a
# symlink, it would not have been uploaded.)

wal_path = os.path.join(destination_dir, backup_info.wal_directory())
if not os.path.exists(wal_path):
os.mkdir(wal_path)


if __name__ == "__main__":
main()
7 changes: 7 additions & 0 deletions barman/infofile.py
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,13 @@ def pg_major_version(self):
else:
return str(major)

def wal_directory(self):
"""
Returns "pg_wal" (v10 and above) or "pg_xlog" (v9.6 and below) based on
the Postgres version represented by this backup
"""
return "pg_wal" if self.version >= 100000 else "pg_xlog"


class LocalBackupInfo(BackupInfo):
__slots__ = "server", "config", "backup_manager"
Expand Down
2 changes: 2 additions & 0 deletions tests/test_infofile.py
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,8 @@ def test_pg_version(self, tmpdir):
b_info = LocalBackupInfo(server, info_file=infofile.strpath)
# BASE_BACKUP_INFO has version 90400 so expect 9.4
assert b_info.pg_major_version() == "9.4"
assert b_info.wal_directory() == "pg_xlog"
# Set backup_info.version to 100600 so expect 10
b_info.version = 100600
assert b_info.pg_major_version() == "10"
assert b_info.wal_directory() == "pg_wal"

0 comments on commit 5915961

Please sign in to comment.