3.0.0에서 3.0.1로 업데이트하는 중 문제 발생

안녕하세요,

오늘 Discourse 앱을 3.0.1로 업데이트했습니다. Postgres 마이그레이션을 처리하는 동안 업데이트가 실패했습니다.
구체적으로는 여기에서 문제가 발생했습니다:

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) already exists.
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: An error has occurred, this and all later migrations canceled:

일부 태그가 중복된 것으로 보였습니다. Postgres에 연결하여 태그를 수정했습니다. 이후 마이그레이션과 업데이트가 정상적으로 완료되었습니다.

질문은, 데이터베이스(DB)를 직접 건드린 제 처리 방식이 올바른 것이었는지 하는 것입니다. 저는 중복된 태그의 이름만 변경했습니다.
중복 태그가 어떻게 생성되었는지는 알 수 없습니다. 지난 2~3년 사이에 삽입된 것 같습니다.
이러한 상황이 다시 발생할 수 있을지 확실하지 않습니다.

저도 같은 문제가 있습니다

정확히 동일한 증상이 나타났나요?

ERROR:  duplicate key value violates unique constraint "index_tags_on_name"
DETAIL:  Key (name)=(e-mail) already exists.

네. 중복된 태그 / index_tags_on_name 때문이기도 합니다.
제 경우에는 태그 이름이 다를 뿐입니다.

현재 파악 중입니다:

  • web-push가 2.6.7이라서 ruby를 3.0.0으로 업그레이드하는 방법을 알아보고 있습니다. 그래서 rails c에 진입조차 못 해서 태그를 수정하는 복잡한 명령어를 실행할 수 없습니다.
  • postgres 데이터베이스에서 태그를 안전하게 삭제하는 방법도 아직 모르겠습니다.

오류가 발생한 로그의 해당 부분을 게시해 주세요!

이 중복된 키 값이 어떻게 생성되었는지 파악하는 데 도움이 될 수 있으므로, 더 자세한 정보를 제공해 주시면 감사하겠습니다.

데이터베이스 복구에는 도움을 드릴 수 없습니다.

루비 문제의 경우, 커맨드 라인 업그레이드(*)를 수행해야 한다고 생각합니다. 예를 들어 아래를 참고하세요.

(*) 수정: 하지만 아래를 참고하세요. 현재 데이터베이스 상태로는 업그레이드가 실패합니다. 실수였습니다.

I, [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:  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.
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: An error has occurred, this and all later migrations canceled:

PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "index_tags_on_name"
DETAIL:  Key (name)=(hws-connect) already exists.

이 오류는 태그가 3개의 주제에서 발견되는 것 같아서 3번 발생했습니다.

이런 일이 일어날 줄 알았으면 태그를 활성화하지 않았을 텐데, 프론트엔드에 이에 대한 경고가 왜 없었는지 모르겠습니다.
그냥 태그를 삭제하고 마침내 제 포럼을 다시 띄우고 싶습니다 :cold_sweat:

앱은 원하는 만큼 재빌드할 수 있습니다. 하지만 오류가 발생하면서 프로세스가 중단됩니다. 따라서 Ruby는 업그레이드되지 않은 상태 그대로입니다.
결국 막혀버린 셈입니다.

안녕하세요,

like를 사용한 select를 시도해 보세요:
SELECT * FROM tags WHERE name LIKE '%hws-connect%'

같은 이름의 태그가 여러 개 발견될 것입니다. 제 경우에도 그 문제가 원인이었습니다.

select를 수행했습니다:

질문은 데이터베이스에서 “hws-connect” 태그를 이름 변경할 때 Discourse 인프라가 손상되지 않는지 여부입니다.
그리고… postgres를 통해 어떻게 이름 변경할 수 있나요?

자, 몇 가지 말씀드릴게요:

  • 수백억 원대 소프트웨어(매우 도움이 되는 커뮤니티의 지원을 받으며)를 (거의) 무료로 사용하는 자체 설치 환경에서는 가끔 발생하는 이상 현상을 감수하셔야 합니다.
  • 최근 태그를 많이 사용하는 두 사이트를 업데이트했는데, 아무런 문제가 없었습니다.
  • 여러 Discourse 인스턴스를 5년 이상 운영해 온 제 경험상, 이런 문제는 한 번도 겪어 본 적이 없는 것 같습니다.

어쨌든, 이 문제와 매우 유사해 보입니다. 비슷한 전략을 사용하여 해결해 보실 수 있습니다:

이미 올바른 방향으로 가고 계신 것 같습니다. 그냥 그 길을 끝까지 따라가시면 됩니다 …

알고 있고, 이 문제는 Discourse나 업그레이드 자체에 대한 것이 아닙니다. 이런 일은 일어나고 괜찮습니다.
다만 도커, 루비, 포스트그레SQL, 디스코스 등 너무 많은 주제와 씨름해야 하는 막힌 상황에 처해 있기를 원하지는 않습니다. 제 일상 업무가 아니고 시간적인 투자가 되기 때문입니다.

링크를 공유해 주셔서 감사합니다!
상태를 업데이트하겠습니다.

업데이트: @merefield 님의 주제에서 가장 큰 수확은

나는 용감해야겠군

:smiley:
DB에서 직접 건드리는 일은 항상 두렵지만, 이번에는 잘 작동했습니다.

같은 문제(중복 태그 / index_tags_on_name)를 겪고 있는 분들을 위해:

  1. 손가락을 깨물고 인셉션 1단계 시작:
    cd /var/discourse
    sudo ./launcher enter app

    만약 “no docker container running” 같은 오류로 실패한다면 다음을 입력하세요.
    sudo docker ps -a --no-trunc
    이 명령은 사용 가능한 도커 컨테이너와 ID를 나열합니다. 해당 ID로 컨테이너를 재시작하세요.
    sudo docker restart <container ID>
    그 다음 sudo ./launcher enter app이 작동해야 합니다.

  2. postgres DB에 접근하고 인셉션 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로 도커 컨테이너를 나옵니다.

  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