Восстановление от сломанных остатков внешнего ключа на postgresql - PullRequest
0 голосов
/ 15 апреля 2020

У нас очень простое отношение один ко многим. site и resolver таблицы. У resolver есть внешний ключ для site_id.

Мы решили удалить таблицу resolver, так как она больше не нужна. Так что мы просто сделали DROP TABLE resolver. Тем не менее, мы используем 2ndQuadrant BDRv1 для асинхронной c мульти-мульти репликации, и это имеет ошибку. Когда вы делаете это, он не очищает ограничения должным образом. Мы фактически заметили это раньше для другого варианта использования и удалили внешний ключ и первичные ключи, прежде чем отбрасывать таблицу, и это сработало замечательно. На этот раз мы пропустили это, и у нас есть это поврежденное состояние в поле.

Это не вызывает особых проблем, за исключением случаев, когда вы пытаетесь УДАЛИТЬ сайт (что, к счастью, не является распространенным сценарием).

could not open relation with OID 16904

Есть обходные пути, но мы должны исправить это в следующем выпуске. Это продукт, который используют многие клиенты, а не наши собственные. Так что это должно быть как можно более плавным. Итак, пока «воссоздай базу данных или таблицу» et c. являются действительными ответами (и, вероятно, должны отображаться в виде ответов, предпочтительно с командами или ссылками), они не всегда являются наиболее подходящими для выполнения sh в развертывании клиента.

Таким образом, ограничение удаления не работает, потому что таблица больше не существует.

ALTER TABLE site DROP CONSTRAINT resolver_site_id_fk;
ERROR:  constraint "resolver_site_id_fk" of relation "site" does not exist
ALTER TABLE resolver DROP CONSTRAINT resolver_site_id_fk;
ERROR:  relation "resolver" does not exist

Итак, я решил выполнить 1049, что он делает, путаясь с внутренними таблицами, оглядываясь по сторонам. Я знаю, отличная идея ..

delete from pg_depend WHERE objid IN (SELECT confrelid FROM pg_constraint WHERE conname = 'resolver_site_id_fk');
delete from pg_trigger WHERE tgconstrrelid IN (SELECT conrelid FROM pg_constraint WHERE conname = 'resolver_site_id_fk');
delete from pg_constraint WHERE conname = 'resolver_site_id_fk' OR conname = 'resolver_pkey';

после этого удаление сайта все еще не удается с помощью

 cache lookup failed for constraint 16912

, что решается путем перезапуска postgresql, что не идеально.

Наверное, мои вопросы:

  • Как мне избежать перезагрузки? Должен быть способ указать кэшу удалить его также, как DROP CONSTRAINT . ОТВЕТ: кажется, что перезапуска приложения (или, возможно, соединения JDB C в моем случае) достаточно.
  • что еще мне следует очистить?
  • какая альтернатива методы можно использовать вместо того, чтобы возиться с внутренними таблицами?
...