报错是这么冒出来的。文件服务器从旧机器迁到新机器,两边都是 CentOS 7.9 的 ext4,用 rsync -av 同步完,站点目录下 750 的属组写权限和 setfacl 加的读写组全变成默认 644,PHP 写上传目录直接 Permission denied。
中间走过弯路,把「备份用的 tar 打包时没带 --acls,一进一出两次都丢」当成主因,改完现象没变。
这类报错背后常见的原因有几处,逐个排除就行。rsync 的 -a 包含 -p 但不包含 ACL,要显式加 -A 和 -X。另一种情况是源端和目标端的挂载选项里没有 acl,内核层直接就丢。
另外,目标文件系统重新格式化时没打开 acl 相关特性。
先对比两边同一个目录的 ACL 差异
getfacl /www/wwwroot/site && getfacl /data/site
接着确认两端的挂载都开了 acl
findmnt -T /www/wwwroot -o OPTIONS
带 ACL 参数重新同步一次
rsync -aHAX --numeric-ids /www/wwwroot/ /data/wwwroot/
剩下的就是用演练模式校验同步结果
rsync -aHAXn --numeric-ids /www/wwwroot/ /data/wwwroot/ | head
恢复的判定其实很直接。getfacl 在两端输出一致,站点上传和写入都不再报 Permission denied,属主和属组也保持原样。
这里还有个坑。跨机器迁移时 UID 对不上也会让权限看着对但实际无效,配 --numeric-ids 并核对两边的 passwd 再同步。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。
