46.2. Концепции логического декодирования#

46.2. Концепции логического декодирования

46.2. Концепции логического декодирования #

46.2.1. Логическое декодирование #

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

В Tantor SE логическое декодирование реализуется путем декодирования содержимого журнала предварительной записи, который описывает изменения на уровне хранения, в прикладной форме, такую как поток кортежей или SQL-запросов.

46.2.2. Слоты репликации #

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

Примечание

Tantor SE также имеет слоты для потоковой репликации (см. Раздел 26.2.5), но они используются немного иначе.

Репликационный слот имеет идентификатор, который является уникальным во всех базах данных в кластере Tantor SE. Слоты сохраняются независимо от соединения, использующего их, и являются надежными при сбоях.

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

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

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

Логический слот репликации также может быть создан на горячем резерве. Чтобы предотвратить удаление необходимых строк из системных каталогов командой VACUUM, на резерве следует установить hot_standby_feedback. Несмотря на это, если какие-либо необходимые строки будут удалены, слот будет аннулирован. Настоятельно рекомендуется использовать физический слот между основным и резервным. В противном случае hot_standby_feedback будет работать, но только пока соединение активно (например, перезапуск узла нарушит его). Затем основной сервер может удалить строки системного каталога, которые могут понадобиться для логического декодирования на резерве (так как он не знает о catalog_xmin на резерве). Существующие логические слоты на резерве также аннулируются, если wal_level на основном сервере снижен до уровня ниже logical. Это происходит, как только резерв обнаруживает такое изменение в потоке WAL. Это означает, что для walsenders, которые отстают (если таковые имеются), некоторые записи WAL до изменения параметра wal_level на основном сервере не будут декодированы.

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

Предостережение

Репликационные слоты сохраняются после сбоев и не знают о состоянии своих потребителей. Они предотвращают удаление необходимых ресурсов, даже если нет активных подключений. Это занимает место, потому что ни необходимые WAL-файлы, ни необходимые строки из системных каталогов не могут быть удалены с помощью команды VACUUM, пока они нужны репликационному слоту. В экстремальных случаях это может привести к остановке базы данных для предотвращения зацикливания идентификаторов транзакций (см. Раздел 24.1.5). Поэтому, если слот больше не требуется, его следует удалить.

46.2.3. Синхронизация слота репликации #

Логические слоты репликации на первичном сервере могут быть синхронизированы с горячим резервом, используя параметр 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. Рекомендуется сначала отключить подписки перед повышением резервного сервера и снова включить их после изменения строки подключения.

Предостережение

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

46.2.4. Выходные плагины #

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

46.2.5. Экспортированные снимки #

Когда создается новый слот репликации с использованием интерфейса потоковой репликации (см. CREATE_REPLICATION_SLOT), экспортируется снимок (см. Раздел 9.28.5), который покажет точное состояние базы данных после которого все изменения будут включены в поток изменений. Это можно использовать для создания новой реплики, используя SET TRANSACTION SNAPSHOT для чтения состояния базы данных в момент создания слота. Эта транзакция затем может быть использована для выгрузки состояния базы данных в этот момент времени, которое затем может быть обновлено с использованием содержимого слота без потери каких-либо изменений.

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