Problema PG::UniqueViolation durante o upgrade para 3.1.0.beta4

Ao atualizar para 3.1.0.beta4, recebi o seguinte erro

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 já está na versão compatível mais recente
discourse-cakeday já está na versão compatível mais recente
discourse-formatting-toolbar já está na versão compatível mais recente
discourse-whos-online já está na versão compatível mais recente
docker_manager já está na versão compatível mais recente
vbulletin-bbcode já está na versão compatível mais recente

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:  violação de chave duplicada viola a restrição de chave exclusiva \"index_users_on_username\"
2023-04-19 00:02:30.080 UTC [634] discourse@discourse DETAIL:  A chave (username)=(xxx) já 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: Ocorreu um erro, todas as migrações posteriores foram canceladas:

PG::UniqueViolation: ERROR:  violação de chave duplicada viola a restrição de chave exclusiva \"index_users_on_username\"
DETAIL:  A chave (username)=(xxx) já existe.

Depois de corrigir os usuários duplicados, recebo novos.

discourse=# REINDEX TABLE users;
ERROR:  não foi possível criar o índice exclusivo \"index_users_on_username_lower\"
DETAIL:  A chave (username_lower)=(mhm) está duplicada.
discourse=# REINDEX TABLE users;
ERROR:  não foi possível criar o índice exclusivo \"index_users_on_username_lower\"
DETAIL:  A chave (username_lower)=(ahmedhafez) está duplicada.
CONTEXT:  parallel worker
discourse=# REINDEX TABLE users;
ERROR:  não foi possível criar o índice exclusivo \"index_users_on_username_lower\"
DETAIL:  A chave (username_lower)=(hany) está duplicada.
discourse=# REINDEX TABLE users;
ERROR:  não foi possível criar o índice exclusivo \"index_users_on_username_lower\"
DETAIL:  A chave (username_lower)=(eng_ali) está duplicada.
CONTEXT:  parallel worker
discourse=# REINDEX TABLE users;
ERROR:  não foi possível criar o índice exclusivo \"index_users_on_username_lower\"
DETAIL:  A chave (username_lower)=(saad_saad) está duplicada.
discourse=# REINDEX TABLE users;
ERROR:  não foi possível criar o índice exclusivo \"index_users_on_username_lower\"
DETAIL:  A chave (username_lower)=(eng_ali) está duplicada.
CONTEXT:  parallel worker
discourse=# REINDEX TABLE users;
ERROR:  não foi possível criar o índice exclusivo \"index_users_on_username_lower\"
DETAIL:  A chave (username_lower)=(mostafa11) está duplicada.
CONTEXT:  parallel worker
1 curtida

Parece ser um índice corrompido ou que de alguma forma os usuários conseguiram criar contas com o mesmo nome de usuário com capitalização diferente.

Você deve conseguir iniciar o contêiner antigo com

./launcher start app

Você pode então tentar reindexar a tabela, ver qual usuário está com problema, corrigi-lo e repetir até que o índice seja reconstruído.

1 curtida

Obrigado pela sua resposta.

Sim, consigo iniciar / entrar no aplicativo, também estou fazendo o que você sugeriu.

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

O problema é que duplicatas continuam aparecendo, tenho mais de 300 mil usuários.
Existe alguma maneira de verificar quantas duplicatas existem ou listá-las todas?

Para corrigir, eu estava atualizando o username_lower assim: eu estava anexando um número no final.

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

Preciso também atualizar a coluna username para corresponder ao username_lower? Existe alguma maneira mais rápida, como corrigir automaticamente essas duplicatas?

Meu site está offline agora, então qualquer ajuda é muito apreciada.

1 curtida

Não estou ciente de nenhuma. Não deveria acontecer, eu acho. De qual versão você está atualizando?

Talvez você possa procurar por usuários onde username! = username_lower?

Ele caiu mesmo você tendo iniciado o aplicativo?

Não. Tudo bem para um nome de usuário ter letras maiúsculas e minúsculas, mas você não quer ter dois nomes de usuário com as mesmas letras.

É o caso de você ter tanto um Joe quanto um joe? Se for esse o caso, acho que deveria haver uma consulta que pudesse encontrá-los, mas não sei como fazer isso de imediato.

2 curtidas

Obrigado, Jay.
Consegui reconstruir e colocar meu site online novamente.

Primeiro, como você sugeriu, a solução é reindexar, corrigir e repetir até terminar. Usei o seguinte comando para ver quantos:

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

ele estava me retornando zero.

Claro, existem muitos duplicados e eu queria saber quantos. então ajustei ligeiramente a consulta:

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

Isso funcionou e retornou cerca de 50 duplicados, então eu os corrigi, reindexei e reconstruí com sucesso.

1 curtida

Ótimo! Fico feliz que você tenha resolvido. Suas anotações devem ser muito úteis para outras pessoas com o mesmo problema.

Editei sua postagem para facilitar a cópia/colagem do seu SQL por outras pessoas.

1 curtida

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