postgresql - 追踪 "could not open relation with OID"错误的原因

标签 postgresql

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

ERROR:  could not open relation with OID nnnnnnnnn
CONTEXT: SELECT a,b,c FROM table_C

错误总是由相同的场景引起:对表 A 的更新导致触发器触发,它将数据插入表 B,触发另一个触发器,该触发器(在许多其他事情中)确实在表 C 上进行选择。那个选择然后将表 C 报告为上述问题的 CONTEXT。导致出现错误消息的查询序列每天都会执行,并且每天都会提示缺少相同的 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 表进行直接更新/删除来简单地删除该引用?

最佳答案

请注意,'reltype' 是表行类型的 OID - 表本身的 OID 是 pg_class.oid(这是一个系统列,因此不会出现在 中\dselect * 输出,需要明确选择)。

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

这看起来是一个相当严重的问题,可能表示某种目录损坏?您可以直接修改 pg_class 等,但显然这样做存在一些风险。我想不出有多少通用的建议可以在这里给出 - 根据您的发现,做什么会有很大的不同。

关于postgresql - 追踪 "could not open relation with OID"错误的原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5030720/

相关文章:

django - 如何在 django (1.8) 迁移中删除索引 varchar_pattern_ops?

node.js - Typescript Sequelize,M :M relation, 查询仅返回单个条目

php - 设置 Postgresql 以与我的本地开发人员一起工作

ruby-on-rails - Rails/postgresql 将数据从数据库迁移到新创建的数据库

postgresql - pcp_attach_node 在 pgpool 中给出 EOFError

node.js - Sequelize postgres 过程返回字符串而不是对象

sql - ruby rails : Duplicates with Join

ruby-on-rails - Rspec 工厂机器人 postgres UUID 问题

SQL 聚合函数别名

oracle - 为 Oracle 中的每一行生成一系列月份