Duplicato chiave viola vincolo univoco su tabella durante aggiornamento

Ciao a tutti, ho un problema strano con un forum che amministro.

Durante un aggiornamento, nella pagina admin/upgrade o nel terminale, è fallito e ho ricevuto questo errore:

--------------------------------------------------------------------------------
1 migrazione fallita!

Impossibile eseguire la migrazione di default
#<ActiveRecord::RecordNotUnique: PG::UniqueViolation: ERRORE: valore di chiave duplicato viola il vincolo di unicità "index_screened_ip_addresses_on_ip_address"
DETTAGLIO:  La chiave (ip_address)=(10.0.0.0/8) esiste già.

Fortunatamente, non ho rotto il forum; con il comando ./launcher restart app (./launcher destroy app / ./launcher start app mi ha salvato una volta quando avevo una pagina vuota dopo un riavvio), quindi non c’è alcuna emergenza, ecco perché ho chiesto un consiglio.

Ho deciso di ispezionare il database: ho alcuni riferimenti all’IP 10.0.0.0/8 che sembrano dei log, ma nella tabella screened_ip_addresses non trovo duplicati.

--
-- Voce TOC 6829 (class 0 OID 382198)
-- Dipendenze: 657
-- Dati per Name: screened_ip_addresses; Type: TABLE DATA; Schema: public; Owner: -
--

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’amministratore del forum mi ha detto di aver pulito alcuni IP nella pagina /admin/logs/screened_ip_addresses e di averne aggiunti altri. Ma dubito che abbia toccato questo IP. La cosa strana è che viene indicato che l’IP è stato aggiunto 14 giorni fa (era l’ultimo aggiornamento, probabilmente quello di PostgreSQL), anche se il forum è del 2015. E sugli altri forum, viene controllata la data di creazione.

Quindi immagino che la tabella sia un po’ disordinata, ma non sembra proprio così.

Non voglio rischiare troppo, soprattutto perché non sono molto bravo con SQL. Quindi vorrei un consiglio sulla procedura da seguire per assicurarmi di poter eseguire l’aggiornamento in sicurezza :raised_hands:

Dovrei pulire la pagina /admin/logs/screened_ip_addresses, provare a eliminare le voci di questa tabella o di un’altra?

Sembra che l’indice sia corrotto. Puoi consultare alcuni altri argomenti relativi agli indici corrotti.

In primo luogo, puoi provare a ricostruire l’indice. Tieni inoltre presente che molte ricerche non troveranno le voci duplicate perché presuppongono che l’indice funzioni correttamente.

Grazie, per essere sicuro, sarebbe qualcosa del genere?

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

Se non aiuta perché l’indice sembra corretto per il sistema, questa soluzione sembra fattibile data la dimensione di questa tabella?

TRUNCATE public.screened_ip_addresses

Eseguo un reindicizzazione, poi aggiungo manualmente quegli IP di nuovo?

Sono al telefono, quindi dovrai leggere il RTFM, ma ricostruirei solo public.screened_ip_addresses. Penso che quando lo farai otterrai errori relativi ai conflitti.

Grazie, ho eseguito il comando, nessun errore segnalato. Proverò un’altra ricostruzione tra qualche ora e vedrò.

edit: ok, il reindicizzazione non ha fatto nulla

1 migrazione fallita!

Migrazione predefinita fallita
#<ActiveRecord::RecordNotUnique: PG::UniqueViolation: ERRORE: il valore della chiave duplicata viola il vincolo di unicità "index_screened_ip_addresses_on_ip_address"
DETTAGLIO:  La chiave (ip_address)=(10.0.0.0/8) esiste già.
>

Ho riavviato l’app, pulito tutti gli IP in /admin/logs/screened_ip_addresses e aggiornato con successo.

Gli IP sono tornati, non ho dovuto aggiungerli manualmente

Forse ho esagerato un po’ con la cautela, ma dato che non è il mio forum, non volevo combinare pasticci. Grazie @pfaffman per l’aiuto!

Vedremo la prossima volta se succede di nuovo, ma almeno so come risolverlo.

Ultimo aggiornamento per questo argomento, l’ultima volta ho eseguito l’aggiornamento tramite la pagina admin/upgrade. Questa volta ho voluto ricostruire con il terminale per essere sicuro. Nessun problema di migrazione. È andato tutto bene.

Posso confermare che il problema è stato risolto :raised_hands: