Erreur lors de l'importation de la sauvegarde : "impossible de créer un index unique"

Salut,

J’essaie de migrer un forum vers un nouveau serveur. Les deux serveurs exécutent la dernière version de Discourse Docker. Lors de l’importation de la sauvegarde via la ligne de commande, j’obtiens l’erreur suivante :

ERREUR : impossible de créer l'index unique « index_incoming_referers_on_path_and_incoming_domain_id »
DÉTAIL : La clé (path, incoming_domain_id)=(« /search/ », 418) est dupliquée.
EXCEPTION : psql a échoué : DÉTAIL : La clé (path, incoming_domain_id)=(« /search/ », 418) est dupliquée.

Cela semble être la même erreur ou une erreur similaire à :

Cependant, dans mon cas, les enregistrements dupliqués se trouvent dans le chemin /search/ plutôt que /m/search comme c’est le cas dans le fil de discussion ci-dessus.

Je me suis connecté au conteneur sur l’ancien serveur (./launcher enter app) et dans la console Rails (rails c), j’ai essayé de rechercher les enregistrements dupliqués en utilisant :

IncomingReferer.where(path: "/search")
et
IncomingReferer.where("path LIKE '%/search%'")

Cependant, cela affiche des centaines d’enregistrements. Comment puis-je identifier les enregistrements dupliqués, et comment puis-je les supprimer en toute sécurité et reconstruire ? Le forum fonctionne actuellement correctement sur l’ancien serveur, nous devons juste passer à du nouveau matériel.

1 « J'aime »

Avez-vous essayé d’utiliser l’interface graphique d’administration ?

1 « J'aime »

Non, j’ai supposé que l’importation via l’interface graphique déclenchait le même processus d’importation ? Je vais essayer cela maintenant.

1 « J'aime »

Je soupçonne que cela signifie que votre index est corrompu. Quelle version de Postgres exécutez-vous ?

Quelque chose comme :

cd /var/discourse
cat shared/standalone/postgres_data/PG*

(Je ne me souviens plus exactement du nom du fichier Postgres).

Vous pouvez rechercher ici « index corrompu Postgres » et trouver un sujet que j’ai écrit sur la façon de localiser ces mauvais enregistrements et de les supprimer.

Vous essayez essentiellement de reconstruire cet index, de supprimer les enregistrements sur lesquels il signale des erreurs, puis de tenter à nouveau de reconstruire l’index jusqu’à ce qu’il se reconstruise correctement.

Je viens d’essayer l’importation via l’interface graphique, avec exactement le même résultat :

L’ancien serveur ne possède pas de fichier nommé PG_VERSION. Comment puis-je connaître la version en cours d’exécution ? J’ai mis à jour l’installation Docker vers la dernière version aujourd’hui.

Le nouveau serveur (nouvellement initialisé) exécute Postgres V13.

cat shared/standalone/postgres_data/PG_VERSION
13

Existe-t-il une procédure recommandée pour effectuer cela ?

J’avais un sujet contenant quelques indices, mais je ne le vois plus. Cela fait presque un an depuis la mise à niveau vers PostgreSQL 12.

  reindex index index_incoming_referers_on_path_and_incoming_domain_id;

Et

 ActiveRecord::Base.connection.execute('reindex index index_incoming_referers_on_path_and_incoming_domain_id;')

sont des méthodes pour tenter de reconstruire l’index. Cela générera une erreur, puis vous pourrez supprimer les enregistrements erronés. Vous devrez inclure à la fois le chemin et l’ID.

Ok, c’est corrigé. Voici ce que j’ai fait :

Entrer dans le conteneur

./launcher enter app

Se connecter à la base de données

su postgres -c 'psql discourse'

Tenter de trouver les doublons

discourse=# select * from incoming_referers where path LIKE '%/search/' ORDER BY incoming_domain_id;

  id  |    path    | incoming_domain_id
------+------------+--------------------
 3339 | /search/   |                 33
 6257 | /search/   |                 91
 1567 | /search/   |                298
 1777 | /search/   |                341
 3010 | /search/   |                418
 6247 | /search/   |                418
 4293 | /search/   |                644
 2899 | /search/   |                653
 3447 | /search/   |                793
 3696 | /search/   |                852
 4395 | /a/search/ |               1050
 6968 | /search/   |               1305
 5634 | /search/   |               1387
 5834 | /search/   |               1437
 6519 | /search/   |               1637
 7127 | /search/   |               1787
 7280 | /search/   |               1827
(17 rows)

Supprimer le doublon

DELETE FROM incoming_referers WHERE path LIKE '%/search/' AND id IN (6247);

Ensuite, reconstruire

discourse=# REINDEX SCHEMA CONCURRENTLY public;
WARNING:  cannot reindex invalid index "public.incoming_referers_pkey_ccnew" concurrently, skipping
WARNING:  cannot reindex invalid index "public.index_incoming_referers_on_path_and_incoming_domain_id_ccnew" concurrently, skipping
WARNING:  cannot reindex invalid index "pg_toast.pg_toast_20732_index_ccnew" concurrently, skipping
REINDEX

J’ai ensuite pris une nouvelle sauvegarde, copiée sur le nouveau serveur, et l’importation s’est déroulée avec succès :smiley:

Ce serait bien que le processus de sauvegarde détecte les doublons pour éviter tout problème. J’ai eu de la chance d’avoir accès au serveur d’origine qui était toujours en cours d’exécution. Si j’avais restauré une sauvegarde froide, cela aurait probablement posé plus de problèmes.

Un grand merci pour votre aide.

3 « J'aime »

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.