Перейти к основному содержимому

Внутреннее устройство WAL

примечание

Эта страница переведена при помощи нейросети GigaChat.

WAL включается автоматически, от администратора не требуется никаких действий, кроме обеспечения того, чтобы требования к дисковому пространству для журналов WAL были выполнены и была произведена необходимая настройка (см. раздел «Настройка WAL»).

Записи WAL добавляются в журналы WAL, когда записывается каждая новая запись. Позиция вставки описана номером последовательности журнала (LSN), который представляет собой смещение байтов в журналах, монотонно увеличивающееся с каждой новой записью. Значения LSN возвращаются как тип данных pg_lsn. Сравнивая эти значения, можно вычислить объем данных WAL между ними, так что они могут быть полезны для вычисления прогресса при репликации и восстановлении.

Журналы WAL хранятся в каталоге pg_wal под каталогом данных в виде набора сегментных файлов, обычно размером 16 МБ каждый (хотя размер можно изменить, изменив параметр --wal-segsize initdb). Каждый сегмент делится на страницы, обычно по 8 КБ каждая (этот размер можно изменить через опцию конфигурации --with-wal-blocksize). Заголовки записей журнала описаны в access/xlogrecord.h, содержание записи зависит от типа события, которое регистрируется. Сегментные файлы получают все возрастающие номера в качестве имен, начиная с 000000010000000000000001. Зацикливание этих номеров не предусмотрено, но потребуется очень, очень много времени, чтобы исчерпать запас доступных номеров.

Если журнал находится на другом диске, чем основные файлы базы данных, это выгодно. Этого можно достигнуть путем перемещения каталога pg_wal в другое место (при выключенном сервере, конечно) и создания символической ссылки из исходного местоположения в основном каталоге данных на новое местоположение.

Цель WAL состоит в том, чтобы гарантировать запись журнала до изменения записей базы данных, но это может быть подорвано дисковыми накопителями, которые ложно сообщают ядру об успешной записи, хотя на самом деле они только кешировали данные и еще не сохранили их на диске. Аварийное отключение питания в такой ситуации может привести к непоправимому повреждению данных. Администраторы должны стараться обеспечить, чтобы диски, содержащие файлы журнала PostgreSQL WAL, не делали таких ложных сообщений (см. раздел «Надежность»).

После того как была сделана контрольная точка и журнал был очищен, положение контрольной точки сохраняется в файле pg_control. Поэтому при начале восстановления сервер сначала читает pg_control, а затем запись контрольной точки, затем он выполняет операцию REDO, просматривая вперед от местоположения журнала, указанного в записи контрольной точки. Поскольку весь контент страниц данных сохраняется в журнале при первом изменении страницы после контрольной точки (при условии, что full_page_writes не отключено), все страницы, измененные с момента контрольной точки, будут восстановлены до согласованного состояния.

Чтобы справиться со случаем, когда pg_control поврежден, нужно поддерживать возможность сканирования существующих сегментов журнала в обратном порядке - от самого нового к самому старому - для поиска последней контрольной точки. Это пока не реализовано. pg_control достаточно мал (менее одной страницы диска), поэтому ему не свойственны проблемы частичной записи, и на момент написания этой статьи не было сообщений о сбоях баз данных исключительно из-за невозможности чтения самого pg_control. Так что, хотя теоретически это слабое место, pg_control не кажется проблемой на практике.