Hoy actualicé nuestra aplicación Discourse a la versión 3.0.1. La actualización falló al intentar procesar la migración de postgres.
Específicamente aquí:
2023-01-27 04:50:48.628 UTC [483] discourse@discourse ERROR: duplicate key value violates unique constraint "index_tags_on_name"
2023-01-27 04:50:48.628 UTC [483] discourse@discourse DETAIL: Key (name)=(e-mail) already exists.
2023-01-27 04:50:48.628 UTC [483] discourse@discourse STATEMENT: UPDATE tags t
SET public_topic_count = x.topic_count
FROM (
SELECT
COUNT(topics.id) AS topic_count,
tags.id AS tag_id
FROM tags
INNER JOIN topic_tags ON tags.id = topic_tags.tag_id
INNER JOIN topics ON topics.id = topic_tags.topic_id AND topics.deleted_at IS NULL AND topics.archetype != 'private_message'
INNER JOIN categories ON categories.id = topics.category_id AND NOT categories.read_restricted
GROUP BY tags.id
) x
WHERE x.tag_id = t.id
AND x.topic_count <> t.public_topic_count;
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
Parece que algunas etiquetas tenían duplicados. Me conecté a postgres y corregí las etiquetas. La migración y la actualización se ejecutaron después.
Mi pregunta es, ¿lo manejé correctamente al manipular la base de datos? Solo cambié el nombre de las etiquetas duplicadas.
No puedo decir cómo se crearon las etiquetas duplicadas. Se insertaron en los últimos 2 o 3 años.
No estoy seguro de si esta situación podría volver a ocurrir.
Sí. También se debe a etiquetas duplicadas / index_tags_on_name.
En mi caso, la etiqueta tiene un nombre diferente.
Actualmente estoy intentando averiguar:
cómo actualizar ruby a 3.0.0 porque se queja de que web-push está en 2.6.7, por lo que ni siquiera puedo ingresar a rails c, para hacer comandos elegantes para arreglar etiquetas
cómo eliminar la etiqueta de forma segura de la base de datos postgres pero aún no tengo ni idea
I, [2023-01-27T07:46:34.317438 #1] INFO -- :
> cd /var/www/discourse && su discourse -c 'bundle exec rake db:migrate'
2023-01-27 07:46:45.663 UTC [584] discourse@discourse ERROR: duplicate key value violates unique constraint "index_tags_on_name"
2023-01-27 07:46:45.663 UTC [584] discourse@discourse DETAIL: Key (name)=(hws-connect) already exists.
2023-01-27 07:46:45.663 UTC [584] discourse@discourse STATEMENT: UPDATE tags t
SET public_topic_count = x.topic_count
FROM (
SELECT
COUNT(topics.id) AS topic_count,
tags.id AS tag_id
FROM tags
INNER JOIN topic_tags ON tags.id = topic_tags.tag_id
INNER JOIN topics ON topics.id = topic_tags.topic_id AND topics.deleted_at IS NULL AND topics.archetype != 'private_message'
INNER JOIN categories ON categories.id = topics.category_id AND NOT categories.read_restricted
GROUP BY tags.id
) x
WHERE x.tag_id = t.id
AND x.topic_count <> t.public_topic_count;
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_tags_on_name"
DETAIL: Key (name)=(hws-connect) already exists.
Este error aparece 3 veces, porque la etiqueta parece encontrarse en 3 temas.
Lamento haber activado las etiquetas si hubiera sabido que esto sucedería y por qué no hubo una advertencia al respecto en el frontend.
Solo quiero eliminarlas y finalmente volver a poner en marcha mi foro
Puedo reconstruir la aplicación tantas veces como quiera. Obtengo el error y se aborta. Por lo tanto, Ruby no se actualiza.
Básicamente estoy atascado.
Mi pregunta es si puedo renombrar la etiqueta “hws-connect” en la base de datos sin corromper la infraestructura de Discourse.
Y… ¿cómo puedo renombrarla a través de postgres?
Tienes que aceptar el extraño fallo al ejecutar tu propia instalación de software multimillonario (respaldado por una comunidad muy útil) que obtuviste (casi) gratis.
Recientemente he actualizado dos sitios que son usuarios bastante intensivos de etiquetas y no he tenido problemas.
En mis más de 5 años ejecutando múltiples instancias de Discourse, creo que he tenido un problema como este una vez.
De todos modos, parece un problema muy similar a este, ¿quizás puedas usar una estrategia similar para resolverlo?:
Parece que ya estabas en el camino correcto, solo tienes que seguirlo…
Lo sé y no es nada sobre Discourse ni sobre la actualización en sí. Sucede y está bien.
Solo desearía no encontrarme en un escenario atascado donde tenga que luchar contra tantos temas (docker, ruby, postgres, discourse). No es mi negocio diario y requiere una inversión de tiempo.
Actualización: la mejor conclusión de tu tema @merefield fue
Supongo que debería ser valiente
Manipular una base de datos siempre me da miedo, pero en este caso funcionó.
Para cualquiera con el mismo problema (etiquetas duplicadas / index_tags_on_name):
Cruje tus dedos y comienza la Fase 1 de Inception: cd /var/discourse sudo ./launcher enter app
Si esto falla porque obtienes algo como “no hay contenedor docker en ejecución” o similar, escribe sudo docker ps -a --no-trunc
Esto listará tu contenedor docker disponible y su ID. Con eso, reinicia el contenedor. sudo docker restart <container ID>
Luego, sudo ./launcher enter app debería funcionar.
Accede a tu base de datos postgres y comienza la Fase 2 de Inception: su discourse psql
El registro de errores de reconstrucción debería haberte dado el nombre de la etiqueta culpable. En mi caso fue
ERROR: duplicate key value violates unique constraint "index_tags_on_name"
2023-01-27 07:46:45.663 UTC [584] discourse@discourse DETAIL: Key (name)=(hws-connect) already exists.
Así que primero busca tu etiqueta con
select * from tags where name='hws-connect';
Eso te da la tabla que puedes ver arriba en mis publicaciones.
Simplemente renombré la etiqueta hws-connect a hws-connect1 con
UPDATE tags SET name = 'hws-connect1' WHERE name='hws-connect';
Sal de Inception con algunas patadas hacia atrás: \q para salir de postgres exit para salir del contenedor docker
Haz la reconstrucción de nuevo con sudo ./launcher rebuild app
Sé feliz porque funciona y verifica en el frontend lo que hiciste:
Ve a tu página de etiquetas https://your-forum/tags
No tengo idea de cómo sucedió y por qué esta actualización falló tan mal; todas las anteriores funcionaron, a través de la web o la terminal.
Limpiaré mis etiquetas ahora.
Extra:
Haces clic en la etiqueta renombrada.
Elimínala de todos los temas. 3 en mi caso.
Vuelve a la página de etiquetas y usa la función superior derecha:
Yo también estoy afectado por esto. Gracias por compartir tus soluciones manuales, acabo de usarlas para solucionar unas 20 de ellas.
Mi foro usaba muchas etiquetas en cualquier tipo de MixEdCaSe y esto nunca fue un problema hasta la actualización. Parece que hay/hubo un error que creó entradas duplicadas, independientemente de las mayúsculas y minúsculas.
id | name | created_at
-------+------------------------+----------------------------
707 | ParkRide | 2019-05-21 21:36:53.213993
18982 | ParkRide | 2020-06-05 18:43:09.409895
(Sí, hay diferencia en el espacio en blanco entre ellas)
Ahora me he quedado atascado con un último duplicado y no se puede solucionar:
discourse=> select name from tags group by name having count(*) > 1;
name
------------
Bike--Ride
(1 row)
discourse=> UPDATE tags SET name = 'Bike--Ride_2' WHERE name = 'Bike--Ride';
ERROR: duplicate key value violates unique constraint "index_tags_on_name"
DETAIL: Key (name)=(Bike--Ride_2) already exists.
discourse=> UPDATE tags SET name = 'Bike--Ride_3' WHERE name = 'Bike--Ride';
ERROR: duplicate key value violates unique constraint "index_tags_on_name"
DETAIL: Key (name)=(Bike--Ride_3) already exists.
discourse=> UPDATE tags SET name = 'something is broken here' WHERE name = 'Bike--Ride';
ERROR: duplicate key value violates unique constraint "index_tags_on_name"
DETAIL: Key (name)=(something is broken here) already exists.
mientras que la actualización falla en
2023-02-01 18:56:58.610 UTC [475] discourse@discourse ERROR: duplicate key value violates unique constraint "index_tags_on_name"
2023-02-01 18:56:58.610 UTC [475] discourse@discourse DETAIL: Key (name)=(Bike--Ride) already exists.
Tuve el mismo error: sin importar el nuevo nombre de etiqueta que usé, informó que ya existía. Lo solucioné actualizando la etiqueta usando el id en lugar de la columna name: