> For the complete documentation index, see [llms.txt](https://overleaf-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://overleaf-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 讀取並寫入。檔案會非同步寫入歷史記錄。
* `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 服務會從編譯器服務提供讀取。

{% 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 工具包使用者：
$ 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 工具包使用者：
$ 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 工具包使用者：
$ 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
開始專案檔案備份...
已載入全域 blobs：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":"file-migration 統計資料","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` 服務中的 event loop 可能會出現一些阻塞，進而導致使用者體驗下降。建議先使用下列預設值： `--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://overleaf-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.
