用户登录
个人主页 用户中心 我的订单 添加授权 管理授权
退出登录
用户登录 用户注册
欢迎来到 UC建站系统

rsync网站数据同步隐藏致命缺陷:80GB文件迁移SSH断连后800MB残缺文件被当成了已同步,rsync不校验内容只对比大小和修改时间的漏洞比想象中危险

上周帮一个做跨境电商的同行从阿里云迁移到腾讯云,网站目录大概80GB、MySQL数据库12GB。用rsync拖了三个小时快跑完的时候SSH断连,自动重连后rsync重新扫了80GB文件但什么也没同步——因为所有文件mtime和size都匹配,rsync判断"没变化"就跳过了。问题在于SSH断连前最后的800MB文件只传了一半,文件大小看起来对但内容是残缺的,rsync不校验内容只对比大小和时间,这800MB残缺文件就被当成了"已同步"

网站数据同步的本质不是"把文件从A搬到B",而是"搬完之后两边数据一模一样且能用"。rsync默认不校验文件内容只对比大小和修改时间,rclone默认走哈希校验但速度慢三到五倍,MySQL主从复制能实时同步但一旦中断想修复差异比重新搭一遍还麻烦。工具选对方向不搞反,比工具本身是什么重要一百倍。

网站数据同步要拆成两块看:文件同步(网站代码、图片、附件、静态资源)和数据库同步(文章、用户、订单、配置)。两块用的工具、逻辑、翻车点完全不同,混在一起用同一个方案是90%翻车的根源。

一、文件同步:rsync和rclone的边界在哪

两台Linux服务器之间同步网站文件,rsync是首选。它的增量算法只传文件变化的部分——一个100MB的日志文件新增了2KB内容,rsync只传这2KB。但rsync的"增量检测"有个前提:默认对比的是文件大小(size)和修改时间(mtime),不对比文件内容。这就是开头那800MB残缺文件被跳过的原因。

对比维度rsyncrclone
核心用途两台Linux服务器之间同步文件本地↔云存储/云↔云之间同步文件
增量检测方式默认:mtime + size(快但不可靠)
加 -c 参数:内容校验(慢但准确)
默认:哈希校验(准确但慢)
可切换为mtime+size(快但不可靠)
支持的后端本地文件系统 + SSH远程40+种:S3/OSS/COS/OneDrive/Google Drive/WebDAV/SFTP等
传输速度单线程但增量极高效,局域网内跑满带宽支持多线程(--transfers),大文件传云存储比rsync快
SSH断连恢复默认每次新建SSH连接,断连后重新扫全量文件支持断点续传,大文件传输中断后从断点继续
适合网站同步吗✅ 最佳选择,配合SSH复用+定时cron⚠️ 适合备份到云存储,不适合服务器间日常同步
什么时候该用rclone?目标不是另一台Linux服务器,而是阿里云OSS、腾讯云COS、AWS S3等对象存储时。rclone原生支持40+种存储后端,能把网站文件直接同步到云存储上做备份或CDN源。但两台Linux服务器之间做日常同步,rclone的哈希校验开销完全是浪费——rsync配合SSH复用和cron定时任务已经是最优解。

二、rsync五个致命翻车点

翻车1:--delete方向搞反,新数据被旧数据覆盖
rsync -avz --delete /旧服务器/ /新服务器/ ——如果源目录是空的或者你搞反了方向,--delete会把目标端所有文件删光。这个参数的字面意思是"让目标目录和源目录完全一致",不是"删除目标端多余的文件"这么温柔。
解法:每次带--delete执行前,先用--dry-run跑一遍看rsync打算删什么,确认无误再去掉--dry-run。

翻车2:SSH断连后半截文件被当完整文件
就是开头说的那个场景。rsync默认不校验文件内容,传输中断后文件大小看起来正确但内容是残缺的,rsync跳过它。
解法:大文件传输加 -c 参数强制内容校验(速度会慢但不会漏);或者传输完成后用md5sum对关键文件做二次校验;最稳的方案是启用SSH连接复用(ControlMaster),大幅降低断连概率。

翻车3:文件权限和属主丢失
默认rsync不保留文件权限、属主和属组。网站同步后WordPress上传目录变成root:root 644,PHP没有写入权限,所有图片上传全部失败。
解法:加 -p(权限)-o(属主)-g(属组)参数。如果是跨服务器同步且两边用户名不同,用 --chown=USER:GROUP 强制修改。

翻车4:排除规则漏了不该排除的东西
用 --exclude='cache/' 排除了缓存目录,但 --exclude 是从源路径的相对路径开始匹配的。如果源路径是 /var/www/,排除规则写 --exclude='var/www/cache/' 匹配不到——因为rsync把 /var/www/ 当作根路径。
解法:--exclude的路径永远以源路径为基准。搞不清就用 --exclude-from=FILE 写到一个文件里,用绝对路径测试通过后再填进去。

1 - rsync网站数据同步隐藏致命缺陷:80GB文件迁移SSH断连后800MB残缺文件被当成了已同步,rsync不校验内容只对比大小和修改时间的漏洞比想象中危险 - UC建站系统

翻车5:路径末尾斜杠的"暗语法"
rsync -avz /source/ /dest/ ——末尾有斜杠:同步目录里的内容。
rsync -avz /source /dest/ ——末尾无斜杠:在dest下创建一个source子目录再同步内容。
差一个斜杠,目录结构完全不同。多少人的网站迁移后访问404,最终发现是wwwroot下面多嵌套了一层目录。
解法:统一加斜杠,或者用rsync -avz /source/ user@host:/dest/ 这种明确写法。永远不省略末尾斜杠。

三、数据库同步:不是拿mysqldump导出再导入就完了

数据库同步分两种情况:一次性迁移(搬家、换服务器)和持续同步(主从复制、读写分离)。两种场景用的工具和策略完全不同。

场景推荐工具/方案核心操作翻车点
一次性迁移
数据库<5GB
mysqldump + mysql导出SQL→传输→导入,简单直接导出期间数据库被写入导致数据不一致。加 --single-transaction(InnoDB)或 --lock-tables(MyISAM)
一次性迁移
数据库>5GB
xtrabackup / mydumper物理热备份或并行导出,比mysqldump快3-5倍xtrabackup要求MySQL版本一致,mydumper导入时注意字符集
持续实时同步MySQL主从复制主库binlog→从库relay log→回放,秒级延迟主从延迟、数据不一致后修复困难、从库宕机恢复需重搭
持续近实时同步Canal + 自定义消费端伪装成MySQL从库解析binlog,推送到MQ或直接写入目标维护成本高,需要专职DBA,小站别碰
跨数据库异构同步DBSyncer / DataXMySQL→ES/PostgreSQL/MongoDB等异构数据源同步字段类型映射不一致、增量同步断点恢复
桌面可视化同步Navicat / DBeaver 数据同步GUI操作,可视化对比+同步,支持结构和数据Navicat付费(¥1,500+/年)、大表同步慢、不适合自动化
MySQL主从复制最大的坑:数据不一致了你可能很久都不知道。主从复制跑着跑着从库可能因为各种原因(网络抖动、SQL执行报错、binlog格式问题)出现数据不一致,但从库的IO线程和SQL线程都显示正常。等到某天从库切换成主库,才发现少了数据。必须定期用 pt-table-checksum 做一致性校验,发现不一致用 pt-table-sync 修复。

四、四种建站场景的同步方案速查

你的场景文件同步方案数据库同步方案月成本
网站搬家(一次性)rsync -avzP /旧/ /新/
先--dry-run再执行
mysqldump --single-transaction → 传输 → mysql导入$0
定时备份到异地rsync + cron 每天凌晨执行
或rclone备份到对象存储
mysqldump定时导出 + rsync传输$0
(云存储按量付费)
多服务器负载均衡rsync + inotifywait
(事件驱动,文件变化即时同步)
MySQL主从复制
(主库读写,从库只读)
$0工具 + 服务器成本
静态站点部署更新rsync --delete
(保持服务器和本地构建目录一致)
不涉及$0
站群多站点统一备份rclone 批量同步到COS/OSS
写脚本遍历所有站点目录
脚本批量mysqldump → rclone上传$0 + 对象存储按量

五、三个同步工具之外的翻车点

同步完才发现字符集不匹配

数据库从一台服务器导出、传输、导入到另一台服务器,整个过程顺利无报错。打开网站一看所有中文内容变成问号——源库是utf8mb4,目标库默认建成了latin1。mysqldump导出时没检查目标库字符集,导入SQL里CREATE TABLE语句的DEFAULT CHARSET被忽略了。

避法:mysqldump导出前先查源库字符集(SHOW CREATE DATABASE),导入前在目标库先建同名库并指定相同字符集。

网站同步时没关写入导致数据不一致

rsync在同步网站目录的时候,用户正在上传图片、提交评论、下订单。rsync读到一半的文件可能是不完整的,同步过去的文件就是损坏的。数据库用mysqldump不加--single-transaction导出,导出过程中有新写入,导出的数据前后不一致。

2 - rsync网站数据同步隐藏致命缺陷:80GB文件迁移SSH断连后800MB残缺文件被当成了已同步,rsync不校验内容只对比大小和修改时间的漏洞比想象中危险 - UC建站系统

避法:文件同步前把网站切到维护模式(停止写入)。数据库导出必须加--single-transaction(InnoDB表)保证一致性快照。

同步完测试了首页就以为全好了

网站迁移后打开首页正常,以为搞定了。结果用户反馈:所有上传的图片打不开、搜索功能报错、后台登录页面500。问题出在:图片目录权限没同步、搜索用了绝对路径指向旧服务器、后台用了Redis缓存还连着旧服务器。

避法:同步后测试清单至少覆盖:首页、内页、图片、上传、搜索、登录、后台。尤其检查配置文件里有没有硬编码的旧服务器IP或域名。

六、一个安全的生产级网站迁移同步流程

把这个流程存成checklist,每次网站迁移照着走一遍,不用靠脑子记:

第1步:源站切维护模式,停止一切写入操作。

3 - rsync网站数据同步隐藏致命缺陷:80GB文件迁移SSH断连后800MB残缺文件被当成了已同步,rsync不校验内容只对比大小和修改时间的漏洞比想象中危险 - UC建站系统

第2步:mysqldump --single-transaction --routines --triggers --events 导出数据库,检查导出文件大小和末尾是否有 "Dump completed" 字样。

第3步:rsync -avzP --dry-run 先跑一次看差异清单,确认无误后去掉 --dry-run 正式执行。重点检查exclude规则是否排除对了缓存、日志、临时文件。

第4步:目标服务器导入数据库前先检查字符集一致,导入后跑 SELECT COUNT(*) 对比源库和目标库的关键表行数。

第5步:修改目标站配置文件(数据库连接、站点URL、缓存配置、CDN回源地址),确认没有任何地方还指向旧服务器。

第6步:按测试清单逐项验证:首页→内页→图片→上传→搜索→登录→后台→API接口。

第7步:切DNS到新服务器IP,TTL提前改短(建议600秒),保留旧服务器运行24-48小时做回滚备份。

第8步:48小时内持续监控新站访问日志和错误日志,确认没有异常后关停旧服务器。


网站数据同步的坑不在于工具难用,而在于每个工具都有自己的"默认假设"——rsync默认假设mtime+size能判断文件是否一致(大部分时候可以,断连场景不可以),MySQL主从复制默认假设网络稳定binlog不会丢(大部分时候可以,抖动场景不可以),mysqldump默认假设导出过程中没人写数据(你忘了加--single-transaction它也不会提醒你)。知道每个工具在什么场景下默认假设会失效,比知道工具怎么用重要得多。最后说一句:每次同步前先跑--dry-run,每次导出数据库都加--single-transaction,迁移后旧服务器至少保留48小时不删。这三条做到了,90%的翻车都能避免。

相关推荐
在线客服
👇找客服拿折扣
QQ咨询&售后
在线时间
11:00 ~ 5:30
QQ:3155555535
👇联系QQ
👇联系WX
首页 程序 帮助 登录