Коли ти працюєш з базою даних, все здається досить простим: додав рядок, оновив запис, видалив клієнта. Але за цією простотою ховається складний і продуманий механізм. Де насправді зберігаються ці дані? Як PostgreSQL примудряється нічого не втратити, навіть якщо сервер раптово вимкнеться?
Щоб розібратися, треба зрозуміти дві ключові штуки: де фізично лежать дані (таблиці, індекси, службова інфа) і як працює механізм захисту цих даних — журнал транзакцій, він же WAL (Write-Ahead Logging).
Вся база даних PostgreSQL зберігається у вигляді набору файлів у спеціальній директорії — data_directory. Зазвичай вона знаходиться тут:
/var/lib/postgresql/17/main
У цій папці — все серце бази: і самі таблиці, і індекси, і метаінфа, і налаштування. Там же знаходиться журнал WAL — механізм, який першим приймає на себе всі зміни. Перш ніж дані потраплять у таблицю на диску, вони записуються в WAL. Це як чорновик, у який база фіксує кожен крок, щоб у разі збою можна було відновити все до останньої операції.
Завдяки такому підходу PostgreSQL забезпечує надійність і стійкість, навіть у найнестабільніших умовах.
Таблиці
Кожна таблиця — це фізично окремий файл або набір файлів. Ці файли знаходяться у підкаталозі base/. Структура приблизно така:
$PGDATA/base/
├── 16384/
│ ├── 12345 ← таблиця
│ ├── 12346 ← індекс
│ └── ...
16384— це внутрішній ідентифікатор бази даних (OID).12345— ідентифікатор конкретної таблиці.
Якщо таблиця велика, PostgreSQL розбиває її на сегменти по 1 ГБ:
12345
12345.1
12345.2
...
Файли не містять "рядки" як у текстовому CSV — це формат "бінарних сторінок" по 8 КБ.
WAL: Write-Ahead Logging — це не просто "лог"
Тепер перейдемо до однієї з найважливіших і часто неправильно зрозумілих частин PostgreSQL — WAL, або Write-Ahead Logging. Незважаючи на слово лог у назві, WAL — це не звичайний текстовий лог-файл, як логи помилок чи запитів. Це життєво важливий механізм узгодженості і відновлення даних, який працює на рівні низькорівневих змін файлової системи.
WAL — це не звіт про події, а попередній запис усіх змін, які PostgreSQL збирається зробити з даними. Цей запис відбувається до фактичної модифікації таблиць на диску. Саме тому називається write-ahead — "запис наперед".
Коли ти, наприклад, вставляєш новий рядок у таблицю, PostgreSQL:
- НЕ одразу оновлює таблицю на диску — це було б повільно і небезпечно.
- Спочатку записує в WAL, що цей рядок буде додано.
- Тільки потім, коли буде зручно (наприклад, у фоновому процесі), дані насправді потрапляють у таблицю.
Це працює як чек у банку: спочатку ти його підписав (WAL), і тільки потім банк оновить рахунок (таблиця). Якщо раптом щось пішло не так — чек все ще на руках, і можна повторити операцію.
Формат і структура WAL
- WAL-файли зберігаються у бінарному форматі.
- Кожен файл — це строго впорядкований потік операцій, які описують внутрішні зміни сторінок даних, індексних структур, комітів і т.д.
- Один WAL-файл має фіксований розмір — за замовчуванням 16 МБ.
Важливо: WAL не містить "SQL-команд" чи "рядків таблиці" у звичному вигляді. Він містить інструкції для рушія PostgreSQL, як відтворити зміни, сторінка за сторінкою.
Що буде при збої?
Якщо сервер PostgreSQL раптово вимкнувся — скажімо, через різке вимкнення живлення — не все втрачено. При наступному запуску база не панікує, а спокійно завантажує з диска останню збережену «стійку» версію даних. Після цього вона бере журнал транзакцій (WAL), у якому залишилися всі останні зміни, і акуратно «докручує» їх — застосовує те, що ще не встигло потрапити в основні файли. В результаті база відновлюється до повністю узгодженого стану, ніби нічого й не сталося.
Додаткові можливості WAL
Point-In-Time Recovery (PITR). Зберігання WAL-файлів дозволяє відновити базу до будь-якої точки часу між двома повними бекапами.
Стрімінгова реплікація. PostgreSQL може передавати WAL-записи на інший сервер у реальному часі. Це дозволяє підтримувати гарячу репліку — копію бази даних, синхронізовану з основною.
Інкрементальне відновлення. У зв'язці з повним бекапом, WAL дозволяє відновити тільки зміни, а не копіювати всю базу заново.
Створення бінарних бекапів: pg_basebackup
Якщо ти вже трохи освоївся з pg_dump, то знаєш, що він чудово підходить для створення логічних бекапів (тобто копіювання структури бази даних і її даних у вигляді SQL-запитів). Але що, якщо треба зробити фізичний бекап? Наприклад, повне дзеркальне копіювання всіх файлів бази даних? Тут на допомогу приходить інструмент pg_basebackup.
pg_basebackup — це утиліта, яка дозволяє створювати фізичні копії даних PostgreSQL. Вона особливо корисна для великих баз даних, де треба ефективно керувати процесом відновлення. Головна перевага pg_basebackup у тому, що він робить це дуже швидко.
Основний синтаксис команди pg_basebackup
Робота з pg_basebackup починається з розуміння його команди. Вона виконується у твоєму терміналі і має такий базовий вигляд:
pg_basebackup -D /backup_directory -F tar -z -P
Розберемо, що тут відбувається:
-D /backup_directory— вказує директорію, куди будуть збережені твої файли резервної копії.-F tar— формат даних. Опціяtarстворює архівний файл у форматі.tar. Ти також можеш використатиplainдля створення файлової структури бази даних.-z— стискає резервну копію, що допомагає зекономити місце на диску. Завжди приємно, коли бекап займає менше місця!-P— вмикає відображення прогресу в реальному часі. Це як додаткова порція впевненості: ти бачиш, що процес іде, і сервер не «завис».
Приклад використання:
pg_basebackup -D /backups/university_backup -F tar -z -P
Після виконання команди у вказаній директорії /backups/university_backup створюється резервна копія у форматі .tar.
Переваги використання pg_basebackup
Ефективність: інкрементальні бекапи дозволяють не дублювати незмінені дані, що економить як час, так і простір.
Простота використання: інструмент pg_basebackup автоматично обробляє всі деталі, включаючи файли WAL.
Надійність: завдяки інтеграції з механікою PostgreSQL, pg_basebackup створює точні копії всієї бази даних, які можна легко відновити.
Приклади використання
А тепер — до практики. Нижче наведені реальні приклади, як можна використати pg_basebackup для створення резервних копій бази даних PostgreSQL. Покажемо, як зробити базовий бекап, як додати стиснення, і як увімкнути архівування журналу транзакцій (WAL) для можливості відновлення «на точку у часі». Ці команди підійдуть як для початкового знайомства, так і для просунутих сценаріїв.
Створення базової резервної копії
pg_basebackup -D /backups/full_backup -F tar -z -P
Результат: повний бекап бази даних в архіві .tar.
Налаштування стиснення і формату
Створимо резервну копію даних з високим рівнем стиснення:
pg_basebackup -D /backups/full_backup -F tar -z -Z 9 -P
Тут -Z 9 вказує рівень стиснення (максимум — 9).
Архівування WAL
Якщо налаштувати архівування WAL, база даних може бути відновлена до будь-якої точки часу. Команда для налаштування резервного копіювання WAL:
pg_basebackup -D /backups/incremental_backup -F tar -z -P --wal-method=archive
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ