先看现象。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 修好。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。

作者 9823189