我工作的 Linux 集群最近开始一次冻结几分钟。我确定出现这种行为的原因是进程非常频繁地进入 D(“不间断睡眠”)状态,并长时间停留在该状态。
不幸的是,这种行为很难随意重现。通常,如果命令在完成前停留在 D 状态几分钟,并且我立即重复完全相同的命令,则该命令的第二次会立即完成。
没有任何一个可执行文件会导致这种行为。似乎几乎所有 Unix 命令都容易受到影响:ls
、grep
、wc
、find
、git
、vim
,凡是你能想到的命令。
此外,相同的行为正在影响集群中的所有节点。
鉴于这种模式,我认为所有节点共享的存储系统一定存在一些问题。不幸的是,我不知道如何超越这种预感。
幸运的是(我猜),当命令进入 D 状态时,它会在那里保留 5-10 分钟。我认为这应该给我足够的时间来调查情况,并希望获得有关正在发生的事情的更多详细信息。
我的问题是:给定处于 D 状态的进程的 PID,我可以运行哪些命令来收集有关正在发生的情况的更多信息?
重要的:目前,我主要感兴趣的是诊断。特别是,我对通过重新启动集群来解决问题不感兴趣,因为这不会告诉我如何防止再次出现相同的情况。
PS 如果有一个比 Unix & Linux SE 更好的 SE 站点来解决这个问题,我将非常乐意迁移这个问题;请告诉我。
答案1
你说你正在集群中运行。也许您正在使用跨多台网络计算机的文件系统?当进程停止工作时,这通常是罪魁祸首一小会儿(即 I/O 必须完成,因为您正在执行内核代码)。
我认为你最好的选择是获取等待进程的堆栈跟踪,这是通过以下方式完成的:
$ sudo su -
# echo w > /proc/sysrq-trigger
# dmesg -T | less -S
less
当然,该命令是可选的。
然后查看该堆栈跟踪。它可能包括对基于网络的文件系统的调用,例如nfs3_proc_getattr
您使用的是 NFS。
另一个解决方案是运行gdb -p <pid>
,但如果您不拥有该进程或调试模式已关闭,则该命令行选项可能会出现权限问题。如果您可以通过这种方式启动 gdb,请where
在出现命令提示符后尝试一下。这也为您提供了堆栈跟踪。我从未尝试在进程处于D
状态时获得这样的结果,因此它实际上可能不起作用。
如果您需要能够从任何计算机编辑这些文件,我没有任何好的解决方案。否则,也许像 HFS 这样的东西会更适合你。这类似于基于网络的文件系统,只是它在本地复制文件,因此当您访问文件时,它位于您所在的计算机上,并且您的命令可以始终保持快速。
最后的想法:我曾经遇到过由于 NFS 导致进程 100% 卡住的情况。我连他们都无能为力kill -9
。摆脱它们的唯一方法是重新启动。同样,这是因为该进程当前位于内核空间中,并且内核无法安全地删除这样的进程。它必须等待返回到用户模式,此时它可以接收 发送的信号kill
。这就是为什么我很长时间没有使用该文件系统的原因。这不值得。如果我在正确卸载 NFS 之前关闭虚拟机,那就完蛋了。 (重新启动 VM 不会恢复旧的 NFS 挂载点。)