3.1.0.beta4アップグレード中のPG::UniqueViolation問題

3.1.0.beta4にアップグレード中に、以下のエラーが発生しました。

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 is already at latest compatible version
discourse-cakeday is already at latest compatible version
discourse-formatting-toolbar is already at latest compatible version
discourse-whos-online is already at latest compatible version
docker_manager is already at latest compatible version
vbulletin-bbcode is already at latest compatible version

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:  duplicate key value violates unique constraint "index_users_on_username"
2023-04-19 00:02:30.080 UTC [634] discourse@discourse DETAIL:  Key (username)=(xxx) already exists.
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: An error has occurred, all later migrations canceled:

PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "index_users_on_username"
DETAIL:  Key (username)=(xxx) already exists.

重複ユーザーを修正した後、再び新しい重複が発生しました。

discourse=# REINDEX TABLE users;
ERROR:  could not create unique index "index_users_on_username_lower"
DETAIL:  Key (username_lower)=(mhm) is duplicated.
discourse=# REINDEX TABLE users;
ERROR:  could not create unique index "index_users_on_username_lower"
DETAIL:  Key (username_lower)=(ahmedhafez) is duplicated.
CONTEXT:  parallel worker
discourse=# REINDEX TABLE users;
ERROR:  could not create unique index "index_users_on_username_lower"
DETAIL:  Key (username_lower)=(hany) is duplicated.
CONTEXT:  parallel worker
discourse=# REINDEX TABLE users;
ERROR:  could not create unique index "index_users_on_username_lower"
DETAIL:  Key (username_lower)=(eng_ali) is duplicated.
CONTEXT:  parallel worker
discourse=# REINDEX TABLE users;
ERROR:  could not create unique index "index_users_on_username_lower"
DETAIL:  Key (username_lower)=(saad_saad) is duplicated.
discourse=# REINDEX TABLE users;
ERROR:  could not create unique index "index_users_on_username_lower"
DETAIL:  Key (username_lower)=(eng_ali) is duplicated.
CONTEXT:  parallel worker
discourse=# REINDEX TABLE users;
ERROR:  could not create unique index "index_users_on_username_lower"
DETAIL:  Key (username_lower)=(mostafa11) is duplicated.
CONTEXT:  parallel worker
「いいね!」 1

インデックスが破損しているか、ユーザーが異なる大文字/小文字で同じユーザー名のアカウントを作成できたかのいずれかのようです。

古いコンテナは次のように起動できます。

./launcher start app

その後、テーブルを再インデックス化し、どのユーザーが壊れているかを確認して修正し、インデックスが再構築されるまで繰り返すことができます。

「いいね!」 1

ご返信ありがとうございます。

はい、アプリを起動/入力でき、ご提案いただいたことも実行しています。

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

問題は重複が継続して発生することです。ユーザーが300K以上います。
重複がいくつあるかを確認したり、すべてをリスト表示したりする方法はありますか?

修正については、次のように username_lower を更新していました。末尾に数字を追加していました。

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

username カラムも username_lower に合わせて更新する必要がありますか?重複を自動的に修正するような、より高速な方法はありませんか?

私のウェブサイトは現在オフラインなので、どのような助けでも大変感謝いたします。

「いいね!」 1

そのような機能があるかは分かりません。通常は発生しないはずですが、どのバージョンからアップグレードしていますか?

もしかしたら、usernameusername_lower が一致しないユーザーを検索できるかもしれません。

アプリを起動したにもかかわらず、ダウンしてしまったのですか?

いいえ。ユーザー名が campuran 大文字と小文字で構成されていても問題ありませんが、同じ文字を持つユーザー名を2つ持つことは避けたいはずです。

例えば、「Joe」と「joe」の両方があるような状況ですか?もしそうであれば、それらを見つけるクエリがあると思いますが、現時点ではその方法が分かりません。

「いいね!」 2

ジェイさん、ありがとうございます。
ウェブサイトを再構築してオンラインに戻すことができました。

まず、提案された通り、完了するまで再インデックス作成、修正、繰り返しの順で実行しました。次のコマンドを使用して、いくつあるかを確認しました。

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

結果はゼロでした。

もちろん、多くの重複があったため、いくつあるかを知りたかったのです。そこで、クエリを少し調整しました。

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

これは機能し、約50件の重複が返されたため、それらを修正し、再インデックス作成と再構築を正常に完了しました。

「いいね!」 1

素晴らしい!解決できて本当に良かったですね。あなたのメモは、同じ問題を抱える他の人々にとって非常に役立つでしょう。

SQLを他の人がコピー&ペーストしやすいように、あなたの投稿を編集しました。

「いいね!」 1

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