1N5*_*818 2 postgresql constraints oid
I'm have an OID that is generating a tuple that is evidently not valid.
This is the error I get when trying to delete a table in psql after some \set VERBOSITY verbose:
delete from my_table where my_column = 'some_value';
ERROR: XX000: cache lookup failed for constraint 34055
LOCATION: ri_LoadConstraintInfo, ri_triggers.c:2832
Run Code Online (Sandbox Code Playgroud)
This is what I found elsewhere.
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",
Run Code Online (Sandbox Code Playgroud)
I read this means the OID is being referenced in other places. Where are these other places and does anyone know how I to clean something like this up?
I really like the /* should not happen */ comment on line 2831.
我想说这意味着您的目录已损坏。
外键约束在内部实现为触发器。当触发该触发器时,它将尝试查找属于它的约束。在您的情况下,这似乎失败了,并导致了错误。
您可以自己看到:
SELECT tgtype, tgisinternal, tgconstraint
FROM pg_trigger
WHERE tgrelid = 'my_table'::regclass;
????????????????????????????????????????
? tgtype ? tgisinternal ? tgconstraint ?
????????????????????????????????????????
? 5 ? t ? 34055 ?
? 17 ? t ? 34055 ?
????????????????????????????????????????
(2 rows)
Run Code Online (Sandbox Code Playgroud)
现在尝试查找该约束:
SELECT conname
FROM pg_constraint
WHERE oid = 34055;
???????????
? conname ?
???????????
???????????
(0 rows)
Run Code Online (Sandbox Code Playgroud)
要从这种损坏中恢复,您应该还原最新的正常备份。
您可以尝试通过pg_dumpall转储正在运行的PostgreSQL集群,创建新集群并在此处还原转储来抢救数据。如果幸运的话,您现在可以很好地使用群集了,就可以使用它了。如果转储或还原由于数据不一致而失败,则必须使用更高级的方法。
与往常一样,在发生数据损坏的情况下,最好先使用
pg_ctl stop -m immediate
Run Code Online (Sandbox Code Playgroud)
并对数据目录进行物理备份。这样,如果您的补救操作进一步损坏了数据,则您将拥有一份副本。