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
.