事情本身不复杂,线索都在日志里。阿里云 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 一变句柄就全废。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。
