db scheintot nach update

ich habe meine pg-db von 8.2.4 auf 8.3 upgedatet (unter windows) -

pgdump gemacht, 8.2 deinstalliert, data-verzeichnis entfernt, 8.3 neu installiert, pgdump wieder importiert.

seitdem ist die datenbank scheintot.
es hat ein wenig gedauert, bis ich die ursache gefunden habe:

in einer der größeren tabellen mit ~100.000.000 rows ist ein eintrag doppelt - doppelter name, doppelte id.
beim einspielend des dumps gabs entsprechende errors:

CREATE UNIQUE INDEX ids_hostname_sda ON "names" USING btree (hostname);
psql:r:/pgdump.backup:484534744: ERROR:  could not create unique index "ids_hostname
DETAIL:  Table contains duplicated values.

    ADD CONSTRAINT names_pkey PRIMARY KEY (id);
psql:r:/pgdump.backup:484534634: ERROR:  could not create unique index "names_pkey"
DETAIL:  Table contains duplicated values.
ALTER TABLE ONLY networks

ich kann mir ehrlich gesagt nicht wirklich erklären, wie das passieren kann.
wie finde ich die betreffende row am schnellsten?
ich bin derzeit dabei, die beiden spalten mit einem nonuniqe-aushilfsindex zu versehen, um das über einen query zu machen - das dauert aber ein paar stunden.

tom

In der Fehlermeldung steht aber lediglich ein unique index auf hostname.

Andreas

Hallo!

In PostgreSQL 8.2 bis mindestens einschließlich Version 8.2.4 gabes laut Tom Lane einen Fehler, der dazu führen konnte, dass Doubletten in einer Tabelle mit Unique Constraint landen konnten - wohl in dem Sinne, dass zwei Versionen desselben Tupels beide live waren. Das hat mich bei einer Tabelle auch erwischt - ursprüngliche Version 8.2.4, Migration zu 8.3.1, Beim Import mit pg_restore kam die Fehlermeldung, dass es einen Constraint-Verletzung für den Primary Key einer Tabelle gab - die Daten dieser Tabelle wurden nicht importiert.

Wenn Du die 8.2.4-er DB noch hast, hilft wahrscheinlich nur, den betreffenden Datensatz zu löschen (welcher es ist, geht normalerweise aus der Fehlermeldung hervor) und ggf. neu anzulegen, sofern das im Rahmen Deines DB-Modells möglich ist (war bei mir aufgrund von komplexem Foreign-Key- und Trigger-Gedöns nicht möglich, allerdings war’s um den einen Datensatz auch nicht schade…).

Danach muss Du nochmal dumpen und restoren. Je nach Foreign-Key/Trigger-Situation genügt es, das allein für die betroffene Tabelle separat zu erledigen, mit --disable-triggers lassen sich die Trigger während des Data-Reloads bei pg_restore auch vorübergehend deaktivieren.

Viele Grüße

Markus