2016-10-19 1 views
1

Ich habe eine OID, die ein Tupel erzeugt, das offensichtlich nicht gültig ist.Postgres: `Cache-Lookup fehlgeschlagen für Constraint 34055`

Dies ist der Fehler, den ich bekommen, wenn eine Tabelle in psql nach einiger \set VERBOSITY verbose zu löschen versuchen:

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

Dies ist, was ich elsewhere gefunden.

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", 

Ich lese das bedeutet die OID wird an anderen Orten referenziert. Wo sind diese anderen Orte und weiß jemand, wie ich so etwas säubern kann?

Ich mag den /* should not happen */ Kommentar auf der Leitung 2831.

Antwort

4

Ich würde sagen, dass dies bedeutet, dass Sie Katalog Korruption haben.

Fremdschlüssel-Constraints werden intern als Trigger implementiert. Wenn dieser Auslöser ausgelöst wird, versucht er, die zugehörige Einschränkung zu finden. Dies scheint in Ihrem Fall zu scheitern, und das verursacht den Fehler.

Sie können selbst sehen:

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

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

nun versuchen, diese Einschränkung zu sehen:

SELECT conname 
    FROM pg_constraint 
    WHERE oid = 34055; 

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

Um aus einer solchen Korruption zu erholen, sollten Sie Ihre letzte gute Sicherung wiederherstellen.

Sie können versuchen, Ihre Daten zu retten, indem Sie pg_dumpall verwenden, um den laufenden PostgreSQL-Cluster auszugeben, einen neuen Cluster zu erstellen und den Dump dort wiederherzustellen. Wenn Sie Glück haben, haben Sie jetzt eine gute Kopie Ihres Clusters, und Sie können das verwenden. Wenn der Dump oder die Wiederherstellung aufgrund von Dateninkonsistenzen fehlschlagen, müssen Sie erweiterte Methoden verwenden.

Wie immer bei Datenkorruption, ist es am besten, zuerst mit

pg_ctl stop -m immediate 

und machen eine physische Sicherung des Datenverzeichnisses die Cluster zu stoppen. Auf diese Weise haben Sie eine Kopie, wenn Ihre Bergung die Daten weiter beschädigt.

Verwandte Themen