> 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/ru/podderzhka/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 истории для 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 %}

#### Обновите

**Toolkit:** Используйте `$ bin/upgrade` скрипт для обновления **toolkit** до последней версии. Когда будет предложено, не **не** подтверждайте запрос **Обновление** образ? — вместо этого вручную отредактируйте **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" не равно нулю, пожалуйста, обратитесь в поддержку и не продолжайте миграцию двоичных файлов.
{% endhint %}
{% endstep %}

{% step %}

#### Переведите этап миграции на 1

Toolkit: Установите `OVERLEAF_FILESTORE_MIGRATION_LEVEL=1` в `config/variables.env`.

Устаревший docker-compose.yml: установите `OVERLEAF_FILESTORE_MIGRATION_LEVEL: '1'` в `окружения` разделе `контейнера sharelatex` сервис.
{% endstep %}

{% step %}

#### Примените изменение конфигурации и запустите экземпляр

Toolkit: `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** контейнера, убедитесь, что владельцем каталога журналов указан `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 %}

#### Остановите экземпляр

Toolkit: `bin/stop sharelatex`

Устаревший docker-compose.yml: `docker compose stop sharelatex`
{% endstep %}

{% step %}

#### Сделайте старые файлы недоступными для приложения

Теперь вы можете переместить старые файлы во вторичное хранилище. Рекомендуем оставить файлы на какое-то время на случай, если позже возникнут проблемы.

{% code overflow="wrap" %}

```bash
# Пользователи 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

# Пользователи устаревшего docker-compose.yml:
# Предполагается, что вы используете стандартный bind-mount в /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
# Если вы используете выборочные bind-mounts, вы можете просто удалить bind-mount для /var/lib/overleaf/data/user_files внутри контейнера.
```

{% endcode %}
{% endstep %}

{% step %}

#### Переведите этап миграции на 2

Toolkit: Установите `OVERLEAF_FILESTORE_MIGRATION_LEVEL=2` в `config/variables.env`.

Устаревший docker-compose.yml: установите `OVERLEAF_FILESTORE_MIGRATION_LEVEL: '2'` в `окружения` разделе `контейнера sharelatex` сервис.
{% endstep %}

{% step %}

#### Примените изменение конфигурации и запустите экземпляр

Toolkit: `bin/up -d`

Устаревший docker-compose.yml: `docker compose up -d`
{% endstep %}

{% step %}

#### Проверьте доступ к двоичным файлам

Откройте проект в редакторе Overleaf в браузере и выберите двоичный файл, например изображение.
{% endstep %}
{% endstepper %}

#### Офлайн-миграция

Если вы хотите запретить пользователям входить в систему, пока работает скрипт миграции двоичных файлов, выполните следующие шаги:

* Войдите в свой экземпляр Overleaf с учетной записью администратора
* Нажмите кнопку **Администратор** кнопку и выберите **Управлять сайтом**
* Нажмите **Открыть/закрыть редактор** вкладку
* Нажмите кнопку **Закрыть редактор** кнопку
* Нажмите кнопку **Отключить всех пользователей** кнопку

После этого, если какие-либо пользователи уже вошли в систему, они будут перенаправлены на страницу обслуживания, а любые новые пользователи, посещающие страницу входа, увидят страницу обслуживания и **не смогут** войти в систему.

Вам нужно повторить эти шаги при перезапуске экземпляра. Чтобы снова открыть сайт, просто перезапустите экземпляр.

#### Онлайн-миграция

Можно запускать скрипты миграции, пока приложение все еще работает. Есть несколько моментов, которые следует учитывать:

* Процесс миграции интенсивно использует ввод-вывод; во время работы скрипта следует следить за использованием ресурсов.
* При высокой параллельности обработки цикл событий в `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 (toolkit: `$ 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/ru/podderzhka/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.
