事情本身不复杂,线索都在日志里。阿里云 ECS 上 CentOS 7.9 挂载内网 NFS,服务端重启过一次之后客户端执行 ls 直接报 Stale file handle,df 也要卡十几秒才返回,手工重新 mount 一次能好,服务端下次一动又复现。

第一反应是「挂载时用了 hard 加较长的 acregmin,客户端的属性缓存迟迟不失效」,验证下来不成立。

原因不止一个,得分开看。服务端重启后旧的文件句柄失效,客户端缓存里的 inode 在导出目录里已经不存在。另一种情况是NFSv3 没有会话恢复机制,只能用新的 file handle 重新解析整条路径。

不容易想到的是,服务端导出目录换过挂载点,底层设备号变了,之前发的句柄全部对不上。

上来先确认当前挂载的协议版本和缓存参数

nfsstat -m | grep -E 'vers|proto|ac'

然后用一次新句柄重新走路径看是否恢复

ls /mnt/nfs/share && stat /mnt/nfs/share

卸载后重新挂载把旧缓存清干净

umount -l /mnt/nfs/share && mount -a

末了换成 v4.1 并缩短超时重传

mount -t nfs -o vers=4.1,soft,timeo=30,retrans=2 10.0.0.12:/data /mnt/nfs/share

恢复的判定其实很直接。ls 和 stat 都不再报 Stale file handle,cat 一个测试文件内容完整,服务端再次重启后客户端十秒内自行恢复。

v3 上碰到句柄失效只能重新挂载,v4.1 有会话和回调,恢复会平滑很多;导出目录不要随便换挂载点,inode 一变句柄就全废。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。

作者 9823189