--link-dest
Mọi người có thể nghĩ rằng 'vào một tệp giống hệt nhau sẽ hoạt động trong mọi trường hợp. Nhưng nó không tồn tại khi tập tin tồn tại, ngay cả khi tập tin đã hết hạn / có nội dung khác nhau.
Đó là vì điều này, từ trang man rsync trên --link-dest
:
"Tùy chọn này hoạt động tốt nhất khi sao chép vào hệ thống phân cấp đích trống, vì rsync coi các tệp hiện có là dứt khoát (vì vậy rsync không bao giờ nhìn vào các thư mục liên kết khi đã tồn tại tệp đích )"
Điều này có nghĩa là nếu y/file
tồn tại giống như nguồn và đã z/file
lỗi thời,
rsync -a --del -link-dest=y source:/file z
sẽ dẫn đến TWO inodes (và gấp đôi không gian đĩa) đang được sử dụng y/file
và z/file
sẽ có cùng nội dung và dấu thời gian.
Tôi đã gặp phải điều này bởi vì tôi thực hiện sao lưu hàng ngày về cơ bản với tập lệnh này chạy một lần mỗi ngày:
mv $somedaysago $today;
yest=$today; today=`date +%Y%m%d`;
rsync -avPShyH --del --link-dest=../$yest host:/dirs $today
Bởi vì các bản sao lưu của tôi kéo dài tới 10 triệu tệp, việc thực hiện rm -rf $olddir; rsync source:$dir newdir
sẽ mất quá nhiều thời gian (đặc biệt là khi chỉ có 0,5% số tệp thay đổi mỗi ngày, phát sinh việc xóa và tạo các mục nhập 10M chỉ để xử lý 50K tệp mới hoặc thay đổi, điều này sẽ khiến tôi sao lưu không đầy đủ trong thời gian cho ngày hôm sau).
Đây là bản demo của tình huống:
a
là nguồn của chúng tôi, 1
thông qua 4
các bản sao lưu được đánh số của chúng tôi:
$ 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
Bây giờ chúng tôi có 2 bản sao lưu a/foobar
giống hệt nhau theo mọi cách, bao gồm dấu thời gian, nhưng chiếm các nút khác nhau.
Mọi người có thể nghĩ rằng một giải pháp sẽ là --delete-before
, nó sẽ giết chết lợi ích của việc quét tăng dần nhưng điều này không giúp ích gì vì tệp sẽ không bị xóa, nhưng được sử dụng làm cơ sở trong trường hợp có thể sao chép tăng dần.
Người ta có thể phỏng đoán thêm sau đó chúng ta có thể tắt hàng rào sao chép tăng dần này --whole-file
, nhưng điều này không giúp ích gì cho thuật toán, không có cách nào để có được những gì chúng ta muốn.
Tôi coi hành vi này là một lỗi khác trong rsync, trong đó một hành vi có lợi có thể được hiểu từ các lựa chọn cẩn thận của các đối số lệnh khác nhau, nhưng kết quả mong muốn là không có sẵn.
Một giải pháp không may chuyển từ một rsync đơn lẻ thành hoạt động nguyên tử sang chạy khô -n
, ghi nhật ký, xử lý nhật ký đó làm đầu vào để xóa trước tất cả các tệp đã thay đổi, sau đó chạy rsync --link-dest
để có được những gì chúng ta muốn - một loại bùn lớn so với một rsync sạch duy nhất.
Phụ lục: đã cố gắng liên kết trước $yesterday
và $today
trên máy chủ dự phòng trước khi sao lưu với các hộp sản xuất với rsync --link-dest=../$yesterday $yesterday/ $today
- nhưng kết quả tương tự - bất kỳ tệp nào tồn tại theo bất kỳ cách nào, thậm chí là 0, sẽ không bao giờ bị xóa và bị hủy liên kết, thay vào đó là toàn bộ bản sao mới sẽ được tạo từ sourcedir với một inode mới và sử dụng nhiều không gian đĩa hơn.
Nhìn vào pax(1)
như một giải pháp trước khi liên kết trước khi sao lưu.
--delete-after
là tốt, nhưng không liên quan đến vấn đề trong tay. Các tệp bị thiếu từ nguồn sẽ bị xóa sau khi sao chép xong. Vấn đề tôi đang làm sáng tỏ liên quan đến một bản sao lưu được thực hiện hôm nay giống hệt với ngày hôm qua nhưng chống lại một tệp lỗi thời cũ không liên kết với inode của ngày hôm qua, nhưng được lưu trữ dưới dạng một tệp mới với tổng dung lượng đĩa gấp đôi so với ngày hôm qua bản sao giống hệt được xem xét.
rsnapshot
chưa? Ngoài ra, hãy xem xét việc viết một tập lệnh nhỏ để phát lại các tệp "giống hệt". Tôi làm cả hai trên hệ thống của tôi.
hardlink(1)
chậm (chậm hơn 15 lần so với quét siêu dữ liệu của rsync); pax
là nhanh hơn nhưng vượt qua các đầu ổ cứng so sánh sao lưu cũ với mới. rsync -n
để có được danh sách delta có nghĩa là đánh hai lần máy chủ sản xuất (quét các tệp 10M có tác động hơn nhiều so với sao chép các thay đổi 50K). Ill mail danh sách về một tùy chọn trong rsync để cho phép điều này.
--delete-after
trong kịch bản sử dụng này, có gì sai với điều này?