跟踪“无法打开与OID的关系”错误的原因

Jac*_*cia 6 postgresql

最近我的PostgreSQL 8.2.4记录了这样的错误:

ERROR:  could not open relation with OID nnnnnnnnn
CONTEXT: SELECT a,b,c FROM table_C
Run Code Online (Sandbox Code Playgroud)

该错误始终是由相同的情况引起的:对表A的更新导致触发触发器,该触发器将数据插入表B,从而触发另一个触发器,该触发器(除其他事项外)确实在表C上选择。在表C上选择然后报告为上述问题的上下文。每天都会执行导致错误消息出现的查询序列,并且每天都会抱怨缺少相同的OID。

查询pg_class时,错误消息中提到的OID很自然不存在。执行有问题的SQL(即在表C上选择)不会引起任何问题。我试图找出所有涉及的表之间的OID和连接,以找出对不存在的OID的引用在哪里,但是我失败了。我从表A开始,获取了其OID(pg_class.reltype)并进行了验证,确认该表具有触发器。当我使用pg_trigger.tgrelid = pg_class.reltype作为条件查询pg_trigger时,问题就开始了。查询产生0行,但是当我仅按relname / tgname查询表时,会得到不同的OID,就像触发器在不同的表上一样。我做了一个快速测试,结果发现,创建一个带有触发器的简单表会产生相同的结果。

所以我的问题是:

  1. 当我可以在pg_class中找到表时,如何浏览pg_trigger(以及其他pg表,如pg_attribute,pg_shdepend)表?

  2. 如果我设法找到对有问题的OID的引用,是否可以通过直接对pg_class表进行更新/删除来简单地删除引用?

ara*_*nid 5

请注意,“ reltype”是表的行类型的OID-表本身的OID是pg_class.oid(这是系统列,因此不会显示\dselect *输出,您需要显式选择它)。

希望这将解决有关目录表如何相互关联的一些谜团!使用oid作为主键的其他许多表也重复相同的模式。

看来这是一个很严重的问题,可能表明某种目录损坏了吗?您可以pg_class直接修改等,但是这样做显然会涉及一些风险。我想不出这么多一般性的建议-根据您的发现,做什么会大相径庭。

  • 那正是我所需要的。毕竟问题变成了琐事。功能之一是依赖于前一段时间删除并重新创建的表。该函数以某种方式正在使用已删除的表的OID。只需重新创建函数并触发(使它们获取当前的OID)即可解决此问题。 (3认同)