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

Протокол потоковой репликации

Чтобы инициировать потоковую репликацию, фронтенд отправляет параметр replication в стартовом сообщении. Булево значение true (или on, yes, 1) указывает бэкенду перейти в режим физической репликации walsender, в котором вместо операторов SQL может быть выдан небольшой набор команд репликации, показанный ниже.

Передача database в качестве значения параметра replication дает команду бэкенду перейти в режим логической репликации walsender, подключившись к базе данных, указанной в параметре dbname. В режиме логической репликации walsender можно выполнять команды репликации, показанные ниже, а также обычные команды SQL.

В режиме физической репликации или логической репликации walsender может использовать только протокол простых запросов.

Для тестирования команд репликации необходимо создать соединение с репликацией через psql или любой другой инструмент, использующий libpq, со строкой соединения, включающей опцию replication, например:

psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;"

Однако зачастую полезнее использовать pg_receivewal (для физической репликации) или pg_recvlogical (для логической репликации).

Команды репликации записываются в журнал сервера, если включена опция log_replication_commands. В режиме репликации принимаются следующие команды:

IDENTIFY_SYSTEM

Запрашивает сервер идентифицировать себя. Сервер отвечает набором результатов, состоящим из одной строки, содержащей четыре поля:

systemid (text)

Уникальный системный идентификатор, идентифицирующий кластер. Его можно использовать для проверки того, что базовая резервная копия, используемая для инициализации резервной копии, была создана на том же кластере.

timeline (int4)

Идентификатор текущей временной шкалы. Также полезно проверить, что резервная копия соответствует основной.

xlogpos (text)

Текущее местоположение flush WAL. Полезно для получения известного места в журнале, где можно начать потоковую передачу.

dbname (text)

База данных подключена или равна нулю.

SHOW имя

Запрашивает сервер отправить текущее значение параметра времени выполнения. Это похоже на команду SQL SHOW.

имя

Имя параметра времени выполнения.

TIMELINE_HISTORY tli

Запрашивает сервер о передаче файла истории временной шкалы для временной шкалы tli. Сервер отвечает набором результатов, состоящим из одной строки, содержащей два поля. Хотя поля обозначены как текст, они фактически возвращают необработанные байты без преобразования кодировки:

filename (text)

Имя файла истории временной шкалы, например, 00000002.history.

content (text)

Содержимое файла истории временной шкалы.

CREATE_REPLICATION_SLOT имя_слота [ TEMPORARY ] { PHYSICAL | LOGICAL модуль_вывода } [ ( параметр [, ...] ) ]

Создать физический или логический слот репликации.

имя_слота

Имя создаваемого слота. Должно быть действительным именем слота репликации.

модуль_вывода

Имя выходного плагина, используемого для логического декодирования.

TEMPORARY

Укажите, что этот слот репликации является временным. Временные слоты не сохраняются на диске и автоматически удаляются при ошибке или по завершении сеанса.

Поддерживаются следующие варианты:

TWO_PHASE [ boolean ]

Если true, то этот логический слот репликации поддерживает декодирование двухфазной фиксации. С помощью этой опции декодируются и передаются команды, связанные с двухфазной фиксацией, такие как PREPARE TRANSACTION, COMMIT PREPARED и ROLLBACK PREPARED. Транзакция будет декодирована и передана в момент PREPARE TRANSACTION. По умолчанию установлено значение false.

RESERVE_WAL [ boolean ]

Если true, то этот физический слот репликации резервирует WAL немедленно. В противном случае WAL резервируется только при подключении клиента потоковой репликации. По умолчанию установлено значение false.

SNAPSHOT { 'export' | 'use' | 'nothing' }

Решает, что делать с моментальным снимком, созданным при инициализации логического слота. 'export', используемый по умолчанию, экспортирует снимок для использования в других сессиях. Эта опция не может быть использована внутри транзакции. 'use' будет использовать снимок для текущей транзакции, выполняющей команду. Эта опция должна использоваться в транзакции, а CREATE_REPLI- CATION_SLOT должна быть первой командой, выполняемой в этой транзакции. Наконец, 'nothing' будет просто использовать снимок для логического декодирования, как обычно, но не будет делать с ним ничего другого.

В ответ на эту команду сервер отправит набор результатов из одной строки, содержащий следующие поля:

slot_name (text)

Имя вновь созданного слота репликации.

consistent_point (text)

Местоположение WAL, в котором слот стал согласованным. Это самое раннее место, с которого можно начать потоковую передачу на этом слоте репликации.

snapshot_name (text)

Идентификатор снимка, экспортированного командой. Снимок действует до тех пор, пока не будет выполнена новая команда на этом соединении или не будет закрыто соединение репликации. Null, если созданный снимок является физическим.

output_plugin (text)

Имя выходного плагина, используемого вновь созданным слотом репликации. Null, если созданный слот является физическим.

CREATE_REPLICATION_SLOT имя_слота [ TEMPORARY ] { PHYSICAL [ RESERVE_WAL ] | LOGICAL модуль_вывода [ EXPORT_SNAPSHOT | NOEXPORT_SNAPSHOT | USE_SNAPSHOT | TWO_PHASE ] }

Для совместимости с более старыми выпусками этот альтернативный синтаксис для команды CREATE_REPLICATION_SLOT все еще поддерживается.

READ_REPLICATION_SLOT имя_слота

Считывает некоторую информацию, связанную со слотом репликации. Возвращает кортеж со значениями NULL, если слот репликации не существует. В настоящее время эта команда поддерживается только для физических слотов репликации.

В ответ на эту команду сервер вернет набор результатов из одной строки, содержащий следующие поля:

slot_type (text)

Тип слота репликации, либо физический, либо NULL. restart_lsn (текст)

Перезапуск_lsn слота репликации. restart_tli (int8)

Идентификатор временной шкалы, связанный с restart_lsn, следующий за текущей историей временной шкалы.

START_REPLICATION [ SLOT имя_слота ] [ PHYSICAL ] XXX/XXX [ TIMELINE tli ]

Указание серверу начать потоковую передачу WAL, начиная с местоположения WAL XXX/XXX. Если указана опция TIMELINE, потоковая передача начинается на временной шкале tli; в противном случае используется текущая временная шкала сервера. Сервер может ответить ошибкой, например, если запрашиваемый участок WAL уже готов к переработке. В случае успеха сервер отвечает сообщением CopyBothResponse, а затем начинает передавать WAL на фронтенд.

Если имя слота задано через имя_слота, оно будет обновляться по мере репликации, чтобы сервер знал, какие сегменты WAL и, если hot_standby_feedback включен, какие транс-действия еще нужны резервному серверу.

Если клиент запрашивает не самую последнюю временную шкалу, но являющуюся частью истории сервера, сервер будет транслировать все WAL на этой временной шкале, начиная с запрашиваемой начальной точки и до того момента, когда сервер переключится на другую временную шкалу. Если клиент запрашивает потоковую передачу ровно в конце старой временной шкалы, сервер полностью пропускает режим COPY.

После передачи всех WAL на временной шкале, которая не является последней, сервер завершает передачу, выходя из режима COPY. Когда клиент подтвердит это, он также выйдет из режима COPY,

сервер отправляет набор результатов с одной строкой и двумя столбцами, указывающими на следующую временную шкалу в истории этого сервера. Первый столбец - это идентификатор следующей временной шкалы (тип int8), а второй - место в WAL, где произошло переключение (тип text). Обычно место переключения - это конец WAL, который был передан, но есть угловые случаи, когда сервер может послать некоторый WAL из старой временной шкалы, который он сам не воспроизводил перед продвижением. Наконец, сервер отправляет два сообщения CommandComplete (одно завершает CopyData, а другое - саму START_REPLICATION) и готов принять новую команду.

Данные WAL передаются в виде серии сообщений CopyData. (Это позволяет смешивать другую информацию; в частности, сервер может отправить сообщение ErrorResponse, если он столкнулся со сбоем после начала потока). Полезная нагрузка каждого сообщения CopyData от сервера к клиенту содержит сообщение одного из следующих форматов:

XLogData (B)

Byte1('w')

Идентифицирует сообщение как данные WAL.

Int64

Начальная точка данных WAL в этом сообщении.

Int64

Текущий конец WAL на сервере.

Int64

Системные часы сервера на момент передачи, в микросекундах с полуночи 2000-01-01.

Byten

Участок потока данных WAL.

Одна запись WAL никогда не разбивается на два сообщения XLogData. Если запись WAL пересекает границу страницы WAL и поэтому уже разбита с помощью записей продолжения, она может быть разбита на границе страницы. Другими словами, первая основная запись WAL и записи ее продолжения могут быть отправлены в разных сообщениях XLogData.

Primary keepalive message (B)

Byte1('k')

Идентифицирует сообщение как keepalive отправителя.

Int64

Текущий конец WAL на сервере.

Int64

Системные часы сервера на момент передачи, в микросекундах с полуночи 2000-01-01.

Byte1

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

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

Standby status update (F)

Byte1('r')

Идентифицирует сообщение как обновление состояния приемника.

Int64

Местоположение последнего байта WAL + 1, полученного и записанного на диск в режиме ожидания.

Int64

Расположение последнего байта WAL + 1, выгруженного на диск в режиме ожидания.

Int64

Расположение последнего байта WAL + 1, примененного в режиме ожидания.

Int64

Системные часы клиента на момент передачи, в микросекундах с полуночи 2000-01-01.

Byte1

Если 1, клиент просит сервер ответить на это сообщение немедленно. Это может быть использовано для пинга сервера, чтобы проверить, все ли еще здоровое соединение.

Hot standby feedback message (F)

Byte1('h')

Идентифицирует сообщение как сообщение обратной связи в режиме горячего резерва.

Int64

Системные часы клиента на момент передачи, в микросекундах с полуночи 2000-01-01.

Int32

Текущий глобальный xmin резервного сервера, исключая catalog_xmin из любых слотов репликации. Если и это значение, и следующее catalog_xmin равны 0, это рассматривается как уведомление о том, что обратная связь с горячим резервом больше не будет отправляться по этому соединению. Более поздние ненулевые сообщения могут вновь запустить механизм обратной связи.

Int32

Эпоха глобального xmin xid на резервном компьютере.

Int32

Наименьшее значение catalog_xmin из всех слотов репликации на резервной копии. Устанавливается в 0, если на резервном сервере нет ката- лога_xmin или если отключена обратная связь с горячим резервом.

Int32

Эпоха каталога catalog_xmin xid на резервном компьютере.

START_REPLICATION SLOT имя_слота LOGICAL XXX/XXX [ ( имя_параметра [ значение_параметра ] [, ...] ) ]

Указание серверу начать потоковую передачу WAL для логической репликации, начиная с любого из расположений WAL

XXX/XXX или подтвержденное значение слота confirmed_flush_lsn (см. раздел pg_replication_slots), в зависимости от того, что больше.

Такое поведение позволяет клиентам избегать обновления статуса локального LSN, когда нет данных для обработки. Однако запуск с LSN, отличного от запрошенного, может не выявить некоторые виды ошибок клиента; поэтому клиент может захотеть проверить, что confirmed_flush_lsn соответствует его ожиданиям, прежде чем выдавать START_REPLICATION.

Сервер может ответить ошибкой, например, если слот не существует. В случае успеха сервер отвечает сообщением CopyBothResponse, а затем начинает передавать WAL на фронтенд.

Сообщения внутри сообщений CopyBothResponse имеют тот же формат, что и для START_REPLICATION ... PHYSICAL, включая два сообщения CommandComplete. Плагин вывода, связанный с выбранным слотом, используется для обработки вывода для потоковой передачи.

SLOT имя_слота

Имя слота для потоковой передачи изменений. Этот параметр является обязательным и должен соответствовать существующему логическому слоту репликации, созданному с помощью CREATE_REPLICATION_SLOT в режиме LOGICAL.

XXX/XXX

Местонахождение WAL, в котором можно начать трансляцию.

имя_параметра

Имя опции, передаваемой плагину логического декодирования слота.

значение_параметра

Необязательное значение в виде строковой константы, связанное с указанной опцией.

DROP_REPLICATION_SLOT имя_слота [ WAIT ]

Сбрасывает слот репликации, освобождая все зарезервированные ресурсы на стороне сервера. Если слот является логическим слотом, который был создан в базе данных, отличной от базы данных, к которой подключен walsender, эта команда завершится неудачей.

имя_слота

Имя слота для сброса.

WAIT

Эта опция заставляет команду ждать, если слот активен, пока он не станет неактивным, вместо того, чтобы по умолчанию выдать ошибку.

BASE_BACKUP [ ( параметр [, ...] ) ]

Указание серверу начать потоковую передачу базовой резервной копии. Система будет автоматически переведена в режим резервного копирования перед началом резервного копирования и выведена из него по его завершении. Принимаются следующие варианты:

LABEL 'метка'

Устанавливает метку резервной копии. Если метка не указана, будет использоваться метка резервной копии базовой резервной копии. Правила кавычек для метки такие же, как для стандартной строки SQL с включенной опцией standard_conforming_strings.

TARGET 'получатель'

Указывает серверу, куда отправлять резервную копию. Если цель - клиент, что является значением по умолчанию, данные резервного копирования отправляются клиенту. Если это сервер, данные резервной копии записываются на сервер по адресу путь, указанный опцией TARGET_DETAIL. Если это blackhole, резервные данные никуда не отправляются; они просто отбрасываются.

Для работы с целью сервера требуются привилегии суперпользователя или роль pg_write_serv- er_files.

TARGET_DETAIL 'дополнительная_информация'

Предоставляет дополнительную информацию о цели резервного копирования.

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

PROGRESS [ boolean ]

Если установлено значение true, запрашивает информацию, необходимую для создания отчета о прогрессе. В ответ будет отправлен приблизительный размер в заголовке каждого табличного пространства, который может быть использован для расчета того, как далеко продвинулся поток. Это вычисляется путем однократного перечисления размеров всех файлов еще до начала передачи, и поэтому может негативно сказаться на производительности. В частности, может потребоваться больше времени, прежде чем будут переданы первые данные. Поскольку файлы базы данных могут меняться во время резервного копирования, размер является приблизительным и может как увеличиваться, так и уменьшаться между моментом приблизительного расчета и отправкой реальных файлов. По умолчанию используется значение false.

CHECKPOINT { 'fast' | 'spread' }

Устанавливает тип контрольной точки, которая будет выполняться в начале базового резервного копирования. По умолчанию используется тип spread.

WAL [ boolean ]

Если установлено значение true, в резервную копию будут включены необходимые сегменты WAL. При этом в каталог pg_wal tar-файла базового каталога будут включены все файлы между началом и окончанием резервного копирования. По умолчанию установлено значение false.

WAIT [ boolean ]

Если установлено значение true, резервное копирование будет ждать, пока не будет заархивирован последний требуемый сегмент WAL, или выдаст предупреждение, если архивация журнала не включена. Если установлено значение false, резервное копирование не будет ни ждать, ни предупреждать, оставляя клиенту ответственность за обеспечение наличия необходимого журнала. По умолчанию используется значение true.

COMPRESSION 'метод'

Указание серверу сжать резервную копию с помощью указанного метода. В настоящее время поддерживаются следующие методы: gzip, lz4 и zstd.

COMPRESSION_DETAIL дополнительная_информация

Указывает детали для выбранного метода сжатия. Этот параметр следует использовать только в сочетании с параметром COMPRESSION. Если значение является целым числом, оно указывает степень сжатия. В противном случае это должен быть список элементов, разделенных запятыми, каждый из которых имеет вид ключевое слово или ключевое слово=значение. В настоящее время поддерживаются следующие ключевые слова: level и workers.

Ключевое слово level задает уровень сжатия. Для gzip уровень сжатия должен быть целым числом от 1 до 9 (по умолчанию Z_DEFAULT_COMPRESSION или -1), для lz4 - целым числом от 1 до 12 (по умолчанию 0 для режима быстрого сжатия), а для zstd - целым числом между ZSTD_minCLevel() (обычно -131072) и ZSTD_maxCLevel() (обычно 22), (по умолчанию ZSTD_CLEVEL_DEFAULT или 3).

Ключевое слово workers задает количество потоков, которые должны использоваться для параллельного сжатия. Параллельное сжатие поддерживается только для zstd.

MAX_RATE скорость

Ограничение (дросселирование) максимального объема данных, передаваемых от сервера к клиенту в единицу времени. Предполагаемая единица измерения - килобайт в секунду. Если указана эта опция, значение должно быть либо равно нулю, либо находиться в диапазоне от 32 кБ до 1 ГБ (включительно). Если передан ноль или опция не указана, то никаких ограничений на передачу не накладывается.

TABLESPACE_MAP [ boolean ]

Если true, включите информацию о символических ссылках, присутствующих в каталоге pg_tblspc, в файл с именем tablespace_map. Файл tablespace map включает имя каждой символической ссылки в том виде, в котором она существует в каталоге pg_tblspc/, и полный путь к этой символической ссылке. По умолчанию используется значение false.

VERIFY_CHECKSUMS [ boolean ]

Если true, контрольные суммы проверяются во время резервного копирования базы, если они включены. Если false, то эта проверка пропускается. По умолчанию используется значение true.

MANIFEST параметр_манифеста

Когда эта опция указана со значением yes или force-encode, создается манифест резервной копии, который отправляется вместе с резервной копией. Манифест представляет собой список всех файлов, присутствующих в резервной копии, за исключением любых WAL-файлов, которые могут быть включены. В нем также хранится размер, время последнего изменения и, в качестве опции, контрольная сумма для каждого файла. Значение force-encode заставляет все имена файлов переводить в шестнадцатеричную кодировку; в противном случае такая кодировка выполняется только для файлов, имена которых представляют собой последовательности октетов, отличные отUTF8. Force-encode предназначен в основном для тестирования, чтобы убедиться, что клиенты, читающие манифест резервного копирования, могут справиться с этим случаем. Для совместимости с предыдущими выпусками по умолчанию используется MANIFEST 'no'.

MANIFEST_CHECKSUMS алгоритм_контрольной_суммы

Указывает алгоритм контрольной суммы, который должен применяться к каждому файлу, включенному в манифест резервного копирования. В настоящее время доступны следующие алгоритмы: NONE, CRC32C, SHA224, SHA256, SHA384 и SHA512. По умолчанию используется CRC32C.

При запуске резервного копирования сервер сначала отправит два обычных набора результатов, а затем один или несколько результатов CopyOutResponse.

Первый обычный набор результатов содержит начальную позицию резервной копии в одной строке с двумя столбцами. Первый столбец содержит начальную позицию, заданную в формате XLogRecPtr, а второй - соответствующий идентификатор временной шкалы.

Второй обычный набор результатов содержит по одной строке для каждого табличного пространства. Поля в этой строке следующие:

spcoid (oid)

OID табличного пространства, или null, если это базовый каталог.

spclocation (текст)

Полный путь к каталогу табличного пространства, или null, если это базовый каталог.

size (int8)

Приблизительный размер табличного пространства в килобайтах (1024 байта), если был запрошен отчет о прогрессе; в противном случае - null.

После второго регулярного набора результатов будет отправлен CopyOutResponse. Полезная нагрузка каждого сообщения Copy- Data будет содержать сообщение в одном из следующих форматов:

new archive (B)

Byte1('n')

Идентифицирует сообщение как указывающее на начало нового архива. Будет создан один архив для основного каталога данных и один для каждой дополнительной табличной области; каждый из них будет использовать формат tar (в соответствии с "форматом обмена ustar", указанным в стандарте POSIX 1003.1-2008).

String

Имя файла для этого архива.

String

Для основного каталога данных - пустая строка. Для других табличных пространств - полный путь к каталогу, из которого был создан этот архив.

manifest (B)

Byte1('m')

Идентифицирует сообщение как указывающее на начало манифеста резервного копирования.

archive or manifest data (B)

Byte1('d')

Идентифицирует сообщение как содержащее архивные или манифестные данные.

Byten

Байты данных.

progress report (B)

Byte1('p')

Идентифицирует сообщение как отчет о проделанной работе.

Int64

Количество байтов из текущей табличной области, для которых была завершена обработка.

После отправки ответа CopyOutResponse или всех подобных ответов будет отправлен окончательный обычный набор результатов, содержащий конечную позицию WAL резервной копии в том же формате, что и начальная позиция.

Архив tar для каталога данных и каждой табличной области будет содержать все файлы в каталогах, независимо от того, являются ли они файлами PostgreSQL или другими файлами, добавленными в тот же каталог. Единственными исключенными файлами являются:

  • postmaster.pid.
  • postmaster.opts.
  • pg_internal.init (найден в нескольких каталогах).
  • Различные временные файлы и каталоги, созданные во время работы сервера PostgreSQL, такие как любой файл или каталог, начинающийся с pgsql_tmp, и временные отношения.
  • Незарегистрированные отношения, за исключением вилки init, которая необходима для воссоздания (пустого) незарегистрированного отношения при восстановлении.
  • pg_wal, включая подкаталоги. Если резервное копирование выполняется с включенными файлами WAL, будет включена синтезированная версия pg_wal, но она будет содержать только файлы, необходимые для работы резервного копирования, а не все остальное содержимое.
  • pg_dynshmem, pg_notify, pg_replslot, pg_serial, pg_snapshots, pg_stat_tmp и pg_subtrans копируются как пустые каталоги (даже если они являются символическими ссылками).
  • Файлы, отличные от обычных файлов и каталогов, такие как символические ссылки (кроме перечисленных выше каталогов) и специальные файлы устройств, пропускаются. (Символьные ссылки в pg_tblspc сохраняются).

Владелец, группа и режим файла устанавливаются, если это поддерживает базовая файловая система на сервере.