SQLite không còn là “hàng demo” nếu bạn biết cách bảo vệ
SQLite đang rũ bỏ cái mác “database cho app nhỏ” để tiến thẳng vào môi trường production của nhiều hệ thống hiện đại. Thay vì tốn hàng trăm MB RAM cho một cụm PostgreSQL cồng kềnh, nhiều anh em chọn SQLite vì sự gọn nhẹ: toàn bộ dữ liệu gói gọn trong một file. Thế nhưng, câu hỏi khiến nhiều người chùn bước vẫn là: “Nếu server sập hoặc file database bị hỏng thì lấy gì mà cứu?”
Hai năm trước, mình từng vận hành một ứng dụng quản lý kho nhỏ dùng SQLite. Một buổi sáng đẹp trời, ổ cứng server dở chứng, file .db bị corrupt ngay lúc đang ghi dữ liệu. Bản backup gần nhất từ Cron job đã cách đó 24 tiếng. Kết quả? Toàn bộ đơn hàng của khách trong ngày hôm đó bốc hơi. Đó là bài học đắt giá về sự chủ quan. Sau sự cố ấy, mình tìm thấy Litestream – giải pháp thay đổi hoàn toàn cuộc chơi về độ tin cậy cho SQLite.
So sánh các phương pháp backup SQLite phổ biến
Trước khi bắt tay vào cấu hình, hãy nhìn lại những cách làm truyền thống để thấy tại sao Litestream lại vượt trội.
1. Copy file thủ công hoặc chạy Cron job
Bạn thiết lập script để định kỳ mỗi tiếng hoặc mỗi ngày copy file data.db đẩy lên Google Drive hoặc S3.
- Ưu điểm: Cực kỳ dễ triển khai, không cần cài đặt phức tạp.
- Nhược điểm: Rủi ro mất dữ liệu (RPO) rất cao. Nếu server sập vào lúc 23h trong khi bản backup cuối là từ 1h sáng, bạn mất trắng 22 giờ dữ liệu. Ngoài ra, copy khi file đang ghi dễ dẫn đến tình trạng file backup bị lỗi cấu trúc.
2. Sử dụng lệnh .backup của SQLite
Dùng lệnh sqlite3 data.db ".backup 'backup.db'" sẽ an toàn hơn vì nó đảm bảo tính nhất quán của dữ liệu tại thời điểm copy.
- Ưu điểm: File backup luôn ở trạng thái tốt, không bị hỏng.
- Nhược điểm: Vẫn chỉ là dạng snapshot. Bạn vẫn phải đối mặt với khoảng trống dữ liệu giữa các lần chạy lệnh backup.
3. Litestream: Streaming WAL (Write-Ahead Log)
Litestream hoạt động theo cơ chế khác biệt hoàn toàn. Thay vì đợi đến giờ mới copy cả file dung lượng lớn, nó theo dõi file WAL của SQLite và đẩy từng thay đổi nhỏ lên S3 ngay lập tức.
- Ưu điểm: RPO (Recovery Point Objective) giảm xuống dưới 1 giây. Nếu server “bốc cháy”, bạn chỉ mất vài mili giây dữ liệu cuối cùng. Tài nguyên tiêu thụ cực thấp, chỉ khoảng vài MB RAM.
- Nhược điểm: Cần duy trì một process chạy ngầm (sidecar) cùng ứng dụng.
Tại sao Litestream lại hiệu quả đến vậy?
Chìa khóa nằm ở chế độ WAL (Write-Ahead Log). Khi bật WAL, SQLite sẽ ghi các thay đổi vào một file phụ (đuôi -wal) trước khi gộp vào file chính. Litestream đóng vai trò như một “camera giám sát”, nó đọc file WAL này và stream từng mẩu dữ liệu lên Cloudflare R2 hoặc AWS S3 theo thời gian thực.
Điểm mình ưng ý nhất là Litestream hoàn toàn không xâm lấn. Bạn không cần sửa bất kỳ dòng code Python, Go hay Node.js nào. Nó đứng độc lập, bảo vệ database từ bên ngoài mà không làm chậm ứng dụng của bạn.
Hướng dẫn triển khai thực tế với Cloudflare R2
Mình chọn Cloudflare R2 cho hướng dẫn này vì họ miễn phí 10GB lưu trữ đầu tiên và đặc biệt là không tính phí băng thông tải ra (Egress fee) – một khoản tiết kiệm đáng kể so với AWS S3.
Bước 1: Khởi tạo Bucket trên R2
Truy cập Dashboard Cloudflare -> R2 -> Create bucket (đặt tên là my-sqlite-backup). Sau đó, tạo một API Token với quyền Edit. Lưu lại Access Key ID và Secret Access Key để dùng ở bước sau.
Bước 2: Cài đặt Litestream lên Server
Với server Ubuntu hoặc Debian, bạn chỉ cần vài dòng lệnh để cài đặt bản mới nhất:
wget https://github.com/benbjohnson/litestream/releases/download/v0.3.13/litestream-v0.3.13-linux-amd64.deb
sudo apt install ./litestream-v0.3.13-linux-amd64.deb
Bước 3: Cấu hình file litestream.yml
Tạo file cấu hình tại /etc/litestream.yml. Đây là nơi định nghĩa “nguồn” và “đích” của dữ liệu.
access-key-id: YOUR_R2_ACCESS_KEY_ID
secret-access-key: YOUR_R2_SECRET_ACCESS_KEY
databases:
- path: /var/www/app/data.db
replicas:
- url: s3://my-sqlite-backup.YOUR_ACCOUNT_ID.r2.cloudflarestorage.com/db
Mẹo nhỏ: Nếu bạn dùng Git quản lý cấu hình, tuyệt đối không dán trực tiếp Key vào file này. Hãy sử dụng biến môi trường để tránh lộ thông tin nhạy cảm.
Bước 4: Kích hoạt chế độ WAL
Litestream chỉ hoạt động khi database ở chế độ WAL. Hãy chạy lệnh này để kích hoạt:
sqlite3 /var/www/app/data.db "PRAGMA journal_mode=WAL;"
Bước 5: Vận hành hệ thống
Khởi động Litestream để bắt đầu quá trình đồng bộ:
sudo systemctl enable litestream
sudo systemctl start litestream
Để chắc chắn mọi thứ đang trơn tru, hãy kiểm tra log:
journalctl -u litestream -f
Quy trình khôi phục dữ liệu (Restore)
Backup là để phòng hờ, nhưng kỹ năng restore mới giúp bạn sống sót khi sự cố xảy ra. Khi server cũ hỏng, bạn dựng server mới và chỉ cần chạy lệnh duy nhất để lấy lại toàn bộ data:
litestream restore -o /var/www/app/data.db s3://my-sqlite-backup.YOUR_ACCOUNT_ID.r2.cloudflarestorage.com/db
Litestream sẽ tự động tải bản snapshot mới nhất và áp dụng các thay đổi từ file WAL để đưa database về trạng thái ngay trước thời điểm gặp sự cố.
Kinh nghiệm thực chiến và lưu ý
- Giám sát chặt chẽ: Litestream hỗ trợ xuất metric cho Prometheus. Hãy thiết lập cảnh báo (Alert) nếu quá trình stream bị gián đoạn quá 5 phút.
- Kiểm soát chi phí: Dù lưu trữ S3 rất rẻ, nhưng nếu ứng dụng ghi dữ liệu liên tục, file WAL sẽ sinh ra rất nhiều. Bạn nên cấu hình
retention(thời gian lưu trữ) khoảng 7-30 ngày để tối ưu chi phí. - Diễn tập định kỳ: Đừng đợi đến lúc cháy nhà mới đi tìm bình cứu hỏa. Mỗi tháng một lần, hãy thử restore dữ liệu lên một server ảo sạch để đảm bảo quy trình luôn sẵn sàng.
- Triển khai với Docker: Bạn có thể chạy Litestream như một sidecar container. Tuy nhiên, cách đơn giản nhất vẫn là cài chung vào image của app và quản lý bằng
supervisord.
Sự kết hợp giữa SQLite và Litestream mang lại sự an tâm tuyệt đối với chi phí gần như bằng 0. Nếu bạn đang chạy các dự án vừa và nhỏ, hãy thử ngay combo này để tận hưởng sự tiện lợi của SQLite mà không còn lo sợ mất dữ liệu.

