JavaRush /Курсы /SQL SELF /Как PostgreSQL хранит данные: структура базы и журнал тра...

Как PostgreSQL хранит данные: структура базы и журнал транзакций (WAL)

SQL SELF
43 уровень , 4 лекция
Открыта

Когда вы работаете с базой данных, всё кажется довольно простым: добавили строку, обновили запись, удалили клиента. Но за этой простотой скрывается сложный и продуманный механизм. Где на самом деле хранятся эти данные? Как 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:

  1. НЕ сразу обновляет таблицу на диске — это было бы медленно и небезопасно.
  2. Сначала записывает в WAL, что эта строка будет добавлена.
  3. Только потом, когда будет удобно (например, в фоновом процессе), данные на самом деле попадают в таблицу.

Это работает как чек в банке: сначала вы его подписали (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
2
Задача
SQL SELF, 43 уровень, 4 лекция
Недоступна
Создание физического бэкапа PostgreSQL с использованием WAL
Создание физического бэкапа PostgreSQL с использованием WAL
1
Опрос
Введение в резервное копирование, 43 уровень, 4 лекция
Недоступен
Введение в резервное копирование
Введение в резервное копирование
Комментарии (1)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Ra Уровень 35 Student
12 августа 2025
Попробовал сделать бэкап,

sudo du -sh /var/lib/postgresql/16/main
43M     /var/lib/postgresql/16/main

sudo mkdir /backups
sudo chown -R postgres /backups
sudo -u postgres pg_basebackup -D /backups -F tar -z -P --checkpoint=fast
Ругалось на чекпоинт, добавил --checkpoint=fast, заработало, но может есть косяки какие-то. ЧЯДНТ?