最近遇到一个杀不死的进程,执行 kill -9 没有任何反应,进程卡在那儿处于不死不休的状态。
一般遇到进程卡死,执行 strace -p pid 可以观察进程的 API 调用过程来确定进程卡在哪一步。但当前这个进程处于假死状态,在 proc/pid 下查看进程状态为:
cat /proc/44607/statusName: pythonState: D (disk sleep)Tgid: 44607Ngid: 0Pid: 44607PPid: 1TracerPid: 112702Uid: 0 0 0 0Gid: 0 0 0 0FDSize: 256Groups: 0NStgid: 44607NSpid: 44607NSpgid: 44607NSsid: 39779VmPeak: 29336 kBVmSize: 29336 kBVmLck: 0 kBVmPin: 0 kBVmHWM: 8692 kBVmRSS: 3212 kBVmData: 3396 kBVmStk: 132 kBVmExe: 2268 kBVmLib: 2788 kBVmPTE: 72 kBVmPMD: 12 kBVmSwap: 3664 kBHugetlbPages: 0 kBThreads: 1SigQ: 8/515089SigPnd: 0000000000000100ShdPnd: 0000000000004103SigBlk: 0000000000000000SigIgn: 0000000001001000SigCgt: 0000000180000002CapInh: 0000000000000000CapPrm: 0000003fffffffffCapEff: 0000003fffffffffCapBnd: 0000003fffffffffCapAmb: 0000000000000000Seccomp: 0Speculation_Store_Bypass: thread vulnerableCpus_allowed: ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffffCpus_allowed_list: 0-191Mems_allowed: 00000000,0000000fMems_allowed_list: 0-3voluntary_ctxt_switches: 39715nonvoluntary_ctxt_switches: 1489
之前通过 kill 杀掉了该进程的父进程,所以当前进程的父进程由1号进程继承。通过 strace 查看进程时,strace 也卡住了。
$ ps -eaf| grep -v grep| grep 44607root 44607 1 0 3月29 ? /anaconda3/bin/python tmp/sum.py .root 112702 1 0 329 ? strace -p 44607
在 proc 文件系统中查看到的出问题的进程的状态为 D,网上的消息说是进程正在等待磁盘IO,并且进入到了内核态。
State: D (disk sleep)
内核态的进程没法在用户态杀掉,只能等待进程自己从内核态出来。因为这个程序是在读取 NFS 文件时卡死的,所以八成与 NFS 有关。并且 NFS 挂载的磁盘当前负载较高,但 NFS 磁盘并没有卡死仍然可以读写。
于是决定停掉 NFS 磁盘上的其它读写任务,看卡死的进程能否恢复。当停掉其它任务后,处于 disk sleep 状态的进程并没有从等待中恢复过来。查阅其他人的处理办法,只有一种选择就是重启服务器。但这个办法肯定不是可行的,毕竟这只是一个常规任务。
除了这种状态为 D (disk sleep) 的进程不好杀,处于 Z 状态的进程也不好杀。
$ ps -eaf| grep 186225$ root 186225 1 0 19:45 rsync -r --size-only pacs2/pacs/images/20201002_20/ pacs1/images/20201002_20$ root 186235 186225 0 19:45 [rsync] <defunct>$ cat /proc/186235/statusName: rsyncState: Z (zombie)Tgid: 186235Ngid: 0Pid: 186235PPid: 186225$ cat /proc/186225/statusName: rsyncState: D (disk sleep)
本来处理僵尸进程,同时杀掉僵尸进程和它的父进程,一般是可以杀掉的。这里出现了一种情况就是它的父进程的状态也是 D (disk sleep),这就导致了僵尸进程杀不掉了。
高并发的读写 NFS 文件系统很容易出现这种资源锁,一旦出现就只能从存储端断开客户端,不能因为进程杀不掉就重启系统。
参考
https://community.pivotal.io/s/article/Dealing-with-Processes-in-State-D---Uninterruptible-Sleep-Usually-IO?language=en_UShttps://stakoverflow.com/questions/1475683/linux-process-stateshttps://unix.stackexchange.com/questions/407321/is-there-any-way-to-kill-or-end-a-process-in-disk-sleephttps://stackoverflow.com/questions/223644/what-is-an-uninterruptible-processhttps://blog.csdn.net/davion_zhang/article/details/48268319https://blog.csdn.net/A___LEi/article/details/127661470?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0-127661470-blog-48268319.235^v27^pc_relevant_t0_download&spm=1001.2101.3001.4242.1&utm_relevant_index=3https://zhuanlan.zhihu.com/p/92381918
全文完。
如果转发本文,文末务必注明:“转自微信公众号:生有可恋”。
文章转载自生有可恋,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




