30.5. Конфликты#
30.5. Конфликты
Логическая репликация ведет себя аналогично обычным операциям DML в том смысле, что данные будут обновлены, даже если они были изменены локально на узле-подписчике. Если входящие данные нарушают какие-либо ограничения, репликация будет остановлена. Это называется конфликтом. При репликации операций UPDATE
или DELETE
отсутствие данных не вызовет конфликта, и такие операции будут просто прне указаны.
Операции логической репликации выполняются с привилегиями роли, которая владеет подпиской. Ошибки разрешений на целевые таблицы вызовут конфликты репликации, а также включенная строковая защита на уровне строк на целевых таблицах, к которой подписчик имеет доступ, независимо от того, будет ли отклонена INSERT
, UPDATE
, DELETE
или TRUNCATE
, которые реплицируются. Ограничение на строковую безопасность может быть снято в будущих версиях Tantor SE.
Конфликт вызовет ошибку и остановит репликацию; его необходимо разрешить вручную пользователем. Подробности о конфликте можно найти в журнале сервера подписчика.
Разрешение может быть выполнено путем изменения данных или разрешений на подписчике таким образом, чтобы они не конфликтовали с входящим изменением, или путем пропуска транзакции, которая конфликтует с существующими данными. Когда конфликт вызывает ошибку, репликация не продолжается, и рабочий процесс логической репликации выдаст следующее сообщение в журнале сервера подписчика:
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
.
Обратите внимание, что пропуск всей транзакции включает пропуск изменений,
которые могут не нарушать никакое ограничение. Это может привести к несогласованности
подписчика.