Повторная синхронизация таблицы подписчиков логической репликации postgres

У меня есть база данных postgres-10, в которой хранится набор узлов и ребер "родитель-потомок", которые публикуются с помощью функции логической репликации new-ish.

CREATE TABLE "node"
(
  id          BIGSERIAL  CONSTRAINT node_pkey PRIMARY KEY,
  //...
  created     TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT (now()),
  modified    TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT (now())
);

CREATE TABLE "edge" (
  id          BIGSERIAL            CONSTRAINT edge_pkey    PRIMARY KEY,
  parent_id   BIGINT     NOT NULL  CONSTRAINT edge__parent REFERENCES node ON DELETE CASCADE,
  child_id    BIGINT     NOT NULL  CONSTRAINT edge__child  REFERENCES node ON DELETE CASCADE
  /* This bad boy ruining everything :-( */
  /* CONSTRAINT no_loops_allowed CHECK (parent_id <> child_id) */
);

В какой-то момент клиентский процесс начал вставлять добавление нескольких петель в граф, где дочерний элемент и родительский элемент были одним и тем же узлом! И нам совершенно не нравились последствия этого поведения, и мы хотели заблокировать его на уровне базы данных.

И вот где это стало грязным. Если бы мы установили новую базу данных подписчиков с новым ограничением, она бы сильно провалилась, сломав наш слот репликации и все подписки (это касается баз данных подписчиков и публикаций, находящихся на одном сервере). По мере того, как базы данных перестают синхронизироваться, наш pg_wal сходит с ума, расширяясь со скоростью 100 ГБ в день или около того (ew).

Я могу подготовить новую базу данных без ограничения и начать репликацию без проблем, я даже могу добавить ограничение обратно. Но с базой данных cliend, с которой возникла проблема, я не могу заново создать подписку и перехватить отсутствующие транзакции с момента ее появления. все развалилось. У кого-нибудь есть предложения о том, как лучше всего импортировать все отсутствующие изменения?

0 ответов

Другие вопросы по тегам