> For the complete documentation index, see [llms.txt](https://ayakaleaf-pro.ayaka.space/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ayakaleaf-pro.ayaka.space/on-premises/ko/support/support-guides/v5.5.7-migration-binary-files-migration.md).

# (v5.5.7 마이그레이션) 바이너리 파일 마이그레이션

## 바이너리 파일 마이그레이션

곧 출시될 주요 버전 `6.0` Server Pro 및 Community Edition의 릴리스는 바이너리 파일의 저장 공간 사용량을 절반으로 줄입니다. 온라인 마이그레이션은 버전에 포함되어 있습니다 `5.5.7` , 업그레이드의 일환으로 최소한의 다운타임만 발생하도록 합니다.

Server Pro부터 `4.x`, 바이너리 파일은 두 번 저장됩니다: "filestore"의 활성 파일 저장소와 전체 프로젝트 기록 시스템에 저장됩니다. 앞으로는 각 파일의 단일 사본이 전체 프로젝트 기록 시스템에 저장됩니다.

마이그레이션을 통합 저장 시스템으로 옮기는 작업은 두 부분으로 구성됩니다: 마이그레이션 단계 제어를 위한 새 플래그와 모든 활성 및 소프트 삭제된 프로젝트를 처리하는 스크립트입니다.

단계:

* `OVERLEAF_FILESTORE_MIGRATION_LEVEL=0` (기본값) 파일은 filestore에서 읽고 쓰입니다. 파일은 비동기적으로 기록 시스템에 기록됩니다.
* `OVERLEAF_FILESTORE_MIGRATION_LEVEL=1` , 파일은 기록 시스템에서 읽되 필요 시 filestore로 대체되며, filestore와 기록 시스템에 모두 기록됩니다. 다음으로 다운그레이드하는 것은 `OVERLEAF_FILESTORE_MIGRATION_LEVEL=0` 가능합니다.
* `OVERLEAF_FILESTORE_MIGRATION_LEVEL=2` 파일은 기록 시스템에서만 읽고 쓰입니다. 다음으로 다운그레이드하는 것은 `OVERLEAF_FILESTORE_MIGRATION_LEVEL=1` "오프라인"으로 수행된 경우가 아니면 불가능합니다.

데이터를 저장할 때 [S3](https://docs.overleaf.com/on-premises/configuration/overleaf-toolkit/s3) 그리고 filestore용 별도 서비스 계정(`OVERLEAF_FILESTORE_S3_ACCESS_KEY_ID`)와 기록(`OVERLEAF_HISTORY_S3_ACCESS_KEY_ID`)을 사용하는 경우: filestore 사용자에게 blob에 대한 기록 버킷 읽기 권한을 부여해 주세요 `OVERLEAF_HISTORY_PROJECT_BLOBS_BUCKET` . 앞으로 filestore 서비스가 컴파일러 서비스에서의 읽기를 처리합니다.

{% hint style="warning" %}
바이너리 파일 마이그레이션은 먼저 비운영/샌드박스 환경에서 수행하는 것을 강력히 권장합니다.
{% endhint %}

{% hint style="success" %}
표준 Server Pro 라이선스는 애플리케이션을 운영 환경뿐 아니라 비운영/샌드박스 환경 하나에서도 실행할 수 있게 해줍니다. 테스트를 위해 비운영 환경을 마련하는 것을 강력히 권장합니다.
{% endhint %}

{% hint style="info" %}
Server Pro/CE 버전으로 업그레이드한 후 `6.0` 나중에 더 이전 버전으로 다운그레이드하고 싶다면 전체 시스템 백업에서 복원해야 합니다.
{% endhint %}

### 마이그레이션 절차

{% stepper %}
{% step %}

#### 백업 생성

전체 [백업](https://docs.overleaf.com/on-premises/maintenance/data-and-backups#performing-a-consistent-backup) 의 일관된 스냅샷으로 인스턴스를 **mongo**, **redis** 및 **sharelatex** 디렉터리의.
{% endstep %}

{% step %}

#### 업데이트

**툴킷:** 다음을 사용하세요 `$ bin/upgrade` 업그레이드하는 스크립트 **툴킷** 을 최신 버전으로 업데이트합니다. 요청이 표시되면 **하지** 프롬프트를 확인하세요 **업그레이드** 이미지? — 대신 수동으로 편집하세요 **config/version** 파일을 열어 값을 다음으로 설정하세요 `5.5.7`.

**레거시 docker-compose.yml:** 의 버전을 업데이트합니다 `sharelatex` 서비스를 `5.5.7`.
{% endstep %}

{% step %}

#### 영향을 받는 프로젝트 수 추정

{% code overflow="wrap" %}

```bash
# Overleaf Toolkit 사용자:
$ bin/docker-compose exec sharelatex /bin/bash -c "source /etc/overleaf/env.sh && source /etc/container_environment.sh && cd /overleaf/services/history-v1 && /sbin/setuser www-data node storage/scripts/back_fill_file_hash.mjs --report"

# 레거시 docker-compose.yml 사용자:
$ docker compose exec sharelatex /bin/bash -c "source /etc/overleaf/env.sh && source /etc/container_environment.sh && cd /overleaf/services/history-v1 && /sbin/setuser www-data node storage/scripts/back_fill_file_hash.mjs --report"
```

{% endcode %}

출력 예시:

{% code fullWidth="false" %}

```
현재 상태:
- 프로젝트 총 수: 10
- 삭제된 프로젝트 총 수: 5
진행 상황을 추정하기 위해 1000개 프로젝트를 샘플링하는 중...
프로젝트 샘플 통계:
- 샘플링된 프로젝트: 9개(전체 프로젝트의 90%)
- 모든 해시가 존재하는 샘플링된 프로젝트: 5개
- 해시 백필이 필요한 프로젝트 비율: 44%(추정)
- 샘플링된 프로젝트에는 전체 프로젝트 기록 시스템과 대조해야 할 파일이 11개 있습니다.
- 샘플링된 프로젝트에는 전체 프로젝트 기록 시스템에 업로드해야 할 파일이 3개 있습니다(전체 파일의 27%로 추정).
삭제된 프로젝트 샘플 통계:
- 샘플링된 삭제된 프로젝트: 4개(전체 삭제된 프로젝트의 80%)
- 모든 해시가 존재하는 샘플링된 삭제된 프로젝트: 3개
- 해시 백필이 필요한 삭제된 프로젝트 비율: 25%(추정)
- 샘플링된 삭제된 프로젝트에는 전체 프로젝트 기록 시스템과 대조해야 할 파일이 2개 있습니다.
- 샘플링된 삭제된 프로젝트에는 전체 프로젝트 기록 시스템에 업로드해야 할 파일이 1개 있습니다(전체 파일의 50%로 추정).
```

{% endcode %}
{% endstep %}

{% step %}

#### 프로젝트 기록 대기열 비우기

{% code overflow="wrap" %}

```bash
# Overleaf Toolkit 사용자:
$ bin/docker-compose exec sharelatex /overleaf/bin/flush-history-queues

# 레거시 docker-compose.yml 사용자:
$ docker compose exec sharelatex /overleaf/bin/flush-history-queues
```

{% endcode %}

모든 프로젝트가 비워질 때까지 비우기를 반복하세요 (`"project_ids":0`).

```
프로젝트를 찾음 {"project_ids":0,"limit":100000,"ts":"2025-09-01T10:35:33.353Z"}
총계 {"succeededProjects":0,"failedProjects":0}
```

{% hint style="danger" %}
만약 "failedProjects"가 0이 아니라면, 지원팀에 연락하고 바이너리 파일 마이그레이션을 계속 진행하지 마세요.
{% endhint %}
{% endstep %}

{% step %}

#### 마이그레이션 단계를 1로 진행

툴킷: 설정 `OVERLEAF_FILESTORE_MIGRATION_LEVEL=1` 의 `config/variables.env`.

레거시 docker-compose.yml: 설정 `OVERLEAF_FILESTORE_MIGRATION_LEVEL: '1'` 다음에서 `환경` 섹션 `sharelatex` 서비스.
{% endstep %}

{% step %}

#### 구성 변경을 적용하고 인스턴스를 시작하세요

툴킷: `bin/up -d`

레거시 docker-compose.yml: `docker compose up -d`
{% endstep %}

{% step %}

#### 바이너리 파일 접근 확인

브라우저에서 Overleaf 편집기로 프로젝트를 열고 이미지 같은 바이너리 파일을 선택하세요.
{% endstep %}

{% step %}

#### 마이그레이션 스크립트를 실행하세요

{% code overflow="wrap" %}

```bash
# Overleaf Toolkit 사용자:
$ bin/docker-compose exec sharelatex /bin/bash -c "source /etc/overleaf/env.sh && source /etc/container_environment.sh && cd /overleaf/services/history-v1 && /sbin/setuser www-data node storage/scripts/back_fill_file_hash.mjs --all"

# 레거시 docker-compose.yml 사용자:
$ docker compose exec sharelatex /bin/bash -c "source /etc/overleaf/env.sh && source /etc/container_environment.sh && cd /overleaf/services/history-v1 && /sbin/setuser www-data node storage/scripts/back_fill_file_hash.mjs --all"
```

{% endcode %}

{% hint style="danger" %}
만약 [로그를 지속적으로 저장하는](https://docs.overleaf.com/on-premises/configuration/overleaf-toolkit/logging#persisting-logs) 파일을 컨테이너 밖에 **sharelatex** 컨테이너에 저장한다면, logs 디렉터리 소유자가 다음으로 설정되어 있는지 확인하세요 `www-data` 사용자(uid=33)로, 출력되는 로그 파일이 기록될 수 있도록 합니다.
{% endhint %}

출력은 다음과 같아야 합니다:

```bash
UV_THREADPOOL_SIZE=16으로 설정
{"name":"default","hostname":"c25e9faaeb53","pid":971,"level":30,"backend":"fs","msg":"Loading backend","time":"2025-07-25T15:00:58.166Z","v":0}
/var/log/overleaf/file-migration-2025-07-25T15_00_58_199Z.log에 로그를 기록하는 중
프로젝트 파일 백업 시작 중...
로드된 전역 blob: 0
삭제되지 않은 프로젝트 처리 중...
프로젝트 1개 처리됨, 경과 시간 0초
실시간 프로젝트 업데이트 완료
삭제된 프로젝트 처리 중...
deletedProjects 컬렉션이 비어 있는 것 같습니다.

삭제된 프로젝트 업데이트 완료
완료되었습니다.

```

마이그레이션이 성공하면 종료 코드 `0`를 받게 되며, 마지막 줄에는 실패가 없다는 내용이 표시됩니다:

```bash
완료되었습니다.
```

로그 파일은 다음과 같습니다(스크립트에 출력된 경로를 사용하세요):

{% code overflow="wrap" %}

```bash
$ docker cp sharelatex:/var/log/overleaf/file-migration-2025-07-25T15_00_58_199Z.log .
$ cat file-migration-2025-07-25T15_00_58_199Z.log
{"name":"file-migration","hostname":"c25e9faaeb53","pid":971,"level":30,"end":"68839a8f577b9f009d947b27 (2025-07-25T14:54:07.000Z)","msg":"actually completed batch","time":"2025-07-25T15:00:58.379Z","v":0}
{"name":"file-migration","hostname":"c25e9faaeb53","pid":971,"level":30,"time":"2025-07-25T15:00:58.383Z","LOGGING_IDENTIFIER":"4effa2000000000000000000","projects":1,"blobs":6,"filesWithHash":5,"filesWithoutHash":2,"filesDuplicated":0,"filesRetries":0,"filesFailed":0,"fileTreeUpdated":0,"badFileTrees":0,"globalBlobsCount":0,"globalBlobsEgress":0,"projectDeleted":0,"projectHardDeleted":0,"fileHardDeleted":0,"mongoUpdates":1,"readFromGCSCount":7,"readFromGCSIngress":28532,"writeToGCSCount":5,"writeToGCSEgress":300,"readFromGCSThroughputMiBPerSecond":0.14925639825786063,"eventLoop":{"idle":48.277844,"active":381.53244699971054,"utilization":0.8876763888372498},"diff":{"eventLoop":{"idle":48.223536,"active":134.04030200059555,"utilization":0.7354190687027976},"projects":1,"blobs":6,"filesWithHash":5,"filesWithoutHash":2,"filesDuplicated":0,"filesRetries":0,"filesFailed":0,"fileTreeUpdated":0,"badFileTrees":0,"globalBlobsCount":0,"globalBlobsEgress":0,"projectDeleted":0,"projectHardDeleted":0,"fileHardDeleted":0,"mongoUpdates":1,"readFromGCSCount":7,"readFromGCSIngress":28532,"writeToGCSCount":5,"writeToGCSEgress":300,"readFromGCSThroughputMiBPerSecond":0.14925639825786063},"deferredBatches":[],"msg":"file-migration stats","v":0}
```

{% endcode %}
{% endstep %}

{% step %}

#### 인스턴스 중지

툴킷: `bin/stop sharelatex`

레거시 docker-compose.yml: `docker compose stop sharelatex`
{% endstep %}

{% step %}

#### 기존 파일을 애플리케이션에서 접근할 수 없게 만들기

이제 기존 파일을 보조 저장소로 옮길 수 있습니다. 나중에 문제가 생길 경우를 대비해 파일을 한동안 보관하는 것을 권장합니다.

{% code overflow="wrap" %}

```bash
# 툴킷 사용자:
$ bin/docker-compose run --rm --entrypoint mv sharelatex --no-clobber --verbose /var/lib/overleaf/data/user_files /var/lib/overleaf/data/old_user_files

# 레거시 docker-compose.yml 사용자:
# /var/lib/overleaf의 기본 bind-mount를 사용하고 있다고 가정합니다
$ docker compose run --rm --entrypoint mv sharelatex --no-clobber --verbose /var/lib/overleaf/data/user_files /var/lib/overleaf/data/old_user_files
# 선택적 bind-mount를 사용 중이라면, 컨테이너 내부의 /var/lib/overleaf/data/user_files에 대한 bind-mount를 간단히 제거하면 됩니다.
```

{% endcode %}
{% endstep %}

{% step %}

#### 마이그레이션 단계를 2로 진행

툴킷: 설정 `OVERLEAF_FILESTORE_MIGRATION_LEVEL=2` 의 `config/variables.env`.

레거시 docker-compose.yml: 설정 `OVERLEAF_FILESTORE_MIGRATION_LEVEL: '2'` 다음에서 `환경` 섹션 `sharelatex` 서비스.
{% endstep %}

{% step %}

#### 구성 변경을 적용하고 인스턴스를 시작하세요

툴킷: `bin/up -d`

레거시 docker-compose.yml: `docker compose up -d`
{% endstep %}

{% step %}

#### 바이너리 파일 접근 확인

브라우저에서 Overleaf 편집기로 프로젝트를 열고 이미지 같은 바이너리 파일을 선택하세요.
{% endstep %}
{% endstepper %}

#### 오프라인 마이그레이션

바이너리 파일 마이그레이션 스크립트가 실행되는 동안 사용자의 로그인을 막고 싶다면 다음 단계를 따르세요:

* 관리자 계정으로 Overleaf 인스턴스에 로그인하세요
* 다음을 클릭하세요: **관리자** 버튼을 누르고 **사이트 관리**
* 다음을 클릭하세요: **편집기 열기/닫기** 탭
* 다음을 클릭하세요: **편집기 닫기** 버튼
* 다음을 클릭하세요: **모든 사용자 연결 끊기** 버튼

이 작업이 완료되면, 로그인한 모든 사용자는 유지보수 페이지로 리디렉션되고, 로그인 페이지를 방문하는 새 사용자는 유지보수 페이지를 보게 되며 **적용되지** 로그인할 수 없습니다.

인스턴스를 다시 시작할 때 이 단계를 반복해야 합니다. 사이트를 다시 열려면 인스턴스를 다시 시작하면 됩니다.

#### 온라인 마이그레이션

애플리케이션이 계속 실행 중인 상태에서도 마이그레이션 스크립트를 실행할 수 있습니다. 다만 고려해야 할 사항이 몇 가지 있습니다:

* 마이그레이션 과정은 I/O 집약적이므로, 스크립트가 실행되는 동안 리소스 사용량을 모니터링해야 합니다.
* 처리 동시성이 높으면 다음의 이벤트 루프가 `filestore` 서비스에서 일부 블로킹이 발생할 수 있으며, 이는 사용자 경험 저하로 이어질 수 있습니다. 다음의 기본값으로 시작하는 것을 권장합니다 `--concurrency=10` 및 `--concurrent-batches=1` .
* 스크립트는 언제든지 중지할 수 있습니다. 다시 시작하면 이전 프로젝트를 검증하고 이미 처리된 파일은 건너뜁니다. 이는 마이그레이션을 덜 바쁜 시간대(예: 밤)에 실행하고 싶을 때 유용합니다.

프로젝트 수가 1000개 미만일 때 유지보수 창에서 사이트를 닫고 오프라인으로 마이그레이션을 실행하는 것을 권장합니다(다음을 사용하여 `--report`) 사이트를 닫고 유지보수 기간에 오프라인으로 마이그레이션을 실행하는 것을 권장합니다. 프로젝트 수가 많다면 스크립트를 실행하고 진행 상황을 모니터링한 다음, 특정 상황에 따라 온라인 또는 오프라인으로 계속 실행할지 결정할 수 있습니다.

#### 레거시 바이너리 파일 데이터 정리

마이그레이션을 마치고 프로젝트가 여전히 모든 파일에 접근할 수 있음을 확인했다면, 다음의 기존 파일 저장소를 제거할 수 있습니다 `/var/lib/overleaf/data/user_files`. 이 파일들을 한동안 보관할 것을 강력히 권장합니다. 먼저 폴더 이름을 바꿔 애플리케이션에서 접근할 수 없게 만들 수 있습니다.

### 문제 해결

여기에 문제 해결 조언을 추가할 예정입니다. 일반적으로는 Server Pro 고객에게만 지원을 제공하지만, 이 마이그레이션의 특성상 바이너리 파일 마이그레이션에 특화된 문제를 겪는 CE 고객도 최대한 지원할 예정입니다.

바이너리 파일 마이그레이션 스크립트가 실패하면(즉, 오류로 종료되거나 실패한 프로젝트 수가 0이 아닌 값으로 출력되면) 다음 세부 정보를 이메일로 지원팀에 보내 주세요 [support+filestoremigration@overleaf.com](mailto:support+filestoremigration@overleaf.com?subject=Binary%20file%20migration%20problem\&body=Instance%20Type%3A%20CE%20or%20Server%20Pro%20%28delete%20as%20appropriate%29%0A%0AInstallation%20Type%3A%20Overleaf%20toolkit%20or%20docker-compose.yml%20or%20other%20%28delete%20as%20appropriate%29%0A%0AScript%20output%3A%0A%0Abin%2Fdoctor%20output%20%28if%20using%20toolkit%29%3A%0A), 다음 내용을 포함하여:

제목: 바이너리 파일 마이그레이션 문제

본문:

* 인스턴스 유형: CE 또는 Server Pro(해당 사항 삭제)
* 설치 유형: Overleaf toolkit 또는 `docker-compose.yml` 또는 기타(해당 사항 삭제)
* 버전: 5.5.x (툴킷: `$ cat config/version`)
* 마이그레이션 스크립트 출력(이는 컨테이너 내부의 `/var/log/overleaf`)
* 보고서: (다음을 사용하여 마이그레이션 스크립트를 실행 `--report`)
* 처리된 프로젝트: (스크립트의 마지막 실행 기준)
* 마이그레이션 소요 시간:
* `bin/doctor` 출력(toolkit 사용 시)
* Toolkit 버전: `$ git rev-parse HEAD` (Toolkit 사용 시)

다음 서비스의 로그 파일을 이메일에 첨부하는 것을 고려하세요. `filestore` 서비스 로그를 이메일에 첨부하세요. 위치는 다음과 같습니다 `/var/log/overleaf/filestore.log` 안쪽의 `sharelatex` 컨테이너 내부에 있으며 다음과 같이 내보낼 수 있습니다:

```bash
$ docker cp sharelatex:/var/log/overleaf/filestore.log .
# <timestamp>를 스크립트에 표시된 타임스탬프로 바꾸세요
$ docker cp sharelatex:/var/log/overleaf/file-migration-<timestamp>.log .
```

첨부하기 전에 로그 파일의 민감한 정보는 반드시 삭제하세요.

#### 누락된 파일

이전 버전의 Server Pro/CE는 사용자 업로드가 끝나기 전에 파일 트리 항목을 생성했기 때문에, 업로드 실패 시 파일이 누락된 것처럼 보일 수 있었습니다. 모든 파일 트리를 처리할 때 이러한 사례 중 일부가 오류로 보고될 수 있습니다.

누락된 파일 수가 적다면, 해당 사례를 수동으로 검토한 뒤 브라우저의 편집기에서 삭제하는 것을 고려하세요.

누락된 파일 수가 많다면 지원팀에 문의하는 것을 고려하세요. 위의 이메일 템플릿을 참고하세요.

#### 깨진 파일 트리 찾기

예를 들어 파일명이 비어 있는 등 잘못된 형식의 파일 트리를 가진 프로젝트에서는 마이그레이션이 실패할 수 있습니다. 다음 `find_malformed_filetrees` 스크립트를 사용하면 이런 문제의 목록을 찾을 수 있으며, 이 스크립트는 데이터베이스의 모든 프로젝트를 검사합니다:

{% code overflow="wrap" %}

```bash
$ bin/docker-compose exec sharelatex /bin/bash -c "cd /overleaf/services/web && /sbin/setuser www-data node scripts/find_malformed_filetrees.mjs > /tmp/malformed-file-trees.json"
```

{% endcode %}

잘못된 경로를 수정하려면 `fix_malformed_filetree` 스크립트를 사용하고, 각 잘못된 경로마다 명령을 한 번씩 실행하세요:

{% code overflow="wrap" %}

```bash
$ bin/docker-compose exec sharelatex /bin/bash -c "cd /overleaf/services/web && /sbin/setuser www-data node scripts/fix_malformed_filetree.mjs --logs=/tmp/malformed-file-trees.json"
```

{% endcode %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://ayakaleaf-pro.ayaka.space/on-premises/ko/support/support-guides/v5.5.7-migration-binary-files-migration.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
