Когда вы работаете с базой данных, всё кажется довольно простым: добавили строку, обновили запись, удалили клиента. Но за этой простотой скрывается сложный и продуманный механизм. Где на самом деле хранятся эти данные? Как 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
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ