> 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/vi/ho-tro/support-guides/v5.5.7-migration-binary-files-migration.md).

# (Di chuyển v5.5.7) Di chuyển tệp nhị phân

## Di chuyển tệp nhị phân

Phiên bản lớn sắp tới `6.0` bản phát hành của Server Pro và Community Edition sẽ giảm một nửa dung lượng lưu trữ của các tệp nhị phân. Một quá trình di chuyển trực tuyến được bao gồm trong phiên bản `5.5.7` , cho phép thời gian gián đoạn tối thiểu trong quá trình nâng cấp.

Kể từ Server Pro `4.x`, các tệp nhị phân được lưu trữ hai lần: trong bộ lưu trữ tệp đang hoạt động trong "filestore" và trong hệ thống lịch sử đầy đủ của dự án. Về sau, mỗi tệp sẽ chỉ được lưu một bản sao trong hệ thống lịch sử đầy đủ của dự án.

Quá trình di chuyển sang hệ thống lưu trữ hợp nhất gồm hai phần: một cờ mới để kiểm soát giai đoạn di chuyển và một script xử lý tất cả các dự án đang hoạt động và đã xóa mềm.

Các giai đoạn:

* `OVERLEAF_FILESTORE_MIGRATION_LEVEL=0` (mặc định), tệp được đọc và ghi vào filestore. Tệp được ghi vào history không đồng bộ.
* `OVERLEAF_FILESTORE_MIGRATION_LEVEL=1` , tệp được đọc từ history với phương án dự phòng sang filestore và được ghi vào cả filestore lẫn history. Hạ cấp xuống `OVERLEAF_FILESTORE_MIGRATION_LEVEL=0` là khả thi.
* `OVERLEAF_FILESTORE_MIGRATION_LEVEL=2` tệp chỉ được đọc và ghi vào history. Hạ cấp xuống `OVERLEAF_FILESTORE_MIGRATION_LEVEL=1` là không thể, trừ khi nó được thực hiện "ngoại tuyến".

Khi lưu trữ dữ liệu trong [S3](https://docs.overleaf.com/on-premises/configuration/overleaf-toolkit/s3) và sử dụng các tài khoản dịch vụ riêng cho filestore (`OVERLEAF_FILESTORE_S3_ACCESS_KEY_ID`)`OVERLEAF_HISTORY_S3_ACCESS_KEY_ID`: Vui lòng cấp cho người dùng filestore quyền đọc vào bucket lịch sử cho các blob `OVERLEAF_HISTORY_PROJECT_BLOBS_BUCKET` . Dịch vụ filestore sẽ phục vụ các yêu cầu đọc từ dịch vụ biên dịch trong tương lai.

{% hint style="warning" %}
Bạn rất nên thực hiện di chuyển tệp nhị phân trong môi trường không phải sản xuất/sandbox trước.
{% endhint %}

{% hint style="success" %}
Giấy phép Server Pro tiêu chuẩn cho phép bạn chạy ứng dụng trong môi trường sản xuất cũng như một môi trường không phải sản xuất/sandbox; rất nên thiết lập một môi trường không phải sản xuất để thử nghiệm.
{% endhint %}

{% hint style="info" %}
Nếu bạn nâng cấp lên phiên bản Server Pro/CE `6.0` và sau đó quyết định muốn hạ cấp xuống phiên bản cũ hơn, thì bạn nên khôi phục từ bản sao lưu toàn hệ thống.
{% endhint %}

### Quy trình di chuyển

{% stepper %}
{% step %}

#### Tạo bản sao lưu

Tạo một [bản sao lưu](https://docs.overleaf.com/on-premises/maintenance/data-and-backups#performing-a-consistent-backup) đầy đủ của phiên bản của bạn với một ảnh chụp nhất quán của các **mongo**, **redis** và **sharelatex** thư mục.
{% endstep %}

{% step %}

#### Cập nhật

**Toolkit:** Sử dụng `$ bin/upgrade` script để nâng cấp **toolkit** lên phiên bản mới nhất. Khi được hỏi, đừng **không** xác nhận lời nhắc **Nâng cấp** image? — thay vào đó, hãy chỉnh sửa thủ công **config/version** tệp và đặt giá trị thành `5.5.7`.

**docker-compose.yml kiểu cũ:** Cập nhật phiên bản của `sharelatex` dịch vụ thành `5.5.7`.
{% endstep %}

{% step %}

#### Ước tính số lượng dự án bị ảnh hưởng

{% code overflow="wrap" %}

```bash
# Người dùng 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"

# Người dùng docker-compose.yml kiểu cũ:
$ 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 %}

Ví dụ đầu ra:

{% code fullWidth="false" %}

```
Trạng thái hiện tại:
- Tổng số dự án: 10
- Tổng số dự án đã xóa: 5
Đang lấy mẫu 1000 dự án để ước tính tiến độ...
Thống kê mẫu cho dự án:
- Dự án được lấy mẫu: 9 (90% của tất cả dự án)
- Dự án được lấy mẫu có đủ tất cả các hash: 5
- Tỷ lệ dự án cần bổ sung hash: 44% (ước tính)
- Các dự án được lấy mẫu có 11 tệp cần được kiểm tra đối chiếu với hệ thống lịch sử đầy đủ của dự án.
- Các dự án được lấy mẫu có 3 tệp cần được tải lên hệ thống lịch sử đầy đủ của dự án (ước tính 27% của tất cả tệp).
Thống kê mẫu cho các dự án đã xóa:
- Dự án đã xóa được lấy mẫu: 4 (80% của tất cả dự án đã xóa)
- Dự án đã xóa được lấy mẫu có đủ tất cả các hash: 3
- Tỷ lệ dự án đã xóa cần bổ sung hash: 25% (ước tính)
- Các dự án đã xóa được lấy mẫu có 2 tệp cần được kiểm tra đối chiếu với hệ thống lịch sử đầy đủ của dự án.
- Các dự án đã xóa được lấy mẫu có 1 tệp cần được tải lên hệ thống lịch sử đầy đủ của dự án (ước tính 50% của tất cả tệp).
```

{% endcode %}
{% endstep %}

{% step %}

#### Xả hàng đợi lịch sử dự án

{% code overflow="wrap" %}

```bash
# Người dùng Overleaf Toolkit:
$ bin/docker-compose exec sharelatex /overleaf/bin/flush-history-queues

# Người dùng docker-compose.yml kiểu cũ:
$ docker compose exec sharelatex /overleaf/bin/flush-history-queues
```

{% endcode %}

Lặp lại việc xả cho đến khi tất cả dự án đã được xả (`"project_ids":0`).

```
found projects {"project_ids":0,"limit":100000,"ts":"2025-09-01T10:35:33.353Z"}
total {"succeededProjects":0,"failedProjects":0}
```

{% hint style="danger" %}
Nếu "failedProjects" không bằng 0, vui lòng liên hệ bộ phận hỗ trợ và không tiếp tục quá trình di chuyển tệp nhị phân.
{% endhint %}
{% endstep %}

{% step %}

#### Chuyển giai đoạn di chuyển sang 1

Toolkit: Đặt `OVERLEAF_FILESTORE_MIGRATION_LEVEL=1` trong `config/variables.env`.

docker-compose.yml kiểu cũ: Đặt `OVERLEAF_FILESTORE_MIGRATION_LEVEL: '1'` trong `môi trường` phần của `sharelatex` dịch vụ.
{% endstep %}

{% step %}

#### Áp dụng thay đổi cấu hình và khởi động phiên bản

Toolkit: `bin/up -d`

docker-compose.yml kiểu cũ: `docker compose up -d`
{% endstep %}

{% step %}

#### Xác minh quyền truy cập vào các tệp nhị phân

Mở một dự án trong trình soạn thảo Overleaf trên trình duyệt và chọn một tệp nhị phân, chẳng hạn như hình ảnh.
{% endstep %}

{% step %}

#### Chạy script di chuyển

{% code overflow="wrap" %}

```bash
# Người dùng 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"

# Người dùng docker-compose.yml kiểu cũ:
$ 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" %}
Nếu bạn đang [lưu giữ log](https://docs.overleaf.com/on-premises/configuration/overleaf-toolkit/logging#persisting-logs) các tệp bên ngoài **sharelatex** container, hãy đảm bảo chủ sở hữu của thư mục logs được đặt thành `www-data` người dùng (uid=33) để tệp log đầu ra có thể được ghi.
{% endhint %}

Kết quả đầu ra sẽ trông như sau:

```bash
Đặt 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}
Đang ghi log vào /var/log/overleaf/file-migration-2025-07-25T15_00_58_199Z.log
Đang bắt đầu sao lưu tệp dự án...
Loaded global blobs: 0
Đang xử lý các dự án chưa bị xóa...
Đã xử lý 1 dự án, thời gian đã trôi qua 0 giây
Đã cập nhật xong các dự án đang hoạt động
Đang xử lý các dự án đã xóa...
Bộ sưu tập deletedProjects dường như trống.

Đã cập nhật xong các dự án đã xóa
Đã xong.

```

Nếu quá trình di chuyển thành công, bạn sẽ nhận được mã thoát là `0`, và các dòng cuối cho biết không có lỗi:

```bash
Đã xong.
```

Tệp log sẽ trông như sau (hãy dùng đường dẫn do script in ra):

{% 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 %}

#### Dừng phiên bản

Toolkit: `bin/stop sharelatex`

docker-compose.yml kiểu cũ: `docker compose stop sharelatex`
{% endstep %}

{% step %}

#### Làm cho các tệp cũ không thể truy cập được đối với ứng dụng

Bây giờ bạn có thể chuyển các tệp cũ sang bộ nhớ phụ. Chúng tôi khuyến nghị giữ lại các tệp này một thời gian phòng khi sau này phát sinh sự cố.

{% code overflow="wrap" %}

```bash
# Người dùng Toolkit:
$ bin/docker-compose run --rm --entrypoint mv sharelatex --no-clobber --verbose /var/lib/overleaf/data/user_files /var/lib/overleaf/data/old_user_files

# Người dùng docker-compose.yml kiểu cũ:
# Chúng tôi giả định rằng bạn đang sử dụng bind-mount mặc định trong /var/lib/overleaf
$ docker compose run --rm --entrypoint mv sharelatex --no-clobber --verbose /var/lib/overleaf/data/user_files /var/lib/overleaf/data/old_user_files
# Nếu bạn đang sử dụng các bind-mount chọn lọc, bạn chỉ cần xóa bind-mount cho /var/lib/overleaf/data/user_files bên trong container.
```

{% endcode %}
{% endstep %}

{% step %}

#### Chuyển giai đoạn di chuyển sang 2

Toolkit: Đặt `OVERLEAF_FILESTORE_MIGRATION_LEVEL=2` trong `config/variables.env`.

docker-compose.yml kiểu cũ: Đặt `OVERLEAF_FILESTORE_MIGRATION_LEVEL: '2'` trong `môi trường` phần của `sharelatex` dịch vụ.
{% endstep %}

{% step %}

#### Áp dụng thay đổi cấu hình và khởi động phiên bản

Toolkit: `bin/up -d`

docker-compose.yml kiểu cũ: `docker compose up -d`
{% endstep %}

{% step %}

#### Xác minh quyền truy cập vào các tệp nhị phân

Mở một dự án trong trình soạn thảo Overleaf trên trình duyệt và chọn một tệp nhị phân, chẳng hạn như hình ảnh.
{% endstep %}
{% endstepper %}

#### di chuyển ngoại tuyến

Nếu bạn muốn ngăn người dùng đăng nhập trong khi script di chuyển tệp nhị phân đang chạy, hãy làm theo các bước sau:

* Đăng nhập vào phiên bản Overleaf của bạn bằng tài khoản quản trị
* Nhấp vào nút **Quản trị** nút và chọn **Quản lý trang web**
* Nhấp vào nút **Mở/Đóng trình soạn thảo** tab
* Nhấp vào nút **Đóng trình soạn thảo** nút
* Nhấp vào nút **Ngắt kết nối tất cả người dùng** nút

Sau khi hoàn tất, nếu có người dùng nào đang đăng nhập thì họ sẽ được chuyển hướng đến trang bảo trì, và bất kỳ người dùng mới nào truy cập trang đăng nhập sẽ thấy trang bảo trì và **sẽ không** có thể đăng nhập.

Bạn cần lặp lại các bước này khi khởi động lại phiên bản. Để mở lại trang web, chỉ cần khởi động lại phiên bản.

#### Di chuyển trực tuyến

Có thể chạy các script di chuyển trong khi ứng dụng vẫn đang chạy. Có một vài điểm cần lưu ý:

* Quá trình di chuyển tốn nhiều I/O, bạn nên theo dõi mức sử dụng tài nguyên trong khi script đang chạy.
* Với mức đồng thời xử lý cao, event loop trong `filestore` dịch vụ có thể gặp phải một số tình trạng bị chặn, dẫn đến trải nghiệm người dùng kém hơn. Chúng tôi khuyến nghị bắt đầu với các giá trị mặc định của `--concurrency=10` và `--concurrent-batches=1` .
* Bạn có thể dừng script bất cứ lúc nào. Khởi động lại nó sẽ xác thực các dự án trước đó và bỏ qua những tệp đã được xử lý. Điều này hữu ích nếu bạn muốn chạy quá trình di chuyển vào những giờ ít bận hơn (ví dụ: ban đêm).

Chúng tôi khuyến nghị đóng trang web và chạy quá trình di chuyển ngoại tuyến trong một khoảng bảo trì khi số lượng dự án của bạn ít hơn 1000 dự án (xem đầu ra của script di chuyển khi chạy với `--report`). Nếu số lượng dự án lớn, bạn có thể chạy script và theo dõi tiến độ của nó, rồi quyết định có tiếp tục chạy trực tuyến hay ngoại tuyến dựa trên trường hợp cụ thể của bạn.

#### Dọn dẹp dữ liệu tệp nhị phân kiểu cũ

Khi bạn đã hoàn tất quá trình di chuyển và xác minh rằng các dự án vẫn có thể truy cập tất cả tệp của chúng, bạn có thể xóa bộ lưu trữ tệp cũ trong `/var/lib/overleaf/data/user_files`. Chúng tôi rất khuyến nghị giữ các tệp này lại một thời gian - bạn có thể làm cho chúng không thể truy cập được đối với ứng dụng bằng cách đổi tên thư mục trước.

### Khắc phục sự cố

Chúng tôi sẽ bổ sung hướng dẫn khắc phục sự cố tại đây. Xin lưu ý rằng mặc dù thông thường chúng tôi chỉ hỗ trợ khách hàng Server Pro, nhưng do tính chất của quá trình di chuyển này, chúng tôi cũng sẽ cố gắng hết sức để hỗ trợ khách hàng CE gặp các vấn đề đặc thù của quá trình di chuyển tệp nhị phân.

Nếu script di chuyển tệp nhị phân thất bại (tức là thoát với lỗi hoặc in ra số lượng dự án thất bại khác 0), vui lòng gửi các chi tiết sau tới đội hỗ trợ của chúng tôi qua email [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), nêu rõ:

Subject: Binary file migration problem

Nội dung:

* Loại phiên bản: CE hoặc Server Pro (xóa phần không phù hợp)
* Loại cài đặt: Overleaf toolkit hoặc `docker-compose.yml` hoặc khác (xóa phần không phù hợp)
* Version: 5.5.x (toolkit: `$ cat config/version`)
* Đầu ra của script di chuyển (nên nằm trong container tại `/var/log/overleaf`)
* Report: (run migration script with `--report`)
* Các dự án đã xử lý: (theo lần chạy cuối cùng của script)
* Thời lượng của quá trình di chuyển:
* `bin/doctor` đầu ra (khi dùng toolkit)
* Phiên bản toolkit: `$ git rev-parse HEAD` (khi dùng Toolkit)

Cân nhắc đính kèm các tệp log của `filestore` dịch vụ vào email. Bạn có thể tìm thấy nó tại `/var/log/overleaf/filestore.log` bên trong `sharelatex` container và xuất chúng như sau:

```bash
$ docker cp sharelatex:/var/log/overleaf/filestore.log .
# thay <timestamp> bằng dấu thời gian được script in ra
$ docker cp sharelatex:/var/log/overleaf/file-migration-<timestamp>.log .
```

Vui lòng che/mask mọi thông tin nhạy cảm khỏi các tệp log trước khi đính kèm chúng.

#### Thiếu tệp

Các phiên bản Server Pro/CE cũ tạo các mục cây tệp trước khi tải lên của người dùng hoàn tất, điều này có thể khiến tệp trông như bị thiếu khi tải lên thất bại. Bạn có thể thấy một vài trường hợp như vậy được báo cáo là lỗi khi xử lý tất cả các cây tệp.

Nếu số lượng tệp bị thiếu ít, hãy cân nhắc xem xét thủ công các trường hợp này và xóa chúng khỏi trình soạn thảo trong trình duyệt.

Nếu số lượng tệp bị thiếu nhiều, hãy cân nhắc liên hệ bộ phận hỗ trợ, xem mẫu email ở trên.

#### Tìm cây tệp bị lỗi

Quá trình di chuyển có thể thất bại với những dự án có cây tệp bị lỗi định dạng (ví dụ, nơi tên tệp trống). Bạn có thể tìm danh sách các vấn đề này bằng `script find_malformed_filetrees` script này, script kiểm tra tất cả dự án trong cơ sở dữ liệu:

{% 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 %}

Để sửa các đường dẫn không hợp lệ, hãy dùng `script fix_malformed_filetree` script, chạy lệnh một lần cho mỗi đường dẫn lỗi:

{% 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/vi/ho-tro/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.
