Índices corruptos en PG12, ¿cómo los arreglo?

Lo siento por volver a subir esto una vez más, obtuve un error muy extraño

discourse=# REINDEX SCHEMA CONCURRENTLY public;
ERROR:  could not create unique index "index_tags_on_name_ccnew"
DETAIL:  Key (name)=(chronicillness) is duplicated.

Asumo que se puede solucionar con la solución sugerida anteriormente por @riking, pero no logro averiguar cómo modificar la sintaxis para adaptarla a mi caso. :frowning:

Vea:

https://twitter.com/petervgeoghegan/status/1264325695997538304?s=20

https://twitter.com/petervgeoghegan/status/1264404749899534338?s=20

Así que tienes dos opciones si ves este error:

  1. Puedes evitar el problema… en este caso, la tabla tags tiene una fila duplicada con el nombre chronicillness.

    1. Ejecuta una consulta en el explorador de datos buscando las filas: select * from tags where name = 'chronicillness'

    2. Elimina el duplicado:

      ./launcher enter app
      rails c
      Tag.find_by(id: ID_ENCONTRADO_EN_EXPLORADOR_DE_DATOS).destroy   
      
  2. Si tienes una copia de seguridad de tu base de datos y detalles que te gustaría compartir con Peter… compártelos con Peter, ya sea de forma privada o en la lista de correo de PG.

Así que tengo una copia de seguridad generada por Discourse de PostgreSQL 10. ¿Eso será útil? ¿Puedo simplemente extraer la parte de PostgreSQL del archivo y enviarla?

No estoy seguro… lo que probablemente Peter necesite es que detengas tu base de datos y copies todo el contenido de la carpeta que contiene la base de datos.

La mejor manera de averiguarlo es enviándole un correo electrónico.

Claro, le enviaré un correo para resolver esto :slight_smile:

NB: Esto es lo que obtuve al ejecutar el SQL en el explorador de datos

id name topic_count created_at updated_at pm_topic_count target_tag
1710 chronicillness 2 2019-12-03T17:49:17.395Z 2019-12-03T17:49:17.395Z 0 NULL

¿Funcionará

Tag.find_by(id: 1710).destroy

para solucionar el problema?

oh … el índice está en LOWER(name)

Ejecuta la consulta de la siguiente manera:

select * from tags where name ilike 'chronicillness'

Deberías obtener 2 filas.

select * from tags where name ilike 'chronicillness'
id name topic_count created_at updated_at pm_topic_count target_tag
329 chronicillness 12 2017-08-22T00:17:38.824Z 2017-08-22T00:17:38.824Z 0 NULL
1710 chronicillness 2 2019-12-03T17:49:17.395Z 2019-12-03T17:49:17.395Z 0 NULL

¿Podría ser un - entre los nombres de las etiquetas?
Veo dos etiquetas: chronicillness y chronic-illness aquí.

Bueno, entonces ese es el problema… Supongo que borras 1710. Después, dos temas estarán sin esa etiqueta.

#<Tag:0x00005607bb92cf48
 id: 1710,
 name: "chronicillness",
 topic_count: 0,
 created_at: Tue, 03 Dec 2019 17:49:17 UTC +00:00,
 updated_at: Tue, 03 Dec 2019 17:49:17 UTC +00:00,
 pm_topic_count: 0,
 target_tag_id: nil>

¿Por qué tengo la sensación de que era un enano que no estaba asociado con nada?

¡Eliminar la etiqueta trajo más cosas!

discourse=# REINDEX SCHEMA CONCURRENTLY public;
ADVERTENCIA:  no se puede reindexar el índice inválido "public.tags_pkey_ccnew" de forma concurrente, omitiendo
ADVERTENCIA:  no se puede reindexar el índice inválido "public.index_tags_on_name_ccnew" de forma concurrente, omitiendo
ADVERTENCIA:  no se puede reindexar el índice inválido "public.index_tags_on_lower_name_ccnew" de forma concurrente, omitiendo
ADVERTENCIA:  no se puede reindexar el índice inválido "pg_toast.pg_toast_309322_index_ccnew" de forma concurrente, omitiendo
ERROR:  no se pudo crear el índice único "index_tags_on_name_ccnew1"
DETALLE:  La clave (name)=(time-management) está duplicada.

La misma solución :slight_smile: Tienes que repetir el proceso.

Eso es lo que estaba haciendo. Pero, ¿son aceptables esas advertencias? No tengo que preocuparme por ellas, ¿verdad?

Sí, todas las advertencias son correctas; tienes un índice corrupto que debe repararse primero.

Así que todos los clonadores han desaparecido y solo me quedan estas advertencias al reindexar:

discourse=# REINDEX SCHEMA CONCURRENTLY public;
ADVERTENCIA:  no se puede reindexar concurrentemente el índice inválido "public.tags_pkey_ccnew", omitiendo
ADVERTENCIA:  no se puede reindexar concurrentemente el índice inválido "public.index_tags_on_name_ccnew", omitiendo
ADVERTENCIA:  no se puede reindexar concurrentemente el índice inválido "public.index_tags_on_lower_name_ccnew", omitiendo
ADVERTENCIA:  no se puede reindexar concurrentemente el índice inválido "public.tags_pkey_ccnew1", omitiendo
ADVERTENCIA:  no se puede reindexar concurrentemente el índice inválido "public.index_tags_on_name_ccnew1", omitiendo
ADVERTENCIA:  no se puede reindexar concurrentemente el índice inválido "public.index_tags_on_lower_name_ccnew1", omitiendo
ADVERTENCIA:  no se puede reindexar concurrentemente el índice inválido "pg_toast.pg_toast_309322_index_ccnew", omitiendo
ADVERTENCIA:  no se puede reindexar concurrentemente el índice inválido "pg_toast.pg_toast_309322_index_ccnew1", omitiendo
REINDEX

¿Hay algo que deba hacerse para eliminar estas advertencias o tendremos que convivir con ellas?

Esto me resulta confuso… no tenemos nombres de índices que terminen en ccnew… ¿los creaste manualmente?

Creo que se utilizan durante la migración de PostgreSQL 10 a 12, ya que los he visto en casi todos los usuarios cuyos índices han tenido problemas. Por ejemplo:
https://meta.discourse.org/t/postgresql-12-update/151236/208?u=itsbhanusharma

https://meta.discourse.org/t/postgresql-12-update/151236/237?u=itsbhanusharma

EDITO: proviene del propio PostgreSQL

El método de recuperación recomendado en estos casos es eliminar el índice inválido e intentar nuevamente ejecutar REINDEX CONCURRENTLY. El índice concurrente creado durante el procesamiento tiene un nombre que termina con el sufijo ccnew, o ccold si se trata de una definición de índice antigua que no logramos eliminar. Los índices inválidos se pueden eliminar usando DROP INDEX, incluidos los índices toast inválidos.

¡Ay… ¿los índices correctos también ya están en la tabla?

Creo que puedes listar los índices de la tabla usando el explorador de datos.

Si los correctos están ahí, simplemente puedes eliminar estos índices problemáticos.

Déjame revisar. Te informaré.

Parece que los índices existen

También existen índices duplicados para los índices problemáticos, con ccnew o ccnew1 añadidos.

No sé cómo verificar si esos índices son válidos, pero si eliminarlos es una opción, estaré encantado de hacerlo y volver a indexar.

EDITA: ¿Funcionará DROP INDEX como se sugiere aquí?

Sí, elimínalos todos… no tengo idea de cómo llegaron ahí… DROP INDEX es lo que debes usar.

./launcher enter app
rails c
DB.exec('drop index tags_pkey_ccnew1')