Бекапи PostgreSQL: pg_dump, pg_basebackup і відновлення на момент часу
Логічні й фізичні бекапи, архівування WAL і PITR — що з цього потрібно вашому проєкту, як налаштувати і, головне, як перевірити, що бекап справді відновлюється.
Бекап, який ніколи не відновлювали, — не бекап, а надія. Мета не в тому, щоб «файлик лежав у S3», а в тому, щоб відповісти на два питання: скільки даних ми можемо втратити (RPO) і за скільки часу підніматимемося (RTO).
Два типи бекапів
Логічний (pg_dump) |
Фізичний (pg_basebackup, pgBackRest) |
|
|---|---|---|
| Що зберігає | SQL-команди / дамп об'єктів | Файли кластера як є |
| Гранулярність | Одна база, таблиця, схема | Увесь кластер |
| Відновлення в іншу версію PostgreSQL | Так | Ні, лише та сама мажорна версія |
| Швидкість на великих базах | Повільно | Швидко |
| Відновлення на момент часу (PITR) | Ні | Так, разом з архівом WAL |
pg_dump: просто і надійно для невеликих баз
# Формат custom (-Fc): стиснення + вибіркове відновлення
pg_dump -h db -U app -d app -Fc -f app-$(date +%F).dump
# Паралельний дамп у директорію для великих баз
pg_dump -h db -U app -d app -Fd -j 4 -f app-$(date +%F).dir
# Глобальні об'єкти (ролі, табличні простори) pg_dump не зберігає!
pg_dumpall -h db -U postgres --globals-only > globals.sqlВідновлення:
createdb -h db -U postgres app_restore
pg_restore -h db -U postgres -d app_restore -j 4 --no-owner app-2026-09-14.dump
# Лише одну таблицю
pg_restore -d app_restore -t orders app-2026-09-14.dumpУвага
pg_dumpзнімає консистентний знімок, але не відновлює дані «на 14:32». Якщо дамп щоночі, а збій о 18:00 — ви втратите день даних. Для меншого RPO потрібен WAL.
WAL і відновлення на момент часу
Кожна зміна в PostgreSQL спочатку записується в WAL (Write-Ahead Log). Якщо зберігати повний фізичний бекап і всі WAL-файли після нього, можна відновити базу на будь-яку секунду — наприклад, за хвилину до того, як хтось виконав DELETE без WHERE.
Не налаштовуйте archive_command скриптами вручну. Використовуйте інструменти, які роблять це правильно: pgBackRest, WAL-G або Barman. Вони вміють паралельне стиснення, шифрування, інкрементальні бекапи, S3 і перевірку цілісності.
Приклад з pgBackRest
# /etc/pgbackrest/pgbackrest.conf
[global]
repo1-type=s3
repo1-s3-bucket=acme-pg-backups
repo1-s3-region=eu-central-1
repo1-s3-endpoint=s3.eu-central-1.amazonaws.com
repo1-path=/production
repo1-retention-full=4
repo1-cipher-type=aes-256-cbc
compress-type=zst
process-max=4
[main]
pg1-path=/var/lib/postgresql/17/main# postgresql.conf
archive_mode = on
archive_command = 'pgbackrest --stanza=main archive-push %p'
wal_level = replicapgbackrest --stanza=main stanza-create
pgbackrest --stanza=main check # архівування WAL працює?
pgbackrest --stanza=main --type=full backup # щотижня
pgbackrest --stanza=main --type=diff backup # щодня
pgbackrest --stanza=main infoВідновлення на момент часу
systemctl stop postgresql
pgbackrest --stanza=main --delta \
--type=time --target="2026-09-14 14:31:00+03" \
--target-action=promote restore
systemctl start postgresqlПравило 3-2-1
- 3 копії даних;
- на 2 різних типах носіїв або в різних системах;
- 1 копія поза основною інфраструктурою (інший регіон, інший акаунт хмари).
ОбережноБекапи в тому самому хмарному акаунті, що й база, не захищають від компрометації акаунта чи помилкового
terraform destroy. Хоча б одна копія має бути в окремому акаунті з обмеженим доступом на видалення (object lock / immutability).
Перевірка відновлення — обов'язкова
Автоматизуйте те, що зазвичай роблять «колись потім»:
- Раз на тиждень піднімати тимчасовий сервер з останнього бекапу.
- Перевіряти, що база стартує і
SELECT count(*)у ключових таблицях дає правдоподібні цифри. - Міряти час відновлення — це і є ваш реальний RTO.
- Надсилати алерт, якщо перевірка не пройшла або останній успішний бекап старший за добу.
pgbackrest --stanza=main verify # перевірка цілісності файлів у репозиторіїРеплікація — не бекап
Репліка миттєво повторює все, включно з DROP TABLE. Вона захищає від падіння сервера, але не від помилки людини чи застосунку. Бекапи з PITR потрібні навіть за наявності реплік.
О 14:32 хтось виконав DELETE FROM orders без WHERE. Нічний pg_dump зроблено о 03:00. Чи можна відновити дані станом на 14:31?
Лише з pg_dump — ні: він дасть стан на 03:00, і зміни за день буде втрачено. Відновити на 14:31 можна, якщо налаштовано фізичний бекап з архівуванням WAL (pgBackRest, WAL-G) — тоді виконується PITR з target-time 14:31.
Збережіть статтю собі
Увійдіть, щоб імпортувати її у власні нотатки, відмічати вивчене, ставити лайки й питати спільноту. Реєстрація безкоштовна: вхід через Google займає кілька секунд.
Увійти через Google Інші способи входу