Перейти к основному содержимому

Конфликты

примечание

Эта страница переведена при помощи нейросети GigaChat.

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

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

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

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

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.