Проблемы при обновлении с 3.0.0 до 3.0.1

Привет,

сегодня я обновил наше приложение Discourse до версии 3.0.1. Обновление не удалось из-за ошибки при выполнении миграции PostgreSQL.
В частности, здесь:

2023-01-27 04:50:48.628 UTC [483] discourse@discourse ERROR:  duplicate key value violates unique constraint "index_tags_on_name"
2023-01-27 04:50:48.628 UTC [483] discourse@discourse DETAIL:  Key (name)=(e-mail) уже существует.
2023-01-27 04:50:48.628 UTC [483] discourse@discourse STATEMENT:  UPDATE tags t
	SET public_topic_count = x.topic_count
	FROM (
	  SELECT
	    COUNT(topics.id) AS topic_count,
	    tags.id AS tag_id
	  FROM tags
	  INNER JOIN topic_tags ON tags.id = topic_tags.tag_id
	  INNER JOIN topics ON topics.id = topic_tags.topic_id AND topics.deleted_at IS NULL AND topics.archetype != 'private_message'
	  INNER JOIN categories ON categories.id = topics.category_id AND NOT categories.read_restricted
	  GROUP BY tags.id
	) x
	WHERE x.tag_id = t.id
	AND x.topic_count <> t.public_topic_count;
	
rake aborted!
StandardError: Произошла ошибка, эта и все последующие миграции отменены:

Кажется, что некоторые теги были дубликатами. Я подключился к PostgreSQL и исправил теги. После этого миграция и обновление прошли успешно.

Мой вопрос: правильно ли я поступил, вмешиваясь в базу данных? Я изменил только имена дублирующихся тегов.
Не могу сказать, как появились дублирующиеся теги. Они были добавлены примерно за последние 2–3 года.
Не уверен, что такая ситуация может повториться.

У меня та же проблема

Вы столкнулись с точно таким же симптомом?

ERROR:  значение дублирующегося ключа нарушает уникальное ограничение "index_tags_on_name"
DETAIL:  Ключ (name)=(e-mail) уже существует.

Да. Это также связано с дублированием тегов / index_tags_on_name.
В моём случае тег просто назван по-другому.

Сейчас пытаюсь разобраться:

  • как обновить Ruby до версии 3.0.0, так как возникает ошибка: gem web-push версии 2.6.7 не совместим, из-за чего я даже не могу запустить rails c, чтобы выполнить команды для исправления тегов
  • как безопасно удалить тег из базы данных PostgreSQL, но пока нет идей

Пожалуйста, опубликуйте фрагмент лога, который показывает ошибку в вашем случае!

Если кто-то когда-нибудь узнает, как появились эти дублирующиеся значения ключей, он оценит больше деталей.

Извините, но я не могу помочь с исправлением базы данных.

Что касается проблемы с Ruby, я думаю, вам нужно выполнить обновление через командную строку (*). Например, посмотрите:

(*) Редакция: но см. ниже, обновление не удаётся с текущим состоянием базы данных. Ой.

Я, [2023-01-27T07:46:34.317438 #1]  INFO -- : > cd /var/www/discourse && su discourse -c 'bundle exec rake db:migrate'
2023-01-27 07:46:45.663 UTC [584] discourse@discourse ERROR:  дублирующее значение ключа нарушает уникальное ограничение "index_tags_on_name"
2023-01-27 07:46:45.663 UTC [584] discourse@discourse DETAIL:  Ключ (name)=(hws-connect) уже существует.
2023-01-27 07:46:45.663 UTC [584] discourse@discourse STATEMENT:  UPDATE tags t
        SET public_topic_count = x.topic_count
        FROM (
          SELECT
            COUNT(topics.id) AS topic_count,
            tags.id AS tag_id
          FROM tags
          INNER JOIN topic_tags ON tags.id = topic_tags.tag_id
          INNER JOIN topics ON topics.id = topic_tags.topic_id AND topics.deleted_at IS NULL AND topics.archetype != 'private_message'
          INNER JOIN categories ON categories.id = topics.category_id AND NOT categories.read_restricted
          GROUP BY tags.id
        ) x
        WHERE x.tag_id = t.id
        AND x.topic_count <> t.public_topic_count;

rake aborted!
StandardError: Произошла ошибка, эта и все последующие миграции отменены:

PG::UniqueViolation: ERROR:  дублирующее значение ключа нарушает уникальное ограничение "index_tags_on_name"
DETAIL:  Ключ (name)=(hws-connect) уже существует.

Эта ошибка появляется 3 раза, так как тег, похоже, найден в 3 темах.

Жалею, что включил теги, если знал бы, что так произойдет, и почему на фронтенде не было предупреждения об этом.
Я просто хочу удалить их и наконец снова запустить свой форум :cold_sweat:

Я могу пересобрать приложение сколько угодно раз. Я получаю ошибку, и процесс прерывается. Таким образом, Ruby не обновляется.
По сути, я застрял.

Привет,

попробуй выполнить запрос типа:
SELECT * FROM tags WHERE name LIKE '%hws-connect%'

Ты найдёшь несколько тегов с одинаковым именем. В моём случае проблема была именно в этом.

Я выполнил выборку:

Мой вопрос: можно ли переименовать тег «hws-connect» в базе данных, не нарушив работу инфраструктуры Discourse?
И… как это можно сделать через PostgreSQL?

Хорошо, несколько моментов:

  • вам придется смириться с редкими сбоями при использовании собственной установки многомилионного программного обеспечения (поддерживаемого очень полезным сообществом), которое вы получили почти бесплатно
  • я недавно обновил два сайта, которые активно используют теги, и у меня не возникло никаких проблем
  • за более чем 5 лет работы с несколькими экземплярами Discourse, думаю, я сталкивался с подобной проблемой лишь один раз?

В любом случае, это очень похоже на эту проблему, возможно, вы сможете использовать аналогичную стратегию для её решения?:

Похоже, вы уже были на правильном пути, вам просто нужно довести дело до конца…

Я понимаю, и это не имеет никакого отношения к дискуссии или самому обновлению. Такое случается, и это нормально.
Просто хотелось бы не попадать в ситуацию, когда приходится разбираться с таким количеством тем (Docker, Ruby, PostgreSQL, Discourse). Это не моя повседневная работа, и это требует временных затрат.

Спасибо за ссылку!
Обновлю свой статус.

Обновление: лучший вывод по вашей теме от @merefield был

Я думаю, мне стоит проявить смелость

:smiley:
Работа с базой данных всегда пугает меня, но в данном случае всё получилось.

Для тех, у кого возникла аналогичная проблема (дубликаты тегов / index_tags_on_name):

  1. Разомните пальцы и приступайте к этапу «Начало» Phase 1:
    cd /var/discourse
    sudo ./launcher enter app

    Если это не сработает и вы получите сообщение вроде «no docker container running» или подобное, выполните:
    sudo docker ps -a --no-trunc
    Это выведет список доступных контейнеров Docker и их ID. Затем перезапустите нужный контейнер:
    sudo docker restart <container ID>
    После этого команда sudo ./launcher enter app должна сработать.

  2. Получите доступ к вашей базе данных PostgreSQL и приступайте к этапу «Начало» Phase 2:
    su discourse
    psql
    Лог ошибки при перестройке должен был указать имя проблемного тега. В моём случае это было:

     ERROR:  duplicate key value violates unique constraint "index_tags_on_name"
    2023-01-27 07:46:45.663 UTC [584] discourse@discourse DETAIL:  Key (name)=(hws-connect) already exists.
    

    Сначала найдите свой тег с помощью:

    select * from tags where name='hws-connect'; 
    

    Это покажет строку таблицы, которую вы можете увидеть выше в моих сообщениях.

  3. Я просто переименовал тег hws-connect в hws-connect1 с помощью:

    UPDATE tags SET name = 'hws-connect1' WHERE name='hws-connect';
    
  4. Выйдите из «Начала», сделав несколько шагов назад:
    \q — выход из postgres
    exit — выход из контейнера docker

  5. Выполните перестройку снова: sudo ./launcher rebuild app

  6. Порадуйтесь успеху и проверьте результат на фронтенде:
    Перейдите на страницу тегов: https://your-forum/tags

Я не имею ни малейшего представления, как это произошло и почему это обновление прошло так неудачно — все предыдущие работали, будь то через веб-интерфейс или терминал.
Теперь займусь очисткой своих тегов.

Бонус:

  1. Нажмите на переименованный тег.
  2. Удалите его из всех тем. В моём случае их было 3.
  3. Вернитесь на страницу тегов и воспользуйтесь функцией в правом верхнем углу:

Всё готово. :v:
Спасибо всем за помощь, ребята.

Молодец! Отличная работа!

Отличное объяснение (и проявленная смелость), спасибо!

На моих форумах тоже используются теги, как и здесь — их очень много:
https://meta.discourse.org/tags

Очевидно, что что-то редкое и неприятное может произойти, из-за чего возникнет дублирование значения ключа.

У меня тоже эта проблема. Спасибо за то, что поделились своими ручными исправлениями — я только что использовал их, чтобы исправить около 20 таких случаев.

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

  id   |          name          |         created_at         
-------+------------------------+----------------------------
   707 | ParkRide               | 2019-05-21 21:36:53.213993
 18982 | ParkRide               | 2020-06-05 18:43:09.409895

(Да, между ними есть разница в пробелах)

Теперь я застрял на последнем дубликате, который невозможно исправить:

discourse=> select name from tags group by name having count(*) > 1; 
    name    
------------
 Bike--Ride
(1 row)

discourse=> UPDATE tags SET name = 'Bike--Ride_2' WHERE name = 'Bike--Ride';
ERROR:  duplicate key value violates unique constraint "index_tags_on_name"
DETAIL:  Key (name)=(Bike--Ride_2) already exists.
discourse=> UPDATE tags SET name = 'Bike--Ride_3' WHERE name = 'Bike--Ride';
ERROR:  duplicate key value violates unique constraint "index_tags_on_name"
DETAIL:  Key (name)=(Bike--Ride_3) already exists.
discourse=> UPDATE tags SET name = 'something is broken here' WHERE name = 'Bike--Ride';
ERROR:  duplicate key value violates unique constraint "index_tags_on_name"
DETAIL:  Key (name)=(something is broken here) already exists.

При обновлении возникает ошибка:

2023-02-01 18:56:58.610 UTC [475] discourse@discourse ERROR:  duplicate key value violates unique constraint "index_tags_on_name"
2023-02-01 18:56:58.610 UTC [475] discourse@discourse DETAIL:  Key (name)=(Bike--Ride) already exists.

Есть ли идеи, как обойти эту проблему?

Хочу сказать спасибо! Это помогло мне в обновлении!

У меня была та же ошибка — независимо от того, какое новое имя тега я использовал, система сообщала, что оно уже существует. Я обошёл это, обновив тег по его ID вместо столбца с именем:

UPDATE tags SET name = 'tag1' WHERE id = 1234