在使用 rsync -avzP/ rsync -avP同步目录后,发现本地和远程的文件夹大小(通常通过 du -sh 查看)不一致,这是 Linux 运维中非常经典的问题。结合你之前提到的 PVE/LXC 环境,导致大小不符的原因通常有以下几种:
1. 文件系统压缩(PVE/ZFS 环境最常见)
- 现象: 本地(目标端)查看到的大小比远程(源端)小很多。
- 原因: 如果你的新 PVE 节点使用了 ZFS 文件系统 并且开启了自动压缩(默认通常是 lz4 或 zstd),那么文件在写入本地磁盘时会被实时压缩。而
du -sh统计的是实际占用的磁盘空间,并非文件的真实大小。 验证方法: 在两端分别运行以下命令查看文件的“视在大小”(即文件原本的实际字节数,绕过文件系统压缩和块大小限制):
du -sh --apparent-size /opt/
如果用这个命令查看到的大小一致,说明数据完整,只是新底座的文件系统帮你省了空间。
2. 没有使用 --delete 参数(本地有残留文件)
- 现象: 本地(目标端)比远程(源端)大。
- 原因: 你的命令
rsync -avP bero:/opt/ /opt/属于增量覆盖同步。如果本地的/opt/目录在同步之前本来就存在一些文件,rsync 只会覆盖同名文件或同步新文件,而不会删除本地独有、远程早已没有的文件。 解决办法: 如果你希望两端完全一致(本地多余的删除),需要加上
--delete参数:rsync -avP --delete bero:/opt/ /opt/
3. 稀疏文件(Sparse Files)被展开
- 现象: 本地比远程大很多。
- 原因:
/opt/里面可能包含某些数据库文件、虚拟磁盘镜像或大日志文件,它们在远程是“稀疏文件”(表面上 10G,实际只占 100M 空间)。rsync默认的-a参数不会保留稀疏属性,会将那些“空洞”用真正的0填满写入本地,导致文件被强行撑大。 解决办法: 同步时必须加上
-S(或--sparse)参数:rsync -avPS bero:/opt/ /opt/
4. 硬链接(Hard Links)未保留
- 现象: 本地比远程大。
- 原因: 如果远程的
/opt/内部有文件使用了硬链接(多个文件名指向同一个数据块),rsync -a默认会把它们当作独立的两个文件分别复制一份,导致本地占用了双倍空间。 解决办法: 需要加上
-H(或--hard-links)参数:rsync -avPH bero:/opt/ /opt/
5. 特殊文件(如套接字 Socket)被忽略
- 现象: 本地和远程文件数量或大小微幅错位。
- 原因: 很多运行在
/opt/的现代应用(如 Docker、数据库、某些服务)会产生.sock(Socket 套接字)或管道文件。rsync默认会跳过这些属于运行时产生的特殊套接字文件(通常会在控制台弹出一行跳过警告),因为它们在程序关闭或启动时会自动创建,不需要也无法跨机器直接复制。
🛠️ 建议的排查与终极同步方案
为了彻底避坑并确保跨节点迁移的数据一致性,推荐按以下步骤操作:
第一步:对比两端的真实字节数(视在大小)
# 在远程机器 bero 上运行
du -sb /opt/
# 在本地机器上运行
du -sb /opt/
如果 -b(以字节为单位的绝对大小)完全一致,说明文件内容已经完整同步,大小差异只是由于两边磁盘的块大小(Block Size)或文件系统压缩率不同引起的,无需担心。
第二步:如果确实不一致,使用全功能命令重新校准
如果你追求极致的完美镜像复制,建议使用以下完全体命令重新跑一次(它会安全地检查、补充漏掉的硬链接、稀疏文件,并清理本地脏数据):
rsync -azvPH --delete --numeric-ids bero:/opt/ /opt/
参数补充说明:
-z:传输时压缩,提速。-H:保留硬链接。-S:保留稀疏文件。--delete:删除本地多余的文件。--numeric-ids:不映射用户/组名,直接按数字 UID/GID 写入(对于跨 LXC 容器迁移,能有效防止权限因用户名对不上而错乱)。