Problema PG::UniqueViolation durante la actualización a 3.1.0.beta4

Al actualizar a 3.1.0.beta4, recibí el siguiente error:

I, [2023-04-19T00:02:26.057232 #1]  INFO -- : > cd /var/www/discourse & su discourse -c 'LOAD_PLUGINS=0 bundle exec rake plugin:pull_compatible_all'
I, [2023-04-19T00:02:27.340128 #1]  INFO -- : discourse-adplugin ya está en la última versión compatible
discourse-cakeday ya está en la última versión compatible
discourse-formatting-toolbar ya está en la última versión compatible
discourse-whos-online ya está en la última versión compatible
docker_manager ya está en la última versión compatible
vbulletin-bbcode ya está en la última versión compatible

I, [2023-04-19T00:02:27.340368 #1]  INFO -- : > cd /var/www/discourse & su discourse -c 'bundle exec rake db:migrate'
2023-04-19 00:02:30.080 UTC [634] discourse@discourse ERROR:  violación de restricción de clave única existente \"index_users_on_username\"
2023-04-19 00:02:30.080 UTC [634] discourse@discourse DETAIL:  La clave (username)=(xxx) ya existe.
2023-04-19 00:02:30.080 UTC [634] discourse@discourse STATEMENT:  UPDATE users SET password_algorithm = '$pbkdf2-sha256$i=64000,l=32$'
	WHERE id IN (
	  SELECT id FROM users
	  WHERE users.password_hash IS NOT NULL
	  AND users.password_algorithm IS NULL
	  LIMIT 5000
	)
	
rake aborted!
StandardError: Se ha producido un error, todas las migraciones posteriores se cancelaron:

PG::UniqueViolation: ERROR:  violación de restricción de clave única existente \"index_users_on_username\"
DETAIL:  La clave (username)=(xxx) ya existe.

Después de corregir los usuarios duplicados, vuelvo a tener otros nuevos.

discourse=# REINDEX TABLE users;
ERROR:  no se pudo crear el índice único \"index_users_on_username_lower\"
DETAIL:  La clave (username_lower)=(mhm) está duplicada.
discourse=# REINDEX TABLE users;
ERROR:  no se pudo crear el índice único \"index_users_on_username_lower\"
DETAIL:  La clave (username_lower)=(ahmedhafez) está duplicada.
CONTEXT:  parallel worker
discourse=# REINDEX TABLE users;
ERROR:  no se pudo crear el índice único \"index_users_on_username_lower\"
DETAIL:  La clave (username_lower)=(hany) está duplicada.
discourse=# REINDEX TABLE users;
ERROR:  no se pudo crear el índice único \"index_users_on_username_lower\"
DETAIL:  La clave (username_lower)=(eng_ali) está duplicada.
CONTEXT:  parallel worker
discourse=# REINDEX TABLE users;
ERROR:  no se pudo crear el índice único \"index_users_on_username_lower\"
DETAIL:  La clave (username_lower)=(saad_saad) está duplicada.
discourse=# REINDEX TABLE users;
ERROR:  no se pudo crear el índice único \"index_users_on_username_lower\"
DETAIL:  La clave (username_lower)=(eng_ali) está duplicada.
CONTEXT:  parallel worker
discourse=# REINDEX TABLE users;
ERROR:  no se pudo crear el índice único \"index_users_on_username_lower\"
DETAIL:  La clave (username_lower)=(mostafa11) está duplicada.
CONTEXT:  parallel worker
1 me gusta

Eso parece ser un índice dañado o que de alguna manera los usuarios pudieron crear cuentas con el mismo nombre de usuario con diferente capitalización.

Deberías poder iniciar el contenedor antiguo con

./launcher start app

Luego puedes intentar reindexar la tabla, ver qué usuario está roto, arreglarlo y repetir hasta que el índice se reconstruya.

1 me gusta

Gracias por tu respuesta.

Sí, puedo iniciar/entrar en la aplicación, y también estoy haciendo lo que sugeriste.

discourse=# REINDEX TABLE users;
ERROR:  could not create unique index "index_users_on_username_lower"
DETAIL:  Key (username_lower)=(mostafa11) is duplicated.

El problema es que los duplicados siguen apareciendo, tengo más de 300K de usuarios.
¿Hay alguna forma de comprobar cuántos duplicados hay o listarlos todos?

Para la corrección, estaba actualizando el username_lower de esta manera: estaba añadiendo un número al final.

UPDATE users SET username_lower = 'xxx' WHERE id = xxx;

¿Necesito también actualizar la columna username para que coincida con username_lower? ¿Hay alguna forma más rápida, como solucionar automáticamente esos duplicados?

Mi sitio web está ahora fuera de servicio, así que cualquier ayuda será muy apreciada.

1 me gusta

No conozco ninguna. No debería ocurrir, creo. ¿Desde qué versión estás actualizando?

¿Quizás puedas buscar usuarios donde username! = username_lower?

¿Se cayó a pesar de que iniciaste la aplicación?

No. Está bien que un nombre de usuario tenga mayúsculas y minúsculas, pero no quieres tener dos nombres de usuario que tengan las mismas letras.

¿Es el caso que tienes tanto un Joe como un joe? Si ese es el caso, creo que debería haber una consulta que pudiera encontrarlos, pero no sé cómo hacerlo de inmediato.

2 Me gusta

Gracias Jay
Pude reconstruir y volver a poner mi sitio web en línea.

Primero, como sugeriste, la solución es reindexar, arreglar y repetir hasta que termine. Usé el siguiente comando para ver cuántos

SELECT username_lower, count(*) from users GROUP by username_lower HAVING count(*) > 1;

me devolvía cero.

Por supuesto, hay muchos duplicados y quería saber cuántos. Así que ajusté ligeramente la consulta:

SELECT username_lower, count(username) from users GROUP by username_lower HAVING count(username) > 1;

Esto funcionó y devolvió alrededor de 50 duplicados, así que los arreglé, reindexé y reconstruí con éxito.

1 me gusta

¡Genial! Me alegra mucho que lo hayas resuelto. Tus notas deberían ser de gran ayuda para otros con el mismo problema.

He editado tu publicación para que a otros les resulte más fácil copiar y pegar tu SQL.

1 me gusta

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.