як змусити rsync зв’язати однакові файли з опцією --link-dest, якщо старий файл вже існує?


11

Можна подумати, що --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в цьому сценарії використання, що з цим погано?
gogoud

1
--delete-afterце добре, але не пов'язано з проблемою. Файли, відсутні в джерелі, будуть видалені після того, як буде зроблена копія. Проблема, яку я з'ясовує, стосується створення резервної копії, яка є ідентичною вчорашньому, але проти старого наявного застарілого файлу, який не пов'язаний з вчорашнім inode, але зберігається як новий файл у два рази більше всього дискового простору, коли вчорашній ідентична копія вважається.
математика

Не зовсім впевнений, що ви ставите під сумнів. Ви розглядали rsnapshot? Крім того, розгляньте можливість написання невеликого сценарію для повторного зв’язку "однакових" файлів. Я обидва в моїх системах.
roaima

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

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

Відповіді:


12

(Перетворено з редагування запитань)

Це вирішується оновленням rsync. Версія 3.1.1 або пізнішої версії тепер замінить однакові файли в цілі та --link-destкаталозі одним файлом з твердим посиланням. Економить багато місця.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.