Конфликты
Эта страница переведена при помощи нейросети 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
.