Как выполнять SQL-запросы, если контейнер не запускается? (сбой пересборки)

Здравствуйте.

Я попытался запустить обновления и перестроить систему, но получил вот эту интересную ошибку:

I, [2023-01-18T08:05:48.701709 #1]  INFO -- : > cd /var/www/discourse && su discourse -c 'LOAD_PLUGINS=0 bundle exec rake plugin:pull_compatible_all'
I, [2023-01-18T08:05:52.431210 #1]  INFO -- :
I, [2023-01-18T08:05:52.431807 #1]  INFO -- : > cd /var/www/discourse && su discourse -c 'bundle exec rake db:migrate'
2023-01-18 08:05:59.081 UTC [1166] discourse@discourse ERROR:  could not create unique index "index_tags_on_name_ccnew_ccnew_ccnew5"
2023-01-18 08:05:59.081 UTC [1166] discourse@discourse DETAIL:  Key (name)=(vuejs) is duplicated.
2023-01-18 08:05:59.081 UTC [1166] discourse@discourse STATEMENT:  REINDEX INDEX CONCURRENTLY index_tags_on_name_ccnew_ccnew
rake aborted!
StandardError: An error has occurred, all later migrations canceled:

PG::UniqueViolation: ERROR:  could not create unique index "index_tags_on_name_ccnew_ccnew_ccnew5"
DETAIL:  Key (name)=(vuejs) is duplicated.
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/pg.rb:110:in `exec'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/pg.rb:110:in `async_exec'

На форуме есть другие темы с похожими проблемами (1, 2, 3), но когда я пытаюсь войти в контейнер, получаю следующее:

/var/discourse# ./launcher enter app
x86_64 arch detected.
Error: No such container: app

Поэтому я не могу вручную удалить индексы.

Есть ли другие предложения, какой подход стоит выбрать дальше?

Привет, Йонуц,

Спасибо за отчет об ошибке. Я изучу эту проблему, но, по-видимому, в вашей базе данных есть проблема с индексом, и недавняя миграция пыталась её исправить. Однако некоторые проблемы невозможно устранить без вмешательства человека.

Считаю, что коммит, который добавил эту миграцию и привёл к сбою, — это следующий:

Вы можете попробовать зафиксировать ваш экземпляр Discourse на предыдущей версии — коммите 690e2f15ab9549486aaa6750e1093c1336bf17f2. Отредактируйте файл app.yml и установите ключ version в секции params. Не забудьте также раскомментировать этот ключ!

После этого всё должно запуститься, и вы сможете удалить дублирующийся тег vuejs. Однако это может привести к нежелательным последствиям, если дублирующийся тег уже используется. Мы постараемся найти более подходящее решение, но до тех пор этот вариант должен сработать.

После загрузки мне удалось найти все дубликаты тегов с помощью плагина Data Explorer:

SELECT name, count(*)
    FROM tags 
    GROUP BY name
     HAVING count(*) > 1

По какой-то причине оказалось около десяти дубликатов тегов. Интересно, почему и как они вообще там появились…

Удалось избавиться от этих проблем: снял блокировку версии из файла yml, пересобрал проект, теперь всё выглядит хорошо.

Спасибо!

:+1:

Мы сталкивались с этим раньше. Это кошмарная проблема, но мы выяснили, что она связана с обновлениями.

Структура индексов в PostgreSQL зависит от локали, установленной в момент установки, и обновления иногда могут превращаться в настоящий кошмар.

https://github.com/docker-library/postgres/issues/582

Если перестроение индексов (reindex) не выполнить достаточно рано, могут возникнуть проблемы. Некоторые из наших более ранних обновлений Docker с PostgreSQL не выполняли эту процедуру… и, к сожалению, в некоторых старых установках это как бомба замедленного действия.

В экосистеме эта проблема в основном решена на сегодняшний день, но некоторые неудобства всё ещё сохраняются.

Возможно, это поможет дополнительно выявить причину, поэтому вот ещё некоторые детали о системе:

Установка действительно старая, с 2014 года, но система обновляется как минимум раз в месяц (хотя обычно — каждые две недели). Таким образом, мы никогда не пропускали крупные версии.

Нет блокировки версий, поэтому по сути мы работаем на последней доступной версии в ветке main (YOLO!)

Хотя некоторое время назад мы пробовали несколько неофициальных плагинов, все установленные плагины являются официальными, и так было уже последние… 5 лет или больше.

У меня та же проблема, я следовал вашим инструкциям до этого предложения.

Как именно удалять дубликаты? Просто выполнив SQL-запрос delete в Data Explorer? А что насчет записей во внешних таблицах, указывающих на этот тег?

Обновление 1

Понял, что выполнять операторы update нельзя.

Теперь я использовал графический интерфейс и просто переименовал тег.

Отредактируйте тег (перейдя по адресу /tag/foo) и либо переименуйте его, либо удалите.