---
author: Alvie Rahman
date: \today
title: Postgres
tags: [ programming ]
---

\tableofcontents

# Chapter 24: Backup and Restore[^c24]

Three types of backups:

- SQL dump---create text file of SQL commands that can recreate the database

   `pg_dump dbname > outfile`

   To restore: `psql dbname < infile`

   - must be run as database superuser
   - can be run remotely
   - set host and username with `-h` and `-U` switches

- File system level backup

   `tar -cf backup.tar /usr/local/pgsql/data`

   - The database server **must** be shut down
   - You can only backup and restore entire database clusters

- Continuous archiving (write ahead log archiving)

   - "We do not need a perfectly consistent file system backup as the starting point."
   - method can be used to create a continuous backup
   - supports point in time recovery
   - can be used to create a warm standby system

   - can only be used to restore an entire database cluster
   - requires a lot of archival storage

## SQL Dump

### Restoring a dump

Important note before you restore a database:

> Before restoring an SQL dump, all the users who own objects or were granted permissions on objects
  in the dumped database must already exist. If they do not, the restore will fail to recreate the
  objects with the original ownership and/or permissions. (Sometimes this is what you want, but
  usually it is not.)

You should probably read the whole document [here](https://www.postgresql.org/docs/9.1/backup-dump.html)

## File system backup

You can run a FS level backup with minimal downtime with `rsync`:

1. Perform a backup with `rsync` while system is live
2. Shut down database server
3. Rerun `rsync` backup command
4. Restart database server

The second `rsync` command will run significantly quicker as it only has to transfer what has
changed since the first backup.

## Write Ahead Log (WAL) archiving

- WAL segment files usually get "recycled" by being renamed
- to archive WAL data, the content of each segment is captured and saved before it is reused

   - you can save the data any way you like

- to enable WAL archiving:

   1. set `wal_level` to `replica` or higher
   1. set `archive_mode` to `on`
   1. set `archive_command` to the command to use to backup

      - e.g.

         ```
         archive_command = 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f'  # Unix
         archive_command = 'copy "%p" "C:\\server\\archivedir\\%f"'  # Windows
         ```

         where `%f` is the filename of the file to archive and `%p` is the path of file to archive:

         ```
         test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_xlog/00000001000000A900000065 /mnt/server/archivedir/00000001000000A900000065
         ```

      - The command must only ever return a exit status of 0 **only if it succeeds*

         - postgres will recycle the file if the command returns 0

      - The archived data should have minimal access permissions
      - the archive command should generally refuse to overwrite files and return non-zero
      - In writing your archive command, you should assume that the file names to be archived can be
        up to 64 characters long and can contain any combination of ASCII letters, digits, and dots.
      - It is not necessary to preserve the original relative path (`%p`) but it is necessary to
        preserve the file name (`%f`).
   
   1. make a base backup

### make a base backup[^pg_basebackup]

1. ensure that WAL archiving is working and set up properly.
1. Run `pg_basebackup -D - -F tar > backup.tar`


[^c24]: https://www.postgresql.org/docs/9.1/backup-dump.html
[^pg_basebackup]: https://www.postgresql.org/docs/13/app-pgbasebackup.html
