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

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

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

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

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

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

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

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

В режиме репликации принимаются следующие команды:

IDENTIFY_SYSTEM

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

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

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

xlogpos (text)
Текущая позиция сброшенных на диск данных WAL. Позволяет узнать позицию в журнале упреждающей записи, с которой может начаться потоковая передача.

dbname (text)
База данных, к которой произведено подключение, или NULL.

SHOW имя

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

имя
Имя параметра времени выполнения. Доступные параметры описываются в главе Конфигурация сервера.

TIMELINE_HISTORY врем_шкала

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

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_REPLICATION_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)
Тип слота репликации: physical или NULL.

restart_lsn (text)
restart_lsn слота репликации.

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

START_REPLICATION [ SLOT имя_слота ] [ PHYSICAL ] XXX/XXX [ TIMELINE врем_шкала ]

Указывает серверу начать потоковую передачу WAL, начиная с позиции XXX/XXX. Если задан параметр TIMELINE, потоковая передача начинается на временной шкале врем_шкала, иначе выбирается текущая временная шкала сервера. Сервер может ответить ошибкой, например, если запрошенный фрагмент 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')
Показывает, что это сообщение проверки активности отправителя.

Int64
Текущая позиция конца WAL на сервере.

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

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

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

Standby status update (F)

Byte1('r')
Показывает, что это сообщение информирует о состоянии получателя.

Int64
Положение байта, следующего за последним байтом WAL, полученным и записанным на диск на резервном сервере.

Int64
Положение байта, следующего за последним байтом WAL, сброшенным на диск на резервном сервере.

Int64
Положение байта, следующего за последним байтом WAL, примененным на резервном сервере.

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 на резервном сервере.

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

Int32
Эпоха идентификатора транзакции catalog_xmin на резервном сервере.

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

Указывает серверу начать потоковую передачу WAL для логической репликации, начиная с позиции XXX/XXX в WAL или с confirmed_flush_lsn слота (см. раздел pg_replication_slots), смотря какое значение больше. Это поведение помогает клиентам избегать необходимости обновлять локальный статус LSN, когда нет данных, требующих обработки. Однако если репликация начинается не с запрошенного LSN, некоторые ошибки на стороне клиента могут остаться незамеченными; поэтому прежде чем передавать START_REPLICATION, клиенту имеет смысл убедиться, что значение confirmed_flush_lsn соответствует его ожиданиям.

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

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

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

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

XXX/XXX
Позиция в WAL, с которой должна начаться потоковая передача.

имя_параметра
Имя параметра, передаваемого плагину вывода логического декодирования этого слота. Параметры, принимаемые стандартным плагином (pgoutput), см. в разделе Протокол логической потоковой репликации.

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

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

Удаляет слот репликации, освобождая все зарезервированные ресурсы на стороне сервера.

имя_слота
Имя удаляемого слота.

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

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

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

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

TARGET 'получатель'
Указывает серверу, куда передавать резервную копию. Если получатель client (по умолчанию), данные резервной копии передаются клиенту. Если выбрано значение server, данные резервной копии записываются на сервер по пути, заданному в параметре TARGET_DETAIL. При значении blackhole данные резервной копии никуда не передаются, а просто отбрасываются.
Чтобы задать получателем server, нужны права суперпользователя или роли pg_write_server_files.

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

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

CHECKPOINT { 'fast' | 'spread' }
Устанавливает тип контрольной точки, которая будет выполняться в начале базового резервного копирования. Значение по умолчанию — spread (продолжительная).

WAL [ boolean ]
При значении true включить в резервную копию необходимые сегменты WAL. Сюда войдут все файлы, которые с начала и до конца копирования находились в подкаталоге pg_wal архива базового каталога. Значение по умолчанию — false.

WAIT [ boolean ]
При значении true резервное копирование будет ждать завершения архивации последнего необходимого сегмента WAL или выдавать предупреждение, если архивация WAL не включена. Значение false выключает и ожидание, и предупреждение, поэтому за обеспечение наличия необходимого журнала будет отвечать клиент. Значение по умолчанию — true.

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

COMPRESSION_DETAIL подробности
Указывает дополнительную информацию о выбранном методе сжатия. Должен использоваться только в сочетании с параметром COMPRESSION. Если значение является целым числом, оно обозначает уровень сжатия. В противном случае это должен быть список элементов через запятую в форме ключевое_слово или ключевое_слово=значение. В настоящее время поддерживаются ключевые слова level, long и workers.

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

Ключевое слово long вклчает режим сопоставления на большой дистанции для улучшения коэффициента сжатия за счет повышенного использования памяти. Режим сопоставления на большой дистанции поддерживается только для zstd.

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

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

TABLESPACEMAP [ boolean ]
При значении true включить информацию о символических ссылках, находящихся в каталоге pg_tblspc, в файл 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 (text)
Полный путь к каталогу табличного пространства или NULL, если это базовый каталог.

size (int8)
Примерный размер табличного пространства в килобайтах (1024 байта), если был запрошен отчет о ходе выполнения передачи; в противном случае NULL.

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

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 каталога данных и всех табличных пространств будет содержать все файлы в этих каталогах, независимо от того, являются ли они файлами QHB или другими файлами, добавленными в тот же каталог. Исключаются только следующие файлы:

  • qhbmaster.pid

  • postmaster.opts

  • pg_internal.init (находится в нескольких каталогах)

  • Различные временные файлы и каталоги, созданные во время работы сервера QHB, например, файлы или каталоги с именем, начинающимся на pgsql_tmp, и временные отношения.

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

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

  • pg_dynshmem, pg_notify, pg_replslot, pg_serial, pg_snapshots, pg_stat_tmp и pg_subtrans копируются как пустые каталоги, даже если они являются символическими ссылками).

  • Файлы, отличные от обычных файлов и каталогов, например, символические ссылки (кроме перечисленных выше каталогов), а также файлы специальных устройств и операционных систем, пропускаются. (Символические ссылки в pg_tblspc сохраняются.)

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