как заставить rsync связать идентичные файлы с опцией --link-dest, если старый файл уже существует?


11

Можно подумать, что --link-destиспользование идентичного файла будет работать во всех случаях. Но это не так, когда файл существует, даже если файл устарел / имеет другое содержимое.

Из-за этого на странице руководства rsync --link-dest:

«Этот параметр лучше всего работает при копировании в пустую целевую иерархию, поскольку rsync рассматривает существующие файлы как окончательные (поэтому rsync никогда не просматривает каталоги link-dest, когда целевой файл уже существует

Это означает, что если y/fileсуществует так же, как источник, и z/fileустарел,

rsync -a --del -link-dest=y source:/file z

приведет к ДВУМ инодам (и в два раза дискового пространства) используются, y/fileи z/file, которые будут иметь такое же содержание и временную метку.

Я сталкивался с этим, потому что я делаю ежедневные резервные копии в основном с помощью этого сценария, запускаемого один раз в день

mv $somedaysago $today; 
yest=$today; today=`date +%Y%m%d`;
rsync -avPShyH --del --link-dest=../$yest host:/dirs $today

Поскольку мои резервные копии занимают до 10 миллионов файлов, выполнение rm -rf $olddir; rsync source:$dir newdirможет занять слишком много времени (особенно, если в день изменяется только 0,5% файлов, что приводит к удалению и созданию 10-миллиметровых записей dir только для обработки 50 тыс. Новых или измененных файлов, что может привести к резервные копии не завершены вовремя на следующий день).

Вот демонстрация ситуации:

aнаш источник, 1через 4наши нумерованные резервные копии:

$ mkdir -p 1 2; echo foo > 1/foobar; cp -lrv 1/* 2
`1/foobar' -> `2/foobar'
$ ls -i1 */foobar
1053003 1/foobar
1053003 2/foobar

$ mkdir a; echo quux > a/foobar
$ mv 1 3; rsync -avPhyH --del --link-dest=../2 a/ 3
sending incremental file list
./
foobar
           5 100%    0.00kB/s    0:00:00 (xfer#1, to-check=0/2)

sent 105 bytes  received 34 bytes  278.00 bytes/sec
total size is 5  speedup is 0.04

$ ls -i1 */foobar
1053003 2/foobar
1053007 3/foobar
1053006 a/foobar

$ mv 2 4; rsync -avPhyH --del --link-dest=../3 a/ 4
sending incremental file list
./
foobar
           5 100%    0.00kB/s    0:00:00 (xfer#1, to-check=0/2)

sent 105 bytes  received 34 bytes  278.00 bytes/sec
total size is 5  speedup is 0.04


$ ls -il1 */foobar
1053007 -rw-r--r-- 1 math math 5 Mar 30 00:57 3/foobar
1053008 -rw-r--r-- 1 math math 5 Mar 30 00:57 4/foobar
1053006 -rw-r--r-- 1 math math 5 Mar 30 00:57 a/foobar

$ md5sum [34a]/foobar
d3b07a382ec010c01889250fce66fb13  3/foobar
d3b07a382ec010c01889250fce66fb13  4/foobar
d3b07a382ec010c01889250fce66fb13  a/foobar

Теперь у нас есть 2 резервные копии a/foobar, которые идентичны во всех отношениях, включая временную метку, но занимают разные inode.

Кто-то может подумать, что было бы решение --delete-before, которое убивает выгоду от инкрементного сканирования, но это также не помогает, так как файл не будет удален, но будет использоваться в качестве основы в случае, если инкрементное копирование возможно.

Можно еще предположить, что мы можем отключить хеджирование с инкрементным копированием --whole-file, но это не поможет алгоритму, нет способа получить то, что мы хотим.

Я считаю это поведение еще одной ошибкой в ​​rsync, где полезное поведение может быть истолковано из тщательного выбора различных аргументов команды, но желаемый результат недоступен.

К сожалению, решение будет состоять в том, чтобы перейти от одиночной rsync как атомарной операции к пробному запуску с -nрегистрацией, обработкой этого журнала в качестве входных данных, чтобы вручную предварительно удалить все измененные файлы, а затем запустить, rsync --link-destчтобы получить то, что мы хотим - большой kludge по сравнению с одним чистым rsync.

Приложение: попытался предварительно связать $yesterdayи $todayна сервере резервного копирования перед резервным копированием с использованием производственных ящиков с rsync --link-dest=../$yesterday $yesterday/ $today- но с тем же результатом - любой файл, который существует любым способом, даже длиной 0, никогда не будет удален и удален из ссылки, а не целиком новая копия будет сделана из источника с новым инодом и занимая больше места на диске.

Рассматривается pax(1)как возможное решение для предварительной компоновки перед резервным копированием.


Я использую --delete-afterв этом сценарии использования, что не так с этим?
gogoud

1
--delete-afterэто хорошо, но не имеет отношения к проблеме под рукой. Файлы, отсутствующие в источнике, будут удалены после завершения копирования. Проблема, которую я объясняю, связана с резервным копированием, которое выполняется сегодня, которое идентично вчерашнему, но со старым существующим устаревшим файлом, который не связан со вчерашним индексом, но хранится как новый файл в два раза больше дискового пространства, чем вчера идентичная копия считается.
математика

Не совсем уверен, что вы спрашиваете. Вы рассматривали rsnapshot? Кроме того, подумайте над написанием небольшого скрипта, чтобы связать «идентичные» файлы. Я делаю оба на моих системах.
Роайма

1
Если вы не получили здесь нужного ответа, вы можете опубликовать его в списке rsync. Разработчики rsync регулярно отвечают там на вопросы вместе со многими опытными пользователями. Вы можете найти их через lists.samba.org/mailman/listinfo/rsync . Я в основном там прячусь и многому учусь.
Джо,

rsnapshot не будет перерабатывать старые резервные копии - и мне нужно: если у меня есть резервные копии на 2 месяца и 2 месяца + 1 день, я могу зациклить одно в качестве новой цели. Поскольку ~ 5% файлов меняются в день, я создаю жесткие ссылки 50 КБ вместо 10 МБ. Эта разница в скорости позволяет создавать резервные копии 5 серверов / ночь против. hardlink(1)медленный (в 15 раз медленнее, чем сканирование метаданных rsync); paxбыстрее, но бьет головки жестких дисков, сравнивая старые резервные копии с новыми. rsync -nполучить дельта-список означает дважды поработать с производственными серверами (сканирование 10M-файлов гораздо более важно, чем копирование 50K-изменений). Я отправлю список опций в rsync, чтобы разрешить это.
математика

Ответы:


12

(Преобразовано из вопроса редактирования)

Это решается обновлением rsync. Версия 3.1.1 или новее теперь заменяет идентичные файлы в целевом --link-destкаталоге и каталоге одним жестко связанным файлом. Экономит много места.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.