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