锁是协调手段,不是并发保护伞
SMB 提供字节范围锁与用于缓存协调的租约,NFSv3 用独立的锁协议、NFSv4 把锁并入协议本身。它们能让协作良好的应用互相避让,但都不会自动保护「同时覆盖写入」这种逻辑冲突:两个进程各自打开、各自写同一段内容,最终结果取决于执行顺序与缓存回收时机。共享目录不适合承载需要事务语义的数据,例如数据库文件。
基本信息
| 适用平台 | Windows SMB 共享、Samba、NFSv3/v4 |
|---|---|
| SMB 侧 | 字节范围锁、租约与机会锁 |
| NFS 侧 | NFSv4 协议内锁与委托,NFSv3 依赖独立锁服务 |
| 查看命令 | Get-SmbOpenFile、smbstatus -L |
| 关键事实 | 不同协议的锁互不感知 |
现象与机制
| 现象 | 可能机制 | 处理方向 |
|---|---|---|
| 文件无法删除或重命名 | 仍有进程持有句柄或存在独占打开 | 定位持有者并让其释放 |
| 提示文件正被使用 | 字节范围锁冲突 | 协调写入顺序或改用应用级队列 |
| 内容被后写者覆盖 | 无锁的并发写入 | 改为分文件写入或加应用层互斥 |
| 读到旧内容 | 缓存与租约尚未收回 | 缩短缓存或关闭客户端缓存 |
| 跨协议访问异常 | SMB 与 NFS 锁不互通 | 限制单一协议写入,其余只读 |
定位与查看
定位与查看
# Windows:找出持有文件句柄的客户端
Get-SmbOpenFile | Where-Object Path -like '*report.xlsx*' | Select-Object ClientUserName,ClientComputerName
# Samba:查看会话持有的锁
smbstatus -L
# Linux 本地查看哪些进程打开了该文件
lsof /srv/data/report.xlsx
# Samba 侧可按需调整机会锁与租约行为,具体参数以版本文档为准
testparm -s /etc/samba/smb.conf | head -n 20把共享目录当数据库或虚拟机磁盘存放位置,是并发写导致数据损坏的典型场景。这类负载要求严格的写入顺序与锁语义,应使用块存储而非文件共享。
混合协议访问同一份数据时,锁与缓存都只在各自协议内生效:SMB 的租约不知道 NFS 的委托,因此一个协议上的写入可能不会及时让另一个协议的客户端看到变化。要避免这种情况,应约定同一目录只由一种协议写入,另一种保持只读。