При обновлении до версии 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 уже находится в последней совместимой версии
discourse-cakeday уже находится в последней совместимой версии
discourse-formatting-toolbar уже находится в последней совместимой версии
discourse-whos-online уже находится в последней совместимой версии
docker_manager уже находится в последней совместимой версии
vbulletin-bbcode уже находится в последней совместимой версии
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.
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
Это похоже либо на повреждённый индекс, либо на то, что пользователи каким-то образом смогли создать учётные записи с одинаковыми именами, но разным регистром букв.
Вы должны иметь возможность запустить старый контейнер командой:
./launcher start app
Затем вы можете попробовать перестроить индекс таблицы, определить, какой пользователь повреждён, исправить его и повторять процесс, пока индекс не будет восстановлен.
Да, я могу запустить / войти в приложение, я также делаю то, что вы посоветовали.
discourse=# REINDEX TABLE users;
ERROR: could not create unique index "index_users_on_username_lower"
DETAIL: Key (username_lower)=(mostafa11) is duplicated.
Проблема в том, что дубликаты продолжают появляться, у меня много пользователей — более 300 тысяч.
Есть ли способ проверить, сколько дубликатов, или вывести их все?
Для исправления я обновлял поле username_lower следующим образом: добавлял номер в конец.
UPDATE users SET username_lower = 'xxx' WHERE id = xxx;
Нужно ли мне также обновлять столбец username, чтобы он соответствовал username_lower? Есть ли более быстрый способ, например, автоматическое исправление этих дубликатов?
Мой сайт сейчас недоступен, поэтому любая помощь будет крайне ценна.
Насколько мне известно, такого способа нет. Думаю, это не должно происходить. С какой версии вы обновляетесь?
Может, стоит поискать пользователей, где username != username_lower?
Он упал, хотя вы запустили приложение?
Нет. Допустимо, чтобы имя пользователя содержало буквы разного регистра, но нельзя иметь два имени пользователя с одинаковыми буквами.
Дело в том, что у вас есть и Joe, и joe? Если так, то, думаю, должен существовать запрос, который найдёт их, но я не знаю, как его составить прямо сейчас.
Спасибо, Джей.
Мне удалось пересобрать систему и снова запустить свой сайт.
Как вы и советовали, решение заключается в повторении цикла: перестроить индекс, исправить ошибки и повторять до завершения. Я использовал следующую команду, чтобы узнать количество:
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 дубликатов. Я исправил их, перестроил индекс, и сборка прошла успешно.