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

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