Архивация WAL и непрерывное резервное копирование в PostgreSQL: Continuous Archiving
- Каталог
pg_walлавинообразно разрастается, занимая все свободное дисковое пространство. - В логах фиксируются ошибки:
archive command failed with exit code 1илиarchive_command: Permission denied. - PostgreSQL аварийно останавливается (PANIC) из-за невозможности записать новую порцию WAL-сегментов на заполненный диск.
1. Настройка непрерывной архивации в postgresql.conf
# Включение режима архивации (требует перезапуска)
wal_level = replica
archive_mode = on
# Надежная команда копирования с проверкой успешности
archive_command = 'test ! -f /mnt/nfs_backup/wal_archive/%f && cp %p /mnt/nfs_backup/wal_archive/%f'
# Таймаут принудительного переключения сегмента (для баз с низкой активностью)
archive_timeout = 900 # 15 минут2. Проверка статуса процессов архивации через системные представления
SELECT
archived_count,
last_archived_wal,
last_archived_time,
failed_count,
last_failed_wal,
last_failed_time
FROM pg_stat_archiver;3. Экстренные действия при отказе archive_command и переполнении pg_wal
Если диск переполнен, временно замените команду архивации на фиктивную, чтобы дать серверу подняться, но помните, что это прервет цепочку PITR:
-- Временная заглушка (только для снятия аварии и освобождения диска!)
ALTER SYSTEM SET archive_command = '/bin/true';
SELECT pg_reload_conf();4. Настройка промышленной архивации через pgBackRest
# /etc/pgbackrest.conf
[global]
repo1-path=/var/lib/pgbackrest
repo1-retention-full=2
[main]
pg1-path=/var/lib/postgresql/16/main# В postgresql.conf:
archive_command = 'pgbackrest --stanza=main archive-push %p' Частые вопросы (FAQ)
Почему PostgreSQL не удаляет старые файлы из pg_wal, если archive_command возвращает ошибку?
PostgreSQL строго гарантирует сохранность данных: файл WAL не будет удален или перезаписан до тех пор, пока archive_command не завершится с нулевым кодом возврата (exit code 0).
Что означают макросы %p и %f в строке archive_command?
%p заменяется на полный путь к архивируемому файлу (например, pg_wal/000000010000000100000001), а %f — только на относительное имя самого WAL-файла.
Можно ли вручную удалять файлы из каталога pg_wal через команду rm?
Категорически запрещено. Удаление активного WAL-сегмента гарантированно приведет к разрушению транзакционной целостности и невозможности запуска кластера базы данных.
Как параметр archive_timeout защищает от потери данных при сбое?
Он принудительно переключает WAL-сегмент по истечении заданного интервала времени, даже если он не заполнился до стандартных 16 МБ, гарантируя регулярную доставку актуальных данных в архив.