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

## Инициализация кластера PostgreSQL

1. Мы зашли на стенд. Теперь все действия с СУБД PostgreSQL мы будем выполнять от локального пользователя postgres. Для этого выполним команду

```bash
student$ sudo -u postgres -i
```

2. Проверяем установленные пакеты

```bash
postgres$ yum list installed | grep postgres
```

Должен быть примерно такой результат

```
postgresql12.x86_64             12.6-1PGDG.rhel7             @pgdg12
postgresql12-contrib.x86_64     12.6-1PGDG.rhel7             @pgdg12
postgresql12-docs.x86_64        12.6-1PGDG.rhel7             @pgdg12
postgresql12-libs.x86_64        12.6-1PGDG.rhel7             @pgdg12
postgresql12-server.x86_64      12.6-1PGDG.rhel7             @pgdg12 
postgresql12-pglogical.x86_64   2.3.3-1.el7                  @barman
postgresql12-server.x86_64      12.6-1PGDG.rhel7             @pgdg12
```

3. Инициализируем кластер. Мы это делаем специально для того, чтобы потом было удобно разворачивать другие экземпляры кластера на других портах для прохождения практики. К тому же нам нужно включить контрольные суммы. Этот важный параметр. О нем мы будем говорить чуть позже.

```bash
postgres$ pg_ctl initdb "-D" "/var/lib/pgsql/12/main5432" -o "--data-checksums"
 
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.

The database cluster will be initialized with locale "en_US.UTF-8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english".

Data page checksums are enabled.

creating directory /var/lib/pgsql/12/main5432 ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting default time zone ... UTC
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok

initdb: warning: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the option -A, or
--auth-local and --auth-host, the next time you run initdb.

Success. You can now start the database server using:

    /usr/pgsql-12/bin/pg_ctl -D /var/lib/pgsql/12/main5432 -l logfile start
```

4. Последняя команда показывает, как надо запустить кластер. Меняем немного команду, для нашего удобства. Путь до файлов кластера баз данных должен быть заканчиваться на main5432, номер порта на котором будет запущен кластер. И флаг `-l logfile` нам не нужен, будем писать в стандартный файл логов postgres-а, путь до которого можно посмотреть в конфигурационном файле `postgresql.conf`.  Запускаем кластер

```log
postgres$ pg_ctl -D /var/lib/pgsql/12/main5432 start
 
waiting for server to start....2021-03-30 10:41:21.319 UTC [18476] 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 10:41:21.319 UTC [18476] LOG:  listening on IPv4 address "127.0.0.1", port 5432
2021-03-30 10:41:21.322 UTC [18476] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2021-03-30 10:41:21.330 UTC [18476] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2021-03-30 10:41:21.343 UTC [18476] LOG:  redirecting log output to logging collector process
2021-03-30 10:41:21.343 UTC [18476] HINT:  Future log output will appear in directory "log".
 done
server started
```

5. Проверяем состояние базы данных

```
postgres$ pg_ctl -D /var/lib/pgsql/12/main5432 status

pg_ctl: server is running (PID: 18476)
/usr/pgsql-12/bin/postgres "-D" "/var/lib/pgsql/12/main5432"
```

## Работа с wal-g

6. Проверяем, что пакеты wal-g установлены

```bash
postgres$ ls -l /usr/local/bin/wal-g
-rwxrwxr-x 1 2000 2000 40014512 Nov 30 09:18 /usr/local/bin/wal-g*
```

7. Создаем файл конфигурации для wal-g

```
postgres$ nano ~/.walg.json
```

8. Заносим в файл следующую информацию

```json
{
    "WALG_FILE_PREFIX": "/var/lib/pgsql/12/backups/wal-g",
    "WALG_COMPRESSION_METHOD": "brotli",
    "WALG_DELTA_MAX_STEPS": "5",
    "PGDATA": "/var/lib/pgsql/12/main5432",
    "PGHOST": "/var/run/postgresql/.s.PGSQL.5432"
}
```

Видим, что в файле конфигурации параметры для wal-g нужно передавать в ввиде json, что вначале может показаться неудобным.
В параметре `WALG_FILE_PREFIX` мы задали хранение на локальный диск сервера PostgreSQL. Это не очень удобный вариант использования wal-g. На текущий момент утилита позволяет хранить резервные копии в удаленных хранилищах AWS, Azure, Google Cloud Storage и YA.
Параметр `WALG_COMPRESSION_METHOD` указывает метод сжатия при передаче данных. При локальном создании копии не сильно полезен, но при удаленном хранении резервных копий – очень полезный параметр.
Параметр `WALG_DELTA_MAX_STEPS` указывает на максимальное количество дельта копий между полными копиями БД.
Параметры `PGDATA` и `PGHOST` показывают, где находятся каталог данных PostgreSQL и сокет для подключения к БД.

9. Создадим каталог для резервных копий и саму резервную копию

```
postgres$ mkdir /var/lib/pgsql/12/backups/wal-g
```

10. Изменяем конфигурацию `postgresql.conf`

```
postgres$ echo "wal_level=replica" >> /var/lib/pgsql/12/main5432/postgresql.auto.conf
postgres$ echo "archive_mode=on" >> /var/lib/pgsql/12/main5432/postgresql.auto.conf 
postgres$ echo "archive_command='wal-g wal-push \"%p\" >> /var/lib/pgsql/12/main5432/log/archive_command.log 2>&1' " >> /var/lib/pgsql/12/main5432/postgresql.auto.conf 
postgres$ echo "archive_timeout=60" >> /var/lib/pgsql/12/main5432/postgresql.auto.conf 
postgres$ echo "restore_command='wal-g wal-fetch \"%f\" \"%p\" >> /var/lib/pgsql/12/main5432/log/restore_command.log 2>&1' " >> /var/lib/pgsql/12/main5432/postgresql.auto.conf

postgres$ cat ~/12/main5432/postgresql.auto.conf
# Do not edit this file manually!
# It will be overwritten by the ALTER SYSTEM command.
wal_level=replica
archive_mode=on
archive_command='wal-g wal-push "%p" >> /var/lib/pgsql/12/main5432/log/archive_command.log 2>&1'
archive_timeout=60
restore_command='wal-g wal-fetch "%f" "%p" >> /var/lib/pgsql/12/main5432/log/restore_command.log 2>&1'
```

11. Перезапускаем кластер PostgreSQL

```
postgres$ pg_ctl -D /var/lib/pgsql/12/main5432/ restart
```

12. Создадим новую базу данных, таблицу в ней и заполним данными

```sql
postgres$ psql
5432=> CREATE DATABASE wal_g;
CREATE DATABASE
5432=> \c wal_g
You are now connected to database "wal_g" as user "postgres".
5432=> CREATE TABLE test(id BIGINT PRIMARY KEY, name TEXT);
CREATE TABLE
5432=> INSERT INTO test(id, name) VALUES (1, 'Value 1'), (2, 'Value 2'), (3, 'Value 3');
INSERT 0 3
5432=> \q
```

13. Запускаем команду создания резервной копии

```log
postgres$ wal-g backup-push /var/lib/pgsql/12/main5432
INFO: 2021/04/05 06:28:48.890232 Couldn't find previous backup. Doing full backup.
INFO: 2021/04/05 06:28:48.902586 Calling pg_start_backup()
INFO: 2021/04/05 06:28:49.225463 Walking ...
INFO: 2021/04/05 06:28:49.225770 Starting part 1 ...
INFO: 2021/04/05 06:28:49.663335 Finished writing part 1.
INFO: 2021/04/05 06:28:49.663366 Starting part 2 ...
INFO: 2021/04/05 06:28:49.663379 /global/pg_control
INFO: 2021/04/05 06:28:49.664117 Finished writing part 2.
INFO: 2021/04/05 06:28:49.667893 Calling pg_stop_backup()
INFO: 2021/04/05 06:28:50.726188 Starting part 3 ...
INFO: 2021/04/05 06:28:50.726239 backup_label
INFO: 2021/04/05 06:28:50.726248 tablespace_map
INFO: 2021/04/05 06:28:50.726492 Finished writing part 3.
INFO: 2021/04/05 06:28:50.731314 Wrote backup with name base_000000010000000000000002
```

14. Посмотрим нашу резервную копию

```
postgres$ wal-g backup-list
name                          last_modified        wal_segment_backup_start
base_000000010000000000000002 2021-04-05T06:28:50Z 000000010000000000000002 
```

15. Давайте обновим одну из записей таблице test

```sql
postgres$ psql -d wal_g
5432=> update test set name = 'Value 4' where id = 1;
UPDATE 1
5432=> \q
```

16. Создадим резервную копию

```log
postgres$ wal-g backup-push /var/lib/pgsql/12/main5432
INFO: 2021/04/05 06:30:26.751923 Delta backup from base_000000010000000000000002 with LSN 2000028.
INFO: 2021/04/05 06:30:26.761953 Calling pg_start_backup()
INFO: 2021/04/05 06:30:26.986952 Walking ...
INFO: 2021/04/05 06:30:26.988078 Starting part 1 ...
INFO: 2021/04/05 06:30:27.008489 Finished writing part 1.
INFO: 2021/04/05 06:30:27.008521 Starting part 2 ...
INFO: 2021/04/05 06:30:27.008536 /global/pg_control
INFO: 2021/04/05 06:30:27.009101 Finished writing part 2.
INFO: 2021/04/05 06:30:27.010012 Calling pg_stop_backup()
INFO: 2021/04/05 06:30:28.068764 Starting part 3 ...
INFO: 2021/04/05 06:30:28.068843 backup_label
INFO: 2021/04/05 06:30:28.068857 tablespace_map
INFO: 2021/04/05 06:30:28.069290 Finished writing part 3.
INFO: 2021/04/05 06:30:28.073783 Wrote backup with name base_000000010000000000000005_D_000000010000000000000002
```

17. Теперь посмотрим на наши резервные копии

```
postgres$ wal-g backup-list
name                                                     last_modified        wal_segment_backup_start
base_000000010000000000000002                            2021-04-05T06:28:50Z 000000010000000000000002
base_000000010000000000000005_D_000000010000000000000002 2021-04-05T06:30:28Z 000000010000000000000005
```

18. Восстановим теперь ее на другом порту 5433

```log
postgres$ wal-g backup-fetch /var/lib/pgsql/12/main5433 LATEST
INFO: 2021/04/05 06:38:43.990358 LATEST backup is: 'base_000000010000000000000005_D_000000010000000000000002'
INFO: 2021/04/05 06:38:44.003763 Delta from base_000000010000000000000002 at LSN 2000028
INFO: 2021/04/05 06:38:44.023523 Finished decompression of part_003.tar.br
INFO: 2021/04/05 06:38:44.023537 Finished extraction of part_003.tar.br
INFO: 2021/04/05 06:38:55.252890 Finished decompression of part_001.tar.br
INFO: 2021/04/05 06:38:55.252964 Finished extraction of part_001.tar.br
INFO: 2021/04/05 06:38:55.253362 Finished extraction of pg_control.tar.br
INFO: 2021/04/05 06:38:55.253372
Backup extraction complete.
INFO: 2021/04/05 06:38:55.253392 base_000000010000000000000002 fetched. Upgrading from LSN 2000028 to LSN 5000028
INFO: 2021/04/05 06:38:55.260607 Finished decompression of pg_control.tar.br
INFO: 2021/04/05 06:38:55.274337 Finished decompression of part_003.tar.br
INFO: 2021/04/05 06:38:55.274351 Finished extraction of part_003.tar.br
INFO: 2021/04/05 06:38:55.292880 Finished decompression of part_001.tar.br
INFO: 2021/04/05 06:38:55.292895 Finished extraction of part_001.tar.br
INFO: 2021/04/05 06:38:55.302957 Finished decompression of pg_control.tar.br
INFO: 2021/04/05 06:38:55.302969 Finished extraction of pg_control.tar.br
INFO: 2021/04/05 06:38:55.302977
Backup extraction complete.
```

19. Создаем файл для восстановления файлов wal из архива, меняем порт с 5432 на 5433 и запускаем кластер PostgreSQL

```log
postgres$ touch "/var/lib/pgsql/12/main5433/recovery.signal"
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-05 06:39:12.419 UTC [3055] 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 06:39:12.420 UTC [3055] LOG:  listening on IPv4 address "127.0.0.1", port 5433
2021-04-05 06:39:12.424 UTC [3055] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5433"
2021-04-05 06:39:12.432 UTC [3055] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5433"
2021-04-05 06:39:12.449 UTC [3055] LOG:  redirecting log output to logging collector process
2021-04-05 06:39:12.449 UTC [3055] HINT:  Future log output will appear in directory "log".
 done
server started
```

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

```sql
postgres$ psql -p5433 -d wal_g
5433=> select * from test;
id |  name
----+---------
  2 | Value 2
  3 | Value 3
  1 | Value 4
(3 rows)
5433=> \q
```
