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