【Linux】df -h 卡住问题的通用排查与解决方案总结

问题现象

执行 df -h 查看磁盘空间时,命令卡住无响应,无法 Ctrl+C 中断(或中断困难)。


根本原因

系统中挂载了网络文件系统 (NFS或CIFS/SMB),且挂载参数为 hard (硬挂载)。当NFS/CIFS服务端(如 192.168.1.100)网络不通或服务异常时,df -h 需要向所有挂载点发起 statfs() 系统调用以获取空间信息,该调用会因等待网络存储响应而陷入不可中断睡眠(D状态),导致命令卡死。


排查步骤

第一步:确认是否存在网络挂载点

bash 复制代码
cat /proc/mounts | grep -E "nfs|cifs"

预期输出示例:

复制代码
192.168.1.100:/data/share /mnt/nfs nfs4 rw,relatime,vers=4.2,hard,proto=tcp,timeo=600,retrans=2,...
//192.168.1.200/share /mnt/cifs cifs rw,relatime,...
  • 若输出中包含 hard 关键字,说明是硬挂载,属于高风险卡死类型。
  • 若输出为 soft,则通常不会导致 df 卡死(应用程序会快速收到超时错误)。

第二步:精准定位卡住的挂载点(备选方法)

如果 cat /proc/mounts 能正常执行,但无法确定具体是哪个挂载点卡住,可以使用 strace 追踪:

bash 复制代码
strace -e trace=statfs df -h 2>&1 | grep -v "ENOENT"

观察输出停止在哪个路径上,该路径即为问题挂载点。

第三步:检查NFS服务端连通性(辅助确认)

bash 复制代码
ping -c 3 192.168.1.100
telnet 192.168.1.100 2049   # NFS默认端口,CIFS为445

如果ping不通或端口不通,即可确认是服务端失联导致。


解决办法

方案一:懒卸载(首选,立即生效)

bash 复制代码
umount -l /mnt/nfs
  • -l(lazy umount):立即从文件系统树中剥离该挂载点,实际清理在后台完成。
  • 执行后 df -h 立刻恢复响应,适用于绝大多数场景。

方案二:强制卸载(当方案一无效时)

bash 复制代码
umount -f /mnt/nfs
  • -f(force):强制卸载,仅对NFS有效,CIFS可能不支持。
  • 如果 umount 命令本身也卡住,按 Ctrl+C 中断后尝试方案一。

方案三:杀掉占用进程后卸载

如果卸载时提示 target is busy,先用 fuser 找出占用进程并杀掉:

bash 复制代码
fuser -mv /mnt/nfs          # 查看哪些进程在访问该目录
kill -9 PID                 # 杀掉所有列出的PID
umount -l /mnt/nfs          # 再次执行懒卸载

方案四:后台异步卸载(终极手段)

如果连 umount -l 都无响应,将其放入后台执行,然后立即使用 df -h:

bash 复制代码
umount -l /mnt/nfs &
df -h                       # 此时大概率已通

预防措施(永久修复)

修改 /etc/fstab 中的挂载参数,避免使用 hard(除非业务有强一致性要求,如Oracle RAC)。

NFS 推荐挂载参数:

复制代码
192.168.1.100:/data/share /mnt/nfs nfs4 soft,timeo=10,retrans=2,vers=4.2 0 0

CIFS/SMB 推荐挂载参数:

复制代码
//192.168.1.200/share /mnt/cifs cifs soft,timeo=10,retrans=2,username=xxx,password=xxx 0 0

参数说明:

  • soft:超时后返回错误给应用程序,而非无限重试。
  • timeo=10:超时时间(单位:十分之一秒,即1秒)。
  • retrans=2:超时后重传次数,达到后返回错误。

特殊情况提示

  • 不要直接重启服务器:卡住的进程处于D状态,重启可能导致关机过程卡在等待IO阶段,耗时数分钟甚至更长。

  • df -h 卡住时不要反复执行:多次执行只会堆积更多D状态进程,消耗系统内存。

  • 如果业务必须使用 hard (如数据库):改用以下命令监控NFS状态,它们不会触发挂起:

    bash 复制代码
    nfsstat -m                     # 查看挂载状态
    cat /proc/self/mountstats      # 查看详细统计信息

快速决策流程图

复制代码
df -h 卡住
    ↓
cat /proc/mounts | grep -E "nfs|cifs"   ← 找出所有网络挂载点
    ↓
umount -l /mnt/nfs                      ← 优先执行懒卸载
    ↓
df -h                                   ← 验证是否恢复
    ↓(如果仍卡)
umount -f /mnt/nfs                      ← 尝试强制卸载
    ↓(如果umount卡住)
umount -l /mnt/nfs & ; df -h            ← 后台卸载,立即查df

如果以上步骤执行后问题仍未解决,可查看 cat /proc/mounts | grep -E "nfs|cifs" 的完整输出,进一步分析是否有多个挂载点或特殊协议参数导致。😊

相关推荐
Elastic 中国社区官方博客5 小时前
更少的位数,相同的召回率:DiskBBQ 更保守的自动校准扫描
大数据·运维·开发语言·人工智能·elasticsearch·搜索引擎
方便面不加香菜5 小时前
Docker Volume -- 管理卷Volume详解
运维·docker·容器
沫璃染墨6 小时前
从零入门计算机网络系列(十八):TCP连接管理详解——从三次握手与四次挥手到TIME_WAIT机制
运维·服务器·网络·c++·网络协议·tcp/ip·tcp
Felven6 小时前
华为鲲鹏920s芯片serdestool工具使用说明
linux·运维·服务器·华为·鲲鹏920·serdestool
江湖有缘6 小时前
Docker实战 | 使用Docker部署lemonitor镜像站点列表程序
运维·docker·容器
莫晓燚6 小时前
mall 电商项目完整部署---实战
linux·运维·docker·容器
咋的啥名都用不了呢~6 小时前
Linux项目部署5(安装Nginx的插件)
linux
CodeYp20197 小时前
第11讲:应用层协议 HTTP
linux·http
爱和冰阔落7 小时前
【Linux网络】JsonCpp 怎么实现序列化?从 Request/Response 到网络计算器消息设计
linux·运维·网络·php
Decay__7 小时前
01_SQLServer 体系架构全解 —— 实例进程、关系引擎、SQLOS 与事务日志深入
运维·数据库·sql·mysql·架构