오늘 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년 사이에 삽입된 것 같습니다.
이러한 상황이 다시 발생할 수 있을지 확실하지 않습니다.
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.
알고 있고, 이 문제는 Discourse나 업그레이드 자체에 대한 것이 아닙니다. 이런 일은 일어나고 괜찮습니다.
다만 도커, 루비, 포스트그레SQL, 디스코스 등 너무 많은 주제와 씨름해야 하는 막힌 상황에 처해 있기를 원하지는 않습니다. 제 일상 업무가 아니고 시간적인 투자가 되기 때문입니다.
손가락을 깨물고 인셉션 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이 작동해야 합니다.
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';
그러면 위 게시물에서 볼 수 있는 테이블이 표시됩니다.
저는 hws-connect 태그를 hws-connect1로 이름 변경했습니다.
UPDATE tags SET name = 'hws-connect1' WHERE name='hws-connect';
뒤로 몇 번 차면서 인셉션에서 빠져나오세요: \q로 postgres를 나옵니다. exit로 도커 컨테이너를 나옵니다.
저도 이 문제에 걸려 있습니다. 수동 수정 방법을 공유해 주셔서 감사합니다. 그 방법을 참고해서 내 머릿속으로만 있던 약 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.