Вопрос или проблема
Возможно ли (в классическом ext4 и/или в любой другой файловой системе) создать два файла, которые указывают на одно и то же содержимое, так что если один файл изменяется, содержимое дублируется и оба файла становятся разными? Это было бы очень удобно для экономии места на моем жестком диске.
Контекст: У меня есть несколько тяжелых видео, которые я делюсь на сервере owncloud, и к которым могут иметь доступ многие люди, поэтому возможно, что некоторые из них изменяют/удаляют эти файлы… Я действительно хочу убедиться, что у меня есть резервная копия этих файлов, и поэтому мне нужно сейчас поддерживать две директории: обычную директорию nextcloud и одну директорию “резервной копии”, что (по крайней мере) удваивает размер, необходимый для хранения.
Я думал создать репозиторий git на основе директории nextcloud, и это упростит процесс резервного копирования, когда новые видео добавляются (просто git add .
), но git
все равно удваивает пространство между blob и рабочей директорией.
Идеально было бы найти решение, которое можно комбинировать с git
(т.е. которое позволит мне создать историю изменений видео с помощью коммитов, выборок… без удвоения дискового пространства).
Более того, мне любопытно получить решение для различных файловых систем (особенно если у вас есть хитрости для файловых систем, которые не реализуют снимки). Обратите внимание, что снимок LVM не является действительно решением, так как я не хочу создавать резервную копию всего своего объема, только некоторых конкретных файлов/папок.
Да, на файловых системах Copy On Write (Btrfs, ZFS). git-annex — это максимально приближенность, которую вы можете получить на ext4. Обратите внимание, что вы можете mount --bind
том, поддерживаемый LVM, или файловую систему Btrfs на папку в другой файловой системе.
Я полагаю, что другие ответы не говорят об этом прямо, так что да, это возможно на btrfs, используя reflinks, а не жесткие ссылки.
- Жесткие ссылки — это два отдельных имени для одного файла, который занимает один и тот же участок диска.
- Reflinks — это два разных файла, которые случайно указывают на один и тот же участок диска.
Когда жесткая ссылка изменяется, другое имя файла также показывает это изменение, так как оба ссылаются на один и тот же файл.
Когда reflink изменяется, другой файл не изменяется. Изменения записываются в новый участок диска, в то время как неизмененные части обоих файлов все еще ссылаются на одни и те же участки диска, экономя место.
В отличие от жесткой ссылки, где две записи в каталоге ссылаются на одну и ту же запись inode, в случае reflinks есть две записи inode, и именно блоки данных разделяются.
Тип ссылки | Потребление дискового пространства |
Скорость | Редактируемый | Использование на различных файловых системах и разделах |
---|---|---|---|---|
Reflinks | ✅ | ✅ | ✅ | ❌ |
Символьные ссылки | ✅ | ✅ | ❌ | ✅ |
Жесткие ссылки | ✅ | ✅ | ❌ | ❌ |
Копия файла | ❌ | ❌ | ✅ | ✅ |
(источник)
Возможно ли (в классическом ext4, и/или в любой другой файловой системе) создать два файла, которые указывают на одно и то же содержимое, так что если один файл изменяется, содержимое дублируется и оба файла становятся разными? Это было бы очень удобно для экономии места на моем жестком диске.
Жесткие ссылки делают это, при условии, что любой, кто редактирует файлы, делает это, создавая новый файл и переименовывая его поверх оригинала. Это бы разорвало связь, так как новый файл связан только с одним именем, а другая ссылка будет перезаписана новым значением.
Проблема в том, что обычно трудно узнать, будет ли программа перезаписывать данные в одном и том же inode или создавать новый файл при сохранении.
Сделать “резервные копии” доступными только для чтения может помочь, так как их нельзя будет изменять, но ссылки все равно можно будет удалить и воссоздать с тем же именем. Но это может привести к множеству ошибок, когда программы не смогут записать в этот inode.
Таким образом, на мой взгляд, дедупликация на уровне файлов, подобная этой, через жесткие ссылки возможна, но только если вы контролируете программы, которые записывают в ссылки.
Ответ или решение
Создание двух файлов, которые указывают на один и тот же контент и могут "разделяться" при изменении одного из них, является распространенной задачей, особенно в контексте экономии дискового пространства. Давайте рассмотрим возможные решения этого вопроса, а также какие файловые системы могут обеспечить такое поведение.
Обзор типов связей и их особенностей
1. Жесткие ссылки (Hard Links)
Жесткие ссылки — это две разных записи в файловой системе, которые указывают на один и тот же inode (место на диске). Когда вы изменяете файл через одну жесткую ссылку, изменения будут видны и при обращении через другую ссылку, так как они ведут к одному и тому же блоку данных. Однако, если вы сохраните изменения, которые создают новый inode (например, с помощью перезаписи файла), это нарушит ссылку. Таким образом, жесткие ссылки не подходят для вашей задачи, так как изменения всегда будут отражаться на всех связанных файлах.
2. Символические ссылки (Symlinks)
Символические ссылки представляют собой отдельные файлы, которые ссылаются на другой файл или директорию. При изменении оригинального файла, символическая ссылка будет указывать на измененный файл. Однако, символические ссылки не позволяют вам сохранить оригинальную версию файла, так как все изменения будут отражены на оригинале. В этом случае, символические ссылки также не подходят для вашей задачи.
3. Reflinks
Reflinks (или "ссылки по переименованию") — это более продвинутая концепция, которая доступна на файловых системах, таких как Btrfs и ZFS. Эти ссылки позволяют создавать "глубокие" ссылки, где два файла ссылаются на один и тот же блок данных. При изменении одного из файлов, изменения происходят в новом блоке данных, в результате оба файла остаются различными, даже если они изначально указывали на одну и ту же область диска. Это позволяет вам экономить пространство, поскольку только измененные части данных занимают дополнительное место.
Оптимальное решение для хранения резервных копий
Ваши потребности в резервном копировании видеофайлов и ведении их истории изменений могут быть лучшим образом реализованы с помощью следующего подхода:
-
Использование файловой системы Btrfs или ZFS: Эти файловые системы поддерживают reflinks, что даст вам возможность экономить дисковое пространство и обеспечивать создание резервных копий без дублирования данных. При каждом изменении файла, только измененные части будут записываться, тогда как остальная часть останется общей.
-
Использование git-annex: Если вы хотите интегрировать версионность в ваш процесс резервного копирования, рассмотрите использование инструмента git-annex, который позволяет управлять файлами, не дублируя их в полном объеме. Он может работать с любыми файлами и предоставляет возможность создания резервных копий и изменения их статуса.
-
Чтение и запись: Если вам важно, чтобы файлы были доступны только для чтения из директории резервной копии, вы можете настроить права доступа на уровне файловой системы, чтобы предотвратить случайное изменение или удаление файлов.
В заключение
Наиболее подходящим решением для вашей задачи является использование reflinks на файловых системах Btrfs или ZFS в сочетании с git-annex. Такой подход обеспечит вас необходимыми функциями резервного копирования и версионности, минимизируя при этом потребление дискового пространства. Пользуйтесь возможностями современных технологий для оптимизации хранения данных и улучшения рабочего процесса.