|
Professor Seleznov
|
Утилита резервирования pgBackRest перестала поддерживаться, проект заархивирован, стало актуальным найти замену для pgBackRest. Главными альтернативами называют WAL-G и Barman. Можно использовать pg_basebackup+pg_receivewal. Преимущество WAL-G в том, что резервирование возможно по протоколу S3 и WAL-G обеспечивает более высокую скорость резервирования, а также, неплохие перспективы развития. Кроме протокола S3, WAL-G может резервировать и восстанавливать из директории в файловой системе и работает с Patroni. Директория не обязательно находится на локальном диске, можно смонтировать любую файловую систему, например, NFS. Утилита свободно распространяемая. В статье рассматривается пример команд, которыми можно резервировать и восстанавливать PostgreSQL утилитой WAL-G.
 WAL-G можно собрать из исходников или из установить из пакета (dpkg -i wal-g-*.deb). Инсталляционный пакет содержит единственный файл wal-g, который будет распакован в какую-нибудь директорию. Если эта директория не находится в $PATH, то, чтобы не писать каждый раз путь к утилите, можно создать символическую ссылку в директории, присутствующей в переменной окружения $PATH:
root@host:~$ ln -s /opt/tantor/usr/bin/wal-g /usr/local/bin/wal-g
Настройки утилиты хранятся в одном файле. Путь к файлу настроек можно указывать параметром --config. Местоположение и название файла параметров WAL-G по умолчанию:
root@host:~$ wal-g | grep config --config string config file (default is $HOME/.walg.json) --turbo Ignore all kinds of throttling defined in config
По умолчанию, местоположение файла параметров $HOME/.walg.json. Для бэкапа в директорию достаточно создать файл:
root@host:~$ su - postgres postgres@host:~$ cat > $HOME/.walg.json << EOF { "WALG_FILE_PREFIX": "/var/lib/postgresql/backup", "WALG_COMPRESSION_METHOD": "brotli", "WALG_DELTA_MAX_STEPS": "5", "PGHOST": "/var/run/postgresql", "PGDATA": "/var/lib/postgresql/tantor-se-server-18/data" } EOF
Резервирование будет выполняться в директорию, на которую указывает ключ WALG_FILE_PREFIX. Алгоритм brotli обеспечивает лучшее и быстрое сжатие. Если вы не хотите сжимать файлы (бэкапы и WAL), то вместо brotli можно поставить none, WAL файлы в архиве будут иметь размер 16Мб, директорию с WAL-файлами можно будет использовать напрямую. Для работы не с директорией, а по протоколу S3 достаточно поменять параметры в файле $HOME/.walg.json, команды резервирования и восстановления остаются теми же самыми. Для проверки того, что wal-g может работать с настройками в файле, можно дать команду:
postgres@host:~$ wal-g backup-list INFO: 2026/04/28 10:33:54.281318 List backups from storages: [default] INFO: 2026/04/28 10:33:54.281702 No backups found
Бэкапов кластера не найдено, так как мы их пока не делали. Конфигурирование PostgreSQL для архивирования WAL Чтобы с бэкапа можно было полностью восстановиться нужно сохранять WAL-файлы. Их можно получать по протоколу репликации или выполнением команды, указанной в параметре конфигурации archive_command. Для сохранения WAL утилитой WAL-G можно установить параметры:
postgres=# alter system set archive_command = 'wal-g wal-push "%p" >> $PGDATA/log/archive_command.log 2>&1'; alter system set restore_command = 'wal-g wal-fetch "%f" "%p" >> $PGDATA/log/restore_command.log 2>&1'; alter system set archive_mode=on;
Параметр archive_commandзадаёт команду, которая будет выполняться после переключения на следующий WAL-сегмент. Команда должна завершаться успешно (возвращать статус "0"), иначе сегмент будет считаться не заархивированным и не сможет удаляться. %p - переменная которая инициализируется названием и путём к WAL-сегменту, в который завершена запись, и который должен быть заархивирован. Сообщения утилиты, которые она выводит в stdout и stderr направляются в файл. Параметр restore_command указывает, какая команда будет выполнена процессом startup, который восстанавливает кластер после запуска экземпляра и определяет по файлу backup_label или pg_control, какой WAL-сегмент нужен для продолжения восстановления (будет накатываться следующим). Эта команда должна создать WAL-файл в директории $PGDATA/pg_wal. Параметр archive_modeвключает действие параметра archive_command. Push или Pull Альтернатива команде archive_mode ("push") - запустить wal-g как службу, чтобы она получала ("pull") файлы журналов:
postgres@host:~$ wal-g wal-receive INFO: 2026/04/28 21:44:41.565679 FILE PATH: 00000002.history.
При использовании этого способа архивирования WAL нужно установить только параметр restore_command,параметр archive_mode должен иметь значение по умолчанию (off). Так как WAL-G принимает только сформированные WAL-файлы, то проще использовать archive_command. Единственно, надо проследить за тем, чтобы с резервируемого хоста нельзя было стирать или менять файлы в директории, куда резервируются файлы, иначе злоумышленник, завладевший резервируемым хостом, сможет стереть или испортить бэкапы. WAL-G может не только вытягивать журналы, но и резервировать кластер PostgreSQL (PGDATA) в режиме "pull", используя репликационный протокол. Опция дорабатывается, при использовании репликационного протокола пока не реализованы многопоточная передача и дельта-бэкапы. Это ограничение касается только создания бэкапов в режие "pull", вытягивание WAL не имеет таких ограничений. Параметр wal-receiveне принимает текущий файл WAL и при исчезновении директории PGDATA/pg_wal нельзя будет восстановить транзакции из текущего файла WAL. Отсутствие потерь (zero data loss, RPO=0) способны обеспечить: утилита pg_receivewal, процесс walreveiver (на физической реплике), Polar DataMax (в TantorXData). WAL-G и pg_receivewal WAL-G можно совместить с pg_receivewal: создавать бэкапы в высокоскоростном режиме со сжатием WAL-G, а журналы вытягивать утилитой pg_receivewal. При использовании pg_receivewal, нужно задать в параметре restore_command команду копирования из директории, куда pg_receivewal вытягивает журналы и отключить archive_mode. Стоит протестировать, что файл *.partial будет применяться при запуске экземпляра. Например, использовать restore_command = 'cp $HOME/backup/%f %p || cp $HOME/backup/%f.partial %p'.Файлы с расширением .partial не применяются при восстановлении, чтобы файл .partial применился, нужно убрать расширение. Тестирование работоспособности команд восстановления также полезно после обновления версий софта, так как в софте могут возникать ошибки. Например, в WAL-G, есть мелкий баг про то, что к названию файла "tar" добавляется в конце названия точка. Создание бэкапа утилитой WAL-G Чтобы изменения подействовали, нужно остановить и запустить (а не перезапустить) экземпляр. Переключимся на новый WAL-сегмент, так как archive_command выполняется только после завершения записи в WAL-файл процессами экземпляра и переключения на следующий:
postgres@host:~$ psql -c "select pg_switch_wal();" pg_switch_wal --------------- 0/30002BC (1 row) postgres@host:~$ cat $PGDATA/log/archive_command.log INFO: 2026/04/28 11:31:34.145668 Files will be uploaded to storage: default INFO: 2026/04/28 11:31:34.192862 FILE PATH: 000000010000000000000003.br
Появился файл archive_command.log, путь к которому был указан в параметре archive_command. Зарезервируем директорию кластера. WAL-G запускается на хосте с кластером, поэтому можно не пользоваться протоколом репликации, а копировать содержимое директории. Первый бэкап всегда полный. В команде создания бэкапа нужно передать название директории кластера:
postgres@host:~$ wal-g backup-push $PGDATA INFO: 2026/04/28 11:40:37.903727 Backup will be pushed to storage: default INFO: 2026/04/28 11:40:37.912409 Couldn't find previous backup. Doing full backup. ... INFO: 2026/04/28 11:40:38.357616 Wrote backup with name base_000000010000000000000005 to storage default
Проверка, что созданный бэкап есть в списке:
postgres@host:~$ wal-g backup-list INFO: 2026/04/28 11:47:02.111831 List backups from storages: [default] backup_name modified wal_file_name storage_name base_000000010000000000000005 2026-04-28T11:40:38+03:00 000000010000000000000005 default
В директории для бэкапов /var/lib/postgresql/backup появятся файлы, которые и являются бэкапом кластера баз данных:
postgres@host:~$ ls -al $HOME/backup/basebackups_005/*/tar_partitions total 2760 -rw-r--r-- 1 postgres postgres 269 Apr 28 11:40 backup_label.tar.br -rw-r--r-- 1 postgres postgres 2806055 Apr 28 11:40 part_001.tar.br -rw-r--r-- 1 postgres postgres 300 Apr 28 11:40 pg_control.tar.br
Следующие пять (WALG_DELTA_MAX_STEPS) бэкапов будут сделаны в режиме DELTA:
postgres@host:~$ wal-g backup-push $PGDATA INFO: 2026/04/28 11:59:41.614186 Backup will be pushed to storage: default INFO: 2026/04/28 11:59:41.628244 LATEST backup is: 'base_000000010000000000000005' INFO: 2026/04/28 11:59:41.629001 Delta backup from base_000000010000000000000005 with LSN 0/5000028. ... INFO: 2026/04/28 11:59:41.833147 Wrote backup with name base_000000010000000000000007_D_000000010000000000000005 to storage default
Полезна команда удаления мусора в архиве - неудачные бэкапы, ненужные журнальные файлы:
postgres@host:~$ wal-g delete garbage --confirm INFO: 2026/04/28 20:49:20.660407 Backup to delete will be searched in storages: [default] INFO: 2026/04/28 20:49:20.660540 retrieving permanent objects INFO: 2026/04/28 20:49:20.661749 Running in default mode. Will remove outdated WAL files and leftover backup files. INFO: 2026/04/28 20:49:20.662257 Start delete INFO: 2026/04/28 20:49:20.663400 Objects in folder: INFO: 2026/04/28 20:49:20.663440 will be deleted: wal_005/00000002000000000000002A.br, from storage: default
Восстановление из бэкапа, созданного WAL-G Остановим экземпляр и удалим директорию PGDATA:
postgres@host:~$ pg_ctl stop waiting for server to shut down.... done server stopped postgres@host:~$ rm -rf $PGDATA/*
Команда симулирует полную потерю мастера ("disaster"). Команда удаляет, в том числе и текущий WAL-сегмент, который не был записан в архив. Транзакции, которые находятся в этом файле, не будут восстановлены. Директория, в которую идёт восстановление должна быть пустой. Команда восстановления директории кластера из бэкапа:
postgres@host:~$ wal-g backup-fetch $PGDATA LATEST INFO: 2026/04/28 12:56:37.402035 Selecting the latest backup... INFO: 2026/04/28 12:56:37.402219 Backup to fetch will be searched in storages: [default] INFO: 2026/04/28 12:56:37.402360 LATEST backup is: 'base_000000010000000000000007_D_000000010000000000000005' INFO: 2026/04/28 12:56:37.406190 Delta from base_000000010000000000000005 at LSN 0/5000028 ... INFO: 2026/04/28 12:56:38.500783 base_000000010000000000000005 fetched. Upgrading from LSN 0/5000028 to LSN 0/7000028 ... Backup extraction complete.
Директория PGDATA восстановлена. Проверим содержимое директории журналов:
postgres@host:~$ ls $PGDATA/pg_wal
Директория пуста, как и директория с диагностическими файлами PGDATA/log, что нормально - логи не бэкапятся, файлы WAL бэкапятся и восстанавливаются отдельно. Вместо управляющего файла будет использоваться файл backup_label:
postgres@host:~$ cat $PGDATA/backup_label START WAL LOCATION: 0/7000028 (file 000000010000000000000007) CHECKPOINT LOCATION: 0/7000098 BACKUP METHOD: streamed BACKUP FROM: primary START TIME: 2026-04-28 11:59:41 MSK LABEL: 2026-04-28 11:59:41.640728 +0300 MSK m=+0.075156967 START TIMELINE: 1
Попробуем запустить экземпляр:
postgres@host:~$ pg_ctl start waiting for server to start.... pg_ctl: could not start server
Экземпляр не смог запуститься, нет журналов для синхронизации файлов кластера, так как в директории pg_wal нет ни одного файла журнала. Попытка запуска экземпляра не портит файлы. Нужно создать файл, который укажет, что выполняется восстановление из бэкапа:
postgres@host:~$ touch $PGDATA/recovery.signal 8) Запустим экземпляр: postgres@host:~$ pg_ctl start done server started
Процесс startup выполнял команду, указанную в параметре конфигурации restore_command и применял скопированные командой WAL-файлы, после чего экземпляр был запущен в соответствии со значениями параметров (recovery_target_*), которыми можно указать, до какого момента выполнять восстановление и что делать после достижения этого момента. Последний примененный журнальный файл тот, который был заархивирован. Было выполнено неполное восстановление. Журнальные файлы, которые не попали в архив, не были применены, и транзакции, которые могли бы в них быть, были потеряны. Заключение После прекращения развития утилиты pgBackRest, актуальным стал выбор перспективных утилит резервирования. Там, где нужна простота и быстрота резервирования, WAL-G - неплохой выбор. WAL-G имеет большое число разработчиков из разных стран и активно развивается. В статье даны примеры, как установить и сконфигурировать WAL-G и команды, которыми можно зарезервировать и восстановить PostgreSQL.-Источник
|