Debugging 在Postgresql中,如何调试删除级联后发生的错误?

Debugging 在Postgresql中,如何调试删除级联后发生的错误?,debugging,postgresql,cascade,Debugging,Postgresql,Cascade,我正在从表中删除这一行,它在FKs上有一系列级联,最终它给了我以下错误: 错误:对表“foo\u route”的插入或更新违反外键约束“foo\u route\u bar\u fk” SQL状态:23503 详细信息:表“bar”中不存在键(bar_键)=(2176) foo_route_bar_fk的定义如下: ALTER TABLE foo_route ADD CONSTRAINT foo_route_bar_fk FOREIGN KEY (bar_key) REFERENCES bar

我正在从表中删除这一行,它在FKs上有一系列级联,最终它给了我以下错误:

错误:对表“foo\u route”的插入或更新违反外键约束“foo\u route\u bar\u fk”

SQL状态:23503

详细信息:表“bar”中不存在键(bar_键)=(2176)

foo_route_bar_fk的定义如下:

ALTER TABLE foo_route  
ADD CONSTRAINT foo_route_bar_fk FOREIGN KEY (bar_key) REFERENCES bar (bar_key) 
MATCH SIMPLE ON UPDATE NO ACTION ON DELETE CASCADE;
我是通过删除一个与这两个表都不相关的表而得到这个错误的。我认为所发生的是一个触发器或级联导致了这个错误,但很难找出原因


我的问题是,如何在postgresql中调试这样的问题导致此错误的一系列步骤是什么?Postgresql只告诉我失败前最后一次操作的结果。如果这是代码,那么错误将提供非常有用的堆栈跟踪。有没有办法在Postgresql中看到类似的内容?

通常,您的Postgresql日志将包含触发错误的语句。这应该允许您遵循级联事件链


但是,我建议您绘制一个FKEY映射,并查看外键上ON事件的映射。如果是我,我将从仅模式转储或pg_autodoc输出开始,然后从那里开始。明显的问题是,在无法进行级联的情况下,您会删除级联,因此您需要在此处查看并重新思考。

您应该在服务器日志中找到更多详细信息。我怀疑您上面显示的是您的客户打印为错误消息的内容。@petereisentruit是的,这是正确的,它来自客户。我将查看server.log。是否有任何有用的默认关闭的登录?与此相关的内容默认应打开。但很多其他有用的东西都不是。这并没有触及你问题的核心,但可能有助于解决促使你提问的实际情况。在SQLFIDLE上进行一点实验可以发现,对于修改引用表会产生约束冲突的情况,以及修改引用表会产生约束冲突的情况,Postgres确实会给出不同的消息。如果您的删除不是层叠的并导致了冲突,您会看到
错误:表“bar”上的更新或删除违反了表“foo\u route\u bar\u fk”上的外键约束“foo\u route\u bar\u fk”
。我认为这意味着您可以相当肯定问题的原因确实是“foo_route”,这意味着它一定是由触发器引起的。我不知道你的数据库有多复杂,但除非它是一个疯狂的庞然大物,否则我猜你没有多少触发器插入到
更新
“foo_route”"? 难道你不能追踪到
插入
更新
的所有可能来源,并从那里向后工作吗?“明显的问题是,在无法执行的情况下,你有删除级联”-解释?我不知道有任何情况会导致级联
DELETE
的尝试失败,除了随后违反其他约束之外。但是,这里的情况似乎不是这样,因为如果是这样,我们希望在错误消息中看到其他约束,而且这里出现的错误消息只能由影响引用列的
插入
更新
引起,不是对引用的一个进行
更新
删除
。好的,从对问题的描述来看,这里发生的是:删除A级联到删除B,这失败了,因为C行仍然引用它。(这就是级联删除很少有用的原因之一,因为它们给应用程序增加了这种复杂性。)但我们知道这不是这里发生的事情,因为我刚才给出的原因。我们从错误消息中知道,在引用列上的
插入
更新
是触发此操作的原因,并且我们还知道,如果它是从引用列中删除的,则它应该级联,而不是错误。旁白:在您描述的场景中,只要在DELETE CASCADE
上将从C指向B的键设置为
,所有内容都将级联通过。您描述的问题只有在约束链中的某些约束设置为级联时才会出现,而其他约束设置为非级联时才会出现。我不相信这是一个
cascade
问题。触发的可能性似乎更大。你真的必须非常努力地构建一个奇怪的模式,或者仅仅通过级联就足以产生OP的错误;事实上,我甚至不确定这是可能的,直到我刚刚设法做到。下面是我设法拼凑的一个例子:基本上,您需要有一个直接引用两个或更多其他列的列,才能实现这一点。我从未在任何地方的真实数据库中看到过这一点,也无法马上想出一个用例。事实上,我突然想到,如果同一个外键被意外地创建了两次,一次是使用层叠,一次是不使用,那么这种错误可能很容易潜入数据库模式。