Можна подумати, що --link-dest
в ідентичному файлі працюватиме у всіх випадках. Але це не тоді, коли файл існує, навіть якщо файл застарів / має різний вміст.
Саме тому зі сторінки man rsync на --link-dest
:
"Цей параметр найкраще працює при копіюванні в порожню ієрархію призначення, оскільки rsync розглядає існуючі файли як остаточні (тому rsync ніколи не виглядає в папці-призначенні, коли файл призначення вже існує )"
Це означає, що якщо воно 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% файлів змінюються в день, що призводить до видалення та створення записів 10M dir просто для обробки 50K нових або змінених файлів, що зробить мою резервні копії не завершені вчасно на наступний день).
Ось демонстрація ситуації:
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
, які однакові за всіма ознаками, включаючи часові позначки, але займають різні вставки.
Можна подумати, що було б рішення --delete-before
, яке вбиває користь від поступового сканування, але це не допомагає, оскільки файл не буде видалений, але використовується як основа в разі можливої інкрементальної копії.
Можна також припустити, що ми можемо вимкнути цей хедж з додатковою копією --whole-file
, але це не допомагає алгоритму, немає способу отримати те, що ми хочемо.
Я вважаю цю поведінку ще однією помилкою в rsync, де вигідна поведінка може бути побудована з ретельного вибору різних аргументів команди, але бажаний результат недоступний.
На жаль, рішення переходило б від однієї rsync як атомної операції до сухого запуску -n
, записуючи її в систему, обробляючи цей журнал як вхід для попереднього видалення всіх змінених файлів, а потім працює, rsync --link-dest
щоб отримати те, що ми хочемо - велика хижа порівняно з однією чистою rsync.
Додаток: намагався попередньо зв’язати $yesterday
і $today
на сервері резервного копіювання перед резервним копією проти виробничих коробок із rsync --link-dest=../$yesterday $yesterday/ $today
- але однаковим результатом - будь-який файл, який існує будь-яким способом, навіть 0 довжини, ніколи не буде видалений і позначений посиланням, а не цілим нова копія буде зроблена з джерела з новим inode та з використанням більше дискового простору.
Розглядаючи pax(1)
як можливе рішення попереднього зв’язування перед резервним копіюванням.
--delete-after
це добре, але не пов'язано з проблемою. Файли, відсутні в джерелі, будуть видалені після того, як буде зроблена копія. Проблема, яку я з'ясовує, стосується створення резервної копії, яка є ідентичною вчорашньому, але проти старого наявного застарілого файлу, який не пов'язаний з вчорашнім inode, але зберігається як новий файл у два рази більше всього дискового простору, коли вчорашній ідентична копія вважається.
rsnapshot
? Крім того, розгляньте можливість написання невеликого сценарію для повторного зв’язку "однакових" файлів. Я обидва в моїх системах.
hardlink(1)
повільно (на 15 разів повільніше, ніж сканування метаданих rsync); pax
швидше, але обертає голови HDD, порівнюючи старі резервні копії з новими. rsync -n
отримати список дельти означає ударити по виробничих серверах двічі (сканування 10-мільйонних файлів має набагато більший вплив, ніж копіювання змін 50К). Я надсилаю поштою список про опцію в rsync, щоб дозволити це.
--delete-after
в цьому сценарії використання, що з цим погано?