香港服务器数据丢了才后悔?一套定时异地备份方案教你自动防护

香港服务器运行稳定,并不代表数据不会丢失。硬盘故障、系统误操作、网站被入侵、勒索病毒、数据库损坏,甚至机房网络或账户异常,都可能导致业务文件无法正常使用。
不少用户已经设置了宝塔面板备份,或者把压缩包保存在服务器的另一块硬盘中,但这些只能算本地备份。一旦整台服务器无法登录,或者攻击者同时删除源文件和备份目录,本地备份也会一起失效。更稳妥的做法,是把网站文件、数据库和关键配置定时传输到香港以外的独立节点。
先看一个常见的网站部署场景
假设一家企业在香港服务器上运行官网、客户后台和 MySQL 数据库,可以采用 A5IDC 产品库中的这款配置:
- CPU:Intel Xeon E-2334,4核8线程
- 内存:32GB DDR4-3200
- 硬盘:960GB M.2 NVMe SSD
- 带宽:15M CN2,赠送100M国际带宽
- 防护:5G DDoS基础防护
这类配置适合企业官网、WordPress内容站、外贸网站以及轻量业务系统。NVMe硬盘可以降低数据库、缓存和备份压缩时的I/O等待,32GB内存也能为MySQL、PHP-FPM和备份任务保留一定余量。
更重要的是,这款服务器提供100M国际带宽。正常业务可以通过CN2线路服务国内用户,异地备份则通过国际出口传输到日本、新加坡、美国或其他地区的存储节点,减少备份任务对网站访问的影响。
不过,服务器配置再高,也不能代替备份。RAID只能降低单块硬盘损坏造成的影响,无法防止误删除、数据库逻辑损坏和入侵后文件被加密。
异地备份应采用什么结构?
比较实用的是“本地临时备份+异地加密备份+多版本保留”的结构。
香港主服务器负责运行网站和数据库,本机只保存最近1至3天的临时备份;每天凌晨将备份同步到香港以外的独立服务器或对象存储;异地节点再保留每日、每周和每月版本。
可以按照下面的周期设置:
| 备份内容 | 执行频率 | 建议保留时间 |
|---|---|---|
| MySQL数据库 | 每4小时一次 | 7天 |
| 网站文件 | 每天一次 | 7个日版本 |
| 完整业务快照 | 每周一次 | 4个周版本 |
| 长期归档 | 每月一次 | 6至12个月 |
| 恢复测试 | 每月一次 | 保留测试记录 |
如果数据库每4小时备份一次,那么发生故障时,理论上最多损失最近4小时内的数据。订单、会员、财务等变化频繁的业务,可以进一步开启MySQL Binlog,把可恢复时间缩短到小时级甚至分钟级。
备份哪些内容才有用?
不能只备份网站目录。一个可以真正恢复的备份,至少应包括以下内容:
- 网站程序、用户上传图片和附件;
- MySQL或MariaDB数据库;
- Nginx、Apache、PHP等运行环境配置;
- SSL证书和定时任务;
- 应用程序的环境变量及必要密钥;
- Docker Compose、Supervisor或进程管理配置;
- 服务器版本、PHP扩展和数据库版本记录。
缓存目录、临时文件、访问日志和可重新生成的缩略图通常没有必要长期备份。提前排除这些目录,可以明显缩小备份体积,减少传输时间。
使用Restic建立加密异地备份
对于Linux香港服务器,可以使用Restic配合一台异地SFTP服务器。Restic支持加密、增量传输、重复数据删除和多版本快照,比每天简单上传一个压缩包更节省空间。
假设备份节点位于日本或美国,并已经创建独立的backup账户,可以先在香港服务器安装Restic:
apt update
apt install restic -y
为备份账户生成独立SSH密钥:
ssh-keygen -t ed25519 -f /root/.ssh/backup_ed25519
ssh-copy-id -i /root/.ssh/backup_ed25519.pub backup@异地服务器IP
随后设置Restic仓库地址和加密密码:
mkdir -p /root/.config/restic
vi /root/.config/restic/env
写入以下内容:
export RESTIC_REPOSITORY="sftp:backup@异地服务器IP:/data/hk-server"
export RESTIC_PASSWORD="请替换为足够复杂的独立密码"
export RESTIC_SFTP_COMMAND="ssh -i /root/.ssh/backup_ed25519"
限制配置文件读取权限:
chmod 600 /root/.config/restic/env
source /root/.config/restic/env
restic init
需要特别保存好Restic加密密码。即使异地备份文件仍然存在,丢失密码后也无法正常恢复。
编写自动备份脚本
先为MySQL创建一个仅供备份使用的配置文件,避免把数据库密码直接写进脚本或定时任务:
vi /root/.my.cnf
内容如下:
[client]
user=root
password=数据库密码
设置权限:
chmod 600 /root/.my.cnf
然后创建备份脚本:
vi /usr/local/sbin/remote-backup.sh
写入以下内容:
#!/bin/bash
set -Eeuo pipefail
source /root/.config/restic/env
BACKUP_DIR="/var/backups/a5idc"
DATE=$(date +%Y-%m-%d_%H-%M-%S)
LOCK_FILE="/var/run/remote-backup.lock"
mkdir -p "$BACKUP_DIR"
exec 9>"$LOCK_FILE"
flock -n 9 || exit 0
echo "[$(date)] 开始导出数据库"
mysqldump \
--defaults-extra-file=/root/.my.cnf \
--all-databases \
--single-transaction \
--quick \
--routines \
--events \
--triggers \
--hex-blob \
| gzip -1 > "$BACKUP_DIR/mysql-$DATE.sql.gz"
echo "[$(date)] 开始上传异地备份"
nice -n 10 ionice -c2 -n7 restic backup \
/www/wwwroot \
/etc/nginx \
/etc/letsencrypt \
/etc/cron.d \
"$BACKUP_DIR/mysql-$DATE.sql.gz" \
--exclude="*/cache/*" \
--exclude="*/tmp/*" \
--exclude="*/logs/*" \
--tag="daily"
echo "[$(date)] 清理历史快照"
restic forget \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 6 \
--prune
find "$BACKUP_DIR" \
-type f \
-name "mysql-*.sql.gz" \
-mtime +2 \
-delete
echo "[$(date)] 异地备份完成"
赋予执行权限并手动运行一次:
chmod 700 /usr/local/sbin/remote-backup.sh
/usr/local/sbin/remote-backup.sh
脚本中的flock可以防止上一次备份尚未结束时,又启动一个新的备份任务。nice和ionice则会降低备份进程的CPU及磁盘优先级,避免压缩、扫描文件时明显影响网站访问。
设置每天自动执行
确认手动执行没有报错后,编辑Crontab:
crontab -e
增加下面一行:
15 3 * * * /usr/local/sbin/remote-backup.sh >> /var/log/remote-backup.log 2>&1
这样服务器每天凌晨3点15分会自动执行异地备份。
如果网站凌晨仍有大量访问,可以将数据库备份和网站文件备份分开执行。例如数据库每4小时备份一次,网站文件每天凌晨备份一次,避免多个压缩、扫描和上传任务同时运行。
大型数据库不要只依赖mysqldump
mysqldump --single-transaction比较适合中小型InnoDB数据库,可以在尽量不锁表的情况下生成一致性备份。
如果数据库已经达到数百GB,或者每天产生大量订单和日志,继续使用逻辑导出可能出现耗时过长、恢复速度慢等问题。此时可以考虑:
- 使用Percona XtraBackup进行物理热备;
- 开启MySQL Binlog进行时间点恢复;
- 将数据库和网站文件分开备份;
- 建立只读副本,在副本上执行备份;
- 对历史订单、访问日志等数据定期归档。
需要注意的是,开启Binlog并不等于完成异地备份。Binlog仍然可能随着主服务器故障一起丢失,应同步到独立节点保存。
如何确认备份真的可以恢复?
备份命令显示成功,只能说明文件已经生成或上传,不能证明数据一定能恢复。建议每周检查一次仓库完整性:
source /root/.config/restic/env
restic check
restic snapshots
查看备份文件:
restic ls latest
将最近一次备份恢复到测试目录:
mkdir -p /data/restore-test
restic restore latest --target /data/restore-test
恢复数据库时,可以先解压SQL文件,再导入独立的测试数据库:
gunzip -c mysql-备份时间.sql.gz | mysql test_restore
至少每月进行一次完整恢复演练,包括网站文件恢复、数据库导入、配置检查和测试域名访问。只有确认测试环境能够正常打开网站、登录后台并查询数据,这份备份才算真正可用。
异地备份还要注意账户隔离
异地节点不应与香港主服务器使用相同的面板密码、SSH密码或管理员账户,否则攻击者控制主服务器后,可能继续登录备份服务器删除数据。
建议为备份系统单独设置:
- 独立SSH密钥;
- 独立备份账户;
- 禁止密码登录;
- 限制可登录IP;
- 单独保存Restic加密密码;
- 开启对象存储版本控制或不可变保留;
- 备份失败时发送邮件、Telegram或企业微信告警。
同步脚本中也不要随意使用带有--delete的命令。主服务器文件被误删或被攻击者清空后,删除操作可能继续同步到异地节点,使远端副本也被清除。使用多版本快照,可以保留删除之前的数据状态。
香港服务器的本地硬盘适合承载实时业务,却不应该成为数据的唯一保存位置。异地节点最好选择不同地区、不同账户,重要业务还可以再增加一份对象存储归档。完成部署后,先主动删除一个测试文件并执行恢复,比等到真正故障发生时才检查备份是否可用更可靠。