Репликация
Логическая репликация
13
Авторские права
© Postgres Professional, 2018–2022
Авторы: Егор Рогов, Павел Лузанов, Илья Баштанов
Использование материалов курса
Некоммерческое использование материалов курса (презентации,
демонстрации) разрешается без ограничений. Коммерческое
использование возможно только с письменного разрешения компании
Postgres Professional. Запрещается внесение изменений в материалы
курса.
Обратная связь
Отзывы, замечания и предложения направляйте по адресу:
Отказ от ответственности
Компания Postgres Professional не несет никакой ответственности за
любые повреждения и убытки, включая потерю дохода, нанесенные
прямым или непрямым, специальным или случайным использованием
материалов курса. Компания Postgres Professional не предоставляет
каких-либо гарантий на материалы курса. Материалы курса
предоставляются на основе принципа «как есть» и компания Postgres
Professional не обязана предоставлять сопровождение, поддержку,
обновления, расширения и изменения.
2
Темы
Отличия логической репликации от физической
Публикации и подписки
Логическое декодирование и слоты логической репликации
Конфликты и их разрешение
Выполнение триггеров на подписчике
3
Сравнение
Физическая
мастер-реплика: поток данных только в одну сторону
трансляция потока журнальных записей или файлов журнала
требуется двоичная совместимость серверов
возможна репликация только всего кластера
Логическая
публикация-подписки: у сервера нет выделенной роли
трансляция изменений табличных строк
необходим уровень журнала logical
требуется совместимость на уровне протокола
возможна выборочная репликация отдельных таблиц
Как мы помним, при физической репликации серверы имеют
назначенные роли: мастер и реплика. Мастер передает на реплику
журнальные записи (в виде файлов или потока записей); реплика
применяет эти записи к своим файлам данных. Применение происходит
чисто механически, без «понимания смысла» изменений, поэтому
важна двоичная совместимость между серверами (одинаковые
платформы и основные версии PostgreSQL). Поскольку журнал общий
для всего кластера, то и реплицировать можно только кластер целиком.
При логической репликации на одном сервере создается публикация,
другие серверы могут на нее подписаться. У сервера нет выделенной
роли: один и тот же сервер может как публиковать изменения, так и
подписываться на другие (или даже свои) публикации. Подписке
передается информация об изменениях строк в таблицах в платформо-
независимом виде; двоичная совместимость не требуется. Для работы
логической репликации в журнале публикующего сервера необходима
дополнительная информация (параметр wal_level = logical). Логическая
репликация позволяет транслировать не все изменения, а только
касающиеся определенных таблиц.
Логическая репликация доступна, начиная с версии 10; более ранние
версии должны были использовать расширение pglogical, либо
организовывать репликацию с помощью триггеров.
4
Модель
Публикация
объект базы данных
выдает изменения данных построчно
изменения в порядке фиксации транзакций
Подписка
подписывается, получает и применяет изменения
таблицы и столбцы сопоставляются по полным именам, строки —
по логическим идентификаторам
поддерживается «бесшовная» начальная синхронизация (экспорт
снимка)
могут возникать конфликты с локальными данными
Логическая репликация использует модель «публикация-подписка».
На одном сервере создается публикация, которая может включать ряд
таблиц одной базы данных. Для репликации из нескольких баз данных
потребуется создать несколько публикаций.
Публикация включает в себя изменения, происходящие с таблицами:
эти изменения передаются на уровне строк («в таблице такой-то такая-
то строка изменилась таким-то образом»).
Изменения выдаются не сразу, а только при фиксации транзакции.
Другие серверы могут создавать подписки на публикации, получать
и применять изменения.
Применение изменений всегда происходит построчно. Хотя каждое
изменение не требует разбора и планирования запроса, массовые
изменения из-за этого будут выполняться медленнее.
Таблицы идентифицируются по полным именам (включая схему),
столбцы также идентифицируются по именам. Это позволяет подписке
использовать отличающуюся схему данных (например, иметь в таблице
дополнительные столбцы).
По умолчанию при создании подписки выполняется начальная
синхронизация содержимого таблиц. Она происходит «бесшовно»
благодаря использованию механизма экспорта снимка данных.
5
Ограничения
Реплицируются не все изменения
только команды INSERT, UPDATE, DELETE, TRUNCATE
только базовые и секционированные таблицы
(не реплицируются последовательности, материализованные
представления)
Подписку и публикацию можно создать только на основном
сервере
не работают на физических репликах
Циклы в репликации не обрабатываются
нельзя реплицировать одну и ту же таблицу
с одного сервера на другой и обратно
Реплицируются только изменения содержимого таблиц, вызванные
командами DML. TRUNCATE реплицируется, начиная с версии 11,
секционированные таблицы — с версии 13.
Не реплицируются команды DDL, что означает необходимость
предварительно создать все необходимые таблицы на стороне
подписки. Не реплицируются остальные объекты, объединяемые
термином relation: последовательности, материализованные
представления, внешние таблицы. Большие объекты (large objects)
также не реплицируются.
Если используется физическая репликация, то и публикацию,
и подписку можно создать только на основном сервере, так как
команды DDL на реплике не поддерживаются.
Нет возможности организовать репликацию одной и той же таблицы
между двумя серверами: изменения, сделанные на первом сервере,
применяются вторым и тут же снова пересылаются первому, который
скорее всего не сможет их применить из-за нарушения ограничений
целостности.
6
Схема работы
поставщик
select, insert
update, delete
подписчик
wal sender
сегменты WAL
select, insert
update, delete
сегменты WAL
logical repl.
worker
применяет
от имени супер-
пользователя
логическое
декодирование
max_wal_senders max_logical_replication_workers
max_replication_slots max_worker_processes
Данные об изменениях таблиц передаются подписке тем же процессом
wal sender, что и при обычной потоковой репликации. Так же, как и при
потоковой репликации, этот процесс читает журнал предзаписи, но не
просто транслирует прочитанные записи, а предварительно декодирует
их. В отличие от физической репликации, в обязательном порядке
используется слот логической репликации.
На стороне подписки информацию принимает фоновый процесс logical
replication worker и применяет ее. В это же время сервер-подписчик
принимает обычные запросы и на чтение, и на запись.
Обратите внимание, что на публикующем сервере может быть
запущено много процессов wal sender — по одному на каждую
подписку. Значения параметров max_wal_senders и
max_replication_slots должны соответствовать нужному количеству
процессов.
На сервере подписки необходимо установить параметры
max_logical_replication_workers (для процессов, принимающих
изменения по подписке) и в целом max_worker_processesак минимум
на единицу больше, так как есть еще процесс logical replication launcher,
но вообще этот пул используется и для других нужд).
8
Логическое декодирование
Переупорядочивающий буфер
wal sender читает журнальные записи и накапливает их в буфере,
раскладывая по транзакциям
буфер в локальной памяти; при необходимости сбрасывается на диск
Модуль вывода
получает накопленные записи при фиксации транзакции
декодирует записи, формируя сообщения об операциях
над табличными строками в платформо-независимом формате
фильтрует сообщения, на которые подписан получатель
Слот логической репликации
гарантирует, что подписка не пропустит изменения
Полезно представлять внутреннее устройство логической репликации.
Журнальные записи читаются процессом wal sender и раскладываются
по отдельным транзакциям в специальном буфере в оперативной
памяти. Это делается для того, чтобы при фиксации транзакции можно
было взять все изменения, сделанные именно этой транзакцией,
и передать их подписчику. При превышении определенного порога
буфер начинает сбрасываться на диск (в каталог PGDATA/pg_replslots).
Заметим, что при наличии нескольких подписчиков и, следовательно,
нескольких процессов wal sender, каждый из этих процессов будет
самостоятельно читать WAL: буфер, упорядочивающий записи,
находится в локальной памяти каждого процесса wal sender.
Когда транзакция фиксируется, ее изменения передаются модулю
вывода, который декодирует их и представляет в платформо-
независимом (текстовом) формате. Процесс wal sender передает эти
декодированные сообщения подписчику (если он на них подписан)
через слот логической репликации. Этот слот похож на обычный
репликационный слот, но к нему привязан модуль вывода.
В журнал на уровне logical дополнительно записывается информация,
необходимая для логического декодирования, в частности:
- новые значения всех столбцов для UPDATE, а не только измененных;
- старые значения столбцов, входящих в логический идентификатор,
для UPDATE и DELETE;
- OID базы данных для COMMIT.
10
Конфликты
Режимы идентификации для изменения и удаления
ALTER TABLE ... REPLICA IDENTITY ...
а) столбцы первичного ключа (по умолчанию)
б) столбцы указанного уникального индекса с ограничением NOT NULL
в) все столбцы
г) без идентификации (по умолчанию для системного каталога)
Конфликты — нарушение ограничений целостности
репликация приостанавливается до устранения конфликта
требуется вручную исправить данные на стороне подписки
Вставка новых строк на стороне подписки происходит достаточно
просто.
Интереснее обстоит дело при изменениях и удалениях — в этом случае
надо как-то идентифицировать старую версию строки. По умолчанию
для этого используются столбцы первичного ключа, но для таблицы
можно указать и другие способы: по уникальному индексу или по всем
столбцам. В первом случае для поиска строки будет использоваться
соответствующий индекс, во втором — полное сканирование таблицы
(что крайне неэффективно для больших таблиц).
Можно вообще отказаться от поддержки репликации для некоторых
таблиц (по умолчанию так работают таблицы системного каталога).
Поскольку таблицы на публикующем сервере и на подписчике могут
изменяться независимо друг от друга, при вставке новых версий строк
возможно возникновение конфликта — нарушение ограничения
целостности. В этом случае процесс применения записей
приостанавливается до тех пор, пока конфликт не будет разрешен.
Автоматического разрешения пока не существует; нужно вручную
исправить данные на подписчике так, чтобы устранить конфликт.
12
Итоги
Логическая репликация: модель «публикация–подписка»
Передаются изменения табличных строк
Возможна выборочная репликация отдельных таблиц
Не требуется двоичная совместимость серверов
13
Практика
1. Создайте две базы данных на одном сервере.
В первой базе данных создайте таблицу с первичным
ключом и добавьте в нее несколько строк.
2. Перенесите определение созданной таблицы во вторую
базу данных с помощью логической резервной копии.
3. Настройте логическую репликацию таблицы из первой базы
данных во вторую.
4. Проверьте работу репликации.
5. Удалите подписку.
2. Воспользуйтесь утилитой pg_dump с ключом --schema-only.
3. Если попробовать выполнить это обычным образом, команда
создания подписки «повиснет» из-за того, что она должна дождаться
завершения активных транзакций на публикующем сервере, то есть и
самой себя в том числе. В таком случае необходимо заранее создать
слот логической репликации, как описано в документации: