linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
Intro
Lessons
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Главы
  • How it worksскоро
  • Уроки
  • База знаний
  • Собеседование
Часть IV — Буферный кеш и журнал

$ глава 20 · 50 минут

Режимы журнала: minimal, replica, logical

Журнал из предыдущих глав мы рассматривали в одной роли - восстановление после сбоя. Но тот же поток изменений умеет питать репликацию, архивирование и логическое декодирование. Разница только в одном: сколько информации в журнал писать.

Это и регулирует wal_level. Чем выше уровень, тем больше журнал знает - и тем больше возможностей открывается, но и тем больше места он занимает. Самое практичное следствие: уровень нельзя выбрать «на всякий случай» задним числом. Если база работала на minimal, а вам вдруг понадобилась реплика - в журнале просто нет нужных данных за прошлое, и придётся менять уровень и перезапускать сервер.

В этой главе разберём три уровня, что каждый даёт и чего лишает, и научимся заглядывать внутрь журнала через pg_walinspect - чтобы увидеть своими глазами, какие записи там лежат.

20.1 Один журнал, три уровня детализации

wal_level определяет, насколько подробно PostgreSQL описывает изменения в журнале. Уровней три, они вложены: каждый следующий пишет всё, что предыдущий, плюс что-то ещё.

  • minimal - пишет ровно столько, чтобы пережить сбой и восстановиться на этом же сервере. Ничего лишнего;
  • replica (по умолчанию) - добавляет информацию, достаточную, чтобы другой сервер мог проиграть журнал и поддерживать копию базы, а также чтобы работало архивирование и восстановление на точку;
  • logical - добавляет ещё данные, нужные, чтобы извлекать из журнала изменения в логическом виде («в таблице X обновилась строка с такими-то значениями»), а не как физические правки страниц.

Смена уровня требует перезапуска сервера - это не параметр, который можно подкрутить на лету.

20.2 minimal: быстро, но в одиночестве

На уровне minimal журнал содержит минимум для crash recovery. Главная выгода - некоторые массовые операции могут почти не писать в журнал. Классический пример: если в одной транзакции создать (или опустошить через TRUNCATE) таблицу и тут же залить в неё данные через COPY, PostgreSQL может пропустить журналирование самих данных. Логика безопасна: если транзакция не закоммитится, таблицы всё равно не будет, а если закоммитится - данные на диск он запишет напрямую. Меньше журнала - быстрее массовая загрузка.

Цена высокая: minimal несовместим ни с физической репликацией, ни с архивированием WAL, ни с восстановлением на точку. Журнал просто не содержит данных, которые им нужны. Поэтому minimal уместен на изолированных инсталляциях, где реплики и PITR заведомо не нужны - например, на временной базе под разовую загрузку и аналитику.

20.3 replica: уровень по умолчанию

replica - то, на чём работает подавляющее большинство баз, и значение по умолчанию. Журнал на этом уровне содержит достаточно, чтобы:

  • физическая репликация - реплика получает поток WAL и проигрывает его у себя, поддерживая побайтовую копию мастера (часть VIII);
  • архивирование - сегменты WAL можно складывать в архив;
  • восстановление на точку (PITR) - имея базовую копию и архив WAL, базу можно восстановить на любой момент в прошлом.

За это платят отказом от оптимизации minimal: массовые загрузки журналируются полностью, потому что реплика и архив должны увидеть все данные. Для обычной OLTP-нагрузки эта разница незаметна, а возможность иметь реплику и бэкап с восстановлением на точку - почти всегда обязательна.

20.4 logical: журнал, который понимает строки

Физическая репликация копирует журнал как есть - реплика становится точной побайтовой копией. Но иногда нужно другое: передать только изменения конкретных таблиц, в другую схему, в другую мажорную версию или вообще в стороннюю систему. Для этого журнал должен описывать изменения логически: не «в странице 42 байты такие-то», а «в таблице orders обновилась строка с id=7, новые значения такие».

Уровень logical добавляет в журнал именно эту информацию. Сколько её писать для UPDATE и DELETE, зависит от REPLICA IDENTITY таблицы - это настройка, которая говорит, как идентифицировать изменённую строку (по первичному ключу по умолчанию, или по всей строке). На logical работают публикации и подписки логической репликации (часть VIII).

Платят за logical дополнительным объёмом журнала. Поэтому его включают, когда логическая репликация или декодирование действительно нужны, а не по умолчанию.

20.5 Матрица возможностей

Сведём всё в таблицу - её удобно держать в голове:

Возможностьminimalreplicalogical
Восстановление после сбоядадада
Архивирование и PITRнетдада
Физическая репликациянетдада
Логическая репликациянетнетда
Объём журналанаименьшийсреднийнаибольший

Главное правило: уровень выбирают заранее, под будущие потребности. Поднять с minimal до replica задним числом, чтобы «прямо сейчас» сделать реплику из текущего состояния, не выйдет - нужных данных в прошлом журнале нет. Меняют уровень с перезапуском, и только новый журнал будет полным. Сводка по уровням и переходам - в wal-level.

20.6 Заглянуть в журнал: pg_walinspect

Журнал не обязан оставаться абстракцией. Расширение pg_walinspect (доступно с PostgreSQL 15) показывает содержимое WAL прямо из SQL.

sql
CREATE EXTENSION IF NOT EXISTS pg_walinspect;
-- статистика по записям в последнем отрезке журнала
SELECT "resource_manager/record_type" AS rmgr, count, record_size
FROM pg_get_wal_stats(pg_current_wal_lsn() - 100000,
                      pg_current_wal_lsn(), false)
ORDER BY count DESC;

В колонке ресурс-менеджера (в выводе её имя - resource_manager/record_type) видно, какая подсистема породила записи: Heap - изменения строк таблиц, Btree - изменения B-tree индексов, Transaction - коммиты и аборты, XLOG - служебные записи (включая full-page images). Так абстрактный «журнал» превращается в конкретный перечень: вот INSERT в таблицу, вот изменение индекса, вот коммит.

Отдельные записи показывает pg_get_wal_records_info - с их LSN, типом и размером. Это лучший способ почувствовать, во что превращается обычный INSERT на уровне журнала.

20.7 pg_waldump: тот же взгляд из командной строки

У pg_walinspect есть старший родственник из командной строки - утилита pg_waldump. Она читает сегменты журнала прямо с диска и печатает записи в человекочитаемом виде, не требуя работающего сервера.

bash
pg_waldump 000000010000000000000001 | head

pg_waldump незаменим, когда сервер не запускается и нужно понять, что было в журнале перед сбоем, или при отладке - какие именно записи породила конкретная операция. pg_walinspect удобнее для живого сервера и SQL-аналитики, pg_waldump - для офлайн-разбора сегментов. Оба показывают один и тот же журнал с разных сторон.

20.8 Конец части: от одного сервера к нескольким

Этой главой замыкается тема журнала на одном сервере. Мы прошли путь от буферного кеша (изменения копятся в памяти) через write-ahead (журнал опережает данные) и контрольные точки (граница для восстановления) к режимам журнала (сколько в него писать).

Уровни replica и logical - это мост к следующей большой теме. Поток WAL, который мы научились читать, можно отправить на другой сервер: байт-в-байт (физическая репликация) или как логические изменения строк (логическая). На этом строятся отказоустойчивость и масштабирование чтения - но это уже часть про репликацию.

Уроки в sandbox

lab-20.1. Что пишет журнал: разбираем WAL через pg_walinspect

Заглянем внутрь журнала. Узнаем текущий wal_level, нагенерим изменения, а потом через pg_walinspect разберём, какие записи они породили - изменения строк, индексов, коммиты. Перед шагами предскажи, записи какой подсистемы будут преобладать.

  1. Узнай текущий уровень журнала: SHOW wal_level; - предскажи, что увидишь (значение по умолчанию).

  2. Запомни стартовую позицию: SELECT pg_current_wal_lsn();.

  3. Нагенерируй изменения: серия INSERT и UPDATE по таблице flights.

  4. Посмотри статистику по записям: pg_get_wal_stats(...) в отрезке от стартового LSN до текущего - найди строку Heap.

  5. Разбери отдельные записи через pg_get_wal_records_info(...) - найди записи типа INSERT/UPDATE.

  6. Найди в статистике записи XLOG с full-page images после CHECKPOINT;.

sandbox с автопроверкой - открыть в песочнице

Резюме

  • `wal_level` задаёт, сколько информации писать в журнал; уровни вложены: minimal ⊂ replica ⊂ logical.
  • minimal - минимум для crash recovery, позволяет некоторым массовым операциям почти не писать в журнал, но исключает репликацию, архивацию и PITR.
  • replica (по умолчанию) - достаточно для физической репликации, архивирования и восстановления на точку; обычная OLTP-нагрузка платит за это незаметно.
  • logical - добавляет логическое описание изменений строк (зависит от `REPLICA IDENTITY`), нужное для логической репликации и декодирования.
  • Уровень выбирают заранее: поднять с minimal до replica задним числом, чтобы сделать реплику из текущего состояния, нельзя - в прошлом журнале нет данных; смена требует перезапуска.
  • `pg_walinspect` (PG15+) показывает содержимое WAL из SQL (`pg_get_wal_stats`, `pg_get_wal_records_info`) по resource_manager: Heap, Btree, Transaction, XLOG.
  • `pg_waldump` читает сегменты журнала из командной строки без работающего сервера - для офлайн-разбора и отладки.

Контрольные вопросы

  1. Чем различаются три уровня wal_level и как они соотносятся?

    Показать ответ

    Уровни вложены. minimal пишет минимум для восстановления после сбоя на этом же сервере. replica добавляет информацию для физической репликации, архивирования и восстановления на точку (PITR) - это значение по умолчанию. logical добавляет ещё логическое описание изменений строк, нужное для логической репликации и декодирования. Каждый следующий уровень пишет всё, что предыдущий, плюс своё; растёт и объём журнала.

  2. Почему на minimal быстрее массовая загрузка и чего за это лишаешься?

    Показать ответ

    На minimal некоторые операции могут пропустить журналирование данных

    • например, COPY в таблицу, созданную или опустошённую в той же транзакции: если транзакция не закоммитится, таблицы не будет, а если закоммитится, данные запишутся на диск напрямую. Меньше журнала - быстрее загрузка. Цена: minimal несовместим с физической репликацией, архивированием WAL и PITR, потому что журнал не содержит нужных им данных. Уместен только на изолированных базах без реплик и бэкапа на точку.
  3. Почему нельзя поднять wal_level задним числом, чтобы сразу сделать реплику?

    Показать ответ

    Потому что более высокий уровень добавляет данные в журнал начиная с момента смены. Если база работала на minimal, в её прошлом журнале просто нет информации, нужной для репликации или PITR, - задним числом она там не появится. Сменить уровень можно (с перезапуском сервера), но полным станет только журнал, записанный после смены. Поэтому уровень выбирают заранее, под будущие потребности.

  4. Что показывает resource_manager в выводе pg_walinspect?

    Показать ответ

    Подсистему, породившую WAL-запись. Heap - изменения строк таблиц (вставки, обновления, удаления), Btree - изменения B-tree индексов, Transaction - коммиты и аборты транзакций, XLOG - служебные записи, включая full-page images. По распределению записей видно, во что превращается операция на уровне журнала: один INSERT в индексированную таблицу порождает и Heap-запись, и Btree-запись, а коммит - запись Transaction.

  5. Когда выбирать pg_walinspect, а когда pg_waldump?

    Показать ответ

    pg_walinspect работает из SQL на живом сервере - удобно для аналитики журнала запросами, фильтрации по resource_manager, интеграции с мониторингом. pg_waldump - утилита командной строки, которая читает сегменты журнала прямо с диска и не требует работающего сервера. Он незаменим, когда сервер не стартует и нужно понять содержимое журнала перед сбоем, или для офлайн-отладки. Оба показывают один журнал с разных сторон.

← Предыдущая19-checkpoints-recoveryСледующая →21-relation-row-locks
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки