> 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/zh-tw/zhi-yuan/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 讀取並寫入 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 使用者對歷史 bucket 中 blobs 的讀取權限 `OVERLEAF_HISTORY_PROJECT_BLOBS_BUCKET` 。未來，filestore 服務將代替 compiler 服務提供讀取。

{% 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":"載入後端","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":"實際完成批次","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":"檔案遷移統計","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 執行個體
* 點擊 **管理員** 按鈕並選擇 **管理網站**
* 點擊 **開啟／關閉編輯器** 分頁
* 點擊 **關閉編輯器** 按鈕
* 點擊 **中斷所有使用者連線** 按鈕

完成後，如果有任何使用者已登入，他們會被重新導向至維護頁面，而任何前往登入頁面的新使用者都會看到維護頁面並 **不會** 能夠登入。

在重新啟動執行個體時，您需要重複這些步驟。若要重新開啟網站，只需重新啟動執行個體。

#### 線上遷移

可以在應用程式仍在執行時執行遷移腳本。需要考慮幾點事項：

* 遷移過程的 IO 負載很高，指令碼執行時應監控資源使用量。
* 在高處理並行度下， `filestore` 服務的事件迴圈可能會出現一些阻塞，進而導致使用者體驗下降。我們建議先使用以下預設值： `--concurrency=10` 以及 `--concurrent-batches=1` .
* 您可以隨時停止指令碼。再次啟動時，會驗證先前的專案並略過已處理過的檔案。若您偏好在較不繁忙的時段執行遷移（例如夜間），這會很有幫助。

我們建議關閉網站，並在維護時段離線執行遷移，前提是您的專案數少於 1000 個（請參閱使用 `--report`）。如果專案數量很大，您可以執行腳本並監控其進度，然後依您的具體情況決定是繼續線上執行還是離線執行。

#### 清理舊版二進位檔案資料

當您完成遷移並確認專案仍可存取其所有檔案後，您可以移除下列位置的舊檔案儲存： `/var/lib/overleaf/data/user_files`。我們強烈建議先保留這些檔案一段時間——您可以先重新命名資料夾，讓應用程式無法存取它們。

### 疑難排解

我們會在此加入疑難排解建議。請注意，雖然我們通常只為 Server Pro 客戶提供支援，但基於此遷移的性質，我們也會盡力支援遇到二進位檔案遷移特定問題的 CE 客戶。

如果二進位檔案遷移指令碼失敗（亦即以錯誤結束或列印出非零數量的失敗專案），請將以下詳細資料透過電子郵件寄給我們的支援團隊 [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/zh-tw/zhi-yuan/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.
