Cuộc Gọi Lúc 2 Giờ Sáng Mà Không Ai Muốn
Một đồng nghiệp của tôi đã mất ba tuần dữ liệu export database vào năm ngoái. Không phải do lỗi phần cứng — mà vì anh ta quên chạy script backup thủ công trước khi một lần migration đi sai hướng. Các file vẫn còn trên server nguồn cho đến khi chúng biến mất, và không có bản sao tự động nào ở bất kỳ đâu.
Nghe quen không? Quy trình backup thủ công sụp đổ dưới áp lực công việc thực tế. Bạn bỏ qua một ngày thứ Sáu, rồi hai ngày, và rồi có gì đó vỡ vào sáng thứ Ba và bạn phải tái tạo dữ liệu từ trí nhớ.
Giải pháp không phải là kỷ luật — mà là tự động hóa. Cụ thể, rsync kết hợp với cron xử lý vấn đề này gọn gàng, không cần phần mềm bổ sung hay đăng ký dịch vụ cloud.
Tại Sao Backup Thủ Công Luôn Thất Bại Về Lâu Dài
Nguyên nhân gốc rễ không phải là sự lười biếng. Quy trình backup thủ công thất bại vì những lý do mang tính cấu trúc:
- Chuyển đổi ngữ cảnh — Bạn đang tập trung vào một lần deployment và bước backup bị bỏ qua trong đầu.
- Thời gian không nhất quán — “Tôi sẽ làm tối nay” trở thành “Tôi sẽ làm ngày mai.”
- Sai công cụ — Copy bằng
cp -rkhông xử lý đúng symlink, quyền file hay các transfer bị gián đoạn. - Không kiểm tra — Bạn đã chạy backup, nhưng nó có hoàn thành không? Dữ liệu có thực sự được ghi vào đích không?
Một khi backup phụ thuộc vào việc ai đó nhớ chạy nó, bạn đã chấp nhận rủi ro mất dữ liệu. Cron loại bỏ yêu cầu về trí nhớ. rsync giải quyết các vấn đề về công cụ.
rsync so với Các Phương Pháp Backup Khác
Thường có ba công cụ được đề cập khi nói về backup trên Linux. Dưới đây là những gì mỗi công cụ thực sự làm — và điểm yếu của chúng.
Tùy chọn 1: cp -r
Đơn giản, có sẵn ở mọi nơi. Nhưng nó copy toàn bộ mỗi lần. Với các thư mục lớn, điều đó có nghĩa là phải transfer toàn bộ ngay cả khi chỉ có một file thay đổi. Nó cũng không giữ nguyên extended attribute hay xử lý graceful các transfer bị gián đoạn.
Tùy chọn 2: Lưu trữ tar
Tạo ra các archive nén, hữu ích cho việc lưu trữ dài hạn hoặc di chuyển backup ra ngoài. Nhược điểm: khôi phục một file đơn lẻ yêu cầu giải nén toàn bộ archive. Và mỗi lần chạy vẫn là một bản copy đầy đủ.
Tùy chọn 3: rsync (đồng bộ tăng dần)
rsync chỉ transfer những gì đã thay đổi — so sánh kích thước file và timestamp sửa đổi (hoặc checksum nếu bạn yêu cầu). Trên server Ubuntu 22.04 production của tôi, backup hàng đêm với tar mất khoảng 12 phút. Chuyển sang rsync giảm xuống dưới 90 giây. Chỉ có các file đã thay đổi được transfer nên delta rất nhỏ.
rsync cũng xử lý các transfer bị gián đoạn bằng cách tiếp tục từ chỗ dừng, và mặc định giữ nguyên quyền file, symlink, timestamp và quyền sở hữu với các flag phù hợp.
Đối với backup server — local hay từ xa — rsync là lựa chọn rõ ràng nhất.
Cài Đặt rsync cho Backup Tự Động
Cài đặt rsync
Hầu hết các bản phân phối Linux đã có sẵn rsync. Nếu chưa có:
# Debian/Ubuntu
sudo apt install rsync
# RHEL/AlmaLinux/Rocky
sudo dnf install rsync
Cấu Trúc Lệnh rsync Cơ Bản
rsync -avz --delete /source/directory/ /destination/directory/
Giải thích các flag:
-a(chế độ archive) — giữ nguyên quyền file, timestamp, symlink, owner, group-v(verbose) — hiển thị những gì đang được transfer (hữu ích trong log)-z(nén) — nén dữ liệu trong quá trình transfer (chủ yếu hữu ích cho remote; bỏ qua với backup local)--delete— xóa các file ở đích không còn tồn tại ở nguồn (giữ chúng đồng bộ)
Lưu ý dấu slash cuối ở nguồn — /source/directory/ có nghĩa là “đồng bộ nội dung của thư mục này.” Không có nó, rsync sẽ tạo một thư mục con tên directory bên trong đích. Đây là một lỗi hay gặp.
Ví Dụ Backup Local
# Backup /var/www lên ổ đĩa ngoài được mount tại /mnt/backup
rsync -av --delete /var/www/ /mnt/backup/www/
Backup Từ Xa Qua SSH
# Backup lên server từ xa
rsync -avz --delete -e ssh /var/www/ user@backup-server:/backups/www/
# Với SSH key cụ thể và cổng không chuẩn
rsync -avz --delete -e "ssh -i /root/.ssh/backup_key -p 2222" \
/var/www/ user@backup-server:/backups/www/
Để backup từ xa tự động (không cần giám sát), bạn cần xác thực SSH không cần mật khẩu. Tạo một cặp key riêng:
# Tạo key trên server nguồn
ssh-keygen -t ed25519 -f /root/.ssh/backup_key -N ""
# Copy public key lên đích
ssh-copy-id -i /root/.ssh/backup_key.pub user@backup-server
Loại Trừ Files và Thư Mục
# Loại trừ cache, file tạm và logs
rsync -av --delete \
--exclude='cache/' \
--exclude='*.log' \
--exclude='tmp/' \
/var/www/ /mnt/backup/www/
Với nhiều mục cần loại trừ, hãy đặt chúng vào một file:
# /etc/rsync-excludes.txt
cache/
*.log
tmp/
*.swp
.git/
rsync -av --delete --exclude-from=/etc/rsync-excludes.txt \
/var/www/ /mnt/backup/www/
Viết Script Backup Sẵn Sàng cho Production
Chạy rsync trực tiếp từ cron hoạt động được, nhưng một wrapper script giúp bạn có logging, xử lý lỗi và nơi để thêm logic sau này mà không cần chỉnh sửa crontab.
#!/bin/bash
# /usr/local/bin/backup-www.sh
SOURCE="/var/www/"
DEST="/mnt/backup/www/"
LOG="/var/log/rsync-backup.log"
DATE=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$DATE] Bắt đầu backup" >> "$LOG"
rsync -av --delete \
--exclude='cache/' \
--exclude='*.log' \
--log-file="$LOG" \
"$SOURCE" "$DEST"
EXIT_CODE=$?
if [ $EXIT_CODE -eq 0 ]; then
echo "[$DATE] Backup hoàn thành thành công" >> "$LOG"
else
echo "[$DATE] Backup THẤT BẠI với exit code $EXIT_CODE" >> "$LOG"
fi
exit $EXIT_CODE
# Cấp quyền thực thi
chmod +x /usr/local/bin/backup-www.sh
# Test thủ công trước
/usr/local/bin/backup-www.sh
Lên Lịch với cron
Khi script đã hoạt động thủ công, hãy giao cho cron.
# Chỉnh sửa root crontab
crontab -e
Thêm lịch của bạn. Cú pháp cron là: phút giờ ngày tháng thứ lệnh
# Chạy hàng ngày lúc 2:30 sáng
30 2 * * * /usr/local/bin/backup-www.sh
# Chạy mỗi 6 tiếng
0 */6 * * * /usr/local/bin/backup-www.sh
# Chạy mỗi Chủ Nhật lúc 1:00 sáng
0 1 * * 0 /usr/local/bin/backup-www.sh
Nếu bạn không chắc về cú pháp cron, crontab.guru cho phép bạn dán một biểu thức và xem kết quả dễ hiểu.
Xác Minh cron Đang Chạy Job Của Bạn
# Kiểm tra log cron hệ thống (Debian/Ubuntu)
grep CRON /var/log/syslog | tail -20
# Kiểm tra log cron (RHEL/AlmaLinux)
grep CRON /var/log/cron | tail -20
Lưu Giữ Nhiều Phiên Bản Backup
rsync thông thường chỉ cho bạn một bản copy — xóa một file ở nguồn và lần chạy tiếp theo cũng xóa nó khỏi backup. Để backup có phiên bản, hãy dùng --backup với --backup-dir:
#!/bin/bash
# Backup có phiên bản: lưu bản sao có ngày tháng của các file đã thay đổi/bị xóa
SOURCE="/var/www/"
BACKUP_ROOT="/mnt/backup"
CURRENT="$BACKUP_ROOT/current"
DATED="$BACKUP_ROOT/versions/$(date +%Y-%m-%d)"
rsync -av --delete \
--backup \
--backup-dir="$DATED" \
"$SOURCE" "$CURRENT/"
/mnt/backup/current/ luôn là bản mirror trực tiếp. Bất kỳ file nào đã thay đổi hoặc bị xóa sẽ được lưu vào thư mục có ngày như /mnt/backup/versions/2026-03-08/. Khôi phục tại một thời điểm cụ thể mà không cần lưu toàn bộ bản copy mỗi lần chạy.
Thêm bước dọn dẹp để tránh tích lũy quá nhiều thư mục phiên bản:
# Xóa các thư mục phiên bản cũ hơn 30 ngày
find "$BACKUP_ROOT/versions/" -maxdepth 1 -type d -mtime +30 -exec rm -rf {} \;
Test Khôi Phục — Đừng Bỏ Qua Bước Này
Backup chưa được test chỉ là dung lượng đĩa khiến bạn cảm thấy yên tâm cho đến khi có sự cố. Sau khi thiết lập xong, hãy thực sự khôi phục thứ gì đó:
# Khôi phục một file đơn lẻ
rsync -av /mnt/backup/www/html/index.php /tmp/restore-test/
# Khôi phục toàn bộ thư mục về vị trí test
rsync -av /mnt/backup/www/ /tmp/full-restore-test/
Hãy làm điều này ít nhất mỗi quý. Quy trình backup thay đổi theo thời gian — cron job được chuyển sang server khác, mount point thay đổi, ổ đĩa đích đầy mà không ai để ý. Một bài test khôi phục sẽ phát hiện tất cả những điều này trước khi chúng trở thành vấn đề.
Tham Khảo Nhanh
- Luôn test lệnh rsync thủ công trước khi thêm vào cron
- Ghi output vào file log — cron job chạy im lặng che giấu các lỗi
- Dùng
--dry-runđể xem trước những gì rsync sẽ transfer mà không thực sự thực hiện - Với backup từ xa, thiết lập SSH key riêng với quyền hạn chế trên đích
- Kiểm tra đích backup có đủ dung lượng trống — rsync thoát với lỗi giữa chừng, nhưng bạn chỉ phát hiện nếu theo dõi log
# Dry run — xem những gì sẽ được transfer mà không thực sự thực hiện
rsync -av --dry-run --delete /var/www/ /mnt/backup/www/
# Kiểm tra dung lượng đĩa đích
df -h /mnt/backup
Thiết lập ban đầu mất khoảng 30 phút. Sau đó, nó chạy mỗi đêm mà bạn không cần nghĩ đến. Đó là toàn bộ mục đích.

