Problème PG::UniqueViolation lors de la mise à niveau 3.1.0.beta4

lors de la mise à niveau vers la version 3.1.0.beta4, j’ai rencontré l’erreur suivante :

I, [2023-04-19T00:02:26.057232 #1]  INFO -- : cd /var/www/discourse & su discourse -c 'LOAD_PLUGINS=0 bundle exec rake plugin:pull_compatible_all'
I, [2023-04-19T00:02:27.340128 #1]  INFO -- : discourse-adplugin est déjà à la dernière version compatible
discourse-cakeday est déjà à la dernière version compatible
discourse-formatting-toolbar est déjà à la dernière version compatible
discourse-whos-online est déjà à la dernière version compatible
docker_manager est déjà à la dernière version compatible
vbulletin-bbcode est déjà à la dernière version compatible

I, [2023-04-19T00:02:27.340368 #1]  INFO -- : cd /var/www/discourse & su discourse -c 'bundle exec rake db:migrate'
2023-04-19 00:02:30.080 UTC [634] discourse@discourse ERROR:  la clé en double viole la contrainte d'unicité « index_users_on_username »
2023-04-19 00:02:30.080 UTC [634] discourse@discourse DETAIL:  La clé (username)=(xxx) existe déjà.
2023-04-19 00:02:30.080 UTC [634] discourse@discourse STATEMENT:  UPDATE users SET password_algorithm = '$pbkdf2-sha256$i=64000,l=32$'
	WHERE id IN (
	  SELECT id FROM users
	  WHERE users.password_hash IS NOT NULL
	  AND users.password_algorithm IS NULL
	  LIMIT 5000
	)
	
rake aborted!
StandardError: Une erreur s'est produite, toutes les migrations ultérieures ont été annulées :

PG::UniqueViolation: ERROR:  la clé en double viole la contrainte d'unicité « index_users_on_username »
DETAIL:  La clé (username)=(xxx) existe déjà.

Après avoir corrigé les doublons d’utilisateurs, j’obtiens à nouveau de nouveaux doublons.

discourse=# REINDEX TABLE users;
ERROR:  impossible de créer l'index unique « index_users_on_username_lower »
DETAIL:  La clé (username_lower)=(mhm) est dupliquée.
discourse=# REINDEX TABLE users;
ERROR:  impossible de créer l'index unique « index_users_on_username_lower »
DETAIL:  La clé (username_lower)=(ahmedhafez) est dupliquée.
CONTEXT:  parallel worker
discourse=# REINDEX TABLE users;
ERROR:  impossible de créer l'index unique « index_users_on_username_lower »
DETAIL:  La clé (username_lower)=(hany) est dupliquée.
discourse=# REINDEX TABLE users;
ERROR:  impossible de créer l'index unique « index_users_on_username_lower »
DETAIL:  La clé (username_lower)=(eng_ali) est dupliquée.
CONTEXT:  parallel worker
discourse=# REINDEX TABLE users;
ERROR:  impossible de créer l'index unique « index_users_on_username_lower »
DETAIL:  La clé (username_lower)=(saad_saad) est dupliquée.
discourse=# REINDEX TABLE users;
ERROR:  impossible de créer l'index unique « index_users_on_username_lower »
DETAIL:  La clé (username_lower)=(eng_ali) est dupliquée.
CONTEXT:  parallel worker
discourse=# REINDEX TABLE users;
ERROR:  impossible de créer l'index unique « index_users_on_username_lower »
DETAIL:  La clé (username_lower)=(mostafa11) est dupliquée.
CONTEXT:  parallel worker
1 « J'aime »

Cela ressemble soit à un index corrompu soit à la possibilité que des utilisateurs aient pu créer des comptes avec le même nom d’utilisateur mais une capitalisation différente.

Vous devriez pouvoir démarrer l’ancien conteneur avec
./launcher start app

Vous pouvez ensuite essayer de réindexer la table, voir quel utilisateur est défectueux, le corriger, et répéter jusqu’à ce que l’index soit reconstruit.

1 « J'aime »

Merci pour votre réponse.

Oui, je peux démarrer / entrer dans l’application, et je fais aussi ce que vous avez suggéré.

discourse=# REINDEX TABLE users;
ERROR:  could not create unique index "index_users_on_username_lower"
DETAIL:  Key (username_lower)=(mostafa11) is duplicated.

Le problème est que les doublons continuent d’apparaître, j’ai plus de 300 000 utilisateurs.
Y a-t-il un moyen de vérifier combien il y a de doublons ou de les lister tous ?

Pour la correction, je mettais à jour le username_lower comme ceci : j’ajoutais un numéro à la fin.

UPDATE users SET username_lower = 'xxx' WHERE id = xxx;

Dois-je également mettre à jour la colonne username pour qu’elle corresponde à username_lower ? Existe-t-il un moyen plus rapide, comme corriger automatiquement ces doublons ?

Mon site web est maintenant hors ligne, donc toute aide est grandement appréciée.

1 « J'aime »

Je n’en connais pas. Ça ne devrait pas arriver, je pense. De quelle version mettez-vous à jour ?

Peut-être pourriez-vous rechercher les utilisateurs où username! = username_lower ?

Il est tombé en panne même si vous avez démarré l’application ?

Non. C’est normal qu’un nom d’utilisateur ait des majuscules et des minuscules, mais vous ne voulez pas avoir deux noms d’utilisateur qui aient les mêmes lettres.

Est-ce que vous avez à la fois un Joe et aussi un joe ? Si c’est le cas, je pense qu’il devrait y avoir une requête qui pourrait les trouver, mais je ne sais pas comment faire sur le moment.

2 « J'aime »

Merci Jay
J’ai pu reconstruire et remettre mon site Web en ligne.

Tout d’abord, comme vous l’avez suggéré, la solution consiste à réindexer, corriger et répéter jusqu’à ce que ce soit fait. J’ai utilisé la commande suivante pour voir combien

SELECT username_lower, count(*) from users GROUP by username_lower HAVING count(*) > 1;

elle me donnait zéro.

Bien sûr, il y a beaucoup de doublons et je voulais savoir combien. J’ai donc légèrement ajusté la requête :

SELECT username_lower, count(username) from users GROUP by username_lower HAVING count(username) > 1;

Cela a fonctionné et a renvoyé environ 50 doublons, je les ai donc corrigés, réindexés et reconstruits avec succès.

1 « J'aime »

Super ! Je suis ravi que vous ayez trouvé une solution. Vos notes devraient être très utiles à d’autres personnes confrontées au même problème.

J’ai modifié votre message pour faciliter le copier-coller de votre SQL par d’autres.

1 « J'aime »

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