Multisite가 업로드를 실제 데이터베이스 이름 대신 'default'로 복원합니다

Discourse 최신 베타 버전, docker 설치, 멀티사이트 환경입니다.

원본 데이터베이스 REDACTED의 백업을 현재 데이터베이스 db8015로 복원하려고 시도하고 있습니다. 업로드 파일은 파일시스템과 데이터베이스 모두에서 default에 저장됩니다.

이 문제는 GUI에서 복원을 트리거할 때도, RAILS_DB=db8015 RAILS_ENV=production script/discourse restore 명령을 사용하여 명령줄에서 복원을 수행할 때도 발생하며, 두 경우 모두 동일한 현상이 나타납니다.

복원 과정 중 RailsMultisite::ConnectionManagement.current_db가 올바른 데이터베이스에서 default로 변경됩니다. 이 문제는 Rake::Task[‘db:_dump’].invoke에 있는 db.rake 파일의 해당 라인으로 좁혀졌습니다. )

해당 라인 이전에는 RailsMultisite::ConnectionManagement.current_db가 올바른 값(db8015)을 가지고 있지만, 해당 라인 이후에는 default가 됩니다.

이 수정 사항이 프로덕션 환경을 어딘가에서 깨뜨린 것 같습니다. @sam?

로그:

[STARTED]
'DHSupport'가 복원을 시작했습니다!
복원을 실행 중으로 표시하는 중...
/var/www/discourse/tmp/restores/db8015/2019-10-11-104940 디렉터리가 존재하는지 확인하는 중...
아카이브를 tmp 디렉터리로 복사하는 중...
아카이브 압축을 해제하는 중... 시간이 좀 걸릴 수 있습니다...
추출할 메타데이터 파일이 없습니다.
메타데이터를 검증하는 중...
  현재 버전: 20191007140446
  복원된 버전: 20190908234054
덤프 파일을 추출하는 중...
discourse_functions 스키마에 없는 함수를 생성하는 중
다른 스키마로 복원할 수 없어, 현재 위치에 복원 중
읽기 전용 모드를 활성화하는 중...
sidekiq를 일시 정지하는 중...

[관련 없는 내용 많이 삭제됨]

테마 캐시 정리
업로드 추출 중...
업로드 재매핑 중...
'uploads/REDACTED'를 'uploads/default'로 재매핑 중
사이트 아이콘 최적화 중...
게시물은 sidekiq의 백그라운드 작업에 의해 다시 베이킹됩니다. 작업이 완료될 때까지 이미지가 누락되어 보일 수 있습니다.
"rake posts:rebake_uncooked_posts"를 수동으로 실행하여 프로세스를 가속화할 수 있습니다.
after_restore_hook 실행 중...
정리 작업 수행 중...
discourse_functions 스키마에서 함수 제거
tmp '/var/www/discourse/tmp/restores/db8015/2019-10-11-104940' 디렉터리 제거 중...
sidekiq 일시 정지 해제 중...
복원 완료를 표시하는 중...

이건 아직도 문제인가요 @sam?

정리하자면, 재현 방법은 다음과 같습니다:

  • Docker 컨테이너에서 멀티사이트를 생성합니다

  • 멀티사이트 중 하나를 백업합니다

  • 새로운 Docker 컨테이너에서 이를 복원합니다

  • 업로드 파일이 잘못된 위치에 있습니다

@kris.kotlarek 로컬에서 이 문제를 재현해 보고 수정할 수 있는지 확인해 주시겠어요?

앞으로도 이 문제에 영향을 받을 가능성이 있다고 생각합니다.

이 문제를 재현하려면 대상 컨테이너만 멀티사이트일 필요가 있습니다.

  • 도커 컨테이너에서 포럼을 생성합니다
  • 백업을 생성합니다
  • 새로운 멀티사이트 도커 컨테이너에서 이를 복원합니다
  • 업로드 파일이 잘못된 위치에 있습니다

이 버그에 대해 시간을 좀 들였고, 조사 결과를 공유드리고자 합니다. 기본적으로 이미 말씀하신 내용을 모두 확인했고, 복원 프로세스는 다음과 같은 구조입니다:

migrate_database
reconnect_database
...
extract_uploads

문제는 마이그레이션 작업 이후 reconnect_database가 원하는 데이터베이스로 전환되지 않고, 기본 데이터베이스에서 작업을 시작한다는 점입니다.

따라서 다음 코드는 잘못된 것입니다.

def extract_uploads
  ...
  current_db_name = 
  RailsMultisite::ConnectionManagement.current_db # default
  optimized_images_exist = File.exist?(File.join(tmp_uploads_path, 'optimized'))

해킹적인 해결책이라면, RailsMultisite::ConnectionManagement.current_db 대신 여전히 올바른 이름을 포함하고 있는 @current_db를 여기에서 사용하는 것입니다. 하지만 이는 reconnect_database가 제대로 작동하지 않는 근본적인 문제를 해결하지는 못합니다.

문제를 찾기 위해 더 깊이 파고들어야 합니다.

마이그레이션 작업 이후에 발생한다는 것에 확신이 있으신가요?

이 코드

  migrate_database
  puts "After migrate, before reconnect #{RailsMultisite::ConnectionManagement.current_db}"
  reconnect_database

다음과 같이 출력됩니다.

Optimizing site icons... Done
After migrate, before reconnect default
Reconnecting to the database...

하지만 lib/tasks/db.rake 파일에서

Rake::Task['db:_dump'].invoke

라인을 주석 처리하면

다음과 같이 출력됩니다.

Optimizing site icons... Done
After migrate, before reconnect db8015
Reconnecting to the database...

맞습니다. restorer.rb에서 Rake::Task["db:migrate"].invoke를 제거했더니 전체 과정에서 데이터베이스가 올바르게 생성되었습니다.
저보다 한 발 앞서 계시네요. 이제 migrate 태스크로 들어가서 어떤 단계에서 프로세스가 깨지는지 확인해볼 계획입니다.
_dump를 지적해 주셔서 감사합니다. 바로 그곳으로 가서 내부에서 무슨 일이 일어나고 있는지 확인하겠습니다.

조사를 좀 해봤는데 결국 해결책을 찾았어요 :slight_smile:

감사합니다!

좀 더 생각해 본 결과, 기본 데이터베이스가 아닌 대상에서 db:dump를 실행하는 것이 실제로 무슨 의미인가요?

데이터베이스가 기본값이 아니라면 db:dump 명령을 그냥 건너뛰는 게 맞지 않을까요?

수정된 PR이 병합되었습니다. 해당 문제를 찾아주셔서 감사합니다. 그 dump 명령은 멀티사이트 마이그레이션에 문제가 있어서 추가되었습니다. 구조를 덤프할 때 어떤 데이터베이스를 사용하든 상관없을 것 같습니다. 모든 멀티사이트는 동일한 구조를 가져야 하니까요.