Логическое декодирование — это процесс извлечения всех сохраняемых изменений в таблицах базы данных в согласованном и понятном формате, который может быть интерпретирован без детальных знаний о внутреннем состоянии базы данных.
В Digital Q.DataBase , логическое декодирование реализовано путем декодирования содержимого журнала предварительной записи (WAL) , описывающего изменения на уровне хранилища, в специфичную для приложения форму, такую как поток кортежей или SQL-инструкций.
В контексте логической репликации слот представляет собой поток изменений, которые могут быть воспроизведены на стороне клиента в том порядке, в котором они были зафиксированы на исходном сервере. Каждый слот передает последовательность изменений из одной конкретной базы данных.
Digital Q.DataBase также поддерживает слоты потоковой репликации (см. Раздел 3.11.2.5 ), но в данном случае они используются несколько иначе.
Слот репликации имеет идентификатор, уникальный в рамках всех баз данных в Digital Q.DataBase кластере. Слоты сохраняются независимо от использующего их соединения и устойчивы к сбоям.
В штатном режиме работы логический слот выдает каждое изменение ровно один раз. Текущая позиция каждого слота фиксируется только во время контрольной точки, поэтому в случае сбоя слот может вернуться к более раннему значению LSN. Это приведет к повторной отправке последних изменений после перезапуска сервера. Клиенты логического декодирования должны самостоятельно обрабатывать повторные сообщения во избежание нежелательных последствий. Клиенты могут сохранять последний LSN, полученный при декодировании, чтобы пропускать любые повторяющиеся данные или (при использовании протокола репликации) запрашивать начало декодирования с этого значения LSN, не полагаясь на выбор точки запуска сервером. Для этой цели предназначена функциональность отслеживания прогресса репликации, см. раздел источники репликации .
Для одной базы данных может существовать несколько независимых слотов. Каждый слот имеет собственное состояние, что позволяет различным потребителям получать изменения из разных точек потока изменений базы данных. Для большинства приложений каждому потребителю потребуется отдельный слот.
Слот логической репликации не содержит информации о состоянии получателя (получателей). Допускается даже использование одного и того же слота несколькими различными получателями в разное время; они просто будут получать изменения, следующие за моментом, когда предыдущий получатель прекратил их обработку. Только один получатель может считывать изменения из слота в любой конкретный момент времени.
Слот логической репликации также можно создать на резервном сервере в режиме hot standby. Чтобы предотвратить
VACUUM
удаление необходимых строк из системных каталогов, параметр
hot_standby_feedback
должен быть задан на
резервном сервере. Несмотря на это, при удалении любых необходимых строк слот аннулируется. Настоятельно рекомендуется использовать физический слот между основным и резервным серверами. В противном случае
hot_standby_feedback
будет функционировать только во время активного соединения (например, перезагрузка узла прервет его работу). В такой ситуации основной сервер может удалить строки системного каталога, необходимые для логического декодирования на резервном сервере (так как основной сервер не имеет информации о
catalog_xmin
на резервном сервере).
Существующие логические слоты на резервном сервере также аннулируются, если значение
wal_level
на основном сервере становится меньше, чем
logical
. Это происходит сразу после того, как резервный сервер обнаружит такое изменение в потоке WAL. Это означает, что для отстающих процессов walsender (если они есть) некоторые записи WAL вплоть до
wal_level
изменение параметра на основном сервере не будет декодировано.
Для создания логического слота требуется информация обо всех транзакциях, выполняющихся в данный момент. На основном сервере эта информация доступна напрямую, однако на резервном сервере её необходимо получить с основного сервера. Таким образом, создание слота может потребовать ожидания какой-либо активности на основном сервере. Если основной сервер простаивает, создание логического слота на резервном сервере может занять значительное время. Этот процесс можно ускорить, вызвав
pg_log_standby_snapshot
функцию на основном сервере.
Слоты репликации сохраняются при сбоях и не имеют информации о состоянии своих потребителей. Они предотвращают удаление необходимых ресурсов
даже при отсутствии использующего их соединения. Это приводит к потреблению дискового пространства,
поскольку ни необходимые файлы WAL, ни необходимые строки системных каталогов
не могут быть удалены
VACUUM
до тех пор, пока они требуются слоту репликации. В исключительных случаях это может привести к остановке базы данных для предотвращения зацикливания идентификаторов транзакций (см.
Раздел 3.9.1.5
).
Поэтому, если слот больше не требуется, его следует удалить.
Слоты логической репликации на основном сервере могут быть синхронизированы с сервером горячего резерва с помощью
failover
параметра функции
pg_create_logical_replication_slot
, или путем
использования
failover
параметра команды
CREATE SUBSCRIPTION
при создании слота с последующим вызовом функции
pg_sync_replication_slots
на резервном сервере. При установке значения
sync_replication_slots
на резервном сервере, слоты отработки отказа могут периодически синхронизироваться в рабочем процессе slotsync. Для работы синхронизации обязательно наличие слота физической репликации между основным и резервным серверами (т. е.
primary_slot_name
должен быть настроен на резервном сервере), а параметр
hot_standby_feedback
должен быть включен на резервном сервере. Также необходимо указать корректное значение
dbname
в параметре
primary_conninfo
.
Настоятельно рекомендуется, чтобы указанный слот физической репликации был задан в
synchronized_standby_slots
список на основном сервере, позволяющий предотвратить получение изменений подписчиком быстрее, чем это делает резервный сервер. Даже при корректной настройке ожидается некоторая задержка при отправке изменений логическим подписчикам из-за ожидания слотов, указанных в
synchronized_standby_slots
.
Когда
synchronized_standby_slots
используется, основной сервер не будет полностью остановлен до тех пор, пока соответствующие резервные серверы, связанные с физическими слотами репликации, указанными в
synchronized_standby_slots
, не подтвердят получение записей WAL до последней позиции, зафиксированной на диске основного сервера.
Возможность возобновления логической репликации после отработки отказа зависит от значения
pg_replication_slots
.
synced
для синхронизированных слотов на резервном сервере в момент отработки отказа. Только постоянные слоты, перешедшие в состояние synced со значением true на резервном сервере до отработки отказа, могут быть использованы для логической репликации после сбоя. Временные синхронизированные слоты не могут использоваться для логического декодирования, поэтому логическая репликация для таких слотов не может быть возобновлена. Например, если синхронизированный слот не смог стать постоянным на резервном сервере из-за отключенной подписки, то работа подписки не может быть возобновлена после отработки отказа, даже после её включения.
Для возобновления логической репликации после отработки отказа с использованием синхронизированных логических слотов необходимо изменить параметр подписки «conninfo» так, чтобы он указывал на новый основной сервер. Это выполняется с помощью команды
ALTER SUBSCRIPTION ... CONNECTION
. Рекомендуется сначала отключить подписки перед повышением роли резервного сервера и снова включить их после изменения строки подключения.
Существует вероятность того, что старый основной сервер снова станет доступен во время повышения роли резервного сервера. Если подписки не будут отключены, логические подписчики могут продолжать получать данные со старого основного сервера даже после повышения роли до тех пор, пока не будет изменена строка подключения. Это может привести к проблемам с согласованностью данных, что не позволит логическим подписчикам продолжить репликацию с нового основного сервера.
Плагины вывода преобразуют данные из внутреннего представления журнала упреждающей записи (WAL) в формат, требуемый потребителю слота репликации.
При создании нового слота репликации с использованием интерфейса потоковой репликации (см.
CREATE_REPLICATION_SLOT
), экспортируется
снимок
(см.
Раздел 2.6.28.5
), который точно отображает состояние базы данных, начиная с которого все изменения будут включены в поток изменений. Это можно использовать для создания новой реплики с помощью
SET TRANSACTION
SNAPSHOT
для чтения состояния базы данных на момент создания слота. Эту транзакцию затем можно использовать для выгрузки состояния базы данных на данный момент времени, которое впоследствии может быть обновлено с использованием содержимого слота без потери изменений.
Создание снимка возможно не всегда. В частности, процедура завершится ошибкой при подключении к горячему резервному серверу. Приложения, не требующие экспорта снимка, могут подавить его создание с помощью
NOEXPORT_SNAPSHOT
параметра.