Wiederherstellung des Backups fehlgeschlagen

Ich habe folgendes Problem. Ich betreibe seit über 10 Jahren ein Discourse-Forum, und da ich seit einiger Zeit keine Updates mehr installieren konnte, wollte ich einen neuen Server einrichten:

Alter Server läuft mit: 3.4.0.beta4-dev

Neuer Server: Neueste Version

Das Backup hat bereits eine Größe von 673,2 MB als .gz-Datei, ohne Uploads.

Leider wird die Wiederherstellung ständig abgebrochen. Die Logdatei enthält diesen Fehler:

[2026-06-16 07:54:52] ERROR:  could not create unique index „index_incoming_referers_on_path_and_incoming_domain_id"
[2026-06-16 07:54:52] DETAIL:  Key (path, incoming_domain_id)=(//, 5) is duplicated.
[2026-06-16 07:54:52] EXCEPTION: psql failed: DETAIL:  Key (path, incoming_domain_id)=(//, 5) is duplicated.

[2026-06-16 07:54:52] /var/www/discourse/lib/backup_restore/database_restorer.rb:93:in 'BackupRestore::DatabaseRestorer#restore_dump'
/var/www/discourse/lib/backup_restore/database_restorer.rb:26:in „BackupRestore::DatabaseRestorer#restore“
/var/www/discourse/lib/backup_restore/restorer.rb:61:in 'BackupRestore::Restorer#run'
/var/www/discourse/script/spawn_backup_restore.rb:20:in „Object#restore“
/var/www/discourse/script/spawn_backup_restore.rb:33:in „block in “
/var/www/discourse/script/spawn_backup_restore.rb:4:in 'Kernel#fork'
/var/www/discourse/script/spawn_backup_restore.rb:4:in „“
[2026-06-16 07:54:52] Trying to rollback...

Was kann ich tun, um dieses Problem zu beheben und die letzten 10 Jahre an Daten nicht zu verlieren?

Vielen Dank im Voraus für jede Hilfe!

Hallo und wow, willkommen zurück nach 9 Jahren!

Es ist wirklich cool, ein so langlebiges Forum zu sehen.

Ich denke, das ist das gleiche Index-Problem, über das hier diskutiert wurde: Can't restore due to corrupt indexes (with some clues on how to deal with corrupt indexes)

Es sieht ungefähr so aus:

Die Tabelle incoming_referers verfolgt die URL-Pfade, über die Besucher auf dein Forum gelangt sind. Sie verfügt über einen eindeutigen Index, was bedeutet, dass keine zwei Zeilen dieselbe Kombination aus Pfad und Domain haben dürfen.

Deine Datenbank enthält zwei Zeilen mit path='//' und incoming_domain_id=5. Wenn versucht wird, diesen eindeutigen Index während der Wiederherstellung neu aufzubauen, findet er das Duplikat und bricht die gesamte Wiederherstellungs-Transaktion ab.

Du musst also dieses Duplikat in incoming_referers finden und bereinigen und anschließend ein neues Backup erstellen, um es auf dem neuen Server wiederherzustellen.

Ich habe dieses Thema mit Anweisungen gefunden, das dir vielleicht hilft.

Vielen Dank für die schnelle Antwort! Ich werde das gleich ausprobieren.

(Beitrag vom Autor gelöscht)

Tut mir leid, dass ich Sie störe, aber ich scheine etwas falsch zu machen. Nach dem Ausführen des Befehls „discourse=# select * from incoming_referers where path LIKE ‘%/search/’ ORDER BY incoming_domain_id;“ erhalte ich einen Syntaxfehler.

Haben Sie „discourse=#“ eingegeben? Wenn ja, versuchen Sie es erneut ohne diesen Teil.

Dann erhalte ich die Fehlermeldung „bash: syntax error near unexpected token `from’“

Zum Vergleich, ich befinde mich aktuell an dieser Stelle: root@community-app:/var/www/discourse#

Ah, du bist noch nicht in der Datenbank.

Führe zuerst psql -U discourse discourse aus (ich glaube).

Dann sollte sich der Prompt in discourse=# ändern.

Okay, ich habe jetzt auch „apt install postgresql-client-common“ installiert. Allerdings erhalte ich immer noch die Fehlermeldung „Error: You must install at least one postgresql-client- package.“

Okay, das weiß ich nicht.

Vielleicht versuchst du es direkt über die Rails-Konsole: rails c

mit

ActiveRecord::Base.connection.execute(<<~SQL)
  SELECT id, path, incoming_domain_id 
  FROM incoming_referers 
  WHERE path = '//' 
  AND incoming_domain_id = 5
SQL

Das könnte dir dasselbe liefern, ohne die Datenbank zu umgehen.

Funktioniert das?

Es tut mir wirklich, wirklich leid, dass ich mich so dumm angestellt habe.

Ich habe Rails jetzt installiert, und es scheint geklappt zu haben. Ich habe es auch mit „rails c“ ausgeführt. Das scheint auch zu funktionieren, aber wenn ich den Befehl eingebe, sieht das so aus:

„root@community:/var/discourse# ActiveRecord::Base.connection.execute(<<~SQL)
-bash: syntax error near unexpected token `<<’
root@community:/var/discourse# SELECT id, path, incoming_domain_id
SELECT: Befehl nicht gefunden
root@community:/var/discourse# FROM incoming_referers
FROM: Befehl nicht gefunden
root@community:/var/discourse# WHERE path = ‘//’
WHERE: Befehl nicht gefunden
root@community:/var/discourse# AND incoming_domain_id = 5
AND: Befehl nicht gefunden
root@community:/var/discourse# SQL“

Mach dir keine Sorgen, vielleicht sind meine Anweisungen einfach nicht so gut :slight_smile:

Ich bin verwirrt, wenn du sagst, dass du Rails gerade erst installiert hast und keinen Zugriff auf deine Datenbank hast. Vielleicht ist alles anders, weil es sich um eine ältere Version handelt, aber ich glaube, ich bin jetzt auch überfragt.

Wie auch immer, sobald du in Rails bist, sollte die Eingabeaufforderung anders aussehen. Aus deiner Ausgabe geht hervor, dass du noch nicht in der Rails-Konsole bist.

Ich glaube nicht einmal, dass du dich im eigentlichen Container befindest. Hast du ./launcher enter app ausgeführt?

OK, ja, das war das Problem. Die Abfrage wurde jetzt erfolgreich ausgeführt, und ich erhielt diese Antwort:

#<PG::Result:0x00007fbde9732ef0 status=PGRES_TUPLES_OK ntuples=1 nfields=3 cmd_tuples=1>

Also, ntuples=1 bedeutet, dass nur eine Zeile gefunden wurde, während laut dem Fehlerprotokoll ein Duplikat vorhanden sein sollte… :woman_shrugging:

Tut mir leid, ich weiß nicht, was ich noch versuchen soll. Ich empfehle, im Forum zu stöbern, es scheint viele ähnliche Fälle zu geben (siehe unten im Abschnitt „Verwandte Themen“), vielleicht findest du dort den nächsten Hinweis.

(Oder warte, bis jemand mit mehr Fachwissen vorbeikommt ;))

Es klingt so, als wäre Ihr alter Server nicht eine Standardinstallation. Wie auch immer,… kurz zusammengefasst: Ein Index auf Ihrem alten Server ist im Laufe der Jahre beschädigt worden (das kann nach Betriebssystem-Updates passieren), sodass zwei identische Zeilen in die Tabelle incoming_referers gelangt sind. Das Backup kopiert sie unverändert, und der neue Server lehnt sie daraufhin ab. Wir beheben das also zuerst auf dem alten Server und erstellen dann ein neues Backup.

Auf dem ALTEN Server öffnen Sie die Rails-Konsole:

./launcher enter app
rails c

Fügen Sie dann diese Zeilen nacheinander ein:

db = ActiveRecord::Base.connection.current_database
DB.exec("DELETE FROM incoming_referers a USING incoming_referers b WHERE a.id > b.id AND a.path = b.path AND a.incoming_domain_id = b.incoming_domain_id")
DB.exec("REINDEX DATABASE #{ActiveRecord::Base.connection.quote_table_name(db)}")

Dadurch werden die Duplikate entfernt und alle Indizes neu aufgebaut (falls auch andere Tabellen betroffen sein sollten).

Wenn REINDEX ohne Fehler abgeschlossen ist, geben Sie exit ein, erstellen Sie ein frisches Backup auf dem alten Server und stellen Sie diese neue Datei wieder her. Falls eine Fehlermeldung bezüglich einer anderen Tabelle erscheint, kopieren Sie diese einfach hierher.

Vielen Dank. Leider erhalte ich in der letzten Zeile eine Fehlermeldung:

„PG::InsufficientPrivilege: FEHLER: muss Eigentümer der Datenbank discourse sein“

Eigentlich sollte es sich bereits um einen „Standard-Server“ handeln. Die Installation wurde damals von der „Discourse“-Mannschaft gegen eine einmalige Gebühr durchgeführt.

Ah, stimmt. Versuchen wir das.

Verlasse die Rails-Konsole (tippe exit), und führe im Container (./launcher enter app) Folgendes aus:

su postgres -c "reindexdb discourse"

Wenn das ohne Fehler abgeschlossen ist, erstelle ein frisches Backup auf dem alten Server und stelle diese neue Datei wieder her. Falls ein Fehler bezüglich einer bestimmten Tabelle angezeigt wird, füge ihn einfach hier ein.

Thank you so, so much! Everything worked out wonderfully, and without your help, I wouldn’t have stood a chance and would surely have had to painfully start the forum over from scratch soon! THANK YOU!

Thanks also to @chapoi for the great support!