Для непрерывного архивирования WAL файлов в реальном времени применяется pg_receivewal, а не archive_command.
Caution
При наличии синхронной реплики архивировать WAL файлов в реальном времени не требуется. Для кластеров СУБД используется не этот сервис, а штатная функциональность archive_command, чтобы везде было единообразно, это упрощает сопровождение.
Сервис работает только с СУБД мастером, использует отдельный слот репликации и выглядит как ещё одна постоянно отстающая асинхронная реплика.
Note
При архивировании WAL файлы сжимаются в формат gzip
(≈ 66% от исходного размера, даже если включен параметр wal_compression). Это позволяет экономить место на сетевом диске и уменьшить нагрузку на ввод-вывод.
Warning
Удаление неактуальных WAL файлов сделано в сервисе резервного копирования!
Преимущества сервиса:
- Архивирование WAL файлов в реальном времени. Гарантируется, что ни одна транзакция не будет потеряна.
Недостатки сервиса:
- Однопоточный режим работы
- Устаревшее сжатие в gzip (по сравнению с zstd)
Выводы: сервис хорошо подходит для небольших нагрузок с медленной и долгой записью каждого WAL файла
Инсталляция сервиса
# создаём файлы
sudo su - postgres -c "nano ~/.pgpass && chmod 600 ~/.pgpass" # в файле нужно сохранить пароль для пользователя bkp_replicator
sudo nano /etc/systemd/system/pg_receivewal@.service
# PostgreSQL v14
sudo systemctl daemon-reload \
&& sudo systemctl enable pg_receivewal@14 \
&& sudo systemctl restart pg_receivewal@14
# PostgreSQL v16
sudo systemctl daemon-reload \
&& sudo systemctl enable pg_receivewal@16 \
&& sudo systemctl restart pg_receivewal@16
sudo systemctl status pg_receivewal@14
sudo systemctl status pg_receivewal@16
Интеграция с Patroni
# разрешаем перезапускать сервис под пользователем postgres без пароля
sudo nano /etc/sudoers.d/permit_pgreceivewal
sudo su postgres -c "sudo /bin/systemctl restart pg_receivewal@14" # тестируем перезапуск
# редактируем конфигурацию Patroni
patrionictl -c /etc/patroni/patrini.yml edit-config
# добавляем в секцию postgresql:
postgresql:
callbacks:
on_role_change: /bin/bash -c 'sudo /bin/systemctl restart pg_receivewal@14'
#on_restart: /bin/bash -c 'sudo /bin/systemctl restart pg_receivewal@14' # закомментировано, т.к. это сделано в настройках pg_receivewal@.service через PartOf=
#on_start: /bin/bash -c 'sudo /bin/systemctl start pg_receivewal@14' # закомментировано, т.к. это сделано в настройках pg_receivewal@.service через PartOf=
#on_stop: /bin/bash -c 'sudo /bin/systemctl stop pg_receivewal@14' # закомментировано, т.к. это сделано в настройках pg_receivewal@.service через PartOf=
Файлы
Systemd special symbols
- does not expand glob patterns like
*
(run command inside a shell) - interprets several
%
prefixes as specifiers (escape%
with%%
) - parses
\
before some characters (escape\
with\\
)
Сервис был временно остановлен. После его запуска продолжит ли он копирование WAL файлов с того места, где остановился?
Да, если на сервере СУБД хватит WAL файлов для исключения «разрыва цепочки».
Иначе нужно сделать так:
- в архивной папке удалить все WAL файлы
- запустить сервис
- сделать полную резервную копию СУБД
- Протестировать, что сервис перезагружается при перезагрузке Patroni / PostgreSQL.
- Протестировать, что Patroni / PostgreSQL не перезагружается при перезагрузке серсиса.
- Протестировать, что архивирование возобновляется при переезде мастера на другой узел.