有趣的是,也许令人困惑的是,我目前系统上有一个僵尸进程在积累 CPU 时间。因此问题是,为什么?通常认为,
ps
的任何输出显示僵尸进程意味着唯一使用的是进程表项;来自维基百科的定义是:"... 僵尸进程或死进程是已完成执行(通过 exit 系统调用)但仍在进程表中具有条目的进程:它是处于“终止状态”的进程。" ,而来自unix.stackexchange的定义是:
https://unix.stackexchange.com/questions/11172/how-can-i-kill-a-defunct-process-whose-parent-is-init“僵尸进程几乎不会占用任何资源,因此让它们悬挂没有性能成本。”
因此我有一个僵尸进程:
# ps -e -o pid,ppid,stat,comm| grep Z
7296 1 Zl myproc <defunct>
似乎正在使用 CPU 时间:
# ps -e -o pid,ppid,bsdtime,stat,comm| grep Z; sleep 10; ps -e -o pid,ppid,bsdtime,stat,comm | grep Z
7296 1 56:00 Zl myproc <defunct>
7296 1 56:04 Zl myproc <defunct>
那么,一个僵尸进程如何累积CPU时间呢?
我改变了我的搜索:
# ps -eT -o pid,lwp,ppid,bsdtime,stat,comm| grep 7296
7296 7296 1 1:29 Zl myproc <defunct>
7296 8009 1 56:11 Dl myproc
我看到有一个正在运行并使用系统I/O的线程。实际上,如果我这样做,我可以看到字段15(stime)在改变:
# watch -d -n 1 cat /proc/8009/stat
Every 1.0s: cat /proc/8009/stat Fri Jun 4 11:19:55 2021
8009 (myproc) D 1 7295 7295 0 -1 516 18156428 12281 37 0 11609 344755
(截取至第15个字段)
我试图用TERM杀死进程8009...但是没有成功。使用KILL命令也无济于事。
听起来像是内核bug。我尝试了strace,这很愚蠢,因为现在我的strace无法退出。
这是在RHEL 7.7上,内核版本为3.10.0-1062。虽然已经有点老了,但足够年轻(在我看来)以致于一个僵尸进程可能会由于某个bug而积累系统资源。
顺便说一句,根据iotop的显示,我们的I/O峰值达到了4 GBps,这很多。我认为这个问题肯定对我们的系统产生了影响,我想重新启动。
/proc/8009目录的ls输出如下:
# ls -l /proc/8009
ls: cannot read symbolic link /proc/8009/cwd: No such file or directory
ls: cannot read symbolic link /proc/8009/root: No such file or directory
ls: cannot read symbolic link /proc/8009/exe: No such file or directory
(以下是正常的/proc/pid输出...但我已经省略了一些)
/proc/8009/fd为空。所以即使我有大量的I/O操作,它也不会写入任何文件。我没有看到文件系统空间被使用,如df -h
输出所示。
最后:尝试重新启动正在变得不可能。 shutdown -r now
无法工作。有几个systemd进程被卡在I/O等待中:
PID USER PRI NI VIRT RES SHR S CPU% MEM% TIME+ Command
22725 root 20 0 129M 2512 1548 R 0.0 0.0 0:00.19 htop
22227 root 20 0 195M 4776 2652 D 0.0 0.0 0:00.00 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
1 root 20 0 195M 4776 2652 D 0.0 0.0 0:58.41 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
这是关机输出。我会说此时 init 相当困惑:
# shutdown -r now
Failed to open /dev/initctl: No such device or address
Failed to talk to init daemon.
重启
说的是同样的事情。我得拔掉这台机器的插头。
...更新:就在我登录控制台的时候,系统重新启动了!可能花了约10分钟的时间。所以我不知道systemd在做什么,但它正在做某些事情。
...另一个更新:今天有3台机器发生了这种情况,它们都具有相同的特征:相同的二进制文件,某种行为(没有打开的文件描述符,但进行了I/O操作,两个线程,子线程累积了CPU时间)。正如@Stephane Chazelas所提到的,我执行了堆栈跟踪。以下是典型输出;我对内核不太熟悉,但也许对未来的某个闯入者有兴趣...请注意242603是父线程,242919是繁忙的子线程:
# grep -H . /proc/242919/task/*/stack
/proc/242919/task/242603/stack:[<ffffffff898a131e>] do_exit+0x6ce/0xa50
/proc/242919/task/242603/stack:[<ffffffff898a171f>] do_group_exit+0x3f/0xa0
/proc/242919/task/242603/stack:[<ffffffff898b252e>] get_signal_to_deliver+0x1ce/0x5e0
/proc/242919/task/242603/stack:[<ffffffff8982c527>] do_signal+0x57/0x6f0
/proc/242919/task/242603/stack:[<ffffffff8982cc32>] do_notify_resume+0x72/0xc0
/proc/242919/task/242603/stack:[<ffffffff89f8c23b>] int_signal+0x12/0x17
/proc/242919/task/242603/stack:[<ffffffffffffffff>] 0xffffffffffffffff
/proc/242919/task/242919/stack:[<ffffffffc09cbb03>] ext4_mb_new_blocks+0x653/0xa20 [ext4]
/proc/242919/task/242919/stack:[<ffffffffc09c0a36>] ext4_ext_map_blocks+0x4a6/0xf60 [ext4]
/proc/242919/task/242919/stack:[<ffffffffc098fcf5>] ext4_map_blocks+0x155/0x6e0 [ext4]
/proc/242919/task/242919/stack:[<ffffffffc0993cfa>] ext4_writepages+0x6da/0xcf0 [ext4]
/proc/242919/task/242919/stack:[<ffffffff899c8d31>] do_writepages+0x21/0x50
/proc/242919/task/242919/stack:[<ffffffff899bd4b5>] __filemap_fdatawrite_range+0x65/0x80
/proc/242919/task/242919/stack:[<ffffffff899bd59c>] filemap_flush+0x1c/0x20
/proc/242919/task/242919/stack:[<ffffffffc099116c>] ext4_alloc_da_blocks+0x2c/0x70 [ext4]
/proc/242919/task/242919/stack:[<ffffffffc098a4d9>] ext4_release_file+0x79/0xc0 [ext4]
/proc/242919/task/242919/stack:[<ffffffff89a4a9cc>] __fput+0xec/0x260
/proc/242919/task/242919/stack:[<ffffffff89a4ac2e>] ____fput+0xe/0x10
/proc/242919/task/242919/stack:[<ffffffff898c1c0b>] task_work_run+0xbb/0xe0
/proc/242919/task/242919/stack:[<ffffffff898a0f24>] do_exit+0x2d4/0xa50
/proc/242919/task/242919/stack:[<ffffffff898a171f>] do_group_exit+0x3f/0xa0
/proc/242919/task/242919/stack:[<ffffffff898b252e>] get_signal_to_deliver+0x1ce/0x5e0
/proc/242919/task/242919/stack:[<ffffffff8982c527>] do_signal+0x57/0x6f0
/proc/242919/task/242919/stack:[<ffffffff8982cc32>] do_notify_resume+0x72/0xc0
/proc/242919/task/242919/stack:[<ffffffff89f8256c>] retint_signal+0x48/0x8c
/proc/242919/task/242919/stack:[<ffffffffffffffff>] 0xffffffffffffffff