# Создание и восстановление резервной копии с помощью pg_probackup

34. Проверяем, что пакеты pg_probackup установлены

```bash
postgres$ yum list installed | grep probackup
pg_probackup-12.x86_64          2.4.10-1.212fad4f931e1269    @pg_probackup
```

35. Создаем каталог и устанавливаем переменную окружения BACKUP_PATH

```bash
postgres$ mkdir /var/lib/pgsql/12/backups/probackup
postgres$ export BACKUP_PATH='/var/lib/pgsql/12/backups/probackup'
```

36. Проверяем, что она установилась

```bash
postgres$ echo $BACKUP_PATH
/var/lib/pgsql/12/backup
```

37. Создадим роль в PostgreSQL для выполнения бекапов и дадим ему соответствующие права

```sql
postgres$ createuser backup

postgres$ psql
5432=> 
ALTER ROLE backup NOSUPERUSER;
ALTER ROLE backup WITH REPLICATION;
GRANT USAGE ON SCHEMA pg_catalog TO backup;
GRANT EXECUTE ON FUNCTION pg_catalog.current_setting(text) TO backup;
GRANT EXECUTE ON FUNCTION pg_catalog.pg_is_in_recovery() TO backup;
GRANT EXECUTE ON FUNCTION pg_catalog.pg_start_backup(text, boolean, boolean) TO backup;
GRANT EXECUTE ON FUNCTION pg_catalog.pg_stop_backup(boolean, boolean) TO backup;
GRANT EXECUTE ON FUNCTION pg_catalog.pg_create_restore_point(text) TO backup;
GRANT EXECUTE ON FUNCTION pg_catalog.pg_switch_wal() TO backup;
GRANT EXECUTE ON FUNCTION pg_catalog.pg_last_wal_replay_lsn() TO backup;
GRANT EXECUTE ON FUNCTION pg_catalog.txid_current() TO backup;
GRANT EXECUTE ON FUNCTION pg_catalog.txid_current_snapshot() TO backup;
GRANT EXECUTE ON FUNCTION pg_catalog.txid_snapshot_xmax(txid_snapshot) TO backup;
GRANT EXECUTE ON FUNCTION pg_catalog.pg_control_checkpoint() TO backup;
```

38. Инициализируем наш бекап

```
postgres$ pg_probackup-12 init
```

39. В нашей директории для бекапов появились следующие папки

```bash
postgres$ ls -l $BACKUP_PATH
total 16
drwxr-xr-x 4 postgres postgres 4096 Apr  2 10:06 ./
drwx------ 7 postgres postgres 4096 Apr  2 09:59 ../
drwx------ 2 postgres postgres 4096 Apr  2 10:06 backups/
drwx------ 2 postgres postgres 4096 Apr  2 10:06 wal/
```

40. Инициализируем инстанс main5432

```
postgres$ pg_probackup-12 add-instance --instance 'main5432' -D ~/12/main5432/
INFO: Instance 'main5432' successfully inited
```

41. Создадим новую базу данных

```sql
postgres$ psql
5432=> create database probackup;
CREATE DATABASE
```

42. Таблицу в этой базе данных и заполним ее тестовыми данными

```sql
5432=> \c probackup
5432=> create table test(id bigserial primary key, name text);
CREATE TABLE
5432=> insert into test (name) values ('Values 1'), ('Values 2'), ('Values 3');
INSERT 0 3
5432=> select * from test;
id |   name
----+----------
  1 | Values 1
  2 | Values 2
  3 | Values 3
(3 rows)
```

43. Создадим резервную копию.  Команда backup принимает три параметра:

    - `-b` - тип создания резервной копии. Для первого запуска нужно создать полную копию кластера PostgreSQL, поэтому команда `FULL`
    - параметр `-–stream` указывает на то, что нужно вместе с созданием резервной копии, параллельно передавать wal по слоту репликации. Запуск потоковой передачи wal.
    - параметр `--temp-slot` указывает на то, что потоковая передача wal-ов будет использовать временный слот репликации

```log
postgres$ pg_probackup-12 backup --instance 'main5432' -b FULL --stream --temp-slot
INFO: Backup start, pg_probackup version: 2.4.10, instance: main5432, backup ID: QQXNPP, backup mode: FULL, wal mode: STREAM, remote: false, compress-algorithm: none, compress-level: 1
WARNING: This PostgreSQL instance was initialized without data block checksums. pg_probackup have no way to detect data block corruption without them. Reinitialize PGDATA with option '--data-checksums'.
WARNING: Current PostgreSQL role is superuser. It is not recommended to run backup or checkdb as superuser.
INFO: PGDATA size: 47MB
INFO: Start transferring data files
WARNING: File: "/var/lib/pgsql/12/main5432/base/16384/16442", invalid file size 8202
INFO: Data files are transferred, time elapsed: 0
INFO: wait for pg_stop_backup()
INFO: pg_stop backup() successfully executed
INFO: Syncing backup files to disk
INFO: Backup files are synced, time elapsed: 10s
INFO: Validating backup QQXNPP
INFO: Backup QQXNPP data files are valid
INFO: Backup QQXNPP resident size: 63MB
INFO: Backup QQXNPP completed
```

Видим, что наш бекап успешно создался. Однако есть два предупреждения. О чем они говорят?

44. Первая ошибка указывает на то, что у нас не включена контрольная сумма. Мы уже знаем, как это исправить. Делаем

```sql
postgres$ psql
5432=> drop database if exists test_checksum;
DROP DATABASE
```

```log
postgres$ pg_ctl -D /var/lib/pgsql/12/main5432 stop
waiting for server to shut down.... done
server stopped

postgres$ pg_checksums -D /var/lib/pgsql/12/main5432 -e
Checksum operation completed
Files scanned:  1266
Blocks scanned: 4111
pg_checksums: syncing data directory
pg_checksums: updating control file
Checksums enabled in cluster

postgres$ pg_ctl -D /var/lib/pgsql/12/main5432 start
waiting for server to start....2021-04-02 11:55:13.139 UTC [502] LOG:  starting PostgreSQL 12.6 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44), 64-bit
2021-04-02 11:55:13.139 UTC [502] LOG:  listening on IPv4 address "127.0.0.1", port 5432
2021-04-02 11:55:13.143 UTC [502] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2021-04-02 11:55:13.150 UTC [502] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2021-04-02 11:55:13.163 UTC [502] LOG:  redirecting log output to logging collector process
2021-04-02 11:55:13.163 UTC [502] HINT:  Future log output will appear in directory "log".
 done
server started
```

Вторая предупреждением указывает, что нам нужно делать резервные копии не под суперпользователем, а под созданным специально для этого пользователем. Чуть выше мы уже это сделали, создав юзера `backup`.

45. Теперь вернемся обратно к резервным копиям и посмотрим список созданных нами бекапов

```log
postgres$ pg_probackup-12 show
====================================================================================================================================
 Instance  Version  ID      Recovery Time           Mode   WAL Mode  TLI  Time   Data   WAL  Zratio  Start LSN   Stop LSN    Status
====================================================================================================================================
 main5432  12       QQXRQO  2021-04-02 12:23:13+00  FULL   STREAM    1/0   20s   32MB  16MB    1.00  0/11000028  0/11000168  OK
```

46. Давайте теперь в нашу таблицу test внесем дополнительные данные

```sql
postgres$ psql -d probackup
5432=> insert into test (name) values ('Values 4');
INSERT 0 1
```

47. И создадим инкрементальную копию

```log
postgres$ pg_probackup-12 backup --instance 'main5432' -b DELTA --stream --temp-slot -U backup 
INFO: Backup start, pg_probackup version: 2.4.10, instance: main5432, backup ID: QQXQWE, backup mode: DELTA, wal mode: STREAM, remote: false, compress-algorithm: none, compress-level: 1
INFO: Parent backup: QQXQBF
INFO: PGDATA size: 32MB
INFO: Start transferring data files
INFO: Data files are transferred, time elapsed: 0
INFO: wait for pg_stop_backup()
INFO: pg_stop backup() successfully executed
INFO: Syncing backup files to disk
INFO: Backup files are synced, time elapsed: 3s
INFO: Validating backup QQXQWE
INFO: Backup QQXQWE data files are valid
INFO: Backup QQXQWE resident size: 21MB
INFO: Backup QQXQWE completed
```

48. Посмотрим список наших резервных копий

```log
postgres$ pg_probackup-12 show
====================================================================================================================================
 Instance  Version  ID      Recovery Time           Mode   WAL Mode  TLI  Time   Data   WAL  Zratio  Start LSN   Stop LSN    Status
====================================================================================================================================
 main5432  12       QQXRRU  2021-04-02 12:23:55+00  DELTA  STREAM    1/1   11s  159kB  32MB    1.00  0/13000028  0/13000168  OK
 main5432  12       QQXRQO  2021-04-02 12:23:13+00  FULL   STREAM    1/0   20s   32MB  16MB    1.00  0/11000028  0/11000168  OK
```

Резервные копии успешно создались

49. Давайте теперь восстановим нашу копию QQXQWE. Останавливаем базу данных на порту 5433, удаляем каталог данных main5433 и запускаем команду восстановления

```log
postgres$ pg_ctl -D /var/lib/pgsql/12/main5433 stop
waiting for server to shut down.... done
server stopped

postgres$ rm -rf /var/lib/pgsql/12/main5433

postgres$ pg_probackup-12 restore --instance 'main5432' -i 'QQXQWE' -D /var/lib/pgsql/12/main5433
INFO: Validating parents for backup QQXQWE
INFO: Validating backup QQXNPP
INFO: Restoring the database from backup at 2021-04-02 12:05:02+00
INFO: Start restoring backup files. PGDATA size: 48MB
INFO: Backup files are restored. Transfered bytes: 48MB, time elapsed: 0
INFO: Restore incremental ratio (less is better): 100% (48MB/48MB)
INFO: Syncing restored files to disk
INFO: Restored backup files are synced, time elapsed: 10s
INFO: Restore of backup QQXQWE completed.

postgres$ sed -i 's/#port = 5432/port = 5433/' /var/lib/pgsql/12/main5433/postgresql.conf

postgres$ pg_ctl -D /var/lib/pgsql/12/main5433 start
waiting for server to start....2021-04-02 12:13:07.623 UTC [1624] LOG:  starting PostgreSQL 12.6 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44), 64-bit
2021-04-02 12:13:07.624 UTC [1624] LOG:  listening on IPv4 address "127.0.0.1", port 5433
2021-04-02 12:13:07.627 UTC [1624] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5433"
2021-04-02 12:13:07.634 UTC [1624] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5433"
2021-04-02 12:13:07.647 UTC [1624] LOG:  redirecting log output to logging collector process
2021-04-02 12:13:07.647 UTC [1624] HINT:  Future log output will appear in directory "log".
 done
server started
```

50. Проверяем, что данные восстановились

```sql
postgres$ psql -d probackup

5432=> select * from test;
 id |   name
----+----------
  1 | Values 1
  2 | Values 2
  3 | Values 3
  4 | Values 4
(4 rows)
```

51. Утилита pg_probackup позволяет поддерживать политику хранения резервных копии. Установим хранение одной полной копии базы данных. Давайте это рассмотрим

```log
postgres$ pg_probackup-12 backup --instance 'main5432' -b FULL --stream
INFO: Backup start, pg_probackup version: 2.4.10, instance: main5432, backup ID: QQXS47, backup mode: FULL, wal mode: STREAM, remote: false, compress-algorithm: none, compress-level: 1
WARNING: Current PostgreSQL role is superuser. It is not recommended to run backup or checkdb as superuser.
INFO: PGDATA size: 32MB
INFO: Start transferring data files
INFO: Data files are transferred, time elapsed: 0
INFO: wait for pg_stop_backup()
INFO: pg_stop backup() successfully executed
INFO: Syncing backup files to disk
INFO: Backup files are synced, time elapsed: 10s
INFO: Validating backup QQXS47
INFO: Backup QQXS47 data files are valid
INFO: Backup QQXS47 resident size: 64MB
INFO: Backup QQXS47 completed

postgres$ pg_probackup-12 show
BACKUP INSTANCE 'main5432'
====================================================================================================================================
 Instance  Version  ID      Recovery Time           Mode   WAL Mode  TLI  Time   Data   WAL  Zratio  Start LSN   Stop LSN    Status
====================================================================================================================================
 main5432  12       QQXS47  2021-04-02 12:31:20+00  FULL   STREAM    1/0   15s   32MB  32MB    1.00  0/15000028  0/15000168  OK
 main5432  12       QQXRRU  2021-04-02 12:23:55+00  DELTA  STREAM    1/1   11s  159kB  32MB    1.00  0/13000028  0/13000168  OK
 main5432  12       QQXRQO  2021-04-02 12:23:13+00  FULL   STREAM    1/0   20s   32MB  16MB    1.00  0/11000028  0/11000168  OK

postgres$ pg_probackup-12 set-config --instance  'main5432' --retention-redundancy=1

postgres$ pg_probackup-12 delete --instance  'main5432' --delete-expired --delete-wal
INFO: Evaluate backups by retention
INFO: Backup QQXS47, mode: FULL, status: OK. Redundancy: 1/1, Time Window: 0d/0d. Active
INFO: Backup QQXRRU, mode: DELTA, status: OK. Redundancy: 2/1, Time Window: 0d/0d. Expired
INFO: Backup QQXRQO, mode: FULL, status: OK. Redundancy: 2/1, Time Window: 0d/0d. Expired
INFO: Delete: QQXRRU 2021-04-02 12:23:55+00
INFO: Delete: QQXRQO 2021-04-02 12:23:13+00
INFO: There are no backups to merge by retention policy
INFO: Purging finished
INFO: There is no WAL to purge by retention policy

postgres$ pg_probackup-12 show
BACKUP INSTANCE 'main5432'
==================================================================================================================================
 Instance  Version  ID      Recovery Time           Mode  WAL Mode  TLI  Time  Data   WAL  Zratio  Start LSN   Stop LSN    Status
==================================================================================================================================
 main5432  12       QQXS47  2021-04-02 12:31:20+00  FULL  STREAM    1/0   15s  32MB  32MB    1.00  0/15000028  0/15000168  OK
```

52. На прошлой лекции мы рассматривали способом проверки целостности каталога данных БД. Этот механизм можно сделать и с помощью использования сторонних утилит, например pg_probackup. Давайте воспользуемся этой утилитой. Останавливаем сервер PostgreSQL. Вносить изменения в файл базы данных и заново запускать сервер PostgreSQL. Ниже не будет комментариев по шагам. Они все есть в лекции 1.

```log
postgres$ psql -d probackup -c "select pg_relation_filepath('test')";
pg_relation_filepath
----------------------
 base/16384/16442
(1 row)

postgres$ pg_ctl -D /var/lib/pgsql/12/main5432 stop
waiting for server to shut down.... done
server stopped

postgres$ pg_checksums -D /var/lib/pgsql/12/main5432 -d
pg_checksums: syncing data directory
pg_checksums: updating control file
Checksums disabled in cluster

postgres$ nano /var/lib/pgsql/12/main5432/base/16384/16442

postgres$ pg_ctl -D /var/lib/pgsql/12/main5432 start
waiting for server to start....2021-03-30 20:33:46.882 UTC [25498] LOG:  starting PostgreSQL 12.6 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44), 64-bit
2021-03-30 20:33:46.882 UTC [25498] LOG:  listening on IPv4 address "127.0.0.1", port 5432
2021-03-30 20:33:46.886 UTC [25498] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2021-03-30 20:33:46.893 UTC [25498] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2021-03-30 20:33:46.906 UTC [25498] LOG:  redirecting log output to logging collector process
2021-03-30 20:33:46.906 UTC [25498] HINT:  Future log output will appear in directory "log".
 done
server started
```

53. Утилита pg_probackup позволяет не только проверяем целостность базы данных, но и проводить логическую согласованность структуры индексов PostgreSQL, но для этого ей нужен дополнительное расширение amcheck. Установим его.

```sql
postgres$ psql -d probackup -c "CREATE EXTENSION amcheck"
CREATE EXTENSION
```

54. Запускаем проверки целостности базы данных

```log
postgres$ pg_probackup-12 checkdb -D /var/lib/pgsql/12/main5432
WARNING: This PostgreSQL instance was initialized without data block checksums. pg_probackup have no way to detect data block corruption without them. Reinitialize PGDATA with option '--data-checksums'.
WARNING: Current PostgreSQL role is superuser. It is not recommended to run backup or checkdb as superuser.
INFO: Start checking data files
WARNING: File: "/var/lib/pgsql/12/main5432/base/16384/16442", invalid file size 8202
INFO: Data files are valid
```

Видно, что pg_probackup смог найти ошибку в файле базы данных.

55. Проверяем, какие данные есть в таблице test

```sql
postgres$ psql -d probackup -c "select * from test"
    bid     |  bbalance  | filler
------------+------------+--------
 1685258241 | 1717859174 |
(1 row)
```

## Домашнее задание.
## Проверка резервной копии

1. Создать новую базу данных и создать там несколько таблиц с данными

2. Воспользоваться утилитой `pg_probackup` и создать полную резервную копию базы данных

3. Восстановить с помощью `pg_probackup` только что созданную нами базу данных

### Чек-лист 

1. Создана новая база данных и создана там несколько таблиц с данными
1. Использована утилита pg_probackup и создана полная резервная копия базы данных
1. Восстановлена с помощью pg_probackup только, что созданная резервная копия

<details>
  <summary>Решение:</summary>

1. Создать новую базу данных и создать там несколько таблиц с данными

```
postgres$ psql
psql (12.6)
Type "help" for help.
5432=> create database restore_one_db;
CREATE DATABASE
5432=> \c restore_one_db
You are now connected to database "restore_one_db" as user "postgres".
5432=> create table test (id int);
CREATE TABLE
5432=> insert into test select id from generate_series(1,1000) id;
INSERT 0 1000
```

2. Воспользоваться утилитой `pg_probackup` и создать полную резервную копию базы данных

```
postgres$ pg_probackup-12 backup --instance 'main5432' -b FULL --stream --temp-slot --backup-path='/var/lib/pgsql/12/backups/probackup'

INFO: Backup start, pg_probackup version: 2.4.10, instance: main5432, backup ID: QR3HV7, backup mode: FULL, wal mode: STREAM, remote: false, compress-algorithm: none, compress-level: 1
WARNING: This PostgreSQL instance was initialized without data block checksums. pg_probackup have no way to detect data block corruption without them. Reinitialize PGDATA with option '--data-checksums'.
WARNING: Current PostgreSQL role is superuser. It is not recommended to run backup or checkdb as superuser.
WARNING: Skip hidden file: '/var/lib/pgsql/12/main5432/.barman-recover.info'
INFO: PGDATA size: 40MB
INFO: Start transferring data files
INFO: Data files are transferred, time elapsed: 0
INFO: wait for pg_stop_backup()
INFO: pg_stop backup() successfully executed
INFO: Syncing backup files to disk
INFO: Backup files are synced, time elapsed: 13s
INFO: Validating backup QR3HV7
INFO: Backup QR3HV7 data files are valid
INFO: Backup QR3HV7 resident size: 72MB
INFO: Backup QR3HV7 completed

postgres$ pg_probackup-12 show
BACKUP INSTANCE 'main5432'
===================================================================================================================================
 Instance  Version  ID      Recovery Time           Mode  WAL Mode  TLI  Time   Data   WAL  Zratio  Start LSN   Stop LSN    Status
===================================================================================================================================
 main5432  12       QR3HV7  2021-04-05 14:35:31+00  FULL  STREAM    1/0   18s   40MB  32MB    1.00  0/15000028  0/15000168  OK
```

3. Восстановить с помощью `pg_probackup` только что созданную нами базу данных

```
postgres$ pg_probackup-12 restore --instance 'main5432' -i 'QR3HV7' -D /var/lib/pgsql/12/main5433 --db-include=restore_one_db --db-include=postgres

INFO: Validating backup QR3HV7
INFO: Backup QR3HV7 data files are valid
INFO: Backup QR3HV7 WAL segments are valid
INFO: Backup QR3HV7 is valid.
INFO: Restoring the database from backup at 2021-04-05 14:35:31+00
INFO: Start restoring backup files. PGDATA size: 72MB
INFO: Backup files are restored. Transfered bytes: 64MB, time elapsed: 0
INFO: Restore incremental ratio (less is better): 89% (64MB/72MB)
INFO: Syncing restored files to disk
INFO: Restored backup files are synced, time elapsed: 11s
INFO: Restore of backup QR3HV7 completed

postgres$ echo port=5433 > /var/lib/pgsql/12/main5433/postgresql.auto.conf

postgres$ pg_ctl -D /var/lib/pgsql/12/main5433 start
waiting for server to start....2021-04-05 14:46:13.380 UTC [6953] LOG:  starting PostgreSQL 12.6 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44), 64-bit
2021-04-05 14:46:13.381 UTC [6953] LOG:  listening on IPv4 address "127.0.0.1", port 5433
2021-04-05 14:46:13.384 UTC [6953] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5433"
2021-04-05 14:46:13.392 UTC [6953] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5433"
2021-04-05 14:46:13.406 UTC [6953] LOG:  redirecting log output to logging collector process
2021-04-05 14:46:13.406 UTC [6953] HINT:  Future log output will appear in directory "log".
 done
server started

postgres$ psql -p5433
psql (12.6)
Type "help" for help.
5433=> \c dbcopy
FATAL:  "base/24576" is not a valid data directory
DETAIL:  File "base/24576/PG_VERSION" does not contain valid data.
HINT:  You might need to initdb.
Previous connection kept
5433=> drop database dbcopy;
DROP DATABASE
5433=> \c restore_one_db
You are now connected to database "restore_one_db" as user "postgres".
5433=> select * from test limit 10;
 id
----
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
(10 rows)
```
</details>
