在使用 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 容器迁移,能有效防止权限因用户名对不上而错乱)。