Échec de la restauration de la sauvegarde

Je rencontre le problème suivant. J’exploite un forum Discourse depuis plus de 10 ans et, n’ayant pas pu installer de mises à jour depuis un certain temps, je souhaite configurer un nouveau serveur :

Serveur ancien : 3.4.0.beta4-dev

Nouveau serveur : Dernière version

La sauvegarde fait déjà 673,2 Mo au format .gz, hors fichiers uploadés.

Malheureusement, la restauration échoue systématiquement. Le fichier de journal contient cette erreur :

[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...

Que puis-je faire pour résoudre ce problème sans perdre les 10 dernières années de données ?

Merci d’avance pour toute aide !

Salut et bienvenue, après 9 ans !

C’est vraiment cool de voir un forum aussi ancien.

Je pense que c’est le même problème d’index que celui dont on parle ici : Can't restore due to corrupt indexes (with some clues on how to deal with corrupt indexes)

C’est quelque chose comme ça :

La table incoming_referers suit les chemins d’URL qui ont dirigé les visiteurs vers votre forum. Elle possède un index unique, ce qui signifie qu’aucune deux lignes ne peuvent avoir la même combinaison de chemin + domaine.

Votre base de données contient deux lignes avec path='//' et incoming_domain_id=5. Lorsqu’elle tente de reconstruire cet index unique lors de la restauration, elle trouve la duplication et annule toute la transaction de restauration.

Vous devrez donc trouver et nettoyer cette duplication dans incoming_referers, puis créer une nouvelle sauvegarde à restaurer sur le nouveau serveur.

J’ai trouvé ce sujet avec des instructions qui pourraient vous aider

Merci beaucoup pour votre réponse rapide ; je vais essayer ça !

(message supprimé par l’auteur)

Désolé de vous déranger, mais je crois que je fais quelque chose de travers — après avoir exécuté la commande « discourse=# select * from incoming_referers where path LIKE ‘%/search/’ ORDER BY incoming_domain_id; », j’obtiens une erreur de syntaxe.

Avez-vous tapé « discourse=# » ? Si oui, réessayez sans cela.

J’obtiens ensuite le message d’erreur « bash : erreur de syntaxe près du jeton inattendu `from’ »

Pour référence, je suis actuellement à : root@community-app:/var/www/discourse#

Ah, vous n’êtes pas encore dans la base de données.

Exécutez d’abord psql -U discourse discourse (je crois)

Et ensuite, l’invite de commande devrait passer à discourse=#

D’accord, j’ai maintenant également installé « apt install postgresql-client-common ». Cependant, je reçois toujours l’erreur « Error: You must install at least one postgresql-client- package. ».

D’accord, je ne sais pas.

Essayez peut-être directement via la console Rails : rails c

avec

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

Cela pourrait vous donner le même résultat sans passer par la base de données.

Cela fonctionne ?

Je suis vraiment, vraiment désolé d’avoir agi aussi bêtement.

J’ai maintenant installé Rails, et cela semble avoir fonctionné. Je l’ai également exécuté avec « rails c ». Cela semble également fonctionner, mais lorsque j’entre la commande, voici ce qui s’affiche :

« 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: command not found
root@community:/var/discourse# FROM incoming_referers
FROM: command not found
root@community:/var/discourse# WHERE path = ‘//’
WHERE: command not found
root@community:/var/discourse# AND incoming_domain_id = 5
AND: command not found
root@community:/var/discourse# SQL »

Ne t’inquiète pas, peut-être que mes instructions ne sont pas très claires :slight_smile:

Je suis un peu perplexe quand tu dis que tu viens d’installer Rails et que tu n’arrives pas à accéder à ta base de données. Peut-être que tout est différent parce qu’il s’agit d’une version plus ancienne, mais là, je pense que je dépasse mes compétences.

Enfin, une fois que tu es dans Rails, l’invite de commande devrait être différente, donc d’après ton affichage, il semble que tu ne sois pas encore dans la console Rails.

Je ne pense même pas que tu sois dans le conteneur. As-tu exécuté ./launcher enter app ?

D’accord, oui, c’était bien le problème. La requête s’est exécutée avec succès et voici la réponse :

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

Donc, ntuples=1 signifie qu’une seule ligne a été trouvée, alors que selon le journal d’erreurs, il devrait y avoir un doublon… :woman_shrugging:

Désolé, je ne sais pas quoi essayer ensuite. Je te recommande de parcourir le forum, il semble y avoir beaucoup de cas similaires (voir ci-dessous ce sujet dans la section connexe), peut-être y trouveras-tu le prochain indice.

(ou attendre qu’une personne plus compétente passe par là ;))

Cela ressemble à une installation non standard de votre ancien serveur. Quoi qu’il en soit, voici un bref résumé de ce qui s’est produit : un index de votre ancien serveur s’est corrompu au fil des ans (cela peut arriver après des mises à jour du système d’exploitation), si bien que deux lignes identiques se sont glissées dans la table incoming_referers. La sauvegarde les copie telles quelles, et le nouveau serveur les refuse ensuite. Nous devons donc d’abord corriger le problème sur l’ancien serveur, puis créer une nouvelle sauvegarde.

Sur l’ANCIEN serveur, ouvrez la console Rails :

./launcher enter app
rails c

Ensuite, collez ces lignes, l’une après l’autre :

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)}")

Cela supprimera les doublons et reconstruira tous les index (au cas où d’autres tables seraient également affectées).

Si REINDEX se termine sans erreur, tapez exit, effectuez une nouvelle sauvegarde sur l’ancien serveur, puis restaurez ce nouveau fichier. Si une erreur concernant une autre table s’affiche, collez-la simplement ici.

Merci beaucoup. Malheureusement, j’obtiens un message d’erreur sur la dernière ligne :

« PG::InsufficientPrivilege: ERROR: must be owner of database discourse »

Il s’agit en réalité d’un « serveur standard ». L’installation a été effectuée à l’époque par l’équipe « Discourse » contre des frais uniques.

Ah, d’accord. Essayons cela.

Quittez la console Rails (tapez exit), et restez dans le conteneur (./launcher enter app), puis exécutez :

su postgres -c "reindexdb discourse"

Une fois que cela s’est terminé sans erreur, faites une sauvegarde fraîche sur l’ancien serveur et restaurez ce nouveau fichier. Si une erreur concernant une table spécifique s’affiche, copiez-collez-la ici.

Merci infiniment ! Tout s’est parfaitement déroulé, et sans votre aide, je n’aurais eu aucune chance et j’aurais probablement dû recommencer le forum à zéro, ce qui aurait été très douloureux ! MERCI !

Merci aussi à @chapoi pour son excellent soutien !