복구 시 실패하지 않도록 백업 내부 데이터베이스에서 중복된 키 태그를 제거하는 방법

이 게시글은 지난 24시간 동안의 상황을 매우 간결하게 정리한 것입니다. 다만 아직 실제로 해결되지 않아, 아래에 어디서 문제가 발생했는지 알려주는 게시글이 올라오기를 희망하고 있습니다.

제 Discourse 업데이트가 중복된 키(duplicate key)로 인해 실패했습니다. 태그 중 하나가 중복되어 있었기 때문입니다. 업데이트 문제를 해결하려면 새로운 Discourse 설치를 한 뒤 최신 백업 파일을 불러와야 했는데, 중복된 키 문제로 인해 재로드가 실패했습니다. 따라서 백업 파일 내부에 들어가서 문제의 태그를 다른 이름으로 수정해야 했습니다.

어떤 이유에서인지 중복 태그 문제를 수정하여 다시 압축한 백업 파일이 원래 백업 파일보다 훨씬 작은 용량을 보였고, 복원하려고 시도했을 때 실패했습니다. 다시 압축하는 과정에서 뭔가 잘못되었던 것 같습니다.

1) 백업 파일 찾기: Discourse 백업 파일의 위치를 확인하려면 다음 명령어를 사용할 수 있습니다:

sudo find / -name "*.tar.gz"

이 명령어는 시스템에서 “.tar.gz” 확장자를 가진 모든 백업 파일을 검색합니다. 기본적으로 컨테이너 안의 shared/backups/default 경로에 있어야 합니다.

2) 사본 만들기: 작업할 백업 파일을 찾았으면, 원본 파일의 백업을 확보하기 위해 사본을 만들어야 합니다. “cp” 명령어를 사용합니다:

bash

sudo cp /path/to/original_backup.tar.gz /path/to/copy_backup.tar.gz

3) 사본 압축 해제: “tar” 명령어를 사용하여 복사된 백업 파일의 내용을 압축 해제합니다:

bash

tar -xzvf /path/to/copy_backup.tar.gz

이 명령어는 백업 파일을 임시 디렉터리로 압축 해제합니다.

4) 데이터베이스 내 태그 편집: 압축 해제된 백업 파일로 이동하여 텍스트 에디터를 사용하여 관련 데이터베이스 파일을 엽니다. 저는 중복된 “socialmedia” 태그 문제로 인해 성공적인 복원이 불가능했던 사례를 겪었습니다. 큰 데이터베이스에는 태그가 많이 존재하며, 검색하려는 특정 태그도 여러 곳에 있을 가능성이 높습니다. 그래서 Nano에서 Ctrl+W를 사용하여 'immutable socialmedia’를 검색했는데, 바로 해당 위치로 이동할 수 있었습니다.

sudo nano /path/to/extracted_database.sql

“socialmedia” 태그의 한 인스턴스를 "socialmedia2"로 수정한 뒤, 이제 한 번만 나타나는지 확인하기 위해 빠르게 검색을 수행했습니다. 복원이 성공하면 관리자 섹션에서 해당 태그들을 수정할 수 있습니다.

5) 다시 압축: 백업 파일을 편집한 후, 수정된 내용으로 새로운 백업 파일을 생성합니다. 수정된 파일을 압축하려면 다음 명령어를 사용합니다:

tar -czvf /path/to/new_modified_backup.tar.gz /path/to/modified_files_directory

6) 올바른 위치로 이동: 새로 수정된 백업 파일을 백업이 저장되는 적절한 디렉터리로 이동합니다. 기본 위치는 보통 "/shared/backups/default"입니다:

sudo mv /path/to/new_modified_backup.tar.gz /shared/backups/default/

7) 서비스 중지 및 시작: 수정된 백업을 복원하기 전에, 복원 과정 중 잠재적인 충돌을 피하기 위해 관련 서비스를 중지하는 것을 잊지 마세요. “./launcher stop app” 명령어를 사용하여 Discourse 애플리케이션을 중지합니다:

./launcher stop app

8) 백업 복원: 수정된 백업에서 복원하려면 “discourse restore” 명령어와 새 백업 파일의 경로를 함께 사용합니다:

discourse restore /shared/backups/default/new_modified_backup.tar.gz

또는 사이트의 /admin 페이지를 통해 수행할 수도 있으며, 이제 백업 섹션에 해당 파일이 표시되어야 합니다.

9) 복원 확인: 복원 과정이 완료된 후, Discourse 애플리케이션과 데이터베이스를 확인하여 중복된 “socialmedia” 태그가 제거되었는지 확인함으로써 변경 사항이 성공적으로 적용되었는지 검증했습니다.

10) 서비스 시작: 이전에 중지했던 서비스를 다시 시작하여 Discourse 애플리케이션을 온라인으로 복귀시킵니다. “./launcher start app” 명령어를 사용하여 Discourse 애플리케이션을 시작합니다:

./launcher start app

11) 임시 파일 및 추가 백업 삭제: 백업 복원이 성공한 후, 디스크 공간을 확보하기 위해 과정에서 생성된 임시 파일과 추가 백업을 삭제했습니다. 파일을 제거하려면 “rm” 명령어를 사용합니다:

sudo rm -r /path/to/temporary_directory
sudo rm /path/to/copy_backup.tar.gz

왜 그랬나요?

앱을 재시작하고, 컨테이너에 진입한 뒤 postgres에 접속하여 데이터 입력 문제를 즉시 처리하는 방식으로 ‘온라인’ 상태에서 이 문제를 해결할 수 없었나요?

에러를 예상하지 못해서 이미 새 버전의 Discourse를 서버에 설치해 놓은 상태였습니다. 중복 키 에러는 백업 파일 안에 있었고, 새로 설치한 앱에는 없었지만, 에러를 먼저 수정해야 한다고 해서 백업을 복원할 수 없었습니다.

그래서 백업 파일 안의 태그를 직접 편집해 보려 했습니다.

하지만 업데이트 시 에러를 확인했나요?

다음에는 직접 수정해서 수고를 덜어 보세요.

앱이 실행되지 않았고 재로드도 불가능해서, 문제를 해결하려고 최신 Discourse 버전으로 업데이트했습니다. 그 결과 백업을 제외하고는 데이터베이스에 접근할 수 없게 되었습니다.

이것은 분명히 제가 여기에 게시한 특수한 사례이며, 더 나은 선택지는 앱 데이터베이스에 직접 접근할 수 있을 때 문제를 인지하고 수정하는 것이었을 것입니다. 하지만 저는 그것을 놓쳤고 다른 옵션을 찾을 수 없었습니다.

걱정 마세요. 적어도 그것이 가능하다는 것을 보여주고, 새로운 것을 배우며, 다른 사람들에게 추가적인 옵션을 제공했으니까요.

잘하셨어요! :clap:

감사합니다. 다만 원래 파일은 128MB였고 새 파일은 29MB라서, 서버에서 다시 압축하는 과정에서 파일 길이가 길어서 잘린 것 같습니다.

이 과정은 작동해야 할 것 같지만, 최종적으로 받은 파일로는 제 디스코스를 복원할 수 없었습니다.

선택하신 경로는 더 위험했지만, 분명히 가능할 것 같은데요? 이 문제에 대해 조언을 해줄 수 있는 분이 있을까요?

백업에서 이 과정을 다시 반복할 수 있을 테니 …

이 문제가 해결되었나요? 마치 how-to(방법 안내) 글처럼 읽히지만, 사이트가 여전히 깨져 있는 것 같습니다.

아마도 제가 이해하지 못하는 무언가를 하고 계신 것일 수 있지만, 일반적으로 ./launcher start app을 실행하여 기존 컨테이너를 시작할 수 있습니다. 그렇게 하지 못한 특별한 이유가 있었나요?

그 후 Rails나 SQL 도구를 사용하여 기존 컨테이너의 데이터베이스를 수정한 뒤, bootstrap/rebuild를 다시 시도해 볼 수 있습니다.

아니면 데이터베이스를 기존 컨테이너가 처리할 수 있는 범위를 넘어 마이그레이션했을 수도 있습니다.

이전에 복원하려는 사이트가 1년 이상 오래된 백업이었던 경우 비슷한 작업을 해본 적이 있습니다. db 덤프가 충분히 작아서 vim으로 편집할 수 있었던 것 같습니다.

답변해 주셔서 감사합니다.

업그레이드가 몇 개 뒤처져 있어서 시작을 거부했습니다. 그래서 최신 Discourse로 업데이트하기 위해 새 인스턴스를 만들고 기존 백업 파일을 업로드했지만, 중복된 키(duplicate keys) 때문에 해당 백업이 거부되었습니다.

혹은 데이터베이스를 기존 컨테이너가 처리할 수 있는 범위를 넘어 마이그레이션한 것일 수도 있습니다.

네, 아마도 그렇습니다. 정확히 무엇을 했는지는 약간 흐릿하지만, 여기저기서 얻은 문제 해결 조언에 따라 몇 가지를 독립적으로 업데이트했습니다. 그중 하나는 최신 PostgreSQL 버전을 설치하는 것이었습니다.

저는 vim으로 편집할 수 있었습니다.

Nano로 편집할 수 있었고 모든 것이 정상으로 보였지만, 재압축(rezip)된 파일 크기가 너무 작아서 어딘가에서 문제가 발생한 것 같습니다. 아마도 Nano로 편집하지 못한 것일 수도 있습니다. 당시에는 잘 작동하는 것처럼 보였습니다.

누군가가 오류를 발견해 수정해 주기를 바랐습니다. 그렇게 하면 ‘사용법’ 가이드가 될 테니까요.

다음으로 확인할 사항:

  • 전체 압축 해제 과정을 다시 수행합니다. 변경 사항 없이 다시 압축을 겁니다. 압축 파일 크기가 이전과 동일한지 확인합니다. 다르면 동일한 옵션으로 압축하지 않은 것일 수 있습니다.

  • 다시 압축을 해제하고, 편집 중인 파일의 크기를 확인합니다. 파일을 편집하고 저장한 후, 크기가 크게 변하지 않았는지 확인합니다.

소소한 업데이트입니다. 지난 주에는 팀의 다른 구성원이 이 문제를 작업했지만 해결책이 나오지 않아, 이번에는 로컬 시스템에서 DB를 직접 편집해 다시 시도해 보았습니다.

진행한 작업은 다음과 같습니다:

  1. 복원하려는 오래된 백업 파일을 다운로드했습니다.
  2. 7zip으로 파일을 압축 해제했습니다.
  3. Visual Studio Code로 dump.sql 파일을 열었습니다.
  4. DB에서 중복된 태그를 직접 찾았습니다.
  5. 태그 주위에 ’ '를 사용하여 검색하여 태그 목록으로 보이는 항목을 찾았습니다. 제 경우 'socialmedia’였습니다. 태그는 찾은 인스턴스에서 아래에서 2번째와 3번째에 있는 것으로 보입니다.

  1. 하나를 다음과 같이 편집했습니다.

132 ‘socialmedia2’:1A socialmedia2 en_GB 3

  1. 7zip으로 dump.sql 파일을 다시 압축했습니다.
  • 아카이브에 추가
  • 아카이브 형식 .gzip
  1. 메인 백업 파일을 다시 압축했습니다.
  • 아카이브에 추가
  • 아카이브 형식 .tar (gzip은 아직 사용 불가능)
  1. 이제 수정된 .tar 백업 파일이 압축되어 있어야 합니다.

  2. Discourse에서 사용하는 형식과 일치하도록 7zip으로 .tar 파일을 압축하여 .tar.gz 파일을 생성합니다.

  • 아카이브에 추가
  • 아카이브 형식 .gzip
  1. 백업으로 업로드하고 관리자 섹션을 통해 복원합니다.

이 시점에서 오류 메시지가 발생했습니다:

Extracting dump file…
[2023-08-08 15:09:15] EXCEPTION: No such file or directory @ rb_check_realpath_internal - /var/www/discourse/tmp/restores/default/2023-08-08-150913/dump.sql.gz

위 과정에서 제가 놓친 부분이 무엇인지 아이디어를 주실 수 있을까요?

생각나는 것 중 하나는, 시스템이 백업 날짜가 아닌 오늘 날짜를 경로에 사용하고 있다는 것입니다(이 글을 작성하는 날짜는 2023-08-08입니다).

이것은 제가 이전에 여기에 올린 글의 후속입니다. 만약 이 방법이 효과가 있다면, 향후 동일한 작업을 수행하려는 다른 사람들이 쉽게 찾을 수 있도록 다시 게시합니다.

노트북에서 DB를 편집하기 위해 제가 수행한 작업:

  1. 관리자 섹션에서 복원하려는 구형 백업을 다운로드했습니다.
  2. 7zip으로 파일을 압축 해제했습니다.
  3. Visual Studio Code로 dump.sql 파일을 열었습니다.
  4. DB에서 중복된 태그를 직접 찾았습니다.
  5. 태그 주위에 ’ '를 사용하여 검색함으로써 태그 목록으로 보이는 부분을 찾았습니다. 제 경우 'socialmedia’였습니다. 태그는 발견된 인스턴스에서 아래에서 두 번째와 세 번째에 위치하는 것으로 보입니다.

  1. 하나를 다음과 같이 수정했습니다.

132 ‘socialmedia2’:1A socialmedia2 en_GB 3

  1. 7zip으로 dump.sql 파일을 다시 압축했습니다.
  • 아카이브에 추가
  • 아카이브 형식 .gzip
  1. 메인 백업 파일을 다시 압축했습니다.
  • 아카이브에 추가
  • 아카이브 형식 .tar (gzip은 아직 사용 불가)
  1. 이제 수정된 압축된 .tar 백업 파일을 볼 수 있어야 합니다.

  2. Discourse에서 사용하는 형식과 일치하도록 7zip으로 .tar 파일을 .tar.gz 파일로 압축했습니다.

  • 아카이브에 추가
  • 아카이브 형식 .gzip
  1. 백업에 업로드하고 관리자 섹션을 통해 복원했습니다.

이 시점에서 다음 오류 메시지가 발생했습니다:

Extracting dump file…
[2023-08-08 15:09:15] EXCEPTION: No such file or directory @ rb_check_realpath_internal - /var/www/discourse/tmp/restores/default/2023-08-08-150913/dump.sql.gz

위 과정에서 제가 놓친 부분이 있는지 아는 분이 있을까요?

제 생각에 유일한 가능성은 백업 날짜가 아닌 오늘의 날짜를 사용하고 있다는 것입니다(이 글을 작성하는 날짜는 2023-08-08입니다).

백업 파일의 정확한 이름이 중요하다고 생각합니다: 포럼 이름, 날짜와 시간戳, 버전 식별자. 따라서 압축을 풀고 수정한 후 다시 압축할 경우, 원래 파일과 동일한 이름으로 다시 생성하는 것을 권장합니다. 물론 원래 파일은 안전하게 보관해 두세요.

새 주제에 있는 게시글들을 이 글로 통합했습니다. 이 문제를 한 곳에 모아서 정리하면 향후 여행객들이 훨씬 더 쉽게 이해할 수 있을 것 같아서요. :+1:

@Ed_S 님, 감사합니다. 다른 곳에서 원본 이름을 유지하는 것이 중요하다는 말을 듣고 그대로 유지했습니다. 위에서 질문드린 내용은, 백업 복원 도구가 왜 /var/www/discourse/tmp/restores/default/2023-08-08-150913/dump.sql.gz 파일을 찾되 찾지 못했는지에 대한 것입니다. 이 날짜는 제가 복원을 진행하던 날입니다.

아, 죄송합니다. 정말 이상해 보이네요. 임시 디렉토리가 오늘 날짜에 따라 이름이 붙여지는 것이 정상일 수 있지만, sql 덤프 파일을 찾을 수 없다는 점은 좋은 상황이 아닙니다.

tar 파일의 내용을 나열해 보면 해당 파일명이 보이나요? 제 경우라면 다음과 같습니다.

root@ubuntu-2gb-nbg1-1:/var/discourse/shared/standalone/backups/default# tar vtfz forumname-2023-08-03-HHMMSS-v2023mmddhhmmss.tar.gz dump.sql.gz | head
-rw-r--r-- discourse/www-data 16336925 2023-08-03 05:31 dump.sql.gz

Ed, 감사합니다. 그 파일이 존재하지 않았습니다. 지연된 점 죄송합니다. 잠시 연락이 두절되어 있었습니다.

해당 위치에 올바른 이름의 파일이 없으므로, 빈 파일을 수동으로 생성해 보았습니다:

sudo mkdir -p /var/www/discourse/tmp/restores/default/2023-08-22-121010/

하지만 복원 버튼을 누를 때마다 약간 다른 파일(마지막 6자리 숫자)을 찾으려고 합니다. 타임스탬프가 생성한 폴더를 찾고 있는 것 같아서, 복원 버튼을 누를 때마다 찾는 폴더가 바뀌는 것으로 추정됩니다.

10단계에서 tar 파일을 생성하는 과정에서 문제가 발생하고 있는 것 같습니다. 해당 파일을 볼 수 있나요? file 명령어로 내용을 설명할 수 있나요? tar tvfz로 내용을 나열할 수 있나요?