Sao lưu cơ sở dữ liệu
Cách lên lịch dump MySQL và PostgreSQL, chuyển chúng ra khỏi máy và xác minh bản sao lưu thực sự khôi phục được.
Cập nhật 23 tháng 8, 2026
VPS không tự động sao lưu toàn bộ máy hay tạo ảnh chụp trạng thái: mọi thứ bạn chưa tự sao chép đều chỉ tồn tại ở một bản duy nhất. Dump cơ sở dữ liệu là việc đầu tiên bạn nên thiết lập, vì không có nơi nào để khôi phục dữ liệu, trong khi trang web có thể triển khai lại từ đầu.
Dump thủ công
PostgreSQL:
pg_dump -Fc -U shop -h 127.0.0.1 shop > /srv/backups/shop-$(date +%F).dump
pg_dumpall -U postgres --roles-only > /srv/backups/roles.sql
MySQL và MariaDB:
mysqldump --single-transaction --quick --routines --events \
-u root shop | gzip > /srv/backups/shop-$(date +%F).sql.gz
--single-transaction tạo dump InnoDB nhất quán mà không khóa bảng — nếu không có nó, trang web của bạn sẽ bị treo trong quá trình export. Định dạng -Fc của PostgreSQL được nén và cho phép bạn khôi phục từng bảng riêng lẻ.
Đừng đặt mật khẩu trên dòng lệnh: hãy tạo ~/.pgpass hoặc ~/.my.cnf với quyền 600.
Chạy theo lịch
mkdir -p /srv/backups && chmod 700 /srv/backups
crontab -e
20 3 * * * /usr/local/bin/db-backup.sh >> /var/log/db-backup.log 2>&1
Script /usr/local/bin/db-backup.sh:
#!/bin/bash
set -euo pipefail
DEST=/srv/backups
STAMP=$(date +%F-%H%M)
pg_dump -Fc -U shop -h 127.0.0.1 shop > "$DEST/shop-$STAMP.dump.tmp"
mv "$DEST/shop-$STAMP.dump.tmp" "$DEST/shop-$STAMP.dump"
find "$DEST" -name '*.dump' -mtime +14 -delete
Việc ghi vào file tạm rồi đổi tên rất quan trọng: nếu dump bị gián đoạn, bạn sẽ không nhầm một file bị cắt cụt với một bản sao lưu hoàn chỉnh. set -euo pipefail dừng script ngay ở lỗi đầu tiên thay vì tiếp tục một cách âm thầm.
Chuyển bản sao lưu ra khỏi máy
Một bản sao trên cùng ổ đĩa sẽ không cứu bạn khỏi sai sót khi di chuyển, ransomware hay cài lại hệ điều hành ở tab “Access”. Hãy gửi dump ra nơi khác:
rsync -az --delete /srv/backups/ backup@other-host:/store/vds/
Hoặc tới bất kỳ storage tương thích S3 nào qua rclone. Lưu ý băng thông tối đa 500 Mbit/s và giới hạn ghi đĩa theo từng tier: 60 MB/s mỗi core.
Kiểm tra khôi phục
Một bản sao lưu bạn chưa từng khôi phục không phải là bản sao lưu.
createdb -U postgres shop_check
pg_restore -U postgres -d shop_check /srv/backups/shop-2026-08-23.dump
psql -U postgres -d shop_check -c "SELECT count(*) FROM users;"
dropdb -U postgres shop_check
Với MySQL: gunzip -c dump.sql.gz | mysql -u root shop_check.
Hãy làm việc này mỗi tháng một lần và ghi lại ngày kiểm tra.
Lỗi thường gặp
| Triệu chứng | Nguyên nhân |
|---|---|
| Dump chỉ vài kilobyte | Script thất bại ở bước xác thực, và lỗi bị đẩy vào /dev/null |
| Hết dung lượng ổ đĩa | Không xóa các bản sao lưu cũ theo mtime |
| Khôi phục lỗi về quyền | Các role không được dump — bạn cần --roles-only |
| Cron im lặng, không có bản sao lưu | Cron không có PATH của bạn — hãy dùng đường dẫn tuyệt đối |
| Trang web chậm vào ban đêm | Dump tranh chấp ổ đĩa — hãy dịch thời gian, thêm --quick |
Hãy giữ ít nhất hai bản sao ở các vị trí khác nhau và theo dõi kích thước dump: kích thước giảm mạnh nghĩa là không phải toàn bộ cơ sở dữ liệu đã được dump.