Apakah rsync dapat dilanjutkan setelah terputus?


188

Saya dulu rsyncmenyalin sejumlah besar file, tetapi OS saya (Ubuntu) dimulai kembali secara tidak terduga.

Setelah reboot, saya berlari rsynclagi, tetapi dari output di terminal, saya menemukan bahwa rsyncmasih menyalin yang sudah disalin sebelumnya. Tapi saya dengar itu rsyncbisa menemukan perbedaan antara sumber dan tujuan, dan karena itu hanya menyalin perbedaan. Jadi saya bertanya-tanya dalam kasus saya apakah rsyncdapat melanjutkan apa yang tersisa terakhir kali?


Ya, rsync tidak akan menyalin lagi file yang sudah disalin. Ada beberapa kasus tepi di mana pendeteksiannya dapat gagal. Apakah itu menyalin semua file yang sudah disalin? Opsi apa yang Anda gunakan? Apa sistem file sumber dan target? Jika Anda menjalankan rsync lagi setelah menyalin semuanya, apakah itu menyalin lagi?
Gilles

@Gilles: Terima kasih! (1) Saya rasa saya melihat rsync menyalin file yang sama lagi dari outputnya di terminal. (2) Opsi sama dengan di posting saya yang lain, yaitu sudo rsync -azvv /home/path/folder1/ /home/path/folder2. (3) Sumber dan target adalah NTFS, sumber beli adalah HDD eksternal, dan target adalah HDD internal. (3) Sekarang sedang berjalan dan belum selesai.
Tim

Ada juga flag --partial untuk melanjutkan file yang ditransfer sebagian (berguna untuk file besar)
jwbensley

3
@Tim Dari atas kepala saya, setidaknya ada kemiringan jam, dan perbedaan dalam resolusi waktu (masalah umum dengan filesystem FAT yang menyimpan waktu dalam peningkatan 2 detik, --modify-windowopsi membantu dengan itu).
Gilles

1
jika Anda tidak memiliki / atau /. di ujung ekor argumen jalur sumber file maka itu akan membuat salinan tambahan dalam subdirektori yang memiliki nama yang sama dengan direktori sumber
Skaperen

Jawaban:


285

Pertama-tama, mengenai bagian "resume" dari pertanyaan Anda, --partialcukup beri tahu pihak penerima untuk menyimpan sebagian file yang ditransfer jika akhir pengiriman menghilang seolah-olah mereka benar-benar ditransfer.

Saat mentransfer file, mereka sementara disimpan sebagai file tersembunyi di folder target mereka (misalnya .TheFileYouAreSending.lRWzDC), atau folder yang dipilih secara khusus jika Anda mengatur --partial-dirsakelar. Ketika transfer gagal dan --partialtidak disetel, file tersembunyi ini akan tetap berada di folder target di bawah nama samar ini, tetapi jika --partialdiatur, file akan diubah namanya menjadi nama file target yang sebenarnya (dalam kasus ini, TheFileYouAreSending), meskipun file tersebut tidak lengkap. Intinya adalah Anda nantinya dapat menyelesaikan transfer dengan menjalankan rsync lagi dengan salah satu --appendatau --append-verify.

Jadi, --partialtidak dengan sendirinya melanjutkan transfer yang gagal atau dibatalkan. Untuk melanjutkannya, Anda harus menggunakan salah satu dari bendera yang disebutkan di atas pada proses selanjutnya. Jadi, jika Anda perlu memastikan bahwa target tidak akan pernah berisi file yang tampaknya baik-baik saja tetapi sebenarnya tidak lengkap, Anda tidak boleh menggunakan --partial. Sebaliknya, jika Anda ingin memastikan bahwa Anda tidak pernah meninggalkan file gagal yang tersesat di direktori target, dan Anda tahu Anda akan dapat menyelesaikan transfer nanti, --partialada di sana untuk membantu Anda.

Sehubungan dengan --appendsakelar yang disebutkan di atas, ini adalah sakelar "resume" yang sebenarnya, dan Anda dapat menggunakannya baik yang Anda gunakan atau tidak --partial. Sebenarnya, ketika Anda menggunakan --append, tidak ada file sementara yang pernah dibuat. File ditulis langsung ke target mereka. Dalam hal ini, --appendmemberikan hasil yang sama seperti --partialpada transfer yang gagal, tetapi tanpa membuat file-file sementara yang tersembunyi.

Jadi, untuk meringkas, jika Anda memindahkan file besar dan Anda ingin opsi untuk melanjutkan operasi rsync yang dibatalkan atau gagal dari titik tepat yang rsyncberhenti, Anda perlu menggunakan --appendatau --append-verifymengaktifkan upaya berikutnya.

Seperti @Alex tunjukkan di bawah, karena versi 3.0.0 rsyncsekarang memiliki opsi baru --append-verify,, yang berperilaku seperti yang --appenddilakukan sebelum saklar itu ada. Anda mungkin selalu menginginkan perilaku --append-verify, jadi periksalah versi Anda rsync --version. Jika Anda menggunakan Mac dan tidak menggunakan rsyncdari homebrew, Anda (setidaknya hingga dan termasuk El Capitan) akan memiliki versi yang lebih lama dan perlu menggunakan --appenddaripada --append-verify. Mengapa mereka tidak melanjutkan perilaku --appenddan malah menyebut pendatang baru --append-no-verifyagak membingungkan. Either way, --appendpada rsyncsebelum versi 3 sama dengan --append-verifypada versi yang lebih baru.

--append-verifytidak berbahaya: Itu akan selalu membaca dan membandingkan data di kedua ujungnya dan tidak hanya menganggap mereka sama. Ini melakukan ini menggunakan checksum, jadi itu mudah di jaringan, tetapi itu memerlukan membaca jumlah data bersama di kedua ujung kawat sebelum benar-benar dapat melanjutkan transfer dengan menambahkan ke target.

Kedua, Anda mengatakan bahwa Anda "mendengar bahwa rsync dapat menemukan perbedaan antara sumber dan tujuan, dan karenanya hanya menyalin perbedaannya."

Itu benar, dan itu disebut transfer delta, tetapi itu hal yang berbeda. Untuk mengaktifkan ini, Anda menambahkan -c, atau --checksumberalih. Setelah saklar ini digunakan, rsync akan memeriksa file yang ada di kedua ujung kabel. Itu melakukan ini dalam potongan, membandingkan checksum di kedua ujungnya, dan jika mereka berbeda, itu hanya mentransfer bagian file yang berbeda. Tetapi, seperti yang ditunjukkan @Jonathan di bawah, perbandingan hanya dilakukan ketika file memiliki ukuran yang sama di kedua ujungnya - ukuran yang berbeda akan menyebabkan rsync mengunggah seluruh file, menimpa target dengan nama yang sama.

Ini membutuhkan sedikit perhitungan pada kedua ujung awalnya, tetapi bisa sangat efisien dalam mengurangi beban jaringan jika misalnya Anda sering membuat cadangan file yang sangat besar file ukuran tetap yang sering berisi perubahan kecil. Contoh yang muncul dalam pikiran adalah file gambar hard drive virtual yang digunakan dalam mesin virtual atau target iSCSI.

Perlu dicatat bahwa jika Anda menggunakan --checksumuntuk mentransfer sejumlah file yang benar-benar baru ke sistem target, rsync masih akan menghitung checksum mereka pada sistem sumber sebelum mentransfernya. Kenapa saya tidak tahu :)

Jadi, singkatnya:

Jika Anda sering menggunakan rsync untuk hanya "memindahkan barang-barang dari A ke B" dan ingin pilihan untuk membatalkan operasi itu dan kemudian melanjutkannya, tidak menggunakan --checksum, tapi jangan gunakan --append-verify.

Jika Anda sering menggunakan rsync untuk mencadangkan barang, menggunakan --append-verifymungkin tidak akan banyak membantu Anda, kecuali jika Anda terbiasa mengirim file besar yang terus bertambah ukurannya tetapi jarang dimodifikasi setelah ditulis. Sebagai tip bonus, jika Anda mencadangkan ke penyimpanan yang mendukung snapshotting seperti btrfsatau zfs, menambahkan --inplacesakelar akan membantu Anda mengurangi ukuran snapshot karena file yang diubah tidak dibuat ulang melainkan blok yang diubah ditulis langsung di atas yang lama. Switch ini juga berguna jika Anda ingin menghindari rsync membuat salinan file pada target ketika hanya perubahan kecil yang terjadi.

Saat menggunakan --append-verify, rsync akan berperilaku seperti biasanya pada semua file dengan ukuran yang sama. Jika mereka berbeda dalam modifikasi atau cap waktu lain, itu akan menimpa target dengan sumber tanpa meneliti file-file tersebut lebih lanjut. --checksumakan membandingkan konten (checksum) dari setiap pasangan file dengan nama dan ukuran yang identik.

DIPERBARUI 2015-09-01 Berubah untuk mencerminkan poin yang dibuat oleh @Alex (terima kasih!)

DIPERBARUI 2017-07-14 Berubah untuk mencerminkan poin yang dibuat oleh @Jonathan (terima kasih!)


4
Ini mengatakan --partialsudah cukup.
Cees Timmerman


2
@ CMCDragonkai Sebenarnya, periksa jawaban Alexander di bawah ini tentang --partial-dir- sepertinya itu adalah peluru yang sempurna untuk ini. Saya mungkin telah melewatkan sesuatu sepenuhnya;)
DanielSmedegaardBuus

2
@DanielSmedegaardBuus Saya mengujinya sendiri pada koneksi yang lambat, dan ini yang saya lihat hanya dengan --partial: rsync menyalin file ke nama sementara, koneksi terputus, remote rsync akhirnya memindahkan file itu ke nama biasa dan berhenti, kemudian berjalan kembali dengan --partialdan tanpa --append , file sementara baru diinisialisasi dengan salinan file jarak jauh yang ditransfer sebagian, kemudian salinan berlanjut dari tempat sambungan mati. (Ubuntu 14.04 / rsync 3.1)
Izkata

4
Apa tingkat kepercayaan Anda pada perilaku yang dijelaskan --checksum? Menurutnya manitu lebih berkaitan dengan memutuskan file mana yang akan ditandai untuk ditransfer daripada dengan delta-transfer (yang, mungkin, adalah rsyncperilaku default).
Jonathan Y.

56

TL; DR:

Cukup tentukan direktori parsial seperti halaman manual rsync merekomendasikan:

--partial-dir=.rsync-partial

Penjelasan yang lebih panjang:

Sebenarnya ada fitur built-in untuk melakukan ini menggunakan --partial-diropsi, yang memiliki beberapa keunggulan dibandingkan --partialdan --append-verify/ --appendalternatif.

Kutipan dari halaman manual rsync:

--partial-dir=DIR
      A  better way to keep partial files than the --partial option is
      to specify a DIR that will be used  to  hold  the  partial  data
      (instead  of  writing  it  out to the destination file).  On the
      next transfer, rsync will use a file found in this dir  as  data
      to  speed  up  the resumption of the transfer and then delete it
      after it has served its purpose.

      Note that if --whole-file is specified (or  implied),  any  par-
      tial-dir  file  that  is  found for a file that is being updated
      will simply be removed (since rsync  is  sending  files  without
      using rsync's delta-transfer algorithm).

      Rsync will create the DIR if it is missing (just the last dir --
      not the whole path).  This makes it easy to use a relative  path
      (such  as  "--partial-dir=.rsync-partial")  to have rsync create
      the partial-directory in the destination file's  directory  when
      needed,  and  then  remove  it  again  when  the partial file is
      deleted.

      If the partial-dir value is not an absolute path, rsync will add
      an  exclude rule at the end of all your existing excludes.  This
      will prevent the sending of any partial-dir files that may exist
      on the sending side, and will also prevent the untimely deletion
      of partial-dir items on the receiving  side.   An  example:  the
      above  --partial-dir  option would add the equivalent of "-f '-p
      .rsync-partial/'" at the end of any other filter rules.

Secara default, rsync menggunakan nama file sementara acak yang akan dihapus ketika transfer gagal. Seperti disebutkan, menggunakan --partialAnda dapat membuat rsync menyimpan file yang tidak lengkap seolah-olah berhasil ditransfer , sehingga dimungkinkan untuk kemudian menambahkannya menggunakan --append-verify/ --appendopsi. Namun ada beberapa alasan mengapa hal ini tidak optimal.

  1. File cadangan Anda mungkin tidak lengkap, dan tanpa memeriksa file jarak jauh yang masih belum diubah, tidak ada cara untuk mengetahuinya.

  2. Jika Anda mencoba untuk menggunakan --backupdan --backup-dir, Anda baru saja menambahkan versi baru dari file ini yang bahkan tidak pernah keluar sebelumnya ke riwayat versi Anda.

Namun jika kita menggunakan --partial-dir, rsync akan menyimpan file parsial sementara, dan melanjutkan mengunduh menggunakan file parsial itu saat Anda menjalankannya, dan kami tidak mengalami masalah di atas.


38

Anda mungkin ingin menambahkan -Popsi ke perintah Anda.

Dari manhalaman:

--partial By default, rsync will delete any partially transferred file if the transfer
         is interrupted. In some circumstances it is more desirable to keep partially
         transferred files. Using the --partial option tells rsync to keep the partial
         file which should make a subsequent transfer of the rest of the file much faster.

  -P     The -P option is equivalent to --partial --progress.   Its  pur-
         pose  is to make it much easier to specify these two options for
         a long transfer that may be interrupted.

Jadi alih-alih:

sudo rsync -azvv /home/path/folder1/ /home/path/folder2

Melakukan:

sudo rsync -azvvP /home/path/folder1/ /home/path/folder2

Tentu saja, jika Anda tidak ingin pembaruan kemajuan, Anda bisa menggunakan --partial, yaitu:

sudo rsync --partial -azvv /home/path/folder1/ /home/path/folder2

@ Flimm tidak sepenuhnya benar. Jika ada gangguan (jaringan atau sisi penerima) maka ketika menggunakan --partial file parsial disimpan DAN digunakan ketika rsync dilanjutkan. Dari manual: "Menggunakan opsi --partial memberi tahu rsync untuk menjaga file parsial yang seharusnya <b> membuat transfer selanjutnya dari sisa file lebih cepat </b>."
gaoithe

2
@Flimm dan @gaoithe, jawaban saya tidak cukup akurat, dan jelas tidak terkini. Saya telah memperbaruinya untuk mencerminkan versi 3+ rsync. Sangat penting untuk menekankan, bahwa --partialitu sendiri tidak melanjutkan transfer yang gagal. Lihat jawaban saya untuk perincian :)
DanielSmedegaardBuus

2
@DanielSmedegaardBuus Saya mencobanya dan itu -Psudah cukup dalam kasus saya. Versi: klien memiliki 3.1.0 dan server memiliki 3.1.1. Saya mengganggu transfer satu file besar dengan ctrl-c. Saya kira saya kehilangan sesuatu.
guettli

Mengapa vv? yaitu vdigunakan 2 kali?
mrgloom

Di mana rsync menyimpan bagian file -azvvP?
mrgloom

1

Saya pikir Anda secara paksa menelepon rsyncdan karenanya semua data akan diunduh saat Anda mengingatnya lagi. gunakan --progressopsi untuk menyalin hanya file-file yang tidak disalin dan --deleteopsi untuk menghapus file apa pun jika sudah disalin dan sekarang tidak ada di folder sumber ...

rsync -avz --progress --delete -e  /home/path/folder1/ /home/path/folder2

Jika Anda menggunakan ssh untuk masuk ke sistem lain dan menyalin file,

rsync -avz --progress --delete -e "ssh -o UserKnownHostsFile=/dev/null -o \
StrictHostKeyChecking=no" /home/path/folder1/ /home/path/folder2

beri tahu saya jika ada kesalahan dalam pemahaman saya tentang konsep ini ...


1
Bisakah Anda mengedit jawaban Anda dan menjelaskan apa yang dilakukan panggilan ssh khusus Anda, dan mengapa Anda menyarankan untuk melakukannya?
Fabien

2
@Fabien Dia memberi tahu rsync untuk mengatur dua opsi ssh (rsync menggunakan ssh untuk menghubungkan). Yang kedua memberitahu ssh untuk tidak meminta konfirmasi jika host yang terhubung dengannya belum diketahui (dengan yang ada di file "host yang dikenal"). Yang pertama memberitahu ssh untuk tidak menggunakan file host default yang dikenal (yang akan menjadi ~ / .ssh / known_hosts). Dia menggunakan / dev / null sebagai gantinya, yang tentu saja selalu kosong, dan karena ssh kemudian tidak menemukan host di sana, biasanya akan meminta konfirmasi, maka opsi dua. Setelah terhubung, ssh menulis host yang sekarang dikenal ke / dev / null, secara efektif melupakannya langsung :)
DanielSmedegaardBuus

1
... tapi Anda mungkin bertanya-tanya apa efeknya, jika ada, itu pada operasi rsync itu sendiri. Jawabannya tidak ada. Ini hanya berfungsi untuk tidak memiliki host yang Anda hubungkan untuk ditambahkan ke file host SSH Anda yang dikenal. Mungkin dia seorang sysadmin yang sering terhubung ke sejumlah besar server baru, sistem sementara atau yang lainnya. Saya tidak tahu :)
DanielSmedegaardBuus

4
"gunakan opsi --progress untuk menyalin hanya file-file yang tidak disalin" Apa?
moi

1
Ada beberapa kesalahan pasangan di sini; satu sangat serius: --deleteakan menghapus file di tujuan yang tidak ada di sumbernya. Yang kurang serius adalah itu --progresstidak mengubah cara sesuatu disalin; itu hanya memberi Anda laporan kemajuan pada setiap file saat disalin. (Saya memperbaiki kesalahan serius; menggantinya dengan --remove-source-files.)
Paul d'Aoust

1

Saya menggunakan skrip sederhana ini. Jangan ragu untuk menyesuaikan bendera tertentu dan / atau mengucilkannya.

#!/bin/bash

while [ 1 ]
do
    rsync -avz --partial [source] [dest]:
    if [ "$?" = "0" ] ; then
        echo "rsync completed normally"
        exit
    else
        echo "Rsync failure. Backing off and retrying..."
        sleep 180
    fi
done

1

Tiba terlambat untuk ini, tetapi saya memiliki pertanyaan yang sama dan saya menemukan jawaban yang berbeda.

The --partialflag ( "menyimpan file sebagian ditransfer" di rsync -h) berguna untuk file besar, seperti --append( "menambahkan data ke file yang lebih pendek"), tapi pertanyaannya adalah tentang sejumlah besar file.

Untuk menghindari file yang telah disalin gunakan -u(atau --update: "lewati file yang lebih baru pada receiver").

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.