“数据丢了”——这是VPS用户最怕听到的四个字。
硬盘会坏、系统会崩、会被攻击、会误操作。我见过太多人因为没有备份,一夜回到解放前:几个月的文章、客户数据、网站配置,全部归零。
备份不是"建议做",而是"必须做"。今天教你搭建完整的VPS备份体系,从自动备份到异地存储,再到一键恢复。
本文适合谁: 所有VPS用户。数据无价,备份免费,没有理由不做。
为什么需要备份?
| 灾难场景 | 发生概率 | 无备份后果 | 有备份后果 |
|---|---|---|---|
| 硬盘故障 | 中 | 数据全丢,从零开始 | 恢复备份,1小时恢复 |
| 被黑客攻击 | 高 | 数据泄露/加密 | 恢复到攻击前状态 |
| 误删文件 | 极高 | 找不回来 | 从备份恢复 |
| VPS商跑路 | 低 | 数据永久丢失 | 异地备份还在 |
| 系统崩溃 | 中 | 重装系统+数据丢失 | 重装+恢复备份 |
铁律:数据至少保存3份,存放在2个不同地方,其中1份是异地。
备份策略选择
| 策略 | 适用场景 | 复杂度 | 成本 |
|---|---|---|---|
| 定期手动备份 | 个人博客 | ⭐ | 免费 |
| Cron自动备份 | 所有场景 | ⭐⭐ | 免费 |
| 异地备份 | 生产环境 | ⭐⭐⭐ | 低 |
| 增量备份 | 大数据量 | ⭐⭐⭐ | 低 |
| 快照备份 | VPS提供商支持 | ⭐ | 看提供商 |
方案一:基础自动备份(Cron + 本地)
最简单的方案:用cron定时执行备份脚本。
创建备份脚本
# 创建脚本目录
mkdir -p /opt/scripts /backup
# 创建备份脚本
cat > /opt/scripts/backup.sh << 'EOF'
#!/bin/bash
# VPS自动备份脚本
# 配置
BACKUP_DIR="/backup"
DATE=$(date +%Y%m%d)
KEEP_DAYS=7
# 创建今日备份目录
mkdir -p $BACKUP_DIR/$DATE
# 1. 备份系统配置
echo "Backing up system configs..."
cp -r /etc/nginx $BACKUP_DIR/$DATE/nginx
cp -r /etc/ssh $BACKUP_DIR/$DATE/ssh
cp /etc/crontab $BACKUP_DIR/$DATE/crontab
crontab -l > $BACKUP_DIR/$DATE/user-crontab
# 2. 备份Web目录(根据实际情况修改)
echo "Backing up web files..."
if [ -d "/var/www" ]; then
tar -czf $BACKUP_DIR/$DATE/www.tar.gz /var/www
fi
# 3. 备份数据库(MySQL)
echo "Backing up MySQL databases..."
if command -v mysqldump &> /dev/null; then
databases=$(mysql -e "SHOW DATABASES;" | grep -Ev "(Database|information_schema|performance_schema|mysql)")
for db in $databases; do
mysqldump --single-transaction --routines --triggers $db | gzip > $BACKUP_DIR/$DATE/mysql-$db.sql.gz
done
fi
# 4. 备份PostgreSQL
echo "Backing up PostgreSQL databases..."
if command -v pg_dumpall &> /dev/null; then
sudo -u postgres pg_dumpall | gzip > $BACKUP_DIR/$DATE/postgres-all.sql.gz
fi
# 5. 备份Docker容器数据
echo "Backing up Docker data..."
if [ -d "/opt/minecraft" ]; then
tar -czf $BACKUP_DIR/$DATE/minecraft.tar.gz /opt/minecraft/data
fi
# 6. 删除旧备份
echo "Cleaning old backups..."
find $BACKUP_DIR -maxdepth 1 -type d -mtime +$KEEP_DAYS -exec rm -rf {} \;
echo "Backup completed: $DATE"
EOF
chmod +x /opt/scripts/backup.sh
设置定时任务
# 每天凌晨4点执行备份
echo "0 4 * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>&1" | crontab -
# 验证
crontab -l
手动执行测试
sudo /opt/scripts/backup.sh
方案二:异地备份(rclone + 云存储)
本地备份不够安全——如果VPS整个挂了,备份也没了。需要用rclone把备份同步到云存储。
安装rclone
curl https://rclone.org/install.sh | sudo bash
配置云存储
rclone config
按提示配置:
n) New remote
name> backup
Storage> 选择存储类型(推荐以下之一)
| 存储类型 | 免费额度 | 推荐度 |
|---|---|---|
| Google Drive | 15GB | ⭐⭐⭐ |
| OneDrive | 5TB | ⭐⭐⭐ |
| S3 (AWS) | 5GB/12个月 | ⭐⭐ |
| Backblaze B2 | 10GB | ⭐⭐⭐ |
| 阿里云OSS | 5GB | ⭐⭐ |
使用Google Drive作为备份目标
# 配置Google Drive
rclone config
# 选择 google drive
# 按浏览器授权提示操作
# 测试连接
rclone ls backup:
# 创建备份目录
rclone mkdir backup:vps-backup/$(hostname)
同步备份到云端
# 同步今日备份到Google Drive
rclone sync /backup/$(date +%Y%m%d) backup:vps-backup/$(hostname)/$(date +%Y%m%d)
# 或者同步整个备份目录
rclone sync /backup/ backup:vps-backup/$(hostname)/ --progress
完整备份脚本(含异地同步)
cat > /opt/scripts/backup-full.sh << 'EOF'
#!/bin/bash
# 完整备份脚本(本地+异地)
DATE=$(date +%Y%m%d)
BACKUP_DIR="/backup/$DATE"
RCLONE_REMOTE="backup:vps-backup/$(hostname)/$DATE"
# 创建备份目录
mkdir -p $BACKUP_DIR
# 执行备份(复用上面的备份逻辑)
/opt/scripts/backup.sh
# 同步到云端
echo "Syncing to cloud..."
rclone sync $BACKUP_DIR $RCLONE_REMOTE --progress
# 清理本地旧备份(保留3天)
find /backup -maxdepth 1 -type d -mtime +3 -exec rm -rf {} \;
echo "Full backup completed: $DATE"
EOF
chmod +x /opt/scripts/backup-full.sh
# 每天凌晨4点执行完整备份
echo "0 4 * * * /opt/scripts/backup-full.sh >> /var/log/backup-full.log 2>&1" | crontab -
方案三:数据库专用备份
数据库是最需要备份的——代码可以重写,但数据丢了就真没了。
MySQL自动备份
# 创建MySQL备份脚本
cat > /opt/scripts/backup-mysql.sh << 'EOF'
#!/bin/bash
# MySQL自动备份
DATE=$(date +%Y%m%d)
BACKUP_DIR="/backup/mysql/$DATE"
mkdir -p $BACKUP_DIR
# 获取所有数据库
DATABASES=$(mysql -e "SHOW DATABASES;" | grep -Ev "(Database|information_schema|performance_schema|mysql)")
# 逐个备份
for DB in $DATABASES; do
echo "Backing up $DB..."
mysqldump --single-transaction --routines --triggers --triggers $DB | gzip > $BACKUP_DIR/$DB.sql.gz
done
# 同步到云端
rclone sync $BACKUP_DIR backup:vps-backup/mysql/$(hostname)/$DATE --progress
# 清理7天前的备份
find /backup/mysql -maxdepth 1 -type d -mtime +7 -exec rm -rf {} \;
echo "MySQL backup completed: $DATE"
EOF
chmod +x /opt/scripts/backup-mysql.sh
# 每6小时备份一次数据库
echo "0 */6 * * * /opt/scripts/backup-mysql.sh >> /var/log/backup-mysql.log 2>&1" | crontab -
PostgreSQL自动备份
cat > /opt/scripts/backup-postgres.sh << 'EOF'
#!/bin/bash
# PostgreSQL自动备份
DATE=$(date +%Y%m%d)
BACKUP_DIR="/backup/postgres/$DATE"
mkdir -p $BACKUP_DIR
# 获取所有数据库
DATABASES=$(sudo -u postgres psql -t -c "SELECT datname FROM pg_database WHERE datistemplate = false;" | tr -d ' ')
# 逐个备份
for DB in $DATABASES; do
echo "Backing up $DB..."
sudo -u postgres pg_dump $DB | gzip > $BACKUP_DIR/$DB.sql.gz
done
# 同步到云端
rclone sync $BACKUP_DIR backup:vps-backup/postgres/$(hostname)/$DATE --progress
# 清理7天前的备份
find /backup/postgres -maxdepth 1 -type d -mtime +7 -exec rm -rf {} \;
echo "PostgreSQL backup completed: $DATE"
EOF
chmod +x /opt/scripts/backup-postgres.sh
方案四:VPS快照备份
很多VPS提供商支持快照功能,一键保存整个系统状态。
各提供商快照功能
| 提供商 | 快照功能 | 免费额度 | 价格 |
|---|---|---|---|
| Vultr | 自动快照 | 1个快照 | $0.05/月/GB |
| RackNerd | 手动备份 | — | 免费(需自己备份) |
| Hostinger | 自动备份 | 1份 | 包含在套餐中 |
| DigitalOcean | 快照 | — | $0.06/月/GB |
| Linode | 图像备份 | — | $0.10/月/GB |
Vultr快照操作
# 通过Vultr API创建快照
curl -s "https://api.vultr.com/v2/instances/$(INSTANCE_ID)/snapshots" \
-X POST \
-H "Authorization: Bearer $VULTR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"description": "Auto snapshot '$(date +%Y%m%d)'"}'
快照 vs 文件备份
| 特性 | 快照备份 | 文件备份 |
|---|---|---|
| 恢复速度 | 极快(分钟级) | 中等(视数据量) |
| 存储成本 | 较高 | 低 |
| 灵活性 | 低(整个系统) | 高(可选择性恢复) |
| 异地存储 | 一般不支持 | 支持 |
| 增量支持 | 一般支持 | 可手动实现 |
推荐组合: 快照做整机备份(防硬盘故障)+ 文件备份做数据备份(防误删)。
灾难恢复
备份的目的是恢复。当你需要恢复数据时:
恢复网站文件
# 从备份恢复Web目录
rclone copy backup:vps-backup/$(hostname)/20260529/www.tar.gz /tmp/
cd /
tar -xzf /tmp/www.tar.gz
恢复MySQL数据库
# 从备份恢复MySQL
rclone copy backup:vps-backup/mysql/$(hostname)/20260529/mydb.sql.gz /tmp/
gunzip /tmp/mydb.sql.gz
mysql -u root -p mydb < /tmp/mydb.sql
恢复PostgreSQL数据库
# 从备份恢复PostgreSQL
rclone copy backup:vps-backup/postgres/$(hostname)/20260529/mydb.sql.gz /tmp/
gunzip /tmp/mydb.sql.gz
sudo -u postgres psql mydb < /tmp/mydb.sql
恢复系统配置
# 从备份恢复Nginx配置
rclone copy backup:vps-backup/$(hostname)/20260529/nginx/ /etc/nginx/
sudo systemctl restart nginx
# 恢复SSH配置
rclone copy backup:vps-backup/$(hostname)/20260529/ssh/ /etc/ssh/
sudo systemctl restart sshd
备份验证
备份不验证等于没有备份。定期检查备份是否真的可用。
# 创建验证脚本
cat > /opt/scripts/verify-backup.sh << 'EOF'
#!/bin/bash
# 备份验证脚本
LATEST_BACKUP=$(ls -t /backup | head -1)
VERIFY_DIR="/tmp/verify-backup"
echo "Verifying backup: $LATEST_BACKUP"
# 检查备份文件是否存在
if [ ! -d "/backup/$LATEST_BACKUP" ]; then
echo "ERROR: Backup directory not found!"
exit 1
fi
# 检查MySQL备份是否可解压
for file in /backup/$LATEST_BACKUP/mysql-*.sql.gz; do
if [ -f "$file" ]; then
if gzip -t "$file"; then
echo "OK: $file is valid"
else
echo "ERROR: $file is corrupted!"
fi
fi
done
# 检查Web备份是否可解压
if [ -f "/backup/$LATEST_BACKUP/www.tar.gz" ]; then
if tar -tzf /backup/$LATEST_BACKUP/www.tar.gz > /dev/null; then
echo "OK: www.tar.gz is valid"
else
echo "ERROR: www.tar.gz is corrupted!"
fi
fi
echo "Verification completed"
EOF
chmod +x /opt/scripts/verify-backup.sh
# 每周验证一次备份
echo "0 5 * * 0 /opt/scripts/verify-backup.sh >> /var/log/verify-backup.log 2>&1" | crontab -
推荐备份方案
根据你的需求选择:
| 需求 | 推荐方案 | 月成本 |
|---|---|---|
| 个人博客 | Cron + rclone + Google Drive | 免费 |
| 个人项目 | Cron + rclone + OneDrive | 免费 |
| 小型业务 | Cron + rclone + B2 + 快照 | $5-10 |
| 生产环境 | 增量备份 + 异地多副本 + 快照 | $10-20 |
最简方案(5分钟搞定)
# 1. 安装rclone
curl https://rclone.org/install.sh | sudo bash
# 2. 配置云存储
rclone config
# 3. 创建备份脚本
cat > /opt/scripts/daily-backup.sh << 'SCRIPT'
#!/bin/bash
DATE=$(date +%Y%m%d)
tar -czf /tmp/backup-$DATE.tar.gz /var/www /etc/nginx /etc/ssh 2>/dev/null
rclone copy /tmp/backup-$DATE.tar.gz backup:vps-backups/$(hostname)/
rm /tmp/backup-$DATE.tar.gz
find /tmp -name "backup-*.tar.gz" -mtime +7 -delete
SCRIPT
chmod +x /opt/scripts/daily-backup.sh
# 4. 添加定时任务
echo "0 4 * * * /opt/scripts/daily-backup.sh" | crontab -
# 5. 测试
/opt/scripts/daily-backup.sh
常见问题
Q: 备份占多少空间?
取决于你的数据量。一个典型的WordPress网站备份约100-500MB。MySQL数据库备份压缩后通常只有原大小的10-20%。
Q: 备份会影响VPS性能吗?
Cron备份通常在凌晨执行,对性能影响很小。如果数据量大,可以用 nice 和 ionice 降低优先级:
nice -n 19 ionice -c3 /opt/scripts/backup.sh
Q: 我用 RackNerd,需要自己备份吗?
是的,RackNerd不提供自动备份服务。但你可以用本文的方案自己备份,完全免费。
Q: Hostinger 的自动备份够用吗?
Hostinger提供每周自动备份,但只保留最近1份。建议还是自己做异地备份,双重保险。
Q: 备份数据需要加密吗?
如果备份包含敏感数据(客户信息、密码等),建议加密:
# 使用GPG加密
tar -czf - /var/www | gpg -c -o backup-$(date +%Y%m%d).tar.gz.gpg
# 解密恢复
gpg -d backup-20260529.tar.gz.gpg | tar -xzf -
总结
备份是VPS运维的底线。花30分钟设置好自动备份,可能救你几个月的数据。
备份铁律:
- 自动化——手动备份早晚会忘
- 异地化——本地备份不够安全
- 验证化——定期检查备份是否可用
- 多重化——至少两种备份方式并行
💡 下一步: 备份搞好了,再做个安全加固,让你的VPS固若金汤。
Disclaimer: Some links are affiliate links. We may earn a commission at no extra cost to you.
