이 작업을 완료했고, Postgres(그리고 Discourse!)도 문제없는 것 같습니다.
수동으로 정리하면서, 적절한 경우 ** 패턴을 사용해 URL을 고유하게 만들었습니다. 단순히 중복 항목을 삭제해도 되는 해로운 캐시일 수도 있었지만, 위험을 감수하고 싶지 않았습니다.
제 경우에는 인덱스가 하나뿐이었기 때문에 모든 인덱스를 재구성하는 것은 과잉 대응이었을 수 있지만, 솔직히 모든 문제를 포착했다는 확신이 들었으니 마음이 놓였습니다.
재구성을 여러 번 실패한 후, 각 실행에 약 30초가 걸리며 문제가 하나씩 보고되었는데, 이때 즉시 문제 항목의 전체 목록을 가져오기 위해 사용했던 제 SQL 마법은 다음과 같습니다:
discourse=# select topic_id, post_id, url, COUNT(*) from topic_links GROUP BY topic_id, post_id, url HAVING COUNT(*) > 1 order by topic_id, post_id;
topic_id | post_id | url | count
----------+---------+-------------------------------------------------------+-------
19200 | 88461 | http://hg.libsdl.org/SDL/rev/**533131e24aeb | 2
19207 | 88521 | http://hg.libsdl.org/SDL/rev/44a2e00e7c66 | 2
19255 | 88683 | http://lists.libsdl.org/__listinfo.cgi/sdl-libsdl.org | 2
19255 | 88683 | http://lists.libsdl.org/**listinfo.cgi/sdl-libsdl.org | 2
19523 | 90003 | http://twitter.com/Ironcode_Gaming | 2
(5 rows)
(예를 들어, 이 쿼리에서 남은 문제 항목은 5개입니다.)
그 다음 각 게시물을 확인하여 무엇이 있는지, 무엇을 수정해야 하는지 살펴봤습니다:
select * from topic_links where topic_id=19255 and post_id=88683
그리고 그중 하나를 수정했습니다:
update public.topic_links set url='http://lists.libsdl.org/__listinfo.cgi/**sdl-libsdl.org' where id=275100;
수정할 항목이 없도록 될 때까지 반복했습니다. ![]()
내부 조인(inner-join) 마법(또는 아마도 조금의 Ruby)으로 이 모든 것을 하나의 쿼리로 처리할 수도 있었겠지만, 저는 전문가가 아니었고 수동으로 처리하는 데 _수 시간_이 걸리지는 않았습니다. 하지만 분명히 지루한 작업이었습니다. ![]()
그 후 CONCURRENTLY 없이 REINDEX DATABASE discourse;를 실행하여 간단하게 유지했고, 이전에 놓친 몇 개의 ccnew* 인덱스를 제거한 후 모든 것이 정상화되었습니다.
사이트는 내내 라이브 상태였으며, 다운타임은 없었습니다.
이것이 _필요_했는지는 모르겠지만, 제 데이터가 조금 더 안전해졌다고 확실히 느끼고 있으며, 예고 없이 찾아올 미래의 재앙으로 치닫고 있다는 느낌은 없습니다.
이 문제를 해결하는 데 올바른 방향으로 이끌어준 @pfaffman님께 감사드립니다.