백업 복원 실패

다음과 같은 문제가 발생했습니다. 10년 넘게 Discourse 포럼을 운영해 왔는데, 최근 업데이트를 설치하지 못해 새 서버를 설정하려 했습니다:

기존 서버 실행 버전: 3.4.0.beta4-dev

새 서버: 최신 버전

업로드를 제외하고도 백업 파일의 크기가 이미 .gz 형식으로 673.2MB입니다.

불행히도 복원 작업이 계속 중단됩니다. 로그 파일에는 다음과 같은 오류가 포함되어 있습니다.

[2026-06-16 07:54:52] ERROR:  could not create unique index “index_incoming_referers_on_path_and_incoming_domain_id”
[2026-06-16 07:54:52] DETAIL:  Key (path, incoming_domain_id)=(//, 5) is duplicated.
[2026-06-16 07:54:52] EXCEPTION: psql failed: DETAIL:  Key (path, incoming_domain_id)=(//, 5) is duplicated.

[2026-06-16 07:54:52] /var/www/discourse/lib/backup_restore/database_restorer.rb:93:in 'BackupRestore::DatabaseRestorer#restore_dump'
/var/www/discourse/lib/backup_restore/database_restorer.rb:26:in ‘BackupRestore::DatabaseRestorer#restore’
/var/www/discourse/lib/backup_restore/restorer.rb:61:in 'BackupRestore::Restorer#run'
/var/www/discourse/script/spawn_backup_restore.rb:20:in ‘Object#restore’
/var/www/discourse/script/spawn_backup_restore.rb:33:in ‘block in ’
/var/www/discourse/script/spawn_backup_restore.rb:4:in 'Kernel#fork'
/var/www/discourse/script/spawn_backup_restore.rb:4:in ‘’
[2026-06-16 07:54:52] Trying to rollback...

이 문제를 해결하고 지난 10년간의 데이터를 잃지 않으려면 어떻게 해야 할까요?

도움 주시면 감사하겠습니다!

안녕하세요, 그리고 9년 만에 다시 돌아오셨네요!

이렇게 오랫동안 운영 중인 포럼을 보니 정말 멋집니다.

이것은 아마도 여기에서 논의되었던 것과 동일한 인덱스 문제일 것 같습니다: Can't restore due to corrupt indexes (with some clues on how to deal with corrupt indexes)

대략 다음과 같은 상황입니다:

incoming_referers 테이블은 방문자를 포럼으로 유도한 URL 경로를 추적합니다. 이 테이블에는 고유 인덱스가 있어 두 행이 동일한 경로 + 도메인 조합을 가질 수 없습니다.

데이터베이스에는 path='//'이고 incoming_domain_id=5인 두 개의 행이 있습니다. 복원 과정에서 이 고유 인덱스를 다시 구축하려고 할 때 중복 항목을 발견하고 전체 복원 트랜잭션을 중단합니다.

따라서 중복된 incoming_referers를 찾아 정리한 후, 새 서버에 복원할 수 있도록 새로운 백업을 만들어야 합니다.

도움이 될 수 있는 설명서가 포함된 이 주제를 찾았습니다.

빠른 답변에 정말 감사합니다! 한번 시도해 볼게요!

죄송합니다만, 제가 뭔가 잘못하고 있는 것 같습니다. “discourse=# select * from incoming_referers where path LIKE ‘%/search/’ ORDER BY incoming_domain_id;” 명령을 실행한 후 구문 오류가 발생하고 있습니다.

"discourse=#"를 입력하셨나요? 그렇다면 해당 부분을 생략하고 다시 시도해 보세요.

그런 다음 "bash: syntax error near unexpected token `from’"라는 오류 메시지가 표시됩니다.

참고로 현재 위치는 root@community-app:/var/www/discourse# 입니다.

아, 아직 데이터베이스에 들어가지 않은 상태군요.

먼저 psql -U discourse discourse를 실행해 보세요 (이렇게 해야 할 것 같습니다).

그럼 프롬프트가 discourse=#로 변경되어야 합니다.

네, 이제 “apt install postgresql-client-common.”도 설치했습니다. 하지만 여전히 “Error: You must install at least one postgresql-client- package.”라는 오류가 나고 있습니다.

음, 그건 저도 잘 모르겠네요.

그렇다면 rails 콘솔을 통해 직접 시도해 보세요: rails c

다음과 같이 실행하면 됩니다.

ActiveRecord::Base.connection.execute(<<~SQL)
  SELECT id, path, incoming_domain_id 
  FROM incoming_referers 
  WHERE path = '//' 
  AND incoming_domain_id = 5
SQL

이렇게 하면 데이터베이스를 거치지 않고 동일한 결과를 얻을 수 있을 것입니다.

이 방법으로 동작하나요?

정말 멍청하게 행동해서 정말 죄송합니다.

이제 Rails를 설치했는데, 잘 작동하는 것 같습니다. 또한 “rails c”로 실행해 보았는데, 이것도 작동하는 것 같지만 명령어를 입력하면 다음과 같은 모습이 나옵니다:

“root@community:/var/discourse# ActiveRecord::Base.connection.execute(<<~SQL)
-bash: syntax error near unexpected token `<<’
root@community:/var/discourse# SELECT id, path, incoming_domain_id
SELECT: command not found
root@community:/var/discourse# FROM incoming_referers
FROM: command not found
root@community:/var/discourse# WHERE path = ‘//’
WHERE: command not found
root@community:/var/discourse# AND incoming_domain_id = 5
AND: command not found
root@community:/var/discourse# SQL”

걱정하지 마세요, 아마 제 설명이 좀 부족했던 것 같네요 :slight_smile:

Rails를 방금 설치했는데 DB에 접근할 수 없다고 하시니 저도 좀 혼란스럽습니다. 구버전이라 상황이 모두 다를 수도 있지만, 저도 이제 한계를 느끼는 것 같습니다.

어쨌든 rails에 들어가시면 프롬프트가 다르게 표시되어야 하는데, 출력 결과를 보면 아직 rails 콘솔에 들어가지 않은 것으로 보입니다.

사실 실제 컨테이너 안에도 들어가지 않은 것 같습니다. ./launcher enter app를 실행해 보셨나요?

아, 맞아요. 그게 문제였네요. 이제 쿼리가 성공적으로 실행되었고, 다음과 같은 응답을 받았습니다:

#<PG::Result:0x00007fbde9732ef0 status=PGRES_TUPLES_OK ntuples=1 nfields=3 cmd_tuples=1>

그러니까 ntuples=1은 한 행만 찾았다는 뜻이고, 에러 로그에 따르면 중복이 있어야 하는데… :woman_shrugging:

죄송하지만 다음에 뭘 시도해야 할지 모르겠습니다. 포럼을 둘러보시는 것을 추천드립니다. 비슷한 사례가 꽤 많은 것 같습니다(이 주제 아래 관련 섹션 참고). 거기서 다음 단서를 찾으실 수 있을지도 모릅니다.

(아니면 더 잘 아시는 분이 지나가실 때까지 기다리시는 것도 방법입니다 ;))

기존 서버가 표준 설치 환경이 아닌 것 같습니다. 어쨌든, 간략히 설명하자면: 기존 서버의 인덱스가 수년간의 사용 과정에서 손상되었습니다(이것은 OS 업그레이드 후에 발생할 수 있습니다). 이로 인해 incoming_referers 테이블에 동일한 두 행이 들어갔습니다. 백업은 이 데이터를 그대로 복사하고, 새 서버는 이를 거부합니다. 따라서 먼저 기존 서버에서 문제를 수정한 뒤, 새 백업을 만들어야 합니다.

기존 서버에서 Rails 콘솔을 열기 위해 다음을 실행하세요:

./launcher enter app
rails c

그런 다음 다음 줄들을 순서대로 붙여넣으세요:

db = ActiveRecord::Base.connection.current_database
DB.exec("DELETE FROM incoming_referers a USING incoming_referers b WHERE a.id > b.id AND a.path = b.path AND a.incoming_domain_id = b.incoming_domain_id")
DB.exec("REINDEX DATABASE #{ActiveRecord::Base.connection.quote_table_name(db)}")

이 작업은 중복 항목을 제거하고 모든 인덱스를 재구성합니다(다른 테이블도 영향을 받았을 수 있으므로).

REINDEX가 오류 없이 완료되면 exit를 입력하고, 기존 서버에서 새 백업을 만든 뒤 해당 새 파일을 복원하세요. 만약 다른 테이블에 대한 오류가 표시되면, 해당 오류를 여기에 붙여넣어 주세요.

매우 감사합니다. 불행히도 마지막 줄에서 오류 메시지가 표시됩니다:

“PG::InsufficientPrivilege: ERROR: must be owner of database discourse”

실제로 이미 “표준 서버”여야 합니다. 설치는 당시 “Discourse” 팀이 일회성 비용으로 수행했습니다.

아, 맞다. 이렇게 해 보자.

Rails 콘솔을 종료하고(exit 입력), 여전히 컨테이너 내부에 있는 상태에서(./launcher enter app) 다음을 실행한다:

su postgres -c "reindexdb discourse"

이 작업이 오류 없이 완료되면, 기존 서버에서 새 백업을 만든 후 그 새 파일을 복원한다. 특정 테이블에 관한 오류가 표시되면 그냥 여기에 붙여넣어라.

정말, 정말 감사합니다! 모든 것이 훌륭하게 해결되었고, 당신의 도움이 없었다면 저는 아무런 기회도 없었을 것이며, 곧 포럼을 처음부터 다시 시작해야 했을 거예요! 감사합니다!

훌륭한 지원을 해 주신 @chapoi 님께도 감사드립니다!