2.7beta7 업데이트 후 임플로션

안녕하세요,

수년간 https://discourse.bokeh.org에서 자체 호스팅 Discourse 인스턴스를 운영해 왔습니다. 전반적으로 매우 안정적이고 유지보수에 거의 노력을 들이지 않아도 되었으며, 특히 업데이트는 항상 완벽하게 완료되어 아무런 문제가 없었습니다.

그러나 오늘 2.7beta7로 업데이트한 후(업데이트는 문제없이 완료된 것으로 보였으나) 사이트가 완전히 마비되었습니다. 페이지가 잘못 렌더링되고 JS 콘솔 오류가 발생하면서 잠시 버텼지만, 롤백을 시도한 후 UI가 완전히 작동하지 않게 되었습니다. 드롭렛에 로그인하여 다음과 같은 시도도 해 보았지만 실패했습니다:

재빌드 (Rebuild)

./launcher rebuild app

여러 번 시도했지만 여러 가지 방식으로 실패했습니다.

Discourse Doctor

./discourse-doctor

복구 (Restore)

./launcher enter app
discourse restore <backup file>

이것도 실패했습니다.

초기화 (Wipe)

"wipe"를 수행한 후 복구를 시도해 보기도 했습니다.

./launcher stop app
./launcher destroy app
rm -r /var/discourse/shared/standalone/

이 과정을 거친 후에는 적어도 재빌드가 성공하여 “새로 설치” 상태, 즉 “축하합니다, Discourse를 설치했습니다!” 메시지가 표시되는 상태까지 도달할 수 있었습니다.

그 후 다시 discourse restore를 실행해 보았지만 이번에도 실패했습니다.

EXCEPTION: 1 posts are not remapped to new S3 upload URL. S3 migration failed for db 'default'. /var/www/discourse/lib/file_store/to_s3_migration.rb:131:in `raise_or_log' /var/www/discourse/lib/file_store/to_s3_migration.rb:86:in `migration_successful?' /var/www/discourse/lib/file_store/to_s3_migration.rb:357:in `migrate_to_s3' /var/www/discourse/lib/file_store/to_s3_migration.rb:65:in `migrate' /var/www/discourse/lib/file_store/s3_store.rb:240:in `copy_from' /var/www/discourse/lib/backup_restore/uploads_restorer.rb:62:in `restore_uploads' /var/www/discourse/lib/backup_restore/uploads_restorer.rb:44:in `restore' /var/www/discourse/lib/backup_restore/restorer.rb:62:in `run' script/discourse:145:in `restore' /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/thor-1.1.0/lib/thor/command.rb:27:in `run' /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/thor-1.1.0/lib/thor/invocation.rb:127:in `invoke_command' /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/thor-1.1.0/lib/thor.rb:392:in `dispatch' /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/thor-1.1.0/lib/thor/base.rb:485:in `start' script/discourse:286:in `' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/cli/exec.rb:63:in `load' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/cli/exec.rb:63:in `kernel_load' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/cli/exec.rb:28:in `run' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/cli.rb:494:in `exec' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/vendor/thor/lib/thor.rb:392:in `dispatch' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/cli.rb:30:in `dispatch' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/vendor/thor/lib/thor/base.rb:485:in `start' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/cli.rb:24:in `start' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/exe/bundle:49:in `block in ' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/friendly_errors.rb:130:in `with_friendly_errors' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/exe/bundle:37:in `' /usr/local/bin/bundle:23:in `load' /usr/local/bin/bundle:23:in `' Trying to rollback... Rolling back... Cleaning stuff up... Dropping functions from the discourse_functions schema... Removing tmp '/var/www/discourse/tmp/restores/default/2021-04-23-235404' directory... Marking restore as finished... Notifying 'system' of the end of the restore... Finished! [FAILED]

이상한 점은 복구 과정에서 사이트가 정상으로 돌아오는 것처럼 보였다는 것입니다. 이전 콘텐츠가 표시되기 시작했거든요. 그런데 실패가 발생했고, 이제는 아무것도 표시되지 않고 계정들도 사라진 상태입니다.

여기서 어떤 조언이나 제안도 정말로 필요하겠습니다. 일주일 전까지의 일일 백업이 있으며(필요하다면 Glacier에 더 오래된 것이 있습니다). 며칠 전 사용하지 않던 카테고리를 삭제했는데, 이것이 문제의 원인이 될 수 있을까요? 확인해 보기 위해 더 오래된 백업을 시도해 볼 예정입니다. 확실한 복구 프로세스에 대한 팁이 있다면 환영합니다.

구버전 백업은 도움이 되지 않았습니다. 복원 과정에서 모든 것이 "거의 정상"처럼 보였습니다.

마지막 순간까지도 그랬다가, 바로 다음 상태로 전환되었습니다:

참고로, 메일링 리스트에서 원래 가져온 게시글은 백업에 포함되지 않는 건가요? 이 게시글들은 이미 수년간 Discourse 사이트에 올라와 있었는데요. 이번 문제 발생 전에는 게시글이 24,000개였지 5,000개가 아니었습니다.

앱을 더 오래된 discourse 버전, 예를 들어 2.7beta6에서 다시 빌드할 수 있는 방법이 있을까요?

아니면, 글자 그대로 문제를 일으키는 게시물이 단 하나뿐일 수도 있겠다는 생각이 듭니다.

EXCEPTION: 1 posts are not remapped to new S3 upload URL. S3 migration failed for db ‘default’.

해당 게시물을 찾아서 삭제하거나 제거할 수 있을까요?

S3에 이미지가 있나요?

@pfaffman 네, s3에 이미지가 있습니다.

음. 어쩌면 고장난 게시물이 하나뿐일 수도 있겠네요. 데이터베이스를 복구하고, 문제를 수정한 뒤, 새로운 데이터베이스로 백업 파일을 다시 만들어야 할 것 같습니다. 하지만 정확히 파악하기는 정말 어렵네요.

그렇게 하는 방법에 대한 설명서가 어딘가에 있나요? 어떤 게시물이 손상되었는지 어떻게 파악할 수 있나요?

수정: 아니면, 해당 업무를 맡을 수 있는 전문가를 계약할 수 있는 방법이 있을까요?

복원할 수 있는 최신 드롭렛 백업 또는 스냅샷이 있으신가요?

복원할 수 있는 최신 드롭렛 백업이나 스냅샷이 있나요?

아쉽게도 없습니다. DO 백업은 주 단위로만 이루어지고, 저는 일 단위의 Discourse 백업을 s3에 설정하여 최근 1주일 치는 최신 상태로, 1년 치는 glacier에 보관하고 있었습니다. 이전에도 Discourse 업그레이드를 여러 번 성공적으로 경험했던 터라, 이 정도면 충분하고 더 나은 방법이라고 생각했습니다(그리고 이전에 성공적인 테스트 복원도 수행했었죠).

예를 들어
version: 94301854938a0b36dd64666fb7a7c8406544a781
이것은 베타 버전으로 올리기 바로 직전의 커밋입니다.

음, 사실은 업데이트를 진행한 거예요. 절망감에 사로잡혀서

Syncing files to S3

단계에서, 1개의 잘못된 게시물을 지적하고 롤백을 시작하기 전에 복원 스크립트를 그냥 강제 종료했어요.

사이트가 실제로 다시 올라와서 안전 모드에서 접근할 수 있었습니다. 코드 블록을 위한 “COPY PASTE” 테마 구성 요소를 비활성화했는데, 이 구성 요소는 최신 베타 버전과 현저히 호환되지 않는 것 같습니다. 그 후로는 안전 모드 없이도 사이트가 대부분 정상적으로 작동하는 것 같습니다. 하지만:

  • 가능한 한 모든 것이 "깔끔하게 정리"되도록 하려면 권장되는 조치가 있나요? 예를 들어 S3에 자산을 다시 업로드하고 "rebake"하는 것 같은? 이에 대한 가장 최신 지침은 어디에서 찾을 수 있나요?

수정: 제가 아는 한, 모든 것이 정상으로 돌아온 것 같습니다. 이전 게시물들의 이미지가 S3/CDN에서 올바르게 로드되고 있습니다. 그렇다면 제 질문은, S3에 이미지를 업로드하는 경우 이 옵션을 체크 해제해야 하는지 여부입니다.

Include uploads in scheduled backups. Disabling this will only backup the database.

체크되어 있으면 중복된 안전 장치를 제공하는 것 같다고 생각했지만, 복원 과정에서 이러한 문제들의 원인이 바로 이것인 것 같습니다?

마지막으로 다른 호스팅 제공업체로 이사를 갈 때, 복원 과정에서 S3 관련 문제가 있었습니다. 그래서 이에 대해 문의했고, 답변은 '예’였습니다. 이미지를 S3에 저장하는 경우, 업로드 파일 없이 백업을 생성해야 합니다. 데이터베이스만 백업하는 것이죠. 하지만 이 경우에도 이것이 해결책인지는 알 수 없습니다. 시도해 보신다면, 먼저 스냅샷을 생성해 두시기 바랍니다.

더 자세한 내용은 여기서 확인하실 수 있습니다: Restore a backup from the command line - #28

직접 시도해 봤는데 아무 문제 없이 잘 작동했습니다. :slightly_smiling_face:

도와드릴 수 있습니다. 월요일, 혹은 위험수당을 주시면 더 빨리 가능합니다.

Contact Us - Literate Computing 페이지 하단의 이메일 주소를 통해 S3에 연락할 수 있습니다.

@pfaffman 감사합니다! 사이트가 이제 완전히 정상적으로 작동하는 것 같지만, 가능하시다면 간단히 점검해 주시거나 sanity check를 해 주시면 좋겠습니다. 만약 원하신다면요. 어쨌든 향후 비상 상황에 대비하여 상업적 연락처 정보를 메모해 두었습니다. :slight_smile:

다른 분들에게 도움이 될 수 있을지 모르겠지만, 다음과 같은 레트로(후기 분석)를 공유합니다.


요약

(성공적인) 업그레이드 이후, 호환되지 않는 비공식 테마 구성 요소 플러그인으로 인해 사이트 UI가 손상되었습니다. 당시에는 이것이 알려지지 않아 백업 복원 절차가 시작되었지만, 이상적이지 않은 설정으로 인해 문제가 발생했습니다.

상세 내용

  1. 2.7beta7로의 업그레이드가 시작되어 성공적으로 완료되었습니다.

  2. 그러나 업그레이드 후 사이트 UI가 심각하게 손상되었습니다: 게시물 본문이 완전히 사라졌고, 상단 내비게이션(사용자/로그인 포함)도 완전히 사라졌으며, JS 콘솔에서 오류가 보고되었습니다.

    1. 그 원인은 코드 블록을 복사/붙여넣기하기 위한 호환되지 않는 제3자 테마 구성 요소였지만, 당시에는 이것이 알려지지 않았습니다.

    2. 또한 당시에는 safe-mode 진입의 가능성이 알려지지 않았습니다. 만약 이것을 알았다면 나머지 문제들을 피할 수 있었을 것입니다.

  3. 직접 내비게이션을 통해 \admin에 접근하여 롤백을 시도했습니다. 이 과정에서 사용자가 즉시 로그아웃되었고, 손상된 UI로는 다시 로그인할 방법이 없는 것으로 보였습니다.

  4. DO Droplet에 로그인하여 S3의 최신 백업 tarball로 수동 복원을 시작했습니다.

  5. 여러 복원 시도가 S3 자산 업로드 후 최종 단계 근처에서 실패했는데, 이는 단일 게시물의 오류 때문이었습니다.

    1. 이는 S3로 자산을 다시 업로드하려는 복원이 불안정할 수 있기 때문인 것으로 보입니다(Meta에 이에 대한 여러 보고가 있음).
    2. 그러나 S3에 이미 저장되어 있으므로 업로드 자산을 백업할 필요가 없었습니다!
  6. 수많은 복원 시도 중 하나에서 "clean slate"로 시작해 보려고 사이트를 초기화하기도 했습니다. 이로 인해 복원 실패 후의 롤백은 이제 빈 사이트로 롤백되었습니다.

  7. 결국 절박한 베팅으로 복원을 실행하고, S3 업로드 중(실패 및 롤백 직전) 스크립트를 강제 종료했습니다.

  8. 사이트가 다시 온라인이 되었지만 이전의 UI 문제가 나타났습니다. 그러나 이제 safe-mode를 알게 되어 사용했고, 플러그인과 테마를 비활성화한 상태로 사이트가 정상적으로 작동했습니다.

  9. 모든 비공식 플러그인과 테마가 제거되었습니다(복사/붙여넣기 구성 요소 포함), 이후 사이트가 정상적으로 작동했습니다.

  10. 이전에 업로드된 이미지가 여전히 로드되고 있는지, 그리고 S3 CDN에서 로드되고 있는지 확인했습니다.

자산이 이미 S3에 남아 있었으므로 최종 업로드와 "rebake"는 필요하지 않았으며, 게시물이 새 URL을 사용하도록 업데이트될 필요도 없었을 것으로 추정됩니다.

스크립트가 중단된 후 남은 복원 단계가 있었는지, 있다면 무엇이었는지 확신할 수 없지만, 현재까지 사이트의 현재 상태에서 아무 문제가 발생하지 않았습니다.

교훈 / 조치 사항

  • 향후 문제 진단 시 safe-mode로 시작하기
  • 백업에 업로드를 포함하는 설정을 끄기 (Discourse에 이 상황에 대한 경고 추가를 제안할 것입니다)
  • 모든 비공식 플러그인과 테마 구성 요소 제거
  • 내장된 새 코드 블록 복사 기능 활성화 제안
  • 복구용 안전장치로 Digital Ocean 주간 이미지 백업 활성화

테마 컴포넌트인가요, 플러그인인가요? 작성자에게 알려주실 수 있을까요?

@merefield 이미 알려진 것 같네요. 그래서 제가 그 가능성을 알게 되었습니다.

https://meta.discourse.org/t/copy-option-for-code-blocks-in-discourse/60961

복원 과정에 대해 제안을 하나 한다면, 더 견고하게 만들 수 있도록 몇 가지 옵션을 제공하는 것이 좋겠습니다. 예를 들어, 성공적인 복원을 방해하는 것이 잘못된 게시물 하나뿐이라면, "잘못된 게시물을 삭제할까요?"라고 묻는다면 망설임 없이 Y 키를 누를 것입니다.

이 기능은 다가오는 2.8 베타 버전 중 하나에 포함될 예정입니다. 불행히도 아직 다가오는 2.7 릴리스를 위해 준비가 되지 않았습니다.

도와달라는 요청을 더 일찍 확인하지 못한 점 죄송합니다. S3에 저장된 업로드 파일로 인해 복원이 실패하는 문제를 겪고 있는 다른 분들을 위한 팁을 드리겠습니다. 백업에서 dump.sql.gz 파일을 추출한 후 파일 이름을 변경하세요. 예를 들어, 원래 백업 파일명이 discourse-2020-10-09-133921-v20201007124955.tar.gz였다면, 결과 파일명은 discourse-2020-10-09-133921-v20201007124955.sql.gz로 변경해야 합니다. 이 파일을 복원하면 정상적으로 작동할 것입니다.