Инкрементальные бэкапы PostgreSQL в pgBackRest

Инкрементальные бэкапы PostgreSQL в pgBackRest — метод резервного копирования, который позволяет сохранять только измененные данные с момента последнего полного или инкрементального бэкапа. Помогает экономить место на диске и уменьшает время выполнения резервного копирования.

Ссылки на ресурсы:

Вы можете установить скрпит с помощью команд или скрипта.

Установка pgBackRest

Выберите один из способов установки:

  • через репозиторий,

  • из исходников.

Установка из репозитория

sudo apt install pgbackrest postgresql-client

Установка из исходников

В Astra Linux нет пакета для установки pgBackRest, поэтому соберите его из исходников.

Примечание

На успешный результат влияет точная установка времени. Рекомендуем ознакомиться с официальной документацией Astra Linux.

  1. Сначала убедитесь, что у вас установлен Perl:

apt list perl
  1. Установите пакеты.

В официальной документации по сборке указаны пакеты:

meson gcc libpq-dev libssl-dev libxml2 libxml2-dev pkg-config liblz4-dev libzstd-dev libbz2-dev libz-dev libyaml-dev libssh2 libssh2-1-dev postgresql-client

Убедитесь, что все пакеты есть в репозитории Astra Linux:

for pkg in meson gcc libpq-dev libssl-dev libxml2 libxml2-dev pkg-config liblz4-dev libzstd-dev libbz2-dev libz-dev libyaml-dev libssh2 libssh2-1-dev postgresql-client; do apt-cache show "$pkg" > /dev/null 2>&1 && echo "$pkg: найден" || echo "$pkg: не найден"; done

Вывод:

meson: найден
gcc: найден
libpq-dev: найден
libssl-dev: найден
libxml2: найден
libxml2-dev: найден
pkg-config: найден
liblz4-dev: найден
libzstd-dev: найден
libbz2-dev: найден
libz-dev: найден
libyaml-dev: найден
libssh2: не найден
libssh2-1-dev: найден
postgresql-client: найден

В ненайденном пакете libssh2 есть уязвимость. Описание на сайте ФСТЭК .

По всей видимости, пакет исправлен и сменил название на libssh2-1:

../_images/pgbackrest_backups_4.png

Соберите pgBackRest без libssh2, потому что он уже установлен:

sudo apt install meson gcc libpq-dev libssl-dev libxml2 libxml2-dev pkg-config liblz4-dev libzstd-dev libbz2-dev libz-dev libyaml-dev libssh2-1-dev postgresql-client

Сборка pgBackRest

Используйте для сборки систему сборки Meson и Ninja.

  1. Соберите версию, которая используется в репозиториях Ubuntu:

sudo mkdir /build && cd /build
sudo wget https://github.com/pgbackrest/pgbackrest/archive/refs/tags/release/2.53.tar.gz
sudo tar -xvf 2.53.tar.gz
sudo meson setup /build/pgbackrest /build/pgbackrest-release-2.53/
sudo ninja -C /build/pgbackrest

Пример вывода при успешной сборке и компиляции:

provisor@sce-54:/build$ sudo meson setup /build/pgbackrest /build/pgbackrest-release-2.53/
The Meson build system
Version: 0.53.2
Source dir: /build/pgbackrest-release-2.53
Build dir: /build/pgbackrest
Build type: native build
WARNING: Unknown options: "unity_size"
Project name: pgbackrest
Project version: 2.53
C compiler for the host machine: cc (gcc 9.4.0 "cc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0")
C linker for the host machine: cc ld.bfd 2.34
Host machine cpu family: x86_64
Host machine cpu: x86_64
Compiler for C supports arguments -Wconversion: YES
Compiler for C supports arguments -Wduplicated-cond: YES
Compiler for C supports arguments -Wduplicated-branches: YES
Compiler for C supports arguments -Wformat-nonliteral: YES
Compiler for C supports arguments -Wformat=2: YES
Compiler for C supports arguments -Wformat-signedness: YES
Compiler for C supports arguments -Wpointer-arith: YES
Compiler for C supports arguments -Wstrict-prototypes: YES
Compiler for C supports arguments -Wvla: YES
Compiler for C supports arguments -Wwrite-strings: YES
Compiler for C supports arguments -Wno-clobbered -Wclobbered: YES
Compiler for C supports arguments -Wno-missing-field-initializers -Wmissing-field-initializers: YES
Compiler for C supports arguments -Wno-implicit-fallthrough -Wimplicit-fallthrough: YES
Compiler for C supports arguments -funroll-loops: YES
Compiler for C supports arguments -ftree-vectorize: YES
Program python3 found: YES (/usr/bin/python3)
Compiler for C supports arguments -fmacro-prefix-map=../pgbackrest-release-2.53/src/=: YES
Compiler for C supports arguments -fmacro-prefix-map=../pgbackrest-release-2.53/test/src/=test/: YES
Library backtrace found: YES
Library bz2 found: YES
Found pkg-config: /usr/bin/pkg-config (0.29.1)
Run-time dependency liblz4 found: YES 1.9.2
Run-time dependency openssl found: YES 1.1.1f
Run-time dependency libpq found: YES 16.4
Run-time dependency libxml-2.0 found: YES 2.9.10
Run-time dependency yaml-0.1 found: YES 0.2.2
Run-time dependency zlib found: YES 1.2.11
Run-time dependency libssh2 found: YES 1.8.0
Run-time dependency libzstd found: YES 1.4.4
Configuring build.auto.h using configuration
Configuring build.auto.h using configuration
Configuring build.auto.h using configuration
Build targets in project: 10

Found ninja-1.10.0 at /usr/bin/ninja

provisor@sce-54:/build$ sudo ninja -C /build/pgbackrest
ninja: Entering directory `/build/pgbackrest'
[250/250] Linking target src/pgbackrest.
  1. Перенесите полученый бинарный файл:

sudo cp /build/pgbackrest/src/pgbackrest /usr/bin/
sudo chmod 755 /usr/bin/pgbackrest
  1. Создайте директории для конфигурационных файлов и логов:

sudo mkdir -p -m 770 /var/log/pgbackrest && sudo chown postgres:postgres /var/log/pgbackrest && sudo mkdir -p /etc/pgbackrest && sudo mkdir -p /etc/pgbackrest/conf.d && sudo touch /etc/pgbackrest/pgbackrest.conf && sudo chmod 640 /etc/pgbackrest/pgbackrest.conf && sudo chown postgres:postgres /etc/pgbackrest/pgbackrest.conf
  1. Создайте директории для репозитория бекапов.

Предупреждение

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

sudo mkdir -p /var/lib/pgbackrest
sudo chmod 750 /var/lib/pgbackrest
sudo chown postgres:postgres /var/lib/pgbackrest

Проверка установки

Проверьте установку:

sudo -u postgres pgbackrest

Вывод:

pgBackRest 2.53 - General help

Usage:
pgbackrest [options] [command]

Commands:
annotate Add or modify backup annotation.
archive-get Get a WAL segment from the archive.
archive-push Push a WAL segment to the archive.
backup Backup a database cluster.
check Check the configuration.
expire Expire backups that exceed retention.
help Get help.
info Retrieve information about backups.
repo-get Get a file from a repository.
repo-ls List files in a repository.
restore Restore a database cluster.
server pgBackRest server.
server-ping Ping pgBackRest server.
stanza-create Create the required stanza data.
stanza-delete Delete a stanza.
stanza-upgrade Upgrade a stanza.
start Allow pgBackRest processes to run.
stop Stop pgBackRest processes from running.
verify Verify contents of the repository.
version Get version.

Use 'pgbackrest help [command]' for more information.

Если ошибок нет, pgBackRest установлен корректно.

Настройка pgBackRest

Отредактируйте конфигурационный файл /etc/pgbackrest/pgbackrest.conf в удобном для вас редакторе.

Предупреждение

Будьте внимательны при редактировании файла. Версии PostgreSQL могут отличаться.

[demo]
pg1-path=/var/lib/postgresql/15/main

[global]
repo1-path=/var/lib/pgbackrest
repo1-retention-full=2

[global:archive-push]
compress-level=3

Настройка PostgreSQL

  1. Добавьте строки в конец файла /etc/postgresql/15/main/postgresql.conf. Крайне рекомендуется добавить комментарий, чтобы в будущем было понятно, зачем были внесены эти изменения.

#2.09.2024 settings for incremental backup. System administrator Ivanov I.
archive_command = 'pgbackrest --stanza=demo archive-push %p'
archive_mode = on
max_wal_senders = 3
wal_level = replica
  1. Перезапустите PostgreSQL:

sudo systemctl restart postgresql
  1. Убедитесь, что PostgreSQL запустился после внесения изменений в конфигурационный файл:

sudo systemctl status postgresql

Корректный вывод:

provisor@astr-sce54:/build$ sudo systemctl status postgresql
● postgresql.service - PostgreSQL RDBMS
Loaded: loaded (/lib/systemd/system/postgresql.service; enabled; vendor preset: enabled)
Active: active (exited) since Mon 2024-09-02 17:15:48 +07; 9s ago
Process: 3903 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
Main PID: 3903 (code=exited, status=0/SUCCESS)
    CPU: 7ms

сен 02 17:15:48 astr-sce54 systemd[1]: Starting PostgreSQL RDBMS...
сен 02 17:15:48 astr-sce54 systemd[1]: Started PostgreSQL RDBMS.

Запуск пакета pgBackRest для кластера

  1. Используйте команду для запуска:

sudo -u postgres pgbackrest --stanza=your_stanza_name --log-level-console=info stanza-create

Примечание

stanza — конфигурация кластера баз данных PostgreSQL, которая определяет месторасположение кластера. способ создания резервной копии, параметры архивирования и т. д. Большинство серверов БД имеют только один кластер базы данных PostgreSQL и, следовательно, один stanza. В то же время, серверы резервного копирования могут иметь отдельную конфигурацию stanza для каждого кластера баз данных, который они обслуживают.

В приведенной команде используется your_stanza_name в качестве имени для конфигурации stanza.

Не называйте stanza именем основного кластера. Более подходящее название описывает базы данных, которые входят в кластер. Поскольку имя stanza используется для первичной и всех реплик, более уместно выбрать имя, которое описывает фактическую функцию кластера. Например app или dw вместо имени локального кластера вроде main или prod.

Вывод:

sudo -u postgres pgbackrest --stanza=demo --log-level-console=info stanza-create
2024-05-28 13:20:12.820 P00 INFO: stanza-create command begin 2.51: --exec-id=40337-0602407f --log-level-console=info --pg1-path=/var/lib/postgresql/15/main --repo1-path=/var/lib/pgbackrest --stanza=demo
2024-05-28 13:20:13.626 P00 INFO: stanza-create for stanza 'demo' on repo1
2024-05-28 13:20:13.633 P00 INFO: stanza-create command end: completed successfully (814ms)
  1. Проверьте созданный репозиторий:

sudo -u postgres pgbackrest --stanza=demo --log-level-console=info check

Вывод:

sudo -u postgres pgbackrest --stanza=demo --log-level-console=info check 2024-05-28 13:24:03.434 P00 INFO: check command begin 2.51: --exec-id=40938-d6c55df1 --log-level-console=info --pg1-path=/var/lib/postgresql/15/main --repo1-path=/var/lib/pgbackrest --stanza=demo 2024-05-28 13:24:04.041 P00 INFO: check repo1 configuration (primary) 2024-05-28 13:24:04.443 P00 INFO: check repo1 archive for WAL (primary) 2024-05-28 13:24:04.443 P00 INFO: WAL segment 0000000100000003000000B9 successfully archived to '/var/lib/pgbackrest/archive/demo/15-1/0000000100000003/0000000100000003000000B9-f099b13a5bce53307041b204c4 edd5215e2402b0.gz' on repo1 2024-05-28 13:24:04.444 P00 INFO: check command end: completed successfully (1011ms)

Создание бэкапа

Инкрементное резервное копирование должно основываться на полной резервной копии. Поскольку полной резервной копии не существует, нужно ее сделать. На время создания бекапа отстановите прием данных от агента.

Предупреждение

Перед бекапом крайне важно завершить работу Staffcop и убедиться, что все процессы остановлены. Дело в том, даже после запрета приема данных от агентов через Iptables или через остановку Nginx внутри могут продолжаться процессы ETL, которые изменят состояние БД.

  1. Остановите передачу данных на сервер Staffcop:

staffcop stop
  1. Сделайте полный бэкап — это первая полная копия всех данных, которая служит основой для будущих инкрементальных резервных копий:

sudo -u postgres pgbackrest --stanza=demo --type=full backup
  1. Создайте инкрементальный бэкап — резервное копирование только тех изменений, которые произошли с момента последнего полного бэкапа:

sudo -u postgres pgbackrest --stanza=demo--type=incr backup

Дополнительные выводы

pgBackRest поддерживает расширенный вывод при создании резервных копий, что позволяет получить более детальную информацию о процессе. В предыдущих примерах не был указан дополнительный вывод, но его можно добавить для более информативного мониторинга.

Используйте параметр --log-level-console для управления уровнем детализации вывода в консоль.

Основные уровни логирования, которые вы можете использовать:

  • error: показывает только ошибки.

  • warn: показывает предупреждения и ошибки.

  • info: показывает информационные сообщения, предупреждения и ошибки.

  • detail: показывает детализированные сообщения, информационные сообщения, предупреждения и ошибки.

  • debug: показывает отладочные сообщения, детализированные сообщения, информационные сообщения, предупреждения и ошибки.

  • trace: показывает трассировочные сообщения, отладочные сообщения, детализированные сообщения, информационные сообщения, предупреждения и ошибки.

Примеры уровней логирования

Если вы хотите создать резервную копию с расширенным выводом, рекомендуется использовать уровень detail или debug.

Уровень detail
sudo pgbackrest --stanza=your_stanza_name --log-level-console=detail backup
Уровень debug

Для большей детализации используйте debug:

sudo pgbackrest --stanza=your_stanza_name --log-level-console=debug backup
Уровень trace

Используйте trace для максимального уровня детализации:

sudo pgbackrest --stanza=your_stanza_name --log-level-console=trace backup
Настройка уровня логирования в конфигурационном файле

Вместо выполнения команды можете задать уровень логирования в конфигурационном файле pgbackrest.conf. Например:

[global]
log-level-console=detail

Просмотр бэкапа

Для просмотра бэкапа выполните:

sudo -u postgres pgbackrest info

Вывод:

sudo -u postgres pgbackrest info
stanza: demo
status: ok
cipher: none

db (current)
wal archive min/max (15): 0000000100000003000000B8/0000000100000003000000BD

full backup: 20240528-132503F
timestamp start/stop: 2024-05-28 13:25:03+07 / 2024-05-28 13:25:39+07
wal start/stop: 0000000100000003000000BB / 0000000100000003000000BB
database size: 98.9MB, database backup size: 98.9MB
repo1: backup set size: 16.8MB, backup size: 16.8MB

incr backup: 20240528-132503F_20240528-133032I
timestamp start/stop: 2024-05-28 13:30:32+07 / 2024-05-28 13:30:40+07
wal start/stop: 0000000100000003000000BD / 0000000100000003000000BD
database size: 99.0MB, database backup size: 16.1MB
repo1: backup set size: 16.8MB, backup size: 4.2MB
backup reference list: 20240528-132503F

Восстановление из инкрементального бекапа

  1. Восстановите из БД из последнего бэкапа.

Посмотрите, какие кластеры есть и какие у них имена:

pg_lsclusters

Остановите кластер:

sudo pg_ctlcluster 15 main stop

На всякий случай проверьте, что кластер остановлен:

pg_lsclusters

Приступите к восстановлению. Для начала посмотрите, какие копии есть:

sudo -u postgres pgbackrest info

Вывод:

stanza: demo
    status: ok
    cipher: none

    db (current)
        wal archive min/max (15): 0000000100000003000000B8/0000000100000003000000C2

        full backup: 20240528-132503F
            timestamp start/stop: 2024-05-28 13:25:03+07 / 2024-05-28 13:25:39+07
            wal start/stop: 0000000100000003000000BB / 0000000100000003000000BB
            database size: 98.9MB, database backup size: 98.9MB
            repo1: backup set size: 16.8MB, backup size: 16.8MB

        incr backup: 20240528-132503F_20240528-133032I
            timestamp start/stop: 2024-05-28 13:30:32+07 / 2024-05-28 13:30:40+07
            wal start/stop: 0000000100000003000000BD / 0000000100000003000000BD
            database size: 99.0MB, database backup size: 16.1MB
            repo1: backup set size: 16.8MB, backup size: 4.2MB
            backup reference list: 20240528-132503F

        incr backup: 20240528-132503F_20240528-143603I
            timestamp start/stop: 2024-05-28 14:36:03+07 / 2024-05-28 14:36:11+07
            wal start/stop: 0000000100000003000000BF / 0000000100000003000000BF
            database size: 99.0MB, database backup size: 16.5MB
            repo1: backup set size: 16.8MB, backup size: 4.2MB
            backup reference list: 20240528-132503F, 20240528-132503F_20240528-133032I

        incr backup: 20240528-132503F_20240528-152508I
            timestamp start/stop: 2024-05-28 15:25:08+07 / 2024-05-28 15:26:51+07
            wal start/stop: 0000000100000003000000C2 / 0000000100000003000000C2
            database size: 114.8MB, database backup size: 77.8MB
            repo1: backup set size: 21.3MB, backup size: 17.8MB
            backup reference list: 20240528-132503F, 20240528-132503F_20240528-133032I, 20240528-132503F_20240528-143603I

Восстановите БД из последнего полного бекапа:

sudo -u postgres pgbackrest --stanza=demo --log-level-console=info --delta restore

Восстановитесь к инкрементальному бэкапу. Обратите внимание, что пути могут отличаться.

staffcop stop
sudo systemctl stop postgresql
rm -rf /var/lib/postgresql/11/main/*
sudo -u postgres pgbackrest --stanza=staffcop --log-level-console=info restore --set=20240929-132900F_20240929-134211I --type=time "--target=2024-09-29 13:42:11+03"

Бэкап восстановлен, pg_wal «перемотана» до даты нужного инкрементального бэкапа. БД доступна только в режиме чтения.

Проверка бэкапа

  1. Зайдите в PostgreSQL и выполните:

sudo systemctl start postgresql
sudo -u postgres psql
select pg_wal_replay_resume();
  1. Запустите кластер:

sudo pg_ctlcluster 15 main start
  1. Убедитесь, что кластер запущен:

pg_lsclusters
../_images/pgbackrest_backups_2.png
  1. Запустите Staffcop:

sudo staffcop start
  1. Посмотрите информацию о восстановлении в логах:

sudo -u postgres cat /var/lib/postgresql/15/demo/postgresql.auto.conf
cat: /var/lib/postgresql/15/demo/postgresql.auto.conf: No such file or directory
sudo -u postgres cat /var/lib/postgresql/15/main/postgresql.auto.conf
# Do not edit this file manually!
# It will be overwritten by the ALTER SYSTEM command.

# Recovery settings generated by pgBackRest restore on 2024-05-28 15:50:57
restore_command = 'pgbackrest --stanza=demo archive-get %f "%p"'
recovery_target_time = '2024-05-28 15:26:51+07'
recovery_target_action = 'promote'

Скрипт для автоматизации

Альтернативно вы можете использовать скрипт.

  1. Сохраните скрип в тестовом файле на вашем сервере. Назовите файл backup-and-restore.sh.

#! /bin/bash

RED="\e[31m"
GREEN="\e[32m"
NORM="\e[0m"

# Определение системного языка
USELANG=0
if [ $(echo ${LANG/_/-} | grep -Ei "\\b(ru|RU)\\b") ]; then USELANG=1; fi

# Определение функции echo с поддержкой вывода на нескольких языках
function echo2(){
if [ $USELANG == 1 ]; then
    echo -e $1; #Show Russian
else
    echo -e $2; #Show English
fi
}

#you root?
UID_ROOT=0
if [ "$UID" -ne "$UID_ROOT" ]; then
echo2 "${RED}Эта операция может быть выполнена только пользователем root${NORM}" "${RED}This operation can only be performed by the root user${NORM}"
exit 1
fi

if [ -e /etc/pgbackrest.conf ]; then
DB=$(grep pg1-path /etc/pgbackrest.conf | sed -e 's/pg1-path=\/var\/lib\///g')
elif [ -e /etc/pgbackrest/pgbackrest.conf ]; then
DB=$(grep pg1-path /etc/pgbackrest/pgbackrest.conf | sed -e 's/pg1-path=\/var\/lib\///g')
else
echo2 "${RED}pgbackrest не установлен, либо не настроен.${NORM}" "${RED}pgbackrest not installed or misconfigured.${NORM}"
exit 1
fi

STANZA=$(grep stanza /etc/$DB/postgresql.conf | sed -e 's/^.*=//g' -e 's/ .*//g')
BACKUPS=$(sudo -u postgres pgbackrest info | grep 'backup:' | sed -e 's/^.*backup: //g')
COUNT=$(sudo -u postgres pgbackrest info | grep -c 'backup:')

echo2 "${GREEN}Количество точек восстановления: $COUNT${NORM}" "${GREEN}Number of recovery points: $COUNT${NORM}"

function error() {
    echo2 "Не могу распознать ответ '$var1'" "Can't recognize the answer '$var1'"
    echo2 "Введите Y или N" "Enter Y or N"
}

function todo_dialog(){
    echo2 "${RED}Создать новую точку восстановления? y/n${NORM}" "${RED}Create a new recovery point? y/n${NORM}"
    read var1
    case $var1 in
        Y)
        backup_dialog
        ;;
        y)
        backup_dialog
        ;;
        N)
        restore_dialog
        ;;
        n)
        restore_dialog
        ;;
        *)
        error
        todo_dialog
        ;;
    esac
}

function backup_dialog(){
    if [ $COUNT >0 ]; then
    echo2 "${RED}Создать новый инкрементальный бэкап?. y/n${NORM}" "${RED}Create an incremental backup?. y/n${NORM}"
    echo2 "${RED}(Нет = создать новый полный бэкап.)${NORM}" "${RED}(No = create a new full backup.)${NORM}"
    read var1
    case $var1 in
        Y)
        TYPE=incr
        backup
        ;;
        y)
        TYPE=incr
        backup
        ;;
        N)
        TYPE=full
        backup
        ;;
        n)
        TYPE=full
        backup
        ;;
        *)
        error
        backup_dialog
        ;;
    esac
    else
    echo2 "${GREEN}Не найдено ни одной точки восстановления. Будет создан полный бэкап.${NORM}" "${GREEN}No recovery points found. A full backup will be created.${NORM}"
    TYPE=full
    backup
    fi
}

function backup(){
    echo2 "${RED}Создание точки восстановления: $TYPE backup${NORM}" "${RED}Creating recovery point: $TYPE backup${NORM}"
    staffcop stop
    echo "select max(id) from agent_event;select count(*) from agent_event;" | staffcop sql
    sudo -u postgres pgbackrest --stanza=$STANZA --type=$TYPE backup
    staffcop start
}

function restore_dialog(){
    if [ $COUNT >0 ]; then
    echo2 "${RED}Восстановить БД из бэкапа? y/n${NORM}" "${RED}Restore DB from a backup? y/n${NORM}"
    read var1
    case $var1 in
        Y)
        restore_prepare
        ;;
        y)
        restore_prepare
        ;;
        N)
        exit 0
        ;;
        n)
        exit 0
        ;;
        *)
        error
        restore_dialog
        ;;
    esac
    else
    echo2 "${RED}Не найдено ни одной точки восстановления.${NORM}" "${RED}No recovery points found.${NORM}"
    todo_dialog
    fi
}

function select_restorepoint(){
    sudo -u postgres pgbackrest info
    echo2 "${RED}Нажмите кнопку от [ 1 ] до [ $COUNT ] для выбора точки восстановления.${NORM}" "${RED}Press button from [ 1 ] to [ $COUNT ] to select a recovery point.${NORM}"
    echo2 "${RED}Или любую другую кнопку для выхода из режима восстановления...${NORM}" "${RED}Or any other button to exit recovery process...${NORM}"
    read var1
    if ((var1 >= 1 && var1 <= COUNT)); then
        SELECTPOINT=$(sudo -u postgres pgbackrest info | grep -m$var1 'backup:' | tail -n1 | sed -e 's/^.*backup: //g')
        SELECTTARGET=$(sudo -u postgres pgbackrest info | grep -m$var1 'timestamp start/stop:' | tail -n1 | sed -e 's/^.*stop: //g' -e 's/ \/.*//g')
    else
        exit 0
    fi
}

function restore_prepare(){
    if [ -e /etc/pgbackrest.conf ]; then
    DBNAME=$(grep pg1-path /etc/pgbackrest.conf | sed -e 's/.*\///g')
    DBVER=$(grep pg1-path /etc/pgbackrest.conf | sed -e 's/.*\/1/1/g' -e 's/\/.*//g')
    else
    DBNAME=$(grep pg1-path /etc/pgbackrest/pgbackrest.conf | sed -e 's/.*\///g')
    DBVER=$(grep pg1-path /etc/pgbackrest/pgbackrest.conf | sed -e 's/.*\/1/1/g' -e 's/\/.*//g')
    fi
    select_restorepoint
    echo2 "${RED}Выбранная точка [ $SELECTPOINT ] [ $SELECTTARGET ]. Начать восстановление? y/n${NORM}" "${RED}Selected point [ $SELECTPOINT ] [ $SELECTTARGET ]. Proceed recovery? y/n${NORM}"
    read var1
    case $var1 in
        Y)
        restore
        ;;
        y)
        restore
        ;;
        N)
        select_restorepoint
        ;;
        n)
        select_restorepoint
        ;;
        *)
        error
        select_restorepoint
        ;;
    esac
}

function restore(){
    staffcop stop
    pg_ctlcluster $DBVER $DBNAME stop
    if [ $(pg_lsclusters | grep -c down) != 0 ]; then
    systemctl stop postgresql
    sudo -u postgres rm -rf /var/lib/$DB/*
    sudo -u postgres pgbackrest --stanza=$STANZA --log-level-console=info restore --set=$SELECTPOINT --type=time "--target=$SELECTTARGET"
    systemctl start postgresql
    echo "select pg_wal_replay_resume();" | sudo -u postgres psql
    pg_ctlcluster $DBVER $DBNAME start
    if [ $(pg_lsclusters | grep -c online) != 0 ]; then
        echo "select max(id) from agent_event;select count(*) from agent_event;" | staffcop sql
        staffcop start
        echo2 "${GREEN}БД успешно восстановлена.${NORM}" "${GREEN}DB recovered successfully.${NORM}"
    else
        echo2 "${RED}Возникла непредвиденная ошибка во время восстановления БД.${NORM}" "${RED}An unexpected error occured during DB recovery.${NORM}"
        pg_lsclusters
        exit 1
    fi
    else
    pg_lsclusters
    echo2 "${RED}ОШИБКА. Кластер не остановлен. Восстановление в данный момент невозможно.${NORM}" "${RED}ERROR. Cluster is not stopped. Recovery is not possible at the moment.${NORM}"
    echo2 "Попробуйте перезапустить скрипт позже." "Try restarting the script later."
    exit 1
    fi
}

todo_dialog
exit 0
  1. Сделайте скрипт исполняемым:

chmod +x backup-and-restore.sh
  1. Запустите скрипт:

sudo ./backup-and-restore.sh
  1. Следуйте инструкциям на экране.