안녕하세요,
포럼을 새 서버로 이주하려고 하고 있습니다. 두 서버 모두 최신 버전의 discourse docker를 실행 중입니다. 명령줄을 통해 백업을 가져올 때 다음과 같은 오류가 발생합니다:
ERROR: could not create unique index "index_incoming_referers_on_path_and_incoming_domain_id"
DETAIL: Key (path, incoming_domain_id)=(/search/, 418) is duplicated.
EXCEPTION: psql failed: DETAIL: Key (path, incoming_domain_id)=(/search/, 418) is duplicated.
이것은 다음과 같은 오류와 동일하거나 유사한 것 같습니다:
I have a duplicate key issue also, is there a documented fix?
discourse=# REINDEX SCHEMA CONCURRENTLY public;
ERROR: could not create unique index "index_incoming_referers_on_path_and_incoming_domain_id_ccnew"
DETAIL: Key (path, incoming_domain_id)=(/search/, 1905) is duplicated.
[1] pry(main)> IncomingReferer.where(path: "/m/search")
=> [#<IncomingReferer:0x0000557176d3f210 id: 44231, path: "/m/search", incoming_domain_id: 4>,
#<IncomingReferer:0x0000557176d925c8 id: 42228, path: "/m/…
그러나 제 경우, 중복된 레코드는 위에서 링크된 스레드에서와 같이 /m/search가 아니라 /search/ 경로에 있습니다.
저는 구 서버의 컨테이너(./launcher enter app)에 연결하여 Rails 콘솔(rails c)에서 다음을 사용하여 중복된 레코드를 검색해 보았습니다:
IncomingReferer.where(path: "/search")
그리고
IncomingReferer.where("path LIKE '%/search%'")
그러나 이렇게 하면 수백 개의 레코드가 표시됩니다. 어떤 레코드가 중복된 것인지 어떻게 파악할 수 있으며, 이 레코드들을 안전하게 삭제하고 다시 구성할 수 있을까요? 현재 포럼은 구 서버에서 정상적으로 작동하고 있으며, 단순히 새 하드웨어로 이전해야 하는 상황입니다.
아니요, GUI를 통해 가져오면 동일한 가져오기 프로세스가 실행되는 줄 알았거든요. 이제 시도해 보겠습니다.
pfaffman
(Jay Pfaffman)
10월 31, 2021, 11:24오후
4
인덱스가 손상된 것 같습니다. 어떤 버전의 Postgres를 사용하고 계신가요?
아래와 같은 명령을 실행해 보세요:
cd /var/discourse
cat shared/standalone/postgres_data/PG*
(정확한 Postgres 파일명을 기억이 나지 않습니다.)
여기서 "postgres corrupt index"를 검색하면,我曾经이 그런 문제 기록을 찾아내고 삭제하는 방법에 대해 작성했던 주제를 찾을 수 있습니다.
기본적으로 해당 인덱스를 재구성한 다음, 오류가 보고된 기록을 삭제하고 다시 인덱스를 재구성해 보는 과정을 반복합니다.
방금 GUI를 통해 가져오기를 시도해 보았는데, 정확히 동일한 결과가 나왔습니다:
구 서버에는 PG_VERSION이라는 파일이 없는데, 어떤 버전이 실행 중인지 어떻게 알 수 있을까요? 오늘 docket 설치를 최신 버전으로 업데이트했습니다.
새 서버(새로 부트스트랩된 것)는 postgres V13을 실행 중입니다.
cat shared/standalone/postgres_data/PG_VERSION
13
pfaffman:
여기서 “postgres corrupt index”를 검색하면, 잘못된 레코드를 추적하고 삭제하는 방법에 대해 제가 이전에 작성한 토픽을 찾을 수 있습니다.
기본적으로 해당 인덱스를 다시 구축하고, 오류가 발생하는 레코드를 삭제한 후 다시 인덱스를 재구성하는 것을 반복하여 성공적으로 재구성될 때까지 진행합니다.
이를 수행하는 권장 절차가 있나요?
pfaffman
(Jay Pfaffman)
11월 1, 2021, 12:33오전
6
힌트가 포함된 주제가 하나 있었는데, 지금은 더 이상 보이지 않습니다. postgres 12 업그레이드 이후 거의 1년이 지났습니다.
reindex index index_incoming_referers_on_path_and_incoming_domain_id;
그리고
ActiveRecord::Base.connection.execute('reindex index index_incoming_referers_on_path_and_incoming_domain_id;')
은 인덱스를 재구성하기 위한 방법입니다. 오류가 발생하면 해당 오류를 확인하여 잘못된 기록을 삭제할 수 있습니다. path와 ID를 모두 포함해야 합니다.
네, 해결했습니다. 다음 작업을 수행했습니다
컨테이너에 진입
./launcher enter app
데이터베이스에 연결
su postgres -c 'psql discourse'
중복 항목을 찾아보기
discourse=# select * from incoming_referers where path LIKE '%/search/' ORDER BY incoming_domain_id;`
id | path | incoming_domain_id
------+------------+--------------------
3339 | /search/ | 33
6257 | /search/ | 91
1567 | /search/ | 298
1777 | /search/ | 341
3010 | /search/ | 418
6247 | /search/ | 418
4293 | /search/ | 644
2899 | /search/ | 653
3447 | /search/ | 793
3696 | /search/ | 852
4395 | /a/search/ | 1050
6968 | /search/ | 1305
5634 | /search/ | 1387
5834 | /search/ | 1437
6519 | /search/ | 1637
7127 | /search/ | 1787
7280 | /search/ | 1827
(17 rows)
중복 항목 삭제
DELETE FROM incoming_referers WHERE path LIKE '%/search/' AND id IN (6247);
그 다음 재인덱싱 수행
discourse=# REINDEX SCHEMA CONCURRENTLY public;
WARNING: cannot reindex invalid index "public.incoming_referers_pkey_ccnew" concurrently, skipping
WARNING: cannot reindex invalid index "public.index_incoming_referers_on_path_and_incoming_domain_id_ccnew" concurrently, skipping
WARNING: cannot reindex invalid index "pg_toast.pg_toast_20732_index_ccnew" concurrently, skipping
REINDEX
그 후 백업을 한 번 더 생성하고, 새 서버로 복사한 뒤 성공적으로 가져왔습니다
백업 과정에서 중복 항목을 감지하여 문제를 방지할 수 있다면 좋겠습니다. 다행히도 여전히 실행 중인 원래 서버에 접근할 수 있었기 때문에 문제가 되지 않았습니다. 만약 콜드 백업(정지된 상태의 백업)을 복원하는 상황이었다면 훨씬 더 큰 문제가 되었을 것입니다.
도와주셔서 정말 감사합니다.