Skip to content
VDS · Cơ sở dữ liệu

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ứngNguyên nhân
Dump chỉ vài kilobyteScript thất bại ở bước xác thực, và lỗi bị đẩy vào /dev/null
Hết dung lượng ổ đĩaKhông xóa các bản sao lưu cũ theo mtime
Khôi phục lỗi về quyềnCác role không được dump — bạn cần --roles-only
Cron im lặng, không có bản sao lưuCron 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 đêmDump 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.