rsync là công cụ sao chép linh hoạt cho cả đường dẫn cục bộ và máy từ xa, nhưng một ký tự hoặc tùy chọn sai có thể tạo ra cấu trúc thư mục ngoài ý muốn—thậm chí xóa dữ liệu ở đích. Quy trình an toàn không bắt đầu bằng lệnh thật. Nó bắt đầu bằng việc xác định rõ nguồn, đích, semantics của dấu gạch chéo cuối, rồi chạy --dry-run với danh sách thay đổi chi tiết.
Bài viết này xây dựng một quy trình có thể lặp lại: kiểm tra phiên bản, chạy thử, truyền qua SSH, tiếp tục khi gián đoạn, xác minh kết quả và chỉ bật --delete sau khi đã chứng minh phạm vi đúng. Các ví dụ dùng Linux/macOS; trên Windows có thể chạy trong WSL hoặc môi trường cung cấp rsync.
1. Hiểu mô hình source → destination
Cú pháp cơ bản là:
rsync [OPTIONS] SOURCE DESTINATION
Cả nguồn và đích có thể là đường dẫn local. Để truyền qua SSH, một phía dùng dạng user@host:/path. Nếu chỉ cung cấp một nguồn mà không có đích, rsync liệt kê thay vì sao chép—một cách kiểm tra hữu ích nhưng không thay thế dry-run đầy đủ.
# Local → local
rsync -a /srv/data/ /mnt/backup/data/
# Local → remote qua SSH
rsync -a /srv/data/ ops@backup.example:/srv/backup/data/
# Remote → local
rsync -a ops@server.example:/srv/export/ /mnt/import/
Trước khi chạy, hãy nói thành lời: “Tôi muốn nội dung nào xuất hiện trực tiếp trong thư mục nào?” Nếu câu trả lời chưa rõ, đường dẫn cũng chưa sẵn sàng.
2. Dấu gạch chéo cuối thay đổi kết quả
Đây là khác biệt quan trọng nhất đối với người mới:
| Lệnh | Ý nghĩa tại đích |
|---|---|
rsync -a /src/photos /backup/ | Sao chép chính thư mục photos, tạo /backup/photos/ |
rsync -a /src/photos/ /backup/photos/ | Sao chép nội dung bên trong photos vào đích |
Dấu gạch chéo ở nguồn mới quyết định “thư mục” hay “nội dung thư mục”. Dấu gạch chéo ở đích thường không cứu được một source viết sai. Hãy tạo cây thử nhỏ trong thư mục tạm và quan sát trước khi áp dụng cho dữ liệu thật.
3. Bắt đầu bằng dry-run và itemize changes
Dùng -n hoặc --dry-run để mô phỏng mà không thay đổi file. Kết hợp -i để xem loại thay đổi và -v để tăng chi tiết:
rsync -avni /srv/data/ /mnt/backup/data/
-a là archive mode; -v verbose; -n dry-run; -i itemize changes. Một quy trình tốt lưu đầu ra dry-run vào log để review:
rsync -ani --delete /srv/data/ /mnt/backup/data/ \
| tee rsync-plan.txt
Dry-run không truyền nội dung thật, nên thống kê byte, tốc độ và progress không đại diện cho lần chạy thật. Nó giúp xác nhận phạm vi file và hành động dự kiến, không phải benchmark.
4. Archive mode giữ gì và không giữ gì?
-a tương đương gần với -rlptgoD: đệ quy, giữ symlink, permission, modification time, group, owner và device/special file khi quyền cho phép. Tuy nhiên, archive mode không tự bao gồm ACL, extended attributes hoặc hard link.
| Nhu cầu | Tùy chọn bổ sung | Lưu ý |
|---|---|---|
| Giữ ACL | -A | Hai filesystem phải hỗ trợ ACL phù hợp |
| Giữ extended attributes | -X | Có thể chứa capability hoặc metadata bảo mật |
| Giữ quan hệ hard link | -H | Tốn thêm bộ nhớ và thời gian quét |
| Không vượt filesystem khác | -x | Hữu ích khi nguồn có mount lồng bên trong |
| Giữ UID/GID dạng số | --numeric-ids | Cần hiểu mapping tài khoản ở đích |
Không mặc định thêm mọi cờ. Chọn theo loại backup và khả năng của filesystem đích; ví dụ FAT/exFAT không thể giữ đầy đủ metadata Unix.
5. Truyền qua SSH an toàn
Rsync thường gọi SSH làm remote shell. Nên dùng key, xác minh host key và chỉ rõ cổng khi cần:
rsync -a --info=progress2 \
-e "ssh -p 2222" \
/srv/data/ ops@backup.example:/srv/backup/data/
Không tắt kiểm tra host key chỉ để automation chạy được. Với job tự động, cấu hình known_hosts trước, dùng key có quyền tối thiểu và hạn chế tài khoản ở máy đích. Dùng dấu nháy đúng cho đường dẫn có khoảng trắng; local shell và remote shell đều có thể tham gia phân tích chuỗi lệnh.
6. Resume khi đường truyền bị gián đoạn
Mặc định, file truyền dở có thể bị loại bỏ. --partial giữ phần chưa hoàn tất để lần sau tiếp tục hiệu quả hơn; -P là dạng gọn của --partial --progress:
rsync -aP /srv/large-files/ \
ops@backup.example:/srv/backup/large-files/
Với job có nhiều file, --info=progress2 cho tiến độ tổng thể dễ đọc hơn. Có thể tách phần dở vào thư mục tương đối:
rsync -a --partial-dir=.rsync-partial --info=progress2 \
/srv/data/ ops@backup.example:/srv/backup/data/
Không đặt partial directory trong vị trí ghi được bởi người dùng không tin cậy. Cũng không kết hợp tùy tiện --inplace với chiến lược partial: --inplace sửa trực tiếp file đích và có thể để lại file hỏng nếu job bị dừng.
7. Quick check khác với --checksum
Theo mặc định, rsync quyết định file cần cập nhật bằng “quick check”, thường dựa vào kích thước và thời gian sửa đổi. --checksum hoặc -c yêu cầu đọc file ở cả hai phía để so checksum trước truyền:
rsync -acni /srv/data/ /mnt/backup/data/
-c hữu ích khi timestamp không đáng tin hoặc cần audit sâu, nhưng có thể tạo I/O rất lớn vì phải đọc toàn bộ dữ liệu. Nó không có nghĩa rsync bình thường bỏ qua kiểm tra tính đúng đắn của file vừa truyền: rsync vẫn có cơ chế checksum để xác minh việc tái tạo file trong quá trình transfer. Đây là hai mục đích khác nhau.
8. Xác minh độc lập bằng SHA-256
Với tập dữ liệu quan trọng, có thể tạo manifest SHA-256 ở nguồn và kiểm tra tại đích. Chạy từ cùng thư mục gốc để tên file tương đối khớp:
# Tại nguồn
cd /srv/data
find . -type f -print0 | sort -z | xargs -0 sha256sum > SHA256SUMS
# Sau khi sao chép, tại đích
cd /srv/backup/data
sha256sum --check SHA256SUMS
Manifest cũng là dữ liệu cần bảo vệ. Nếu threat model có kẻ tấn công, checksum và file dữ liệu đặt cùng nơi không chứng minh tính xác thực; cần chữ ký số hoặc kênh tin cậy cho manifest.
9. Exclude đúng nhưng vẫn kiểm tra cây kết quả
Dùng --exclude cho cache, file tạm hoặc artifact có thể tái tạo:
rsync -avni \
--exclude='.cache/' \
--exclude='*.tmp' \
--exclude='node_modules/' \
/srv/app/ /mnt/backup/app/
Pattern được đánh giá tương đối với gốc transfer và có semantics riêng. Khi danh sách dài, dùng --exclude-from=rsync-excludes.txt, lưu file rule trong version control và test bằng cây mẫu. Đừng giả định glob của rsync giống hoàn toàn glob của shell.
10. --delete là mirror, không phải backup lịch sử
--delete làm đích loại bỏ file không còn ở nguồn. Nó hữu ích để tạo mirror, nhưng nguy hiểm nếu đảo nguồn/đích, source mount bị rỗng hoặc exclude viết sai. Luôn dry-run:
rsync -ani --delete /srv/data/ /mnt/mirror/data/
- Xác minh source filesystem đã mount và chứa dữ liệu mong đợi.
- Kiểm tra đường dẫn tuyệt đối bằng
pwdvàfind. - Lưu log danh sách file sẽ xóa, review trước lần chạy thật.
- Dùng snapshot/versioning ở đích để có đường lui.
- Không xem mirror có
--deletelà bản backup duy nhất.
Nếu ransomware mã hóa hoặc người dùng xóa file ở nguồn, mirror có thể sao chép trạng thái hỏng sang đích. Backup đúng nghĩa cần retention độc lập và khả năng phục hồi phiên bản cũ.
11. Hai giai đoạn cho một lần đồng bộ quan trọng
Mẫu vận hành dưới đây tách review và thực thi:
# Giai đoạn 1: lập kế hoạch
rsync -ani --delete --exclude-from=rsync-excludes.txt \
/srv/data/ /mnt/backup/data/ > rsync-plan.txt
# Giai đoạn 2: chỉ chạy sau khi review plan
rsync -ai --delete --partial-dir=.rsync-partial \
--exclude-from=rsync-excludes.txt \
/srv/data/ /mnt/backup/data/ | tee rsync-run.txt
Giữa hai giai đoạn, dữ liệu vẫn có thể thay đổi. Với workload đang ghi liên tục, hãy tạo filesystem/database snapshot nhất quán rồi rsync từ snapshot. Sao chép thư mục database đang chạy không tự đảm bảo backup có thể phục hồi.
12. Đọc exit code và không che lỗi
Automation phải kiểm tra exit code của rsync. Kết quả “partial transfer” không nên được ghi nhận như thành công hoàn toàn. Khi pipe qua tee trong Bash, bật pipefail để pipeline không chỉ trả exit code của lệnh cuối:
set -o pipefail
rsync -ai /srv/data/ /mnt/backup/data/ | tee rsync-run.txt
status=$?
if [ "$status" -ne 0 ]; then
echo "rsync failed with status $status" >&2
exit "$status"
fi
Log nên có thời gian, host, phiên bản rsync, source, destination, options và exit code. Không ghi password hoặc private key vào command line hay log.
13. Checklist trước và sau khi chạy
- Chạy
rsync --versionở cả hai phía và xác nhận tính năng tương thích. - Xác minh source, destination, mount point và dung lượng trống.
- Kiểm tra dấu gạch chéo cuối của source.
- Chạy
-ani; review toàn bộ file thêm, đổi và xóa. - Kiểm tra ACL/xattr/hard link có cần giữ hay không.
- Dùng SSH key quyền tối thiểu và host key đã xác minh.
- Chọn chiến lược partial/resume phù hợp với file lớn.
- Kiểm tra exit code, log và số lượng/kích thước file sau chạy.
- Với dữ liệu quan trọng, kiểm tra checksum độc lập và thử phục hồi.
- Nếu dùng
--delete, đích phải có snapshot hoặc retention riêng.
Tài liệu tham khảo
- Tài liệu chính thức rsync(1)
- README chính thức của dự án rsync
- GNU Coreutils manual: SHA-2 checksum utilities
Kết luận
Rsync an toàn là một quy trình, không phải một tổ hợp cờ dài. Hãy hiểu source có dấu gạch chéo cuối, lập kế hoạch bằng dry-run, chọn metadata cần bảo toàn, chuẩn bị resume, kiểm tra exit code và xác minh dữ liệu sau truyền. Đặc biệt, chỉ dùng --delete khi đã review chính xác phạm vi và có bản phục hồi độc lập. Làm đúng các bước đó, rsync trở thành công cụ đồng bộ nhanh, minh bạch và đáng tin cậy cho cả thao tác thủ công lẫn automation.




Chưa có bình luận. Hãy là người đầu tiên chia sẻ ý kiến.