백업에서 SVG 파일을 복원할 때 발생하는 오류

백업 복원(멀티사이트 환경에서 시도했으나, 아래 내용을 참고하면 이것이 문제가 아닌 것 같습니다)을 시도하면 다음과 같은 현상이 발생합니다.

Migrating the database...
EXCEPTION: lib/discourse.rb:57:in `exec': Failed to migrate database.
rake aborted!
Errno::ENOENT: No such file or directory @ rb_sysopen - /var/www/discourse/public/uploads/default/original/2X/7/7be997f9f48c034ddf5d4eb95d2ea7416f010241.svg
/var/www/discourse/app/models/optimized_image.rb:87:in `block in create_for'
/var/www/discourse/app/models/optimized_image.rb:24:in `block (2 levels) in lock'
/var/www/discourse/lib/distributed_mutex.rb:33:in `block in synchronize'
/var/www/discourse/lib/distributed_mutex.rb:29:in `synchronize'
/var/www/discourse/lib/distributed_mutex.rb:29:in `synchronize'
/var/www/discourse/lib/distributed_mutex.rb:14:in `synchronize'
/var/www/discourse/app/models/optimized_image.rb:23:in `block in lock'
/var/www/discourse/lib/distributed_mutex.rb:33:in `block in synchronize'
/var/www/discourse/lib/distributed_mutex.rb:29:in `synchronize'
/var/www/discourse/lib/distributed_mutex.rb:29:in `synchronize'
/var/www/discourse/lib/distributed_mutex.rb:14:in `synchronize'
/var/www/discourse/app/models/optimized_image.rb:22:in `lock'
/var/www/discourse/app/models/optimized_image.rb:59:in `create_for'
/var/www/discourse/lib/site_icon_manager.rb:28:in `block in ensure_optimized!'
/var/www/discourse/lib/site_icon_manager.rb:24:in `each'
/var/www/discourse/lib/site_icon_manager.rb:24:in `ensure_optimized!'
/var/www/discourse/lib/tasks/db.rake:83:in `block in <top (required)>'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/exe/rake:27:in `<top (required)>'
/var/www/discourse/vendor/bundle/ruby/2.6.0/bin/ruby_executable_hooks:24:in `eval'
/var/www/discourse/vendor/bundle/ruby/2.6.0/bin/ruby_executable_hooks:24:in `<main>'
Tasks: TOP => db:migrate

처음에는 이것이 순수한 멀티사이트 문제인 줄 알았지만, 비멀티사이트 환경에서도 실패하고 있습니다.

재미있는 점은, 업로드가 아예 추출되지 않았다는 것입니다(편집: 그 시점에서는). 해당 특정 업로드는 아카이브에는 포함되어 있습니다.

tar tvf public/backups/default/redacted-forum-2020-03-02-165725-v20190130013015.tar.gz |grep 7be997f9f48c034ddf5d4eb95d2ea7416f010241
-rw-r--r-- daemon/daemon     3074 2019-05-27 08:21 uploads/default/original/2X/7/7be997f9f48c034ddf5d4eb95d2ea7416f010241.svg

원본 데이터베이스 덤프 버전 v20190130013015

그 후 업로드를 수동으로(default 폴더에) 추출한 뒤 복원을 다시 실행했고, 이번에는 성공했습니다.

그리고 나서야 발견했습니다… 업로드는 db:migrate 이후에 추출되는데, db:migrate는 이미 파일이 존재하는 것을 전제로 SiteIconManager.ensure_optimized!를 실행하고 있었습니다…

즉, 두 가지 문제가 있습니다:

  • SiteIconManager.ensure_optimized!가 이미지가 추출되기 전에 실행됩니다. (실제로는 두 번 실행됩니다 - 업로드가 추출된 후에도 한 번 더 실행됩니다)
  • 리맵이 아직 실행되지 않았기 때문에 파일이 default 폴더에 있을 것으로 기대하고 있습니다.

이 특정 경우에서는 svg 업로드에 대한 코드가 다른 코드 경로를 따르기 때문에 치명적으로 실패합니다. 다른 업로드의 경우에도 조용히 실패하는 것으로 보입니다.

참고로, db:migrate 중 이미지 최적화를 건너뛰는 SKIP_POST_DEPLOYMENT_MIGRATIONS=1을 사용하면 이를 우회할 수 있을 것 같아 보였지만, 시도해 본 결과 작동하지 않았습니다.

6개의 좋아요

이건 @sam이 봐야 할 것 같아?

1개의 좋아요

꽤나 직관적으로 보입니다:

그리고

이 플로우를 마지막으로 다룬 사람은 @gerhard입니다.

@RGJ 진단을 빠르게 진행하려면, 복원이 실패하는 단일 SVG 파일만 있는 빈 데이터베이스를 만들어 주시면 테스트하기 훨씬 쉬워질 것입니다.

7개의 좋아요

최소한의 용량으로 만든 백업 파일을 PM으로 보냈는데, 복원이 되지 않습니다.

버그가 발생하려면 favicon 또는 manifest에 “작은” svg 파일이 필요합니다.

참고로 SKIP_POST_DEPLOYMENT_MIGRATIONS가 명시적으로 리셋되므로, 그 방법이 우회책으로 작동하지 않은 이유를 이제야 알았습니다.

5개의 좋아요

문제를 보고해 주시고 예제 파일을 제공해 주셔서 감사합니다. 해당 문제는 수정되었습니다.

6개의 좋아요