Orang mungkin berpikir bahwa --link-dest
file yang identik akan berfungsi dalam semua kasus. Tapi itu tidak ketika file itu ada, bahkan jika file sudah ketinggalan zaman / memiliki konten yang berbeda.
Karena ini, dari halaman manual rsync pada --link-dest
:
"Opsi ini bekerja paling baik ketika menyalin ke hierarki tujuan kosong, karena rsync memperlakukan file yang ada sebagai definitif (jadi rsync tidak pernah melihat di dir-link-dest ketika file tujuan sudah ada )"
Ini berarti bahwa jika y/file
ada sama dengan sumber, dan z/file
kedaluwarsa,
rsync -a --del -link-dest=y source:/file z
akan menghasilkan DUA inode (dan dua kali ruang disk) yang digunakan, y/file
dan z/file
, yang akan memiliki konten dan datestamp yang sama.
Saya menemukan ini karena saya melakukan backup harian pada dasarnya dengan skrip ini dijalankan sekali per hari:
mv $somedaysago $today;
yest=$today; today=`date +%Y%m%d`;
rsync -avPShyH --del --link-dest=../$yest host:/dirs $today
Karena cadangan saya menjangkau hingga 10 juta file, melakukan rm -rf $olddir; rsync source:$dir newdir
akan memakan waktu terlalu lama (terutama ketika hanya 0,5% dari file berubah per hari, menyebabkan penghapusan dan pembuatan entri 10M dir hanya untuk menangani 50 ribu file baru atau yang diubah, yang akan membuat saya cadangan tidak lengkap pada waktunya untuk hari berikutnya).
Inilah demo situasi:
a
adalah sumber kami, 1
melalui 4
cadangan-cadangan bernomor kami:
$ 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
Sekarang kami memiliki 2 cadangan a/foobar
yang identik dalam semua hal, termasuk cap waktu, tetapi menempati berbagai inode.
Orang mungkin berpikir akan ada solusinya --delete-before
, yang membunuh manfaat dari pemindaian bertahap tetapi ini tidak membantu karena file tidak akan dihapus, tetapi digunakan sebagai dasar jika salinan tambahan mungkin dilakukan.
Orang mungkin menduga lebih lanjut maka kita dapat mematikan lindung nilai tambahan-salin ini --whole-file
, tetapi ini tidak membantu algoritma apa pun, tidak ada cara untuk mendapatkan apa yang kita inginkan.
Saya menganggap perilaku ini bug lain di rsync, di mana perilaku yang menguntungkan dapat ditafsirkan dari pemilihan yang cermat dari berbagai argumen perintah, tetapi hasil yang diinginkan tidak tersedia.
Sebuah solusi sayangnya akan bergerak dari rsync tunggal sebagai operasi atom ke dry-run dengan -n
, logging itu, memproses log itu sebagai input untuk secara manual menghapus semua file yang diubah, kemudian menjalankan rsync --link-dest
untuk mendapatkan apa yang kita inginkan - sebuah lumpur besar dibandingkan dengan rsync bersih tunggal.
Tambahan: mencoba melakukan pra-tautan $yesterday
dan $today
pada server cadangan sebelum pencadangan terhadap kotak produksi dengan rsync --link-dest=../$yesterday $yesterday/ $today
- tetapi hasil yang sama - file apa pun yang ada dengan cara apa pun, bahkan 0 panjangnya, tidak akan pernah dihapus dan tautan-dihancurkan, sebagai gantinya keseluruhan salinan baru akan dibuat dari sumber dengan inode baru dan menggunakan lebih banyak ruang disk.
Melihat pax(1)
sebagai solusi pra-tautan-sebelum-cadangan yang mungkin.
--delete-after
baik-baik saja, tetapi tidak terkait dengan masalah yang dihadapi. File yang hilang dari sumber akan dihapus setelah salinan selesai. Masalah yang saya jelaskan berkaitan dengan cadangan yang dilakukan hari ini yang identik dengan kemarin tetapi terhadap file lama yang sudah ada yang tidak tertaut ke inode kemarin, tetapi disimpan sebagai file baru dua kali total ruang disk saat kemarin salinan identik dianggap.
rsnapshot
? Juga, pertimbangkan untuk menulis skrip kecil untuk menghubungkan kembali file "identik". Saya melakukan keduanya pada sistem saya.
hardlink(1)
lambat (15x lebih lambat dari pemindaian metadata rsync); pax
lebih cepat tetapi meronta-ronta kepala HDD membandingkan cadangan lama dengan yang baru. rsync -n
untuk mendapatkan daftar delta berarti memukul server produksi dua kali (memindai 10 juta file jauh lebih berdampak daripada menyalin perubahan 50 ribu). Sakit mail daftar tentang opsi di rsync untuk memungkinkan ini.
--delete-after
dalam skenario penggunaan ini, apa yang salah dengan ini?