
Недавно я настроил машину с Ubuntu Server для размещения игровых серверов. Я установил плагин резервного копирования для каждого игрового сервера, который создает частые резервные копии файлов игрового мира в определенной папке на машине. Я также установил задачу cron
автоматического копирования этих резервных копий в мою папку Dropbox каждую ночь с помощью rsync с -a
опцией.
Через несколько месяцев мой аккаунт Dropbox достиг своего лимита хранилища, и я понял, что не смогу хранить так много резервных копий, поэтому я настроил плагин резервного копирования игрового сервера так, чтобы он не сохранял так много резервных копий, затем подождал несколько дней, чтобы посмотреть, удалит ли он старые резервные копии, как это запланировано на еженедельной основе. Плагин резервного копирования в конечном итоге выполнил свою работу и удалил старые резервные копии, поэтому я ожидал, что rsync
задача cron впоследствии удалит старые резервные копии из моей папки Dropbox, чтобы они соответствовали исходной папке, но этого не произошло. Поэтому у меня есть пара вопросов:
По умолчанию делает
rsync
толькодобавлятьфайлы в папку назначения, которые были добавлены в исходную папку иизменятьфайлы, которые были изменены в исходной папке, ноНЕ удалятьфайлы, которые были удалены из исходной папки?Если это так, то как лучше всего
rsync
это сделать? Я хочу, чтобы папка назначения полностью отражала исходную папку, а это означает удаление всех файлов, которые были удалены из исходной папки.
Я вижу, что на странице руководства перечислены некоторые опции, rsync
которые могут помочь, но поскольку я с ними не знаком,...
решение1
Чтобы удалить файлы в цели, добавьте --delete
опцию в вашу команду. Например:
rsync -avh source/ dest/ --delete
Примечание: -avh
для--archive --verbose --human-readable
решение2
Thersyncкоманда не удалит ни одного файла, пока вы используете некоторые из ее опций delete
в этой команде. Так что если какой-либо файл или папка добавлены в источник, они будут синхронизированы с целью без какого-либо удаления.
Я предлагаю вам использовать rsync
для создания резервной копии исходных файлов и использовать find ... rm
для удаления файлов за определенный период времени или размер файлов:
rsync [options] SOURCE TARGET
find TARGET -maxdepth 1 -type f -mtime +60 -exec rm -f {} \;
Приведенный выше блок кода создает резервную копию исходного кода, а затем удаляет все файлы, которые последний раз изменялись более 2 месяцев назад.
ОБНОВЛЯТЬ
Поскольку я обнаружил, что delete
опции предназначены только для TARGET, то если некоторые файлы удалены из источника, rsync --delete
удалить их из TARGET. И delete
опция by after
и before
, как указано в ее странице руководства:
--delete-before receiver deletes before transfer, not during
Значит это:
- rsync удаляет файлы из ЦЕЛИ, которые удалены из ИСТОЧНИКА.
- rsync начинает синхронизацию файлов.
--delete-after receiver deletes after transfer, not during
Значит это:
- rsync начинает синхронизацию файлов.
- rsync удаляет файлы из ЦЕЛИ, которые удаляются из ИСТОЧНИКА после синхронизации.
ПРИМЕЧАНИЕ: --delete-{before/after}
Орудие только в ЦЕЛИ.
решение3
Команда
$ rsync -avhn --delete local/ remote/
заботится о том, чтобы всегда синхронизировать изменения, сделанные локально, с удаленным. Это означает, что он заботится о том, чтобы синхронизироватьместныйиудаленныйтакой что
- файлыдобавленвместныйдобавлены кудаленный
- файлыудаленныйотместныйудаляются изудаленный
- файлыдобавленвудаленныйудалены
- файлыудаленныйотудаленныйвосстановлены изместныйесли они существуют, в противном случае игнорируются
Объясняемые параметры:
-a
режим архива-v
увеличить многословие-h
выводить числа в удобном для восприятия человеком формате-n
пробный запуск, выполнение пробного запуска без внесения каких-либо изменений.Всегда используйте этот флаг изначально, чтобы предотвратить потерю данных.. Когда будете довольны, удалите его.
Пусть результаты говорят сами за себя:
Создать 2 каталога
$ mkdir local/ remote/
Создавать в них файлы
$ touch local/local_only remote/remote_only local/exists_locally_and_remotely remote/exists_locally_and_remotely`
Посмотрите, что было создано (до rsync):
$ ls local/ remote/ local/: exists_locally_and_remotely local_only remote/: exists_locally_and_remotely remote_only
вызов rsync:
$ rsync -avh --delete local/ remote/ sending incremental file list deleting remote_only local_only sent 160 bytes received 50 bytes 420.00 bytes/sec total size is 0 speedup is 0.00
Посмотрите результат (после rsync):
$ ls local/ remote/ local/: exists_locally_and_remotely local_only remote/: exists_locally_and_remotely local_only
Как вы видите, файлудаленный/только удаленныйбылудалено, файллокальный/только локальныйбылсинхронизированный.
решение4
Если во время rsync scync возникнут какие-либо ошибки, rsync не удалит должным образом файлы, даже если вы использовали --delete
, --delete-after
, или --delete-before
.
Вот почему так важно устранять ошибки rsync.
Большинство моих ошибок были связаны с использованием --perms
опции при синхронизации с файловой системой не Linux. Когда я заменил --perms
на --no-perms
, эти ошибки исчезли, а затем удаление сработало.
--perms
нормально, когда вы синхронизируете файловую систему Linux с другой файловой системой Linux, но если вы синхронизируете Linux с файловой системой, отличной от Linux (например, NTFS, FAT), --perms
возникают ошибки, потому чтоrsync не может установить разрешения Linux для файловых систем, отличных от Linux. Опять же, ошибки = нет удаления.
-- При синхронизации с разделом, отличным от Linux, я использую , --no-perms
чтобы избежать ошибок, которые саботируют --delete
, --delete-after
, или --delete-before
.
Если после этого вы все еще получаете ошибки и не можете понять, как их устранить, вы можете выполнить команду, которая предназначена исключительно для удаления несинхронизированных файлов:
sudo rsync -r --delete --existing --ignore-existing --ignore-errors --progress /path/to/source/ /path/to/destination
Команда выше удалит то, что не синхронизировано, но не синхронизирует файлы. Поэтому вам следует снова выполнить синхронизацию после этого. Эта команда основана на этомотвечать, за исключением того, что я также добавил --ignore-errors
аргумент, поэтому он будет удален даже при наличии ошибок.