Rsync có thể tiếp tục sau khi bị gián đoạn?


188

Tôi đã từng rsyncsao chép một số lượng lớn tệp, nhưng hệ điều hành (Ubuntu) của tôi khởi động lại bất ngờ.

Sau khi khởi động lại, tôi chạy rsynclại, nhưng từ đầu ra trên thiết bị đầu cuối, tôi thấy rằng rsyncvẫn sao chép những cái đã được sao chép trước đó. Nhưng tôi nghe nói rsynccó thể tìm thấy sự khác biệt giữa nguồn và đích, và do đó chỉ cần sao chép sự khác biệt. Vì vậy, tôi tự hỏi trong trường hợp của tôi nếu rsynccó thể tiếp tục những gì còn lại lần trước?


Có, rsync sẽ không sao chép lại các tệp mà nó đã được sao chép. Có một vài trường hợp cạnh mà phát hiện của nó có thể thất bại. Nó đã sao chép tất cả các tập tin đã được sao chép? Bạn đã sử dụng tùy chọn nào? Các hệ thống tập tin nguồn và đích là gì? Nếu bạn chạy lại rsync sau khi nó sao chép mọi thứ, nó có sao chép lại không?
Gilles

@Gilles: Cảm ơn! (1) Tôi nghĩ rằng tôi đã thấy rsync sao chép lại cùng một tệp từ đầu ra của nó trên thiết bị đầu cuối. (2) Tùy chọn giống như trong bài viết khác của tôi, tức là sudo rsync -azvv /home/path/folder1/ /home/path/folder2. (3) Nguồn và đích đều là NTFS, nguồn mua là ổ cứng ngoài và mục tiêu là ổ cứng gắn trong. (3) Nó hiện đang chạy và chưa hoàn thành.
Tim

Ngoài ra còn có cờ - partial để tiếp tục các tệp được chuyển một phần (hữu ích cho các tệp lớn)
jwbensley

3
@Tim Tắt đỉnh đầu của tôi, có ít nhất độ lệch đồng hồ và sự khác biệt về độ phân giải thời gian (một vấn đề phổ biến với các hệ thống tệp FAT lưu trữ thời gian với gia số 2 giây, --modify-windowtùy chọn giúp điều đó).
Gilles

1
nếu bạn không có / hoặc /. ở phần đuôi của đối số đường dẫn nguồn tệp, sau đó nó sẽ tạo thêm một bản sao trong thư mục con có cùng tên với thư mục nguồn
Skaperen

Câu trả lời:


285

Trước hết, liên quan đến phần "tiếp tục" trong câu hỏi của bạn, --partialchỉ cần nói với đầu nhận sẽ giữ các tệp được chuyển một phần nếu kết thúc gửi biến mất như thể chúng đã được chuyển hoàn toàn.

Trong khi truyền tệp, chúng được lưu tạm thời dưới dạng tệp ẩn trong các thư mục đích của chúng (ví dụ .TheFileYouAreSending.lRWzDC) hoặc thư mục được chọn cụ thể nếu bạn đặt công --partial-dirtắc. Khi chuyển không thành công và --partialkhông được đặt, tệp ẩn này sẽ vẫn còn trong thư mục đích dưới tên khó hiểu này, nhưng nếu --partialđược đặt, tệp sẽ được đổi tên thành tên tệp đích thực tế (trong trường hợp này TheFileYouAreSending), mặc dù tệp chưa hoàn thành Vấn đề là sau này bạn có thể hoàn thành việc chuyển bằng cách chạy lại rsync bằng --appendhoặc --append-verify.

Vì vậy, bản thân nó--partial không tiếp tục chuyển khoản thất bại hoặc bị hủy. Để tiếp tục, bạn sẽ phải sử dụng một trong những lá cờ nói trên trong lần chạy tiếp theo. Vì vậy, nếu bạn cần đảm bảo rằng mục tiêu sẽ không bao giờ chứa các tệp có vẻ ổn nhưng thực sự không đầy đủ, bạn không nên sử dụng . Ngược lại, nếu bạn muốn đảm bảo rằng bạn không bao giờ bỏ lại các tệp bị lỗi bị ẩn trong thư mục đích và bạn biết rằng bạn sẽ có thể hoàn tất việc chuyển tiền sau đó, có mặt để giúp bạn.--partial--partial

Liên quan đến công --appendtắc được đề cập ở trên, đây là công tắc "tiếp tục" thực tế và bạn có thể sử dụng nó cho dù bạn có đang sử dụng hay không --partial. Trên thực tế, khi bạn đang sử dụng --append, không có tệp tạm thời nào được tạo. Các tập tin được viết trực tiếp đến mục tiêu của họ. Về mặt này, --appendcho kết quả tương tự như khi --partialchuyển khoản không thành công, nhưng không tạo ra các tệp tạm thời bị ẩn đó.

Vì vậy, để tổng hợp, nếu bạn đang di chuyển các tệp lớn và bạn muốn tùy chọn tiếp tục hoạt động rsync bị hủy hoặc thất bại từ điểm chính xác rsyncđã dừng, bạn cần sử dụng --appendhoặc --append-verifybật lần thử tiếp theo.

Như @Alex chỉ ra bên dưới, vì phiên bản 3.0.0 rsynchiện có một tùy chọn mới --append-verify, hoạt động giống như --appendtrước khi công tắc đó tồn tại. Bạn có thể luôn muốn hành vi của --append-verify, vì vậy hãy kiểm tra phiên bản của bạn với rsync --version. Nếu bạn đang sử dụng máy Mac và không sử dụng rsynctừ homebrew, bạn sẽ (ít nhất là và bao gồm cả El Capitan) có phiên bản cũ hơn và cần sử dụng --appendhơn là --append-verify. Tại sao họ không tiếp tục hành vi --appendvà thay vào đó đặt tên cho người mới đến --append-no-verifylà một chút khó hiểu. Dù bằng cách nào, --appendtrên rsynctrước khi phiên bản 3 cũng giống như --append-verifytrên các phiên bản mới hơn.

--append-verifykhông nguy hiểm: Nó sẽ luôn đọc và so sánh dữ liệu ở cả hai đầu và không chỉ cho rằng chúng bằng nhau. Nó thực hiện việc này bằng cách sử dụng tổng kiểm tra, vì vậy nó dễ dàng trên mạng, nhưng nó yêu cầu đọc lượng dữ liệu được chia sẻ ở cả hai đầu của dây trước khi nó thực sự có thể tiếp tục chuyển bằng cách nối thêm vào mục tiêu.

Thứ hai, bạn nói rằng bạn "nghe nói rằng rsync có thể tìm thấy sự khác biệt giữa nguồn và đích, và do đó chỉ cần sao chép sự khác biệt."

Điều đó đúng, và nó được gọi là chuyển delta, nhưng đó là một điều khác. Để kích hoạt tính năng này, bạn thêm -choặc --checksumchuyển đổi. Khi công tắc này được sử dụng, rsync sẽ kiểm tra các tệp tồn tại ở cả hai đầu của dây. Nó thực hiện điều này trong các khối, so sánh tổng kiểm tra ở cả hai đầu và nếu chúng khác nhau, nó chỉ chuyển các phần khác nhau của tệp. Nhưng, như @Jonathan chỉ ra bên dưới, việc so sánh chỉ được thực hiện khi các tệp có cùng kích thước ở cả hai đầu - các kích thước khác nhau sẽ khiến rsync tải lên toàn bộ tệp, ghi đè lên mục tiêu có cùng tên.

Điều này đòi hỏi một chút tính toán ở cả hai đầu ban đầu, nhưng có thể cực kỳ hiệu quả trong việc giảm tải mạng nếu ví dụ bạn thường xuyên sao lưu các tệp có kích thước cố định rất lớn thường chứa các thay đổi nhỏ. Ví dụ xuất hiện trong tâm trí là các tệp hình ảnh ổ cứng ảo được sử dụng trong các máy ảo hoặc các mục tiêu iSCSI.

Đáng chú ý là nếu bạn sử dụng --checksumđể chuyển một loạt tệp hoàn toàn mới cho hệ thống đích, rsync vẫn sẽ tính toán tổng của chúng trên hệ thống nguồn trước khi chuyển chúng. Tại sao tôi không biết :)

Vì vậy, trong ngắn hạn:

Nếu bạn thường sử dụng rsync để chỉ "chuyển nội dung từ A sang B" và muốn tùy chọn hủy thao tác đó và sau đó tiếp tục lại, đừng sử dụng --checksum, nhưng hãy sử dụng --append-verify.

Nếu bạn đang sử dụng rsync để sao lưu công cụ thường xuyên, sử dụng --append-verifycó thể sẽ không giúp ích gì cho bạn, trừ khi bạn có thói quen gửi các tệp lớn liên tục tăng kích thước nhưng hiếm khi được sửa đổi sau khi viết. Là một mẹo bổ sung, nếu bạn đang sao lưu vào bộ lưu trữ hỗ trợ chụp nhanh , btrfshoặc zfsthêm công --inplacetắc sẽ giúp bạn giảm kích thước ảnh chụp do các tệp đã thay đổi không được tạo lại mà thay vào đó các khối thay đổi được ghi trực tiếp lên các khối cũ. Công tắc này cũng hữu ích nếu bạn muốn tránh rsync tạo các bản sao của tệp trên mục tiêu khi chỉ có những thay đổi nhỏ xảy ra.

Khi sử dụng --append-verify, rsync sẽ hoạt động giống như mọi khi trên tất cả các tệp có cùng kích thước. Nếu chúng khác nhau về sửa đổi hoặc dấu thời gian khác, nó sẽ ghi đè lên mục tiêu bằng nguồn mà không xem xét kỹ hơn các tệp đó. --checksumsẽ so sánh nội dung (tổng kiểm) của mỗi cặp tệp có cùng tên và kích cỡ.

CẬP NHẬT 2015-09-01 Thay đổi để phản ánh các điểm được tạo bởi @Alex (cảm ơn!)

CẬP NHẬT 2017-07-14 Thay đổi để phản ánh các điểm được tạo bởi @Jonathan (cảm ơn!)


4
Điều này nói --partiallà đủ.
Cees Timmerman


2
@CMCDragonkai Trên thực tế, hãy xem câu trả lời của Alexandeller bên dưới --partial-dir- có vẻ như đó là viên đạn hoàn hảo cho việc này. Tôi có thể đã bỏ lỡ một cái gì đó hoàn toàn;)
DanielSmedegaardBuus

2
@DanielSmedegaardBuus Tôi đã thử nghiệm nó ra bản thân mình trên một kết nối chậm, và đây là những gì tôi thấy với chỉ --partial : bản rsync file vào tên tạm thời, kết nối bị gián đoạn, rsync từ xa cuối cùng di chuyển file đó vào tên thường xuyên và bỏ, sau đó khi Chạy lại có --partialkhông có --append , tệp tạm thời mới được khởi tạo với một bản sao của tệp từ xa được chuyển một phần, sau đó bản sao tiếp tục từ nơi kết nối bị chết. (Ubuntu 14.04 / rsync 3.1)
Izkata

4
Mức độ tự tin của bạn trong hành vi được mô tả là --checksumgì? Theo đó, mannó có liên quan nhiều hơn đến việc quyết định những tập tin nào được gắn cờ để chuyển hơn là chuyển delta (có lẽ là rsynchành vi mặc định của nó).
Jonathan Y.

56

TL; DR:

Chỉ cần chỉ định một thư mục một phần là các trang man rsync khuyến nghị:

--partial-dir=.rsync-partial

Giải thích dài hơn:

Thực sự có một tính năng tích hợp để thực hiện việc này bằng cách sử dụng --partial-dirtùy chọn, có một số lợi thế so với --partial--append-verify/ --appendthay thế.

Trích từ trang man 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.

Theo mặc định, rsync sử dụng tên tệp tạm thời ngẫu nhiên sẽ bị xóa khi chuyển không thành công. Như đã đề cập, sử dụng --partialbạn có thể làm cho rsync giữ tệp không đầy đủ như thể nó đã được chuyển thành công , để sau đó có thể thêm vào tệp bằng cách sử dụng --append-verify/ --appendtùy chọn. Tuy nhiên, có một số lý do này là tối ưu.

  1. Các tệp sao lưu của bạn có thể không đầy đủ và không kiểm tra tệp từ xa vẫn không được thay đổi, không có cách nào để biết.

  2. Nếu bạn đang cố gắng sử dụng --backup--backup-dir, bạn vừa thêm một phiên bản mới của tệp này thậm chí chưa từng thoát ra khỏi lịch sử phiên bản của bạn.

Tuy nhiên, nếu chúng tôi sử dụng --partial-dir, rsync sẽ bảo vệ tệp một phần tạm thời và tiếp tục tải xuống bằng cách sử dụng tệp một phần đó vào lần tới khi bạn chạy nó và chúng tôi không gặp phải các vấn đề trên.


38

Bạn có thể muốn thêm -Ptùy chọn vào lệnh của bạn.

Từ mantrang:

--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.

Vì vậy, thay vì:

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

Làm:

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

Tất nhiên, nếu bạn không muốn cập nhật tiến độ, bạn chỉ có thể sử dụng --partial, tức là:

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

@Flimm không hoàn toàn chính xác. Nếu có sự gián đoạn (mạng hoặc bên nhận) thì khi sử dụng - một phần, tệp một phần được giữ VÀ nó được sử dụng khi rsync được nối lại. Từ trang hướng dẫn: "Sử dụng tùy chọn --partial sẽ cho rsync giữ một phần tệp sẽ <b> thực hiện chuyển tiếp phần còn lại của tệp nhanh hơn nhiều </ b>."
gaoithe

2
@Flimm và @gaoithe, câu trả lời của tôi không hoàn toàn chính xác và chắc chắn không cập nhật. Tôi đã cập nhật nó để phản ánh phiên bản 3+ của rsync. Tuy nhiên, điều quan trọng là phải nhấn mạnh rằng điều --partialđó không tự nó tiếp tục chuyển giao thất bại. Xem câu trả lời của tôi để biết chi tiết :)
DanielSmedegaardBuus

2
@DanielSmedegaardBuus Tôi đã thử nó và thế -Plà đủ trong trường hợp của tôi. Phiên bản: máy khách có 3.1.0 và máy chủ có 3.1.1. Tôi đã làm gián đoạn việc chuyển một tập tin lớn với ctrl-c. Tôi đoán tôi đang thiếu một cái gì đó.
guettli

Tại sao vv? tức là vdùng 2 lần?
mrgloom

Trường hợp rsync lưu một phần của tập tin với -azvvP?
mrgloom

1

Tôi nghĩ rằng bạn đang buộc phải gọi rsyncvà do đó tất cả dữ liệu sẽ được tải xuống khi bạn nhớ lại. sử dụng --progresstùy chọn để chỉ sao chép những tệp không được sao chép và --deletetùy chọn xóa bất kỳ tệp nào nếu đã được sao chép và hiện tại nó không tồn tại trong thư mục nguồn ...

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

Nếu bạn đang sử dụng ssh để đăng nhập vào hệ thống khác và sao chép các tập tin,

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

cho tôi biết nếu có bất kỳ sai lầm nào trong cách hiểu của tôi về khái niệm này ...


1
Bạn có thể vui lòng chỉnh sửa câu trả lời của bạn và giải thích những gì cuộc gọi ssh đặc biệt của bạn làm, và tại sao bạn khuyên làm điều đó?
Fabien

2
@Fabien Anh ấy nói với rsync để đặt hai tùy chọn ssh (rsync sử dụng ssh để kết nối). Cái thứ hai bảo ssh không nhắc xác nhận nếu máy chủ mà anh ta kết nối không được biết đến (bằng cách tồn tại trong tệp "máy chủ đã biết"). Cái đầu tiên bảo ssh không sử dụng tệp máy chủ đã biết mặc định (sẽ là ~ / .ssh / know_hosts). Anh ta sử dụng / dev / null thay vào đó, tất nhiên luôn trống và vì sau đó ssh sẽ không tìm thấy máy chủ trong đó, nên thông thường sẽ nhắc xác nhận, do đó tùy chọn hai. Khi kết nối, ssh ghi máy chủ hiện được biết đến / dev / null, thực sự quên nó ngay lập tức :)
DanielSmedegaardBuus

1
... nhưng có lẽ bạn đã tự hỏi nó có ảnh hưởng gì, nếu có, nó có tác dụng với chính hoạt động rsync. Câu trả lời là không. Nó chỉ phục vụ để không có máy chủ bạn đang kết nối để thêm vào tệp máy chủ SSH đã biết của bạn. Có lẽ anh ta là một sysadmin thường kết nối với một số lượng lớn máy chủ mới, hệ thống tạm thời hoặc không có gì. Tôi không biết :)
DanielSmedegaardBuus

4
"sử dụng tùy chọn --proceed để chỉ sao chép những tệp không được sao chép" Cái gì?
moi

1
Có một vài lỗi ở đây; một điều rất nghiêm trọng: --deletesẽ xóa các tệp ở đích không tồn tại trong nguồn. Điều ít nghiêm trọng hơn là --progresskhông sửa đổi cách mọi thứ được sao chép; nó chỉ cung cấp cho bạn một báo cáo tiến độ trên mỗi tệp khi nó sao chép. (Tôi đã sửa lỗi nghiêm trọng; thay thế bằng --remove-source-files.)
Paul Keyboardoust

1

Tôi đang sử dụng kịch bản đơn giản này. Hãy thoải mái điều chỉnh các cờ nhất định và / hoặc tối ưu hóa nó.

#!/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

Đến muộn, nhưng tôi có cùng một câu hỏi và tôi đã tìm thấy một câu trả lời khác.

Các --partiallá cờ ( "giữ các tập tin một phần chuyển" trong rsync -h) rất hữu ích cho các tập tin lớn, như là --append( "nối thêm dữ liệu vào file ngắn"), nhưng câu hỏi là về một số lượng lớn các tập tin.

Để tránh các tệp đã được sao chép, hãy sử dụng -u(hoặc --update: "bỏ qua các tệp mới hơn trên máy thu").

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.