База данных и таблица

α=> CREATE DATABASE backup_archive;
CREATE DATABASE
α=> \c backup_archive
You are now connected to database "backup_archive" as user "student".
α=> CREATE TABLE t(s text);
CREATE TABLE
α=> INSERT INTO t VALUES ('Привет, мир!');
INSERT 0 1

Настройка непрерывной архивации

postgres$ mkdir /var/lib/postgresql/archive
student$ psql -U postgres -c "ALTER SYSTEM SET archive_mode = on"
ALTER SYSTEM
student$ psql -U postgres -c "ALTER SYSTEM SET archive_command = 'test ! -f /var/lib/postgresql/archive/%f && cp %p /var/lib/postgresql/archive/%f'"
ALTER SYSTEM
α=> \q
student$ sudo pg_ctlcluster 10 alpha restart

Базовая резервная копия

Поскольку нам потребуется восстанавливаться из одной копии два раза, сделаем ее в формате tar.

postgres$ mkdir /var/lib/postgresql/backup
postgres$ pg_basebackup -U student --wal-method=none --format=tar --pgdata=/var/lib/postgresql/backup
NOTICE:  pg_stop_backup complete, all required WAL segments have been archived
postgres$ ls -l /var/lib/postgresql/backup
total 37472
-rw-r--r-- 1 postgres postgres 38368768 июн 13 20:00 base.tar

Добавление строк в таблицу

student$ psql -d backup_archive
α=> INSERT INTO t VALUES ('Еще одна строка');
INSERT 0 1
student$ psql -U postgres -c "SELECT pg_switch_wal()"
 pg_switch_wal 
---------------
 0/15002680
(1 row)

Чтобы произошло реальное переключение, надо, чтобы в журнал попала следующая (любая) запись:

α=> SELECT pg_walfile_name(pg_current_wal_lsn());
     pg_walfile_name      
--------------------------
 000000020000000000000015
(1 row)

α=> VACUUM t;
VACUUM
α=> SELECT pg_walfile_name(pg_current_wal_lsn());
     pg_walfile_name      
--------------------------
 000000020000000000000016
(1 row)

Восстановление из базовой резервной копии

postgres$ rm -rf /var/lib/postgresql/10/beta/*
postgres$ tar -xf /var/lib/postgresql/backup/base.tar -C /var/lib/postgresql/10/beta

Порт:

postgres$ echo 'port = 5433' >> /var/lib/postgresql/10/beta/postgresql.auto.conf

Для простоты отключим непрерывное архивирование на резервном сервере.

postgres$ sed -i "s/archive_mode = 'on'/archive_mode = 'off'/" /var/lib/postgresql/10/beta/postgresql.auto.conf

В файл recovery.conf записываем только команду восстановления:

postgres$ echo "restore_command = 'cp /var/lib/postgresql/archive/%f %p'" >/var/lib/postgresql/10/beta/recovery.conf
student$ sudo pg_ctlcluster 10 beta start
student$ psql -p 5433 -d backup_archive
β=> SELECT * FROM t;
        s        
-----------------
 Привет, мир!
 Еще одна строка
(2 rows)

Восстановились все строки.

Восстановление из базовой резервной копии - immediate

β=> \q
student$ sudo pg_ctlcluster 10 beta stop
postgres$ rm -rf /var/lib/postgresql/10/beta/*
postgres$ tar -xf /var/lib/postgresql/backup/base.tar -C /var/lib/postgresql/10/beta
postgres$ echo 'port = 5433' >> /var/lib/postgresql/10/beta/postgresql.auto.conf
postgres$ sed -i "s/archive_mode = 'on'/archive_mode = 'off'/" /var/lib/postgresql/10/beta/postgresql.auto.conf

В файл recovery.conf записываем команду восстановления и целевую точку:

postgres$ echo "restore_command = 'cp /var/lib/postgresql/archive/%f %p'" >/var/lib/postgresql/10/beta/recovery.conf
postgres$ echo "recovery_target = 'immediate'" >>/var/lib/postgresql/10/beta/recovery.conf
student$ sudo pg_ctlcluster 10 beta start
student$ psql -p 5433 -d backup_archive
β=> SELECT * FROM t;
      s       
--------------
 Привет, мир!
(1 row)

Восстановилась только первая строка.