Представьте файл Договор_поставки.docx в общей библиотеке. Сотрудник на ноутбуке наводит порядок, удаляет папку «Старое», вместе с ней уходит и договор. Через несколько секунд у коллег на других компьютерах папка тоже исчезает. Никакого сбоя тут нет: система сделала ровно то, чего от неё просили. Именно поэтому синхронизацию так легко принять за страховку, хотя это совсем другой механизм.

Синхронизация отвечает на вопрос «как сделать так, чтобы у всех было одно и то же». Резервная копия отвечает на другой: «как вернуть то, что было раньше, если одинаковым у всех стало что-то неправильное». Seafile синхронизирует изменения общей библиотеки, включая удаления, на другие компьютеры. Значит, ошибка одного человека быстро становится ошибкой всей команды. Чтобы с этим жить, нужны три разных понятия, которые в разговорах постоянно сливаются в одно.

Библиотека, локальная копия и история — три разные вещи

Первое понятие — сама библиотека на сервере. Это корневая единица хранения в Seafile: в ней лежат папки и файлы, на уровне библиотеки живёт и история. Второе — синхронизированная копия на устройстве. Это рабочее отражение библиотеки на ноутбуке или настольном компьютере, и оно подчиняется библиотеке, а не наоборот. Третье — история: сохранённые состояния библиотеки, из которых можно достать старую версию файла или удалённое содержимое.

Из этого разделения следует практическое правило. Локальная папка на ноутбуке — не место, где «хранится файл», а окно в библиотеку. Если в окне что-то исчезло и это исчезновение дошло до сервера, искать пропажу нужно не в корзине операционной системы, а в корзине библиотеки. Корзина ОС может помочь, но это лотерея: ничего не гарантирует, что клиент удалил файл именно через неё и что она не очищена.

Там, где команда решает, какой инструмент ставить, стоит заранее понять, насколько вам важны именно такие механизмы библиотек и истории. Сравнение подходов к серверу файлов разобрано в материале Seafile или Nextcloud: что выбрать для сервера; здесь же мы остаёмся внутри Seafile и смотрим, что происходит с одним файлом.

Один файл, два несчастья

Дальше мы будем следить за одним и тем же файлом — тем самым договором. С ним может случиться две разные неприятности, и они требуют разных действий:

  • Удаление. Файл или содержащая его папка пропали, и это изменение разошлось по устройствам.
  • Конфликт редактирования. Файл никто не удалял, но два человека изменили его одновременно, и версий стало две.

В первом случае вопрос звучит как «где лежит пропавшее и как давно оно там лежит». Во втором — «какая из двух живых версий правильная». Первый вопрос про время и сроки хранения, второй — про содержание и решение людей. Смешивать их опасно: восстановление из корзины не решит конфликт, а разбор конфликта не вернёт удалённое.

Удаление: куда уходит файл и откуда его вернуть

Когда файл удалён из библиотеки, он не исчезает мгновенно. По документации Seafile, удалённые файлы доступны в корзине библиотеки, и их можно восстановить. Для нашей истории это означает следующее: сотруднику не нужно паниковать и искать копию в почте. Нужно открыть именно ту библиотеку, где лежал договор, найти её корзину и вернуть файл оттуда.

Тут стоит обратить внимание на слово «библиотеки». У каждой библиотеки своя корзина и своя история. Если команда держит документы в трёх библиотеках — «Договоры», «Проекты», «Общее», — то удалённое из «Договоров» нужно искать именно в «Договорах». Звучит очевидно, но в момент, когда пропал важный файл, человек часто открывает не ту библиотеку и делает вывод, что файла нет нигде.

После восстановления файл снова появляется в библиотеке, а значит, и в синхронизированных копиях: возврат — такое же изменение, как и удаление, и оно тоже расходится по устройствам. Полезная привычка: после восстановления убедиться не только на сервере, но и на пострадавшем компьютере, что клиент подтянул файл обратно.

Когда удалена не только вещь, но и её дом

Самый любопытный случай — наш сотрудник удалил не договор, а целую папку «Старое». Договор лежал в Старое/2024/Поставщики/. Что произойдёт при восстановлении одного файла из корзины, если родительских папок уже нет?

Документация описывает это так: если родительская папка тоже удалена, файл или папка восстанавливается в корень библиотеки. Иначе говоря, Seafile не воссоздаёт цепочку вложенных папок вокруг вернувшегося файла. Договор появится наверху, рядом с остальным содержимым корня, и кто-то должен будет перенести его обратно.

Практические последствия у этого поведения такие:

  • Файл «пропал» повторно, только теперь он лежит не там, где его ищут. Если в корне уже много всего, восстановленное легко не заметить.
  • Если восстанавливать пачку файлов из разных веток удалённой папки, они все окажутся в одном месте, и разобрать их по смыслу придётся вручную.
  • Имена файлов в корне могут совпасть с чем-то уже существующим. Что именно делает система при совпадении, в используемых нами материалах не описано, поэтому проверьте это на тестовой библиотеке, прежде чем рассчитывать на определённое поведение.

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

Конфликт: два правильных файла и одно решение

Теперь второй сценарий. Договор никто не удалял. Менеджер правит его в самолёте без сети, юрист в это же время правит ту же копию в офисе. Оба сохраняют изменения. Когда ноутбук менеджера выходит в сеть, клиенту приходится решать, чью версию считать основной.

Seafile действует так: сохраняет первую синхронизированную версию, а другую переименовывает в conflict file с отметкой автора и времени. Обратите внимание на формулировку «первую синхронизированную». Это не «самую свежую» и не «самую правильную». Выигрывает не тот, кто правил позже или аккуратнее, а тот, чьё изменение раньше дошло до сервера. Если юрист был онлайн и синхронизировался сразу, его версия займёт основное имя, а правки менеджера окажутся в файле с пометкой.

Это важный момент, потому что многие воспринимают conflict file как «мусор рядом с настоящим». На деле это полноценная версия чьей-то работы. Вот как выглядит ситуация для нашей пары версий:

Две версии одного договора после конфликта
ФайлЧто этоПочему так
Основное имя договораВерсия, которая первой дошла до сервераПорядок синхронизации, а не качество правок
Файл с пометкой автора и времениВерсия второго участникаSeafile не выбрасывает её, а переименовывает

Решение, какую оставить, Seafile за людей не принимает. Здесь работает простая последовательность: открыть обе версии рядом, понять, чем они различаются, свести нужное в один файл, а лишний удалить. Удаление conflict file — тоже удаление, и оно тоже разойдётся по устройствам, поэтому делать его лучше после того, как итоговый файл проверен теми, чьи правки в нём были.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации Россия, США, Франция и Великобритания. Оплата картой РФ и по СБП.

АРЕНДОВАТЬ СЕРВЕР

Где эти два случая пересекаются

Интереснее всего ситуация, когда обе беды случаются подряд. Допустим, конфликт разобран неудачно: итоговый файл собран из версии юриста, а правки менеджера потерялись. Через неделю выясняется, что в договоре не хватает пункта о штрафах. Что делать?

Если из основной версии пункт исчез не удалением файла, а перезаписью содержимого, то это уже вопрос не корзины, а истории. Срок истории, по документации Seafile, ограничивает доступ к удалённым файлам, старым версиям и snapshots библиотеки. То есть одна и та же настройка определяет и то, сколько времени можно вернуть удалённое, и то, как далеко можно откатиться по версиям, и то, насколько старый снимок библиотеки доступен целиком.

Тут и сходятся оба случая на одном файле:

  1. Удалили папку с договором — возвращать нужно из корзины, пока не истёк срок истории.
  2. Перезаписали договор при разборе конфликта — возвращать нужно старую версию, и опять же, пока она не вышла за срок.
  3. Хотите сравнить два состояния договора месяц назад и сейчас — нужен snapshot, и он тоже существует лишь в пределах срока.

За пределами срока ничего из этого недоступно: документация прямо говорит, что старое содержимое за пределами срока недоступно через эти функции. Это и есть главное ограничение, о котором надо думать до запуска, а не в день пропажи. Обещать команде «мы всё восстановим» можно только внутри срока истории.

Как подобрать срок истории под реальные потребности

Срок истории настраивается отдельно для каждой библиотеки её владельцем. Это значит, что единой «политики по умолчанию на всех» можно не придерживаться, и, что важнее, владельцы должны сознательно выбирать срок для своих библиотек. Если никто этого не делает, срок остаётся тем, какой стоит, и о нём никто не помнит.

Чтобы выбрать разумное значение, полезно задать себе не вопрос «сколько хранить», а вопрос «как долго после ошибки мы о ней обычно узнаём». Ниже — условный пример, в котором цифры взяты для иллюстрации, а не как рекомендация:

Условный пример: как рабочий ритм влияет на срок истории
БиблиотекаКак обычно замечают потерюО чём это говорит
Рабочие черновикиВ тот же день или на следующийКороткий срок обычно достаточен, лишняя история только занимает место
Договоры и закрывающие документыПри сверке, иногда через месяцы, иногда в конце квартала или годаСрок должен покрывать самый длинный цикл сверки
Общие материалы для всей командыКогда кому-то понадобится старый файл, непредсказуемоНужен компромисс; важные документы лучше вынести в отдельную библиотеку с отдельным сроком

Вывод из таблицы такой. Библиотека «Договоры» должна жить дольше, чем библиотека черновиков, потому что у ошибок в ней дольше «время обнаружения». А если важные и неважные файлы лежат в одной библиотеке, вам придётся выбирать один срок для всех. Поэтому деление на библиотеки — это не только удобство доступа, но и способ управлять сроком хранения истории там, где это действительно нужно.

Но срок истории — не бесплатная настройка. Чем дольше хранится история, тем больше места она может занимать: прошлые версии и удалённое содержимое тоже где-то лежат. Точный прирост зависит от того, как часто и насколько сильно меняются файлы, и без замеров на ваших данных его не посчитать. Для сервера это означает простую вещь: объём диска надо планировать не по текущему размеру библиотек, а с запасом на историю. Если вы разворачиваете Seafile на собственном сервере, посмотрите на ресурсы VPS именно с этой стороны: у VPS MAATRIX на NVMe-накопителях тарифы различаются по объёму диска, от 40 ГБ у Ba до 320 ГБ у Djed, и выбор стоит делать с учётом будущего роста истории, а не только нынешнего содержимого. Эти ресурсы — заявленные параметры тарифа, а не обещание конкретной ёмкости под вашу нагрузку, так что реальный расход лучше проверить на пилотной библиотеке.

Репетиция до запуска: тестовая библиотека и два сценария

Лучший способ поверить в механизм — сломать его самому, пока не поздно. Создайте тестовую библиотеку, положите в неё несколько файлов и вложенную папку, подключите её на двух устройствах. Дальше пройдите оба сценария из этой статьи.

Репетиция удаления

Удалите на одном компьютере папку целиком и посмотрите, что произошло на втором: исчезла ли она там. Затем найдите её в корзине библиотеки и верните файл из середины дерева. Убедитесь, что он появился в корне, как описано в документации о восстановлении удалённых файлов, и проверьте, как ведёт себя клиент на втором устройстве. Заодно запишите, сколько времени заняло у неподготовленного участника такое восстановление: это хороший показатель того, нужна ли команде короткая инструкция.

Репетиция конфликта

Отключите сеть на одном устройстве, измените файл на обоих, затем подключите сеть. Посмотрите, какая версия осталась под основным именем и как выглядит переименованный вариант. Это поведение описано для конфликтов файлов, но то, как именно называется conflict file в вашей версии клиента и как он выглядит в списке, лучше увидеть своими глазами. Заодно проверьте, замечают ли сотрудники появление лишнего файла: по опыту таких проб это обычно выясняется быстро.

Репетиция доступа чужой учётной записи

Третий случай связан не с ошибкой, а с правами. Создайте тестового пользователя, дайте ему доступ к одной библиотеке и проверьте, что он видит и что может делать. Отдельно проверьте, может ли он удалить файл, который потом придётся восстанавливать, и кто в этом случае сможет открыть корзину. Тонкая настройка прав на уровне отдельных папок зависит от редакции и возможностей конкретной установки, поэтому не рассчитывайте на неё заранее: сначала посмотрите, что доступно именно у вас. Пока этого нет, разумнее опираться на разделение по библиотекам, где права выдаются на всю библиотеку целиком.

Если пилот вы хотите поднять на отдельном сервере, под него подойдёт небольшой VPS. В публичном предложении MAATRIX указан root-доступ и автоматическое создание VPS в течение пары минут после оплаты; доступные локации и образы лучше уточнить в форме заказа, так как точное наличие там может отличаться.

Чего синхронизация не умеет, даже когда всё настроено идеально

Всё сказанное выше работает внутри Seafile и внутри срока истории. Но есть вещи, которые настройками библиотеки не исправить. Если сервер потерян целиком, никакая корзина не поможет — она живёт на том же сервере. Если срок истории вышел, содержимое недоступно через описанные функции. Если ошибку заметили слишком поздно, вернуть уже нечего. Синхронизация распространяет изменения, в том числе неудачные, и независимой копией не является. Поэтому для действительно важных данных нужна отдельная копия вне самой системы синхронизации, но это уже отдельная тема, и здесь важно лишь то, что корзина и история решают задачу «вернуть недавнее», а не «пережить всё».

Автоматические резервные копии у провайдера тоже нельзя предполагать по умолчанию: в публичных данных MAATRIX о них для всех тарифов не заявлено, поэтому вопрос копирования стоит решать отдельно и осознанно.

Что на самом деле значит «синхронизировалось»

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

Заметьте, что ни в первом, ни во втором случае сам факт синхронизации успехом не считается. Синхронизация сработала и тогда, когда удалила папку, и тогда, когда выбрала «первую» версию договора. Успех — это когда команда знает, какую из двух сохранённых версий нужно оставить, и может объяснить почему: потому что в ней есть все нужные пункты, а не потому, что она первой добежала до сервера.