我们有一个非常简单的一对多关系。site
和resolver
桌子。resolver
有一个外键site_id
。
我们决定删除该resolver
表,因为它不再有用了。所以我们只是简单地做了DROP TABLE resolver
。但是,我们使用2ndQuadrant BDRv1进行异步多多复制,它有一个错误。当您这样做时,它不会正确清除约束。实际上,我们之前在另一个用例中注意到了这一点,并在删除表之前删除了外键和主键,效果很好。这次我们错过了,我们在现场遇到了这种腐败状态。
除非您尝试删除该站点(幸好这不是常见的情况),否则它不会造成太大的麻烦。
could not open relation with OID 16904
有一些解决方法,但我们需要在下一个版本中清理它。它是许多客户部署的产品,而不是我们自己的部署。所以它需要尽可能的平滑。因此,虽然“重新创建数据库或表”等是有效的答案(并且可能应该作为答案出现,最好带有命令或链接),但它们并不总是在客户部署中最可行的。
因此,删除约束不起作用,因为该表不再存在。
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
所以,我决定通过环顾四周来弄乱内部表格来完成它的工作。我知道,好主意..
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一样。回答:似乎重新启动应用程序(或者在我的情况下可能是 JDBC 连接)就足够了。
- 我还应该清理什么?
- 我可以使用哪些替代方法而不是弄乱内部表?