先看现象。CentOS 7.9 挂载 NFS 存放上传文件,fstab 里带了 nolock,两个 PHP 进程同时处理同一个订单文件时互相覆盖,日志里能看到两边都在写同一个临时文件。
原因不止一个,得分开看。nolock 关掉了 NLM 锁协议,flock 和 fcntl 在客户端本地看起来成功,服务端完全不知道。还有一种是早期为了绕开 rpc.statd 起不来的报错直接加了 nolock,一直没改回来。
另外,应用的锁写在本地 /tmp,多台客户端各锁各的。
少数情况下是NFSv3 下 lockd 和 statd 没启动,加 nolock 掩盖了真正的问题。
上来先看挂载项里有没有 nolock
findmnt -no OPTIONS /mnt/upload
随后启动锁相关服务并去掉 nolock
systemctl enable --now rpc-statd && mount -o remount,lock /mnt/upload
再往下确认 lockd 已经在跑
rpcinfo -p | grep -E 'lockd|statd'
末了改 fstab 并验证两端并发写
sed -i 's#,nolock##' /etc/fstab && mount -a
恢复的判定其实很直接。findmnt 里不再出现 nolock,两个进程并发写同一文件时其中一个拿到锁等待,服务端 rpcinfo 能看到 nlm 相关端口。
提醒一点。nolock 只适合只读共享或者单客户端场景,多客户端共享写一定要开锁;与其关锁,不如把 rpc-statd 修好。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。
