Khi quản trị một website tin tức, thương mại điện tử hay ứng dụng nội bộ, dữ liệu của bạn hầu như không bao giờ nằm tập trung ở một chỗ duy nhất. Thông tin tài khoản, bài viết, đơn hàng và cấu hình hệ thống thường nằm trong database (như MySQL hay PostgreSQL). Trong khi đó, toàn bộ ảnh sản phẩm, hợp đồng PDF, hóa đơn điện tử hoặc file đính kèm của người dùng lại được lưu ở một thư mục trên ổ đĩa VPS (/var/www/uploads) hoặc đẩy lên dịch vụ object storage (như S3 hay Cloudflare R2).
Rất nhiều quản trị viên thiết lập backup theo cách tách biệt: một script chạy dump database lúc 1h00 sáng, và một script khác nén thư mục upload lúc 3h00 sáng. Cả hai script sáng hôm sau đều báo kết thúc thành công với mã 0.
Thế nhưng, khi xảy ra sự cố cần phục hồi, bạn có thể rơi vào tình huống dở khóc dở cười:
- Khách hàng tải file hóa đơn lúc 2h15 sáng: Bản nén file lúc 3h00 có chứa file này, nhưng database chụp lúc 1h00 hoàn toàn không có thông tin gì về đơn hàng hay hóa đơn đó. Kết quả là hệ thống xuất hiện những "file mồ côi" không thuộc về ai.
- Hoặc ngược lại: Database chụp sau, chứa thông tin tham chiếu tới một bức ảnh đại diện mới, nhưng thư mục file chụp trước đó vài chục phút chưa kịp ghi nhận file ảnh. Khi dựng lại website, người dùng click vào xem chi tiết sẽ thấy hàng loạt hình ảnh bị vỡ liên kết (lỗi 404).
Khoảng chênh lệch này trong kỹ thuật gọi là consistency gap (độ lệch nhất quán dữ liệu). Để restore thành công một website hoạt động trơn tru, bạn không thể coi database và file là hai tác vụ rời rạc. Chúng phải là hai thành phần của cùng một backup set, được gắn với cùng một mốc thời gian và được bảo vệ bằng một bản kê kiểm soát (manifest).
Một backup set cần liên kết database, file và manifest bằng cùng mốc phục hồi.
Bước 1: Lập bản đồ dữ liệu để biết chính xác website lưu gì ở đâu
Trước khi viết script hay cài đặt công cụ backup, bạn cần phân loại rõ từng nhóm dữ liệu đang chạy trên VPS:
| Nhóm dữ liệu | Vị trí lưu trữ thường gặp | Tính chất thay đổi | Cách sao lưu và khôi phục |
|---|---|---|---|
| Dữ liệu giao dịch & nghiệp vụ | MySQL, MariaDB, PostgreSQL | Thay đổi liên tục, không thể tái tạo từ mã nguồn | Bắt buộc backup bằng công cụ chuyên dụng của database (dump hoặc physical backup). |
| Tài liệu & file người dùng tải lên | Thư mục /uploads, /media hoặc Object Storage | Tăng dần theo thời gian, không thể tái tạo nếu mất | Bắt buộc backup, phải khớp mốc thời gian với bản ghi database. |
| Mã nguồn website (Source code) | Thư mục dự án hoặc Docker image | Thay đổi theo từng đợt phát hành (release) | Có thể khôi phục lại từ Git repository hoặc image registry; chỉ cần lưu đúng commit hash hoặc số version. |
| File cấu hình & secret | File .env, file cấu hình Nginx/Apache | Ít thay đổi nhưng rất nhạy cảm | Cần lưu trữ ở nơi bảo mật riêng, tách biệt khỏi mã nguồn công khai. |
| Bộ nhớ đệm (Cache), ảnh thumbnail thu nhỏ | Thư mục cache, Redis, Memcached | Tạo ra tự động trong quá trình chạy | Không cần backup; hệ thống có thể tự sinh lại sau khi khôi phục dữ liệu chính. |
Việc tách bạch này giúp bạn tránh lãng phí dung lượng và thời gian cho những thư mục cache nặng hàng gigabyte, đồng thời đảm bảo không bao giờ bỏ sót những thư mục tài liệu riêng tư nằm ngoài mã nguồn.
Bước 2: Ba phương án đồng bộ mốc thời gian giữa Database và File
Tùy vào quy mô website và mức độ chấp nhận gián đoạn dịch vụ, bạn có thể áp dụng một trong ba cách sau để đảm bảo database và file khớp mốc dữ liệu:
Phương án 1: Tạm dừng thao tác ghi (Maintenance window)
Đây là cách đơn giản, an toàn và dễ kiểm soát nhất đối với phần lớn website doanh nghiệp vừa và nhỏ:
- Chuyển website sang chế độ bảo trì (maintenance mode) hoặc bật cờ read-only vào khung giờ thấp điểm (chẳng hạn 2h00 sáng).
- Chờ vài giây để các tiến trình đang xử lý dở hoàn tất việc ghi xuống đĩa.
- Chạy lệnh backup database bằng công cụ chuyên dụng.
- Chạy lệnh sao lưu thư mục file upload (hoặc chụp snapshot volume lưu file).
- Sau khi cả hai bước hoàn tất và kiểm tra mã trả về thành công, tắt chế độ bảo trì để website hoạt động bình thường.
Ưu điểm lớn nhất của cách này là tính nhất quán tuyệt đối: trong suốt quá trình sao lưu, không có bất kỳ người dùng nào upload thêm file mới hay tạo thêm bản ghi nào trong database.
Phương án 2: Dùng cơ chế snapshot đồng bộ ở tầng ứng dụng hoặc hạ tầng
Nếu website sử dụng hạ tầng cloud và dữ liệu file/database nằm trên cùng một volume (hoặc multi-volume hỗ trợ đồng bộ):
- Ứng dụng kích hoạt lệnh khóa tạm thời (quiesce/flush tables) trong vài giây.
- Hệ thống kích hoạt chụp snapshot ổ đĩa tức thì.
- Mở khóa để ứng dụng tiếp tục chạy.
- Tiến trình sao lưu sẽ đọc và đóng gói dữ liệu từ bản snapshot đó thay vì đọc trực tiếp trên ổ đĩa đang chạy.
Phương án 3: Lưu trữ theo cơ chế Point-in-time Recovery (PITR)
Với các hệ thống thương mại điện tử lớn không thể bật bảo trì:
- Database được sao lưu bằng bản full backup định kỳ kết hợp lưu trữ liên tục log giao dịch (Binary log trong MySQL hoặc WAL trong PostgreSQL).
- Thư mục file hoặc object storage bật tính năng đánh phiên bản (versioning).
- Khi cần phục hồi về một mốc thời gian chính xác (ví dụ 14h20 ngày hôm qua), bạn khôi phục database về đúng log position của mốc đó, đồng thời chỉ định object storage lấy đúng phiên bản file tồn tại tại thời điểm đó.
Bước 3: Backup database bằng công cụ chuyên dụng của hệ quản trị
Một lỗi rất phổ biến của người mới quản trị VPS là dùng lệnh cp, tar hoặc rsync để copy trực tiếp thư mục chứa dữ liệu của database (như /var/lib/mysql) khi dịch vụ MySQL vẫn đang chạy.
Cách làm này cực kỳ nguy hiểm. Khi database đang hoạt động, rất nhiều dữ liệu và chỉ mục (index) vẫn đang nằm trên bộ nhớ RAM hoặc trong transaction log chưa kịp ghi hoàn chỉnh xuống file. Bản nén sinh ra bằng cách copy sống thư mục sẽ gần như chắc chắn bị hỏng cấu trúc (corrupt) và không thể khởi động lại khi restore.
Quy tắc bất di bất dịch là: luôn dùng công cụ do chính hệ quản trị database cung cấp:
- Với MySQL/MariaDB: Dùng
mysqldumpvới cờ--single-transaction(nếu sử dụng InnoDB) để tạo bản dump dữ liệu nhất quán mà không làm khóa các thao tác đọc của người dùng. Với database lớn hàng chục gigabyte, hãy cân nhắc công cụ physical backup chuyên dụng nhưmariadb-backuphoặc Percona XtraBackup. - Với PostgreSQL: Dùng
pg_dump. Công cụ này tự động tạo một snapshot nhất quán của database tại thời điểm bắt đầu chạy mà không làm gián đoạn các kết nối khác.
Sau khi sinh file dump, hãy lưu trữ file vào thư mục an toàn, không bao giờ đặt file .sql trực tiếp vào thư mục web public (như public_html) vì có thể bị quét và tải về lộ dữ liệu nhạy cảm.
Bước 4: Đóng gói thành một "Backup Set" có Manifest kiểm soát
Thay vì để các file backup nằm trôi nổi với các mốc giờ khác nhau, hãy gom bản backup database và bản backup file thành một bộ duy nhất với mã định danh thống nhất:
Ví dụ, tạo một thư mục backup với tên chuẩn: backup-20261012-020000/, bên trong chứa:
database.sql.gz: Bản xuất database lúc 2h00.uploads.tar.gz: Bản nén thư mục file upload lúc 2h00.manifest.json: File mô tả kiểm soát toàn bộ gói sao lưu.
Nội dung file manifest.json ghi lại các thông tin căn bản để người kỹ thuật sau này (hoặc script tự động) có thể kiểm tra trước khi bung dữ liệu:
{
"backup_set_id": "prod-20261012-020000",
"created_at": "2026-10-12T02: 00:00Z",
"app_version": "v2.4.1",
"database": {
"engine": "PostgreSQL 16.2",
"file": "database.sql.gz",
"checksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"storage": {
"target": "uploads.tar.gz",
"total_files": 14250,
"checksum_sha256": "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb"
},
"status": "COMPLETE"
}Nếu một trong hai bước (dump database hoặc nén file) gặp sự cố (ví dụ ổ đĩa đầy giữa chừng), toàn bộ backup set đó phải được đánh dấu là FAILED và kích hoạt gửi cảnh báo ngay cho quản trị viên. Tuyệt đối không xóa bản backup cũ tốt của ngày hôm trước khi bản backup mới chưa hoàn thành trọn vẹn cả hai phần.
Bước 5: Thứ tự khôi phục dữ liệu đúng kỹ thuật
Khi xảy ra sự cố cần dựng lại website trên một VPS mới, thứ tự restore các thành phần cũng quyết định việc website có vận hành suôn sẻ hay không.
Trình tự an toàn thường áp dụng:
- Chuẩn bị môi trường máy chủ: Cài đặt hệ điều hành, cài đặt web server và cài đặt đúng phiên bản database tương thích.
- Khôi phục file cấu hình và secret: Đặt file
.envhoặc cấu hình kết nối database vào đúng vị trí an toàn. - Khôi phục dữ liệu file upload trước: Giải nén toàn bộ thư mục ảnh và file tài liệu về đúng đường dẫn quy định, đồng thời phân quyền sở hữu (
chown -R www-data:www-data) chính xác để web server có quyền đọc/ghi. - Khôi phục Database: Chạy lệnh import database từ file dump. Khi dữ liệu được import xong, toàn bộ bản ghi đã sẵn sàng và liên kết trực tiếp tới các file upload đã có sẵn trên đĩa.
- Khởi động mã nguồn và kiểm tra nội bộ: Chạy ứng dụng nhưng chưa trỏ tên miền thật về. Hãy mở trình duyệt truy cập qua IP hoặc file
hostsđể kiểm tra các luồng:
- Đăng nhập tài khoản quản trị.
- Mở thử một bài viết hoặc sản phẩm cũ xem hình ảnh có hiển thị đúng không.
- Thử upload một file mới và tạo một đơn hàng mẫu để kiểm tra quyền ghi.
- Mở lại traffic chính thức: Khi mọi kiểm tra đều trơn tru, tiến hành trỏ DNS tên miền về máy chủ mới. Chi tiết các bước diễn tập phục hồi từng bước được hướng dẫn tại Checklist thử restore website trên môi trường tách biệt.
Checklist kiểm tra tính đồng bộ của hệ thống backup
Hãy dành 10 phút kiểm tra lại hệ thống backup hiện tại của website bạn theo các tiêu chí sau:
- ☐ Script backup database và script backup file có đang chạy ở hai khung giờ cách xa nhau không?
- ☐ Database có được xuất bằng công cụ chuyên dụng (
mysqldump,pg_dump) hay đang copy sống thư mục dữ liệu? - ☐ File backup có được gom chung thành một backup set có kiểm tra mã checksum SHA-256 không?
- ☐ Các thư mục cache, log rác và file tạm đã được cấu hình loại trừ (exclude) khỏi bản backup file chưa?
- ☐ Bạn đã từng thử dựng lại website trên một VPS phụ và kiểm tra ngẫu nhiên xem các hình ảnh có bị lỗi 404 sau khi import database hay không?
- ☐ File backup sau khi tạo xong có được tự động chuyển sang một máy chủ lưu trữ khác ngoài chiếc VPS chính theo quy tắc backup 3-2-1 và thiết lập thời gian lưu trữ xoay vòng an toàn không?
Một bản backup database hoàn hảo sẽ không có nhiều giá trị nếu toàn bộ hình ảnh và tài liệu đính kèm bị biến mất. Khi database và file được phối hợp thành một khối thống nhất có cùng mốc thời gian trong chiến lược backup VPS tổng thể, bạn mới có thể tự tin rằng website của mình luôn sẵn sàng hồi sinh nguyên vẹn sau bất kỳ sự cố nào.



