Valeur de clé en double viole la contrainte d'unicité sur une table lors de la mise à niveau

Bonjour à tous, je rencontre un problème étrange avec l’un des forums que je maintiens.

Lors d’une mise à niveau, sur la page admin/upgrade ou dans le terminal, l’opération a échoué avec cette erreur :

--------------------------------------------------------------------------------
1 migration a échoué !

Échec de la migration par défaut
#<ActiveRecord::RecordNotUnique: PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "index_screened_ip_addresses_on_ip_address"
DETAIL:  Key (ip_address)=(10.0.0.0/8) already exists.

Heureusement, je n’ai pas cassé le forum grâce à la commande ./launcher restart app (./launcher destroy app / ./launcher start app m’a déjà sauvé une fois lorsque j’avais une page blanche après un redémarrage), donc il n’y a pas d’urgence, c’est pourquoi je cherche des conseils.

J’ai décidé d’inspecter la base de données. J’ai quelques références à l’IP 10.0.0.0/8 qui ressemblent à des logs, mais dans la table screened_ip_addresses, je ne vois aucun doublon.

--
-- Entrée TOC 6829 (classe 0 OID 382198)
-- Dépendances : 657
-- Données pour Name : screened_ip_addresses ; Type : TABLE DATA ; Schéma : public ; Propriétaire : -
--

COPY public.screened_ip_addresses (id, ip_address, action_type, match_count, last_match_at, created_at, updated_at) FROM stdin;
236	10.0.0.0/8	2	0	\N	2020-05-24 19:44:41.587257	2020-05-24 19:44:41.587257
237	192.168.0.0/16	2	0	\N	2020-05-24 19:44:47.150337	2020-05-24 19:44:47.150337
239	172.16.0.0/12	2	0	\N	2020-05-24 19:44:57.347656	2020-05-24 19:44:57.347656
240	fc00::/7	2	0	\N	2020-05-24 19:45:02.270948	2020-05-24 19:45:02.270948
261	154.71.107.147	1	0	\N	2020-06-05 13:15:17.718236	2020-06-07 00:27:57.204765
257	154.126.107.81	1	0	\N	2020-06-02 09:51:31.191431	2020-06-07 00:27:58.538628
259	197.1.186.242	1	0	\N	2020-06-05 08:39:52.218198	2020-06-07 00:27:58.985867
258	89.158.72.7	1	0	\N	2020-06-02 20:44:41.584317	2020-06-07 00:27:59.542337
260	196.179.229.13	1	0	\N	2020-06-05 08:39:52.227515	2020-06-07 00:28:00.288445
238	127.0.0.0/8	2	0	\N	2020-05-24 19:44:52.369958	2020-05-24 19:44:52.369958

L’administrateur du forum m’a dit qu’il avait nettoyé certaines IP sur la page /admin/logs/screened_ip_addresses et en avait ajouté d’autres. Mais je doute qu’il ait touché cette IP. L’étrange, c’est qu’il est indiqué que l’IP a été ajoutée il y a 14 jours (c’était la dernière fois que j’ai effectué une mise à niveau, probablement la mise à niveau de PostgreSQL), alors que le forum date de 2015. Sur d’autres forums, cela vérifie la date de création.

Donc, je suppose que la table est un peu désorganisée, mais cela ne semble pas vraiment être le cas.

Je ne veux pas trop jouer avec la chance, surtout parce que je ne suis pas très fort en SQL. Je cherche donc des conseils sur la procédure à suivre pour m’assurer de pouvoir effectuer la mise à niveau en toute sécurité :raised_hands:

Devrais-je nettoyer la page /admin/logs/screened_ip_addresses, essayer de purger les entrées de cette table ou d’une autre ?

Cela ressemble à un index corrompu. Vous pouvez consulter d’autres sujets traitant des index corrompus.

Vous pouvez d’abord essayer de reconstruire l’index. Notez également que de nombreuses recherches ne trouveront pas les entrées en double, car elles supposent que l’index fonctionne correctement.

Merci, pour être sûr, cela ressemblerait à cela ?

cd /var/discourse
./launcher enter app
su postgres
psql
\connect discourse
REINDEX SCHEMA CONCURRENTLY public;

Si cela n’aide pas car l’index semble correct pour le système, cette solution semble-t-elle viable compte tenu de la taille de cette table ?

TRUNCATE public.screened_ip_addresses

Je lance un reindex, puis j’ajoute manuellement ces adresses IP à nouveau ?

Je suis sur mon téléphone, donc tu devras lire la documentation, mais je reconstruirais uniquement public.screened_ip_addresses. Je pense que tu rencontreras des erreurs concernant les conflits.

Merci, j’ai exécuté la commande, aucune erreur n’a été signalée. Je vais essayer une autre reconstruction dans quelques heures et je verrai.

edit : ok, la réindexation n’a rien fait.

1 migration a échoué !

Échec de la migration par défaut
#<ActiveRecord::RecordNotUnique: PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_screened_ip_addresses_on_ip_address"
DETAIL:  Key (ip_address)=(10.0.0.0/8) already exists.
>

J’ai redémarré l’application, nettoyé toutes les adresses IP dans /admin/logs/screened_ip_addresses, et mis à niveau avec succès.

Les adresses IP sont revenues, je n’ai pas eu besoin de les ajouter manuellement.

Peut-être que j’ai été un peu trop prudent, mais comme ce n’est pas mon forum, je ne voulais pas tout gâcher. Merci @pfaffman pour l’aide !

Je verrai la prochaine fois si cela se reproduit, mais au moins je saurai comment le corriger.

Dernière mise à jour pour ce sujet, dernière fois que j’ai procédé à une mise à niveau via la page admin/upgrade. Cette fois, je voulais reconstruire via le terminal pour être certain. Aucun problème de migration. Tout s’est bien passé.

Je peux confirmer que le problème est résolu :raised_hands: