29.5. Конфликты#

29.5. Конфликты

29.5. Конфликты #

Логическая репликация ведет себя аналогично обычным операциям DML в том смысле, что данные будут обновлены, даже если они были изменены локально на узле-подписчике. Если входящие данные нарушают какие-либо ограничения, репликация будет остановлена. Это называется конфликтом. При репликации операций UPDATE или DELETE отсутствие данных не вызовет конфликта, и такие операции будут просто прне указаны.

Операции логической репликации выполняются с привилегиями роли, которая владеет подпиской. Ошибки разрешений на целевые таблицы вызовут конфликты репликации, а также включенная строковая защита на уровне строк на целевых таблицах, к которой подписчик имеет доступ, независимо от того, будет ли отклонена INSERT, UPDATE, DELETE или TRUNCATE, которые реплицируются. Ограничение на строковую безопасность может быть снято в будущих версиях Tantor BE.

Конфликт вызовет ошибку и остановит репликацию; его необходимо разрешить вручную пользователем. Подробности о конфликте можно найти в журнале сервера подписчика.

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

ERROR:  duplicate key value violates unique constraint "test_pkey"
DETAIL:  Key (c)=(1) already exists.
CONTEXT:  processing remote data for replication origin "pg_16395" during "INSERT" for replication target relation "public.test" in transaction 725 finished at 0/14C0378

LSN транзакции, содержащей изменение, нарушающее ограничение, и имя источника репликации можно найти в журнале сервера (LSN 0/14C0378 и источник репликации pg_16395 в приведенном выше случае). Транзакция, вызвавшая конфликт, может быть пропущена с помощью ALTER SUBSCRIPTION ... SKIP с конечным LSN (т.е. LSN 0/14C0378). Конечный LSN может быть LSN, на котором транзакция зафиксирована или подготовлена на издателе. В качестве альтернативы, транзакция также может быть пропущена вызовом функции pg_replication_origin_advance(). Перед использованием этой функции подписка должна быть временно отключена либо с помощью ALTER SUBSCRIPTION ... DISABLE, либо подписка может быть использована с опцией disable_on_error. Затем вы можете использовать функцию pg_replication_origin_advance() с node_name (т.е. pg_16395) и следующим LSN после конечного LSN (т.е. 0/14C0379). Текущую позицию источников можно увидеть в системном представлении pg_replication_origin_status. Обратите внимание, что пропуск всей транзакции включает пропуск изменений, которые могут не нарушать никаких ограничений. Это может легко сделать подписчика несогласованным.

Когда streaming режим установлен в parallel, конечный LSN неудачных транзакций может не быть записан. В этом случае может потребоваться изменить режим потоковой передачи на on или off и вызвать те же конфликты снова, чтобы конечный LSN неудачной транзакции был записан в журнал сервера. Для использования конечного LSN, пожалуйста, обратитесь к ALTER SUBSCRIPTION ... SKIP.