两台采集机把结果写到同一个 NFS 目录,代码里 flock 加了排他锁,返回值也是 0。合并后的文件里仍有整段被覆盖,时间戳显示两边同一秒在写。第一次遇到会往复杂处想,其实漏掉的多是个小前提。
mount | grep nfs rpcinfo -p 10.0.8.21 | grep -E 'lockd|statd' flock -n /mnt/share/out.lock -c './collect.sh'
flock 走的是本地内核的锁表,NFSv3 默认不带锁服务,rpc.lockd 没起或者挂载时带了 nolock,锁请求在本地就直接成功。锁只在单机有效,跨主机等于没加。这一点先确认清楚,后面就不用反复试。
「NFS 文件锁失效」相关的日志我一般连着看前后五分钟,单看一条报错经常判断不出是哪一步失败。新版本先放一台机器上跑一天再全量,问题一般在这段时间暴露。
备份不是备了就行,恢复一次才算数,很多备份文件打开才发现是空的。
具体做法是,挂载参数里去掉 nolock 并确认 rpc.statd 和 lockd 在跑;换成 fcntl.lockf 走 POSIX 锁 NFS 支持得更好;文件锁靠不住就改成写临时文件再 rename 到目标名;rename 之后用 stat 的 inode 确认没有互相覆盖。
改完照着核一遍,两台机器同时跑采集 目标文件行数等于两边之和 覆盖告警不再出现。
