백업이 계속 포럼을 멈추게 합니다

백업 생성 시 공간 부족 문제로 사이트가 다운되는 상황이 반복되고 있습니다.

백업과 업로드 파일을 저장하기 위해 별도의 DO 볼륨을 사용하고 있습니다. 볼륨 용량은 300GB입니다.

백업 설정:

이 문제는 몇 달째 반복되고 있습니다. 관리자 인박스에서 백업 실패에 대한 알림을 받게 됩니다(아래 참조).

디바이스에 남은 공간 없음
[2024-02-14 03:43:34] Finalizing backup...
[2024-02-14 03:43:34] Creating archive: elite-fourum-2024-02-14-033845-v20240204204532.tar.gz
[2024-02-14 03:43:34] Making sure archive does not already exist...
[2024-02-14 03:43:34] Creating empty archive...
[2024-02-14 03:43:34] Archiving data dump...
[2024-02-14 03:43:58] Archiving uploads...
[2024-02-14 03:55:03] Removing tmp '/var/www/discourse/tmp/backups/default/2024-02-14-033845' directory...
[2024-02-14 03:55:03] Gzipping archive, this may take a while...
[2024-02-14 04:25:38] EXCEPTION: /var/www/discourse/lib/discourse.rb:138:in `exec': Failed to gzip archive.

gzip: /var/www/discourse/public/backups/default/elite-fourum-2024-02-14-033845-v20240204204532.tar.gz: No space left on device

[2024-02-14 04:25:38] /var/www/discourse/lib/discourse.rb:172:in `execute_command'
/var/www/discourse/lib/discourse.rb:138:in `exec'
/var/www/discourse/lib/discourse.rb:34:in `execute_command'
/var/www/discourse/lib/backup_restore/backuper.rb:253:in `create_archive'
/var/www/discourse/lib/backup_restore/backuper.rb:40:in `run'
/var/www/discourse/lib/backup_restore.rb:13:in `backup!'
/var/www/discourse/app/jobs/regular/create_backup.rb:10:in `execute'
/var/www/discourse/app/jobs/base.rb:297:in `block (2 levels) in perform'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/rails_multisite-5.0.0/lib/rails_multisite/connection_management.rb:82:in `with_connection'
/var/www/discourse/app/jobs/base.rb:284:in `block in perform'
/var/www/discourse/app/jobs/base.rb:280:in `each'
/var/www/discourse/app/jobs/base.rb:280:in `perform'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:202:in `execute_job'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:170:in `block (2 levels) in process'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/sidekiq-6.5.12/lib/sidekiq/middleware/chain.rb:177:in `block in invoke'
/var/www/discourse/lib/sidekiq/pausable.rb:132:in `call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/sidekiq-6.5.12/lib/sidekiq/middleware/chain.rb:179:in `block in invoke'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/sidekiq-6.5.12/lib/sidekiq/middleware/chain.rb:182:in `invoke'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:169:in `block in process'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:136:in `block (6 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/sidekiq-6.5.12/lib/sidekiq/job_retry.rb:113:in `local'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:135:in `block (5 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/sidekiq-6.5.12/lib/sidekiq.rb:44:in `block in <module:Sidekiq>'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:131:in `block (4 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:263:in `stats'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:126:in `block (3 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/sidekiq-6.5.12/lib/sidekiq/job_logger.rb:13:in `call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:125:in `block (2 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/sidekiq-6.5.12/lib/sidekiq/job_retry.rb:80:in `global'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:124:in `block in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/sidekiq-6.5.12/lib/sidekiq/job_logger.rb:39:in `prepare'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:123:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:168:in `process'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:78:in `process_one'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:68:in `run'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/sidekiq-6.5.12/lib/sidekiq/component.rb:8:in `watchdog'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/sidekiq-6.5.12/lib/sidekiq/component.rb:17:in `block in safe_thread'
[2024-02-14 04:25:38] Deleting old backups...
[2024-02-14 04:25:38] Cleaning stuff up...
[2024-02-14 04:25:38] Removing '.tar' leftovers...
[2024-02-14 04:25:39] Marking backup as finished...
[2024-02-14 04:25:39] Notifying 'system' of the end of the backup...

그런데 그 후에는 알림을 받지 못하는 상태인 것으로 보이는 부분적으로(?) 완료된 백업 파일들이 생성됩니다. 이 파일들이 쌓여 결국 매일 새로운 백업 생성이 시도될 때 사이트가 동시에 다운되는 지점에 도달합니다.

이 파일들은 /admin/backups 페이지에 표시되지 않으므로, 수동으로 SSH로 접속하여 삭제해야 합니다.

이 문제를 재현하는 것이 어렵고 따라서 수정하기도 어렵다는 점은 알지만, 제가 명백히 잘못하고 있는 부분이 있는지, 혹은 다른 사용자들도 동일한 문제에 직면하고 있는지 궁금합니다.

압축되지 않은 백업 파일 조각을 제거한 후 먼저 시도해 볼 것은 최대 백업 수를 2로 줄이는 것입니다.

어떤 경우든 이 백업들을 다른 곳, 예를 들어 홈 디렉터리로 가져올 수 있는 방법을 마련하는 것이 가장 좋다고 생각합니다. 호스팅 업체에 문제가 생겨 계정이 삭제되면 현재로서는 아무것도 남지 않게 됩니다. 계정이 탈취된 경우나, 심지어 화재가 발생한 경우에도 마찬가지입니다.

수동적이든 자동적이든, 백업을 오프사이트에 복사할 수 있는 방법을 갖추면 조각을 확인하고 삭제하는 방법에 매우 근접하게 됩니다.

이전에도 제안한 적이 있지만, 백업 파일이 생성된 후 며칠 동안 읽히지 않았다면 대시보드가 경고하도록 해야 합니다. 이는 비교적 간단한 확인 사항이며, 제 생각에는 오프사이트 사본이 있는지 확인하는 좋은 대안입니다.

또한 백업을 블록 스토리지에 저장하도록 선택할 수 있으며, 다른 제공업체를 사용하여 이를 수행할 수도 있습니다. 이렇게 하면 설치 환경과 백업이 모두 손실될 가능성이 줄어듭니다.

백업과 압축된 백업 파일이 동시에 필요하지 않은 작업이 오랫동안 미뤄지고 있다고 생각합니다만, 그것을 기다릴 가치는 없습니다. 그 사이에, 유지 중인 N개의 백업에 필요한 공간, 압축되지 않은 형태로 생성 중인 백업 1개에 필요한 공간, 그리고 가장 오래된 N개 백업이 삭제되기 전에 잠시 필요로 하는 압축된 백업 1개에 필요한 공간이 필요합니다.

즉, N+2개의 백업에 해당하는 디스크 공간이 필요하며, 백업이 실패하면 해당 조각을 삭제해야 합니다.

5개의 좋아요

해당 디렉터리도 300GB 파티션에 위치해 있음을 확인해야 합니다. 디스크가 가득 차는 원인이 바로 그 파티션입니다.

또한 업로드 파일도 해당 파티션으로 이동하는 것을 고려해 볼 수 있습니다.

1개의 좋아요

그 방법을 바로 알 수 있을까요? 변경해야 하는 yml 설정이나 뭐가 있을까요?

또한 재구축 시 정적 오프라인 화면을 설정해 두었기 때문에, 그게 문제를 복잡하게 만드는 건지 모르겠어요.

아래와 같은 설정을 의미합니다.

volumes:
  - volume:
      host: /your/big/partition/tmp
      guest: /var/www/discourse/tmp

아마도 백업을 큰 파티션에 저장하기 위해 이미 이와 유사한 설정을 하고 계실 것 같습니다?

복잡하게 만듭니다. 다만, 문제가 Discourse가 정상적으로 실행되고 있음에도 불구하고 계속 정적인 오프라인 페이지가 표시되는 것이 아니라면, 이것이 원인은 아닐 가능성이 높습니다.

1개의 좋아요

이 주제를 만든 후에야 Digital Ocean 볼륨을 확장할 때 콘솔에서 명령어를 실행해야 한다는 사실을 알게 되었습니다. 즉, 300GB 중 일부만 사용하고 있었던 것이죠.

그 문제를 수정하고 다른 것은 아무것도 변경하지 않았는데, 오늘 다시 문제가 발생했습니다. 사이트가 다운되었을 당시 압축이 풀린 tar 파일이 2개, 압축된 파일이 3개 있었습니다.

다음에는 위에서 논의된 전략을 시도해 보겠습니다.

하지만 말씀드리고 싶은 것은 관리자 UI에 실패한 백업이 있다는 표시가 있으면 좋겠다는 것입니다. 아니면 새로운 백업 프로세스를 트리거할 때 모든 *.tar 파일을 삭제하는 것은 어떨까요? 이 경우, 관리자 UI에서는 볼 수 없는 90GB 분량의 압축이 풀린 백업이 있었습니다. 또한 어느 쪽으로부터도 “백업 실패” DM을 받지 못했습니다.

2개의 좋아요

드롭렛의 메모리 사용량은 어떤가요? 백업 프로세스는 정리 루틴을 실행하고 실패 시 관리자에게 알림을 보내야 합니다. 프로세스가 OOM 킬러에 의해 종료되면 이 동작이 이루어지지 않습니다.

아마도 그것이 지금 일어나고 있는 일일지도 모릅니다! 몇몇 사이트에서 "중단된 백업이 부분 백업을 남기고 디스크를 가득 채운다"는 상황을 본 적이 있습니다. 제가 내린 최선의 설명은 백업 도중 OS 재부팅이었지만, OS 재부팅이 없는 상황에서 이를 본 적도 있습니다..

백업 프로세스가 메모리 부족으로 인해 종료되는 것이 가장 그럴듯한 설명으로 보입니다. 재현하기가 충분히 어려워서 이 현상을 설명할 수 있을 정도입니다.

. . . .

아, 아쉽군요. 이 문제가 있었던 것으로 기억하는 사이트 중 하나는 16GB의 RAM을 갖추고 있어서, 이것이 원인이 될 것 같지는 않습니다. 해당 사이트에서는 약 일주일마다 백업이 S3로 전송된 후(혹은 전송되지 않은 후) 로컬 디스크에 남는다는 점이 문제입니다. 또한 100GB 이상의 여유 디스크 공간이 있으므로, 디스크가 가득 차기까지 몇 달이 걸리며 그제서야 큰 문제가 됩니다.

방금 삭제한 파일 목록입니다:

forum-2024-03-11-123904-v20240202052058.tar.gz
forum-2024-03-09-123159-v20240202052058.tar.gz                           
forum-2024-03-07-123727-v20240202052058.tar.gz                           
forum-2024-03-05-123019-v20240202052058.tar.gz
forum-2024-03-03-123934-v20240202052058.tar.gz  

동의합니다. 제가 관리하는 포럼에서는 백업이 S3로 전송되지 않고 서버에 그대로 남아 있는 경우가 있는데, 이로 인해 포럼이 최소 한 번 이상 다운된 적이 있습니다.

1개의 좋아요

도움이 될지 모르겠지만 여기 DO의 메트릭을 공유합니다

7일

24시간

확대 보기