Khi việc nâng cấp Kernel hoặc Package gặp sự cố
Hiếm có điều gì làm gián đoạn ngày làm việc nhanh hơn một bản cập nhật kernel làm hỏng bootloader hoặc một bản nâng cấp shared library khiến các daemon quan trọng bị crash. Các công cụ khôi phục thảm họa tiêu chuẩn—như bản sao rsync, ảnh đĩa clone hay file nén tar—mất quá nhiều thời gian để tải về và khôi phục. Quá trình khôi phục hệ thống 100 GB qua mạng LAN gigabit có thể ngốn từ 20 đến 30 phút downtime trước cả khi bạn bắt đầu xử lý sự cố.
Bạn cần một cơ chế đáng tin cậy ở cấp độ filesystem. Cơ chế này phải có khả năng đóng băng các trạng thái hoạt động tốt ngay lập tức và cho phép bạn quay ngược lại các thay đổi gây lỗi chỉ trong vài giây mà không tốn thêm dung lượng đĩa.
Cách Btrfs và Snapper bảo vệ trạng thái hệ thống
Btrfs (B-tree File System) được tích hợp trực tiếp vào nhân Linux mainline. Nó sử dụng kiến trúc Copy-on-Write (CoW) để xử lý lưu trữ theo cách hoàn toàn khác biệt so với các filesystem truyền thống như ext4.
1. So sánh Subvolume và Thư mục thông thường
Một subvolume Btrfs nhìn bề ngoài giống như một thư mục bình thường, nhưng kernel lại xử lý nó như một filesystem root độc lập. Mỗi subvolume có cây inode riêng biệt. Bạn có thể mount chúng với các tùy chọn mount khác nhau, thiết lập hạn ngạch dung lượng (quota) cho từng subvolume hoặc tạo snapshot riêng lẻ cho từng cái.
2. Snapshot Copy-on-Write (CoW)
Việc tạo một snapshot Btrfs mất chưa đầy 5 mili giây. Nhờ kiến trúc CoW, một snapshot mới tạo không hề sao chép nhân đôi các khối dữ liệu (file block). Nó chỉ đơn thuần sao chép cây metadata root trỏ tới các khối dữ liệu hiện có. Khi hệ thống ghi một khối file 4 KB đã sửa đổi, Btrfs sẽ ghi khối mới này vào vùng nhớ trống và cập nhật lại con trỏ hiện hành. Snapshot vẫn giữ nguyên con trỏ trỏ về khối gốc ban đầu. Một snapshot mới tạo hầu như không chiếm thêm chút dung lượng lưu trữ nào.
3. Quản lý Snapshot tự động với Snapper
Các script tạo snapshot thủ công chạy qua cron sẽ nhanh chóng trở nên khó quản lý. Snapper—ban đầu được phát triển bởi openSUSE—hoạt động như một system daemon. Nó đảm nhận việc tạo snapshot theo mốc thời gian (timeline), các hook trước và sau khi nâng cấp cho trình quản lý gói (package manager), cùng chính sách dọn dẹp (pruning) tự động để ổ đĩa của bạn không bị đầy dung lượng.
Hướng dẫn thiết lập từng bước: Subvolume, Snapper và Rollback
Bước 1: Phân vùng và cấu trúc Subvolume
Định dạng phân vùng đĩa mục tiêu (chẳng hạn như /dev/nvme0n1p2) với Btrfs:
# Định dạng phân vùng
sudo mkfs.btrfs -L sys_storage -f /dev/nvme0n1p2
# Mount root cấp cao nhất (subvolume id=5)
sudo mount /dev/nvme0n1p2 /mnt
# Tạo các subvolume riêng cho hệ thống và dữ liệu người dùng
sudo btrfs subvolume create /mnt/@
sudo btrfs subvolume create /mnt/@home
sudo btrfs subvolume create /mnt/@var_log
sudo btrfs subvolume create /mnt/@snapshots
# Unmount điểm gắn tạm thời
sudo umount /mnt
Mount các subvolume này trong /etc/fstab với các tùy chọn tối ưu hiệu năng:
# Các mục cấu hình trong /etc/fstab
LABEL=sys_storage / btrfs subvol=@,defaults,noatime,compress=zstd:1 0 0
LABEL=sys_storage /home btrfs subvol=@home,defaults,noatime,compress=zstd:1 0 0
LABEL=sys_storage /var/log btrfs subvol=@var_log,defaults,noatime 0 0
LABEL=sys_storage /.snapshots btrfs subvol=@snapshots,defaults,noatime,compress=zstd:1 0 0
Bước 2: Cài đặt và cấu hình Snapper
Cài đặt các gói Snapper tùy theo bản phân phối của bạn:
# Trên hệ thống Ubuntu/Debian
sudo apt update && sudo apt install -y snapper
# Trên Rocky Linux, AlmaLinux hoặc Fedora
sudo dnf install -y snapper
Tạo profile cấu hình chuẩn cho root filesystem:
# Khởi tạo profile root
sudo snapper -c root create-config /
# Kiểm tra các cấu hình đang hoạt động
sudo snapper list-configs
Mở /etc/snapper/configs/root và tinh chỉnh chính sách lưu giữ để kiểm soát dung lượng đĩa hiệu quả:
# Giới hạn lưu giữ trong /etc/snapper/configs/root
TIMELINE_MIN_AGE="1800"
TIMELINE_LIMIT_HOURLY="12"
TIMELINE_LIMIT_DAILY="7"
TIMELINE_LIMIT_WEEKLY="4"
TIMELINE_LIMIT_MONTHLY="2"
TIMELINE_LIMIT_YEARLY="0"
Kích hoạt các systemd timer tự động của Snapper:
sudo systemctl enable --now snapper-timeline.timer
sudo systemctl enable --now snapper-cleanup.timer
Bước 3: Thiết lập Hook Trước/Sau khi chạy Package Manager
Snapper có thể tự động tạo các cặp snapshot trước và sau khi thay đổi package. Khi sử dụng DNF trên Fedora/RHEL, snapper sẽ tự động đăng ký plugin của nó. Trên Debian và Ubuntu, hãy cấu hình hook script hoặc cài đặt libpam-snapper:
# Kiểm tra lịch sử snapshot hiện có
sudo snapper -c root list
So sánh các thay đổi của hệ thống trước và sau khi cập nhật. Nếu snapshot 18 được tạo trước khi nâng cấp và 19 được tạo sau đó, bạn có thể kiểm tra các file đã bị sửa đổi hoặc xem trực tiếp unified diff:
# Hiển thị các file đã sửa đổi, thêm mới hoặc bị xóa giữa snapshot 18 và 19
sudo snapper -c root status 18..19
# Xem chi tiết thay đổi văn bản trong file cấu hình đã sửa đổi
sudo snapper -c root diff 18..19 /etc/nginx/sites-available/default
Bước 4: Thực hiện Rollback hệ thống
Nếu quá trình nâng cấp làm hỏng một dịch vụ như OpenSSL hoặc gây lỗi kernel panic, hãy hoàn nguyên về snapshot hoạt động tốt gần nhất.
Xác định ID của snapshot mục tiêu từ danh sách:
sudo snapper -c root list
Trên các bố cục kiểu openSUSE hoặc hệ thống mount qua ID subvolume mặc định, hãy chạy:
# Rollback root về snapshot #18 còn hoạt động tốt
sudo snapper -c root rollback 18
sudo reboot
Snapper sẽ tạo một bản sao lưu trạng thái bị lỗi, tạo một snapshot có quyền ghi từ snapshot 18 và chỉ định nó làm subvolume root mặc định mới.
Khôi phục thảm họa qua Live USB
Nếu bạn sử dụng cách mount tường minh subvol=@ trong /etc/fstab và không thể truy cập vào shell, hãy boot từ bất kỳ môi trường Linux live nào để hoán đổi subvolume thủ công:
# Mount filesystem cấp cao nhất
sudo mount -o subvolid=5 /dev/nvme0n1p2 /mnt
# Lưu trữ lại subvolume root bị lỗi
sudo mv /mnt/@ /mnt/@_corrupted_$(date +%F)
# Tạo một subvolume có quyền ghi mới từ snapshot #18
sudo btrfs subvolume snapshot /mnt/@snapshots/18/snapshot /mnt/@
# Dọn dẹp và khởi động lại
sudo umount /mnt
sudo reboot
Thực tiễn tốt nhất cho môi trường Production
- Loại trừ các đường dẫn có tần suất ghi cao: Luôn tách biệt các thư mục ghi nhiều dữ liệu—chẳng hạn như
/var/lib/docker,/var/lib/containersvà/var/lib/mysql—thành các subvolume riêng. Vô hiệu hóa CoW đối với cơ sở dữ liệu (chattr +C /path) để tránh phân mảnh B-tree nghiêm trọng. - Giám sát metadata và dung lượng dự phòng: Btrfs cần dung lượng trống để cấp phát metadata cho các lần ghi mới. Lỗi hết dung lượng đĩa trên Btrfs có thể khiến việc xóa snapshot gặp khó khăn. Hãy luôn giữ mức sử dụng volume dưới 80%.
- Lên lịch scrub định kỳ: Chạy
btrfs scrub start /mỗi tháng một lần. Thao tác scrub sẽ quét các khối dữ liệu và khối parity, kiểm tra checksum SHA256/CRC32c để phát hiện và sửa chữa hiện tượng silent bit rot trước khi nó làm hỏng dữ liệu production.

