Postgres:缓存查找约束34055失败

4

我有一个OID,生成的元组显然无效。

这是在一些\set VERBOSITY verbose之后尝试在psql中删除表时出现的错误:

delete from my_table where my_column = 'some_value';
ERROR:  XX000: cache lookup failed for constraint 34055
LOCATION:  ri_LoadConstraintInfo, ri_triggers.c:2832

我在其他地方找到了这个。

2827             :     /*
2828             :      * Fetch the pg_constraint row so we can fill in the entry.
2829             :      */
2830         548 :     tup = SearchSysCache1(CONSTROID, ObjectIdGetDatum(constraintOid));
2831         548 :     if (!HeapTupleIsValid(tup)) /* should not happen */
2832           0 :         elog(ERROR, "cache lookup failed for constraint %u", constraintOid);
2833         548 :     conForm = (Form_pg_constraint) GETSTRUCT(tup);
2834             : 
2835         548 :     if (conForm->contype != CONSTRAINT_FOREIGN) /* should not happen */
2836           0 :         elog(ERROR, "constraint %u is not a foreign key constraint",

我读到这意味着OID在其他地方被引用。这些其他地方在哪里?有人知道如何清理这样的东西吗?

我真的很喜欢第2831行上的/* should not happen */注释。

1个回答

7

我认为这意味着您拥有目录损坏的问题。

外键约束在内部被实现为触发器。当该触发器触发时,它会尝试找到属于它的约束条件。在您的情况下,这似乎失败了,导致了错误。

您可以自行查看:

SELECT tgtype, tgisinternal, tgconstraint
   FROM pg_trigger
   WHERE tgrelid = 'my_table'::regclass;

┌────────┬──────────────┬──────────────┐
│ tgtype │ tgisinternal │ tgconstraint │
├────────┼──────────────┼──────────────┤
│      5 │ t            │        34055 │
│     17 │ t            │        34055 │
└────────┴──────────────┴──────────────┘
(2 rows)

现在尝试查找该约束:
SELECT conname
   FROM pg_constraint
   WHERE oid = 34055;

┌─────────┐
│ conname │
├─────────┤
└─────────┘
(0 rows)

为了从这种损坏中恢复,您应恢复最新的好备份。
您可以尝试使用 pg_dumpall来转储正在运行的 PostgreSQL 集群,创建一个新集群并将转储还原到那里来挽救数据。如果幸运的话,现在您有了一个良好的集群副本,可以使用它。如果由于数据不一致性而导致转储或还原失败,则必须使用更高级的方法。
像往常一样,在出现数据损坏的情况下,最好首先停止该集群:
pg_ctl stop -m immediate

并且制作数据目录的物理备份。这样,如果您的救援操作进一步损坏了数据,您就有了一份副本。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接