本文约 3,195 字,预计阅读 8 分钟。文中命令与配置均经过实测,可直接参考执行。
引言:每次都全量拷贝,太慢也太浪费
scp -r 或打包上传的方式,每次都要传几个 GB。而 WordPress 每天真正变化的文件可能只有几十 MB(新上传的图片、缓存、日志)。
rsync 的核心价值是增量:只传变化的部分,第二次同步往往几秒完成。
原理分析:rsync 怎么知道哪些变了
rsync 默认用”快速检查”算法比较源与目标的:
- 比较文件大小与修改时间;
- 不同则传输差异块(delta transfer)。
常用参数:
| 参数 | 含义 |
|---|---|
-a |
归档模式(保留权限、属主、时间、软链接,等价于 -rlptgoD) |
-v |
显示过程 |
-z |
传输时压缩(跨机房有用,局域网可省) |
-P |
显示进度 + 支持断点续传 |
--delete |
删除目标端源端已没有的文件(保持严格一致) |
--exclude |
排除规则 |
--dry-run |
只演练不实际执行 |
--bwlimit |
限速(避免占满带宽) |
保姆级实操
第一步:本机目录同步(最简单)
rsync -avP /var/www/mimangfei.com/ /backup/mimangfei-files/
注意源路径末尾的斜杠:/src/ 表示同步目录内的内容,/src 表示同步目录本身。这个细节决定文件会不会多一层。
第二步:必须排除的目录
rsync -avP \
--exclude='wp-content/cache/' \
--exclude='wp-content/upgrade/' \
--exclude='wp-content/updraft/' \
--exclude='wp-content/backups-*/' \
--exclude='wp-content/wflogs/' \
--exclude='wp-content/aiowps_backups/' \
--exclude='*.log' \
--exclude='.git/' \
--exclude='node_modules/' \
/var/www/mimangfei.com/ /backup/mimangfei-files/
排除缓存与备份目录非常重要——否则你会”备份备份的备份”,体积指数膨胀。
写成文件更好维护:
# /etc/rsync-exclude.txt
wp-content/cache/
wp-content/upgrade/
wp-content/updraft/
*.log
.git/
node_modules/
rsync -avP --exclude-from=/etc/rsync-exclude.txt /var/www/mimangfei.com/ /backup/files/
第三步:远程同步(异地备份)
先配 SSH 免密:
ssh-keygen -t ed25519 -C "backup"
ssh-copy-id backup@backup-server
同步:
rsync -avzP --delete \
--exclude-from=/etc/rsync-exclude.txt \
-e "ssh -p 22" \
/var/www/mimangfei.com/ backup@backup-server:/data/backup/mimangfei/
--delete 要谨慎:它会删除目标端多余的文件。第一次同步前务必 --dry-run 确认规则正确,否则可能误删异地数据。
rsync -avzP --delete --dry-run /var/www/mimangfei.com/ backup@host:/data/backup/
第四步:定时同步脚本
#!/usr/bin/env bash
# /usr/local/bin/rsync-backup.sh
set -euo pipefail
SRC="/var/www/mimangfei.com/"
DEST="backup@backup-server:/data/backup/mimangfei/"
LOG="/var/log/rsync-backup.log"
rsync -azP --delete \
--exclude-from=/etc/rsync-exclude.txt \
--bwlimit=5000 \
-e "ssh -o StrictHostKeyChecking=no -p 22" \
"$SRC" "$DEST" >> "$LOG" 2>&1
echo "$(date) rsync 完成,退出码 $?" >> "$LOG"
crontab(每 6 小时):
0 */6 * * * /usr/local/bin/rsync-backup.sh
第五步:迁移前的预同步(缩短停机时间)
换服务器时,最耗时的往往是传文件。可以提前同步,切换时只传增量:
# 迁移前几天:先全量同步一次(不停机)
rsync -avzP /var/www/site/ root@new-server:/var/www/site/
# 切换当天:停止写入(关闭评论、开启维护模式)后再同步增量
rsync -avzP --delete /var/www/site/ root@new-server:/var/www/site/
# 导出并导入数据库,改 DNS
这样几十 GB 的站点,切换时的停机窗口能压缩到几分钟。
第六步:处理属主与权限
rsync 到远程后,属主可能不对:
ssh root@new-server 'chown -R www-data:www-data /var/www/site/'
或用 --chown:
rsync -avzP --chown=www-data:www-data /var/www/site/ root@new:/var/www/site/
常见踩坑与失败案例
--delete误删 —— 源路径写错(比如漏了斜杠)会导致目标端被清空。永远先--dry-run。- 案例:某运维写了
--exclude='cache',结果把主题里的cache目录和插件的缓存类文件也排除了,恢复后站点报错。排除规则要写具体路径(wp-content/cache/)而不是模糊名。 - 同步后站点 500 —— 属主变成 root,PHP 写不了。同步后执行 chown。
wp-content/uploads太大导致同步慢 —— 图片可单独同步到对象存储,rsync 只同步代码部分。- SSH 端口不是 22 —— 用
-e "ssh -p 2222"。 - 没限速导致线上卡顿 —— 生产环境务必加
--bwlimit(单位 KB/s)。
总结
rsync 是 WordPress 文件级备份与迁移的利器,核心用法就一句:rsync -avzP --delete --exclude-from=... 源 目标。三条纪律:排除缓存与备份目录、删除操作先 dry-run、同步后修正属主。用它做异地增量备份,成本极低;用它做迁移前预同步,能把停机时间从几小时压到几分钟。配合 mysqldump 做数据库备份,文件与数据双保险,整套方案不依赖任何插件,站点挂了也能用。
