Valor de clave duplicada viola la restricción única en una tabla durante la actualización

Hola a todos, tengo un problema extraño con un foro que mantengo.

Durante una actualización, en la página admin/upgrade o en la terminal, falló y obtuve este error:

--------------------------------------------------------------------------------
¡1 migración falló!

No se pudo migrar default
#<ActiveRecord::RecordNotUnique: PG::UniqueViolation: ERROR:  el valor de clave duplicado viola la restricción única "index_screened_ip_addresses_on_ip_address"
DETALLE:  La clave (ip_address)=(10.0.0.0/8) ya existe.

Afortunadamente, no rompí el foro; con el comando ./launcher restart app (./launcher destroy app / ./launcher start app me salvó una vez cuando tuve una página en blanco tras un reinicio), así que no hay ninguna emergencia en absoluto, por eso quería alguna orientación.

Decidí inspeccionar la base de datos; tengo algunas referencias a la IP 10.0.0.0/8 que parecen ser registros, pero en la tabla screened_ip_addresses no tengo duplicados.

--
-- Entrada del TOC 6829 (clase 0 OID 382198)
-- Dependencias: 657
-- Datos para Nombre: screened_ip_addresses; Tipo: TABLE DATA; Esquema: public; Propietario: -
--

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

El administrador del foro me dijo que limpió algunas IPs en la página /admin/logs/screened_ip_addresses y agregó otras. Pero dudo que haya tocado esta IP. Lo extraño es que dice que la IP fue agregada hace 14 días (fue la última vez que actualicé, y probablemente fue la actualización de PostgreSQL), aunque el foro es de 2015. Y en otros foros, verifica con la fecha de creación.

Así que supongo que la tabla está un poco desordenada, pero no parece realmente así.

No quiero probar demasiado la suerte, especialmente porque no soy bueno con SQL. Por eso quería alguna orientación sobre el procedimiento a seguir para asegurarme de que pueda actualizar de forma segura :raised_hands:

¿Debería limpiar la página /admin/logs/screened_ip_addresses, intentar purgar entradas de esta tabla o de otra?

Parece que el índice está corrupto. Puedes buscar en otros temas sobre índices corruptos.

Primero, puedes intentar reconstruir el índice. Ten en cuenta también que muchas búsquedas no encontrarán las entradas duplicadas porque asumen que el índice funciona correctamente.

Gracias, ¿seguro que sería algo así?

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

Si no ayuda porque el sistema considera que el índice está bien, ¿parece viable esta solución dada el tamaño de esta tabla?

TRUNCATE public.screened_ip_addresses

¿Ejecuto un reíndice y luego añado manualmente esas IPs de nuevo?

Estoy en el teléfono, así que tendrás que leer el RTFM, pero yo reconstruiría solo public.screened_ip_addresses. Creo que al hacerlo obtendrás errores sobre los conflictos.

Gracias, ejecuté el comando y no se mencionó ningún error. Intentaré otra reconstrucción en unas horas y lo veré.

edición: ok, la reindexación no hizo nada.

¡1 migración falló!

No se pudo migrar default
#<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.
>

Reinicié la aplicación, limpié todas las IPs en /admin/logs/screened_ip_addresses y actualicé con éxito.

Las IPs volvieron, no tuve que añadirlas manualmente.

Quizás me tomé un poco demasiado de precaución, pero como no es mi foro, no quería estropear nada. ¡Gracias @pfaffman por la ayuda!

Supongo que la próxima vez veré si vuelve a ocurrir, pero al menos sabré cómo solucionarlo.

Última actualización para este tema, la última vez que actualicé a través de la página admin/upgrade. Esta vez quise reconstruir con la terminal para estar seguro. Sin problemas de migración. Todo salió bien.

Puedo confirmar que el problema está cerrado :raised_hands: