core code helper

Бекапи PostgreSQL: pg_dump, pg_basebackup і відновлення на момент часу

Логічні й фізичні бекапи, архівування WAL і PITR — що з цього потрібно вашому проєкту, як налаштувати і, головне, як перевірити, що бекап справді відновлюється.

0 імпортували Імпортувати собі

Бекап, який ніколи не відновлювали, — не бекап, а надія. Мета не в тому, щоб «файлик лежав у 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 = replica
pgbackrest --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).

Перевірка відновлення — обов'язкова

Автоматизуйте те, що зазвичай роблять «колись потім»:

  1. Раз на тиждень піднімати тимчасовий сервер з останнього бекапу.
  2. Перевіряти, що база стартує і SELECT count(*) у ключових таблицях дає правдоподібні цифри.
  3. Міряти час відновлення — це і є ваш реальний RTO.
  4. Надсилати алерт, якщо перевірка не пройшла або останній успішний бекап старший за добу.
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 Інші способи входу