如何事后找出被因使用过多内存被杀死的进程(OOM)
在 2024-02-27 发布于 linux系统 分类
通常linux系统中会有一个专门的程序监控左右程序的运行,当有进程内存占用过大的时候,监控程序会杀死这个进程。 这样可以防止整个系统的内存被用完导致崩溃的情况。这个监控程序一般被成为Out-Of-Memory Killer。 程序因占用内存过多被杀死的情况一般被称为(OOM)。
当系统的大部分内存被一个程序占用的时候,系统会出现响应缓慢的情况。 此时我们往往会收到各种告警,但是因为系统响应缓慢,一般无法远程登陆查看情况。 因此事后找出哪个进程被OOM Killer杀死对于防止后续类似情况出现就非常重要。
简单来说,可以通过下面的命令从systemd日志中找出来那个进程被OOM Killer杀死:
journalctl --list-boots | \
awk '{ print $1 }' | \
xargs -I{} journalctl --utc --no-pager -b {} -kqg 'killed process' -o verbose --output-fields=MESSAGE
下面是对这个命令的拆解:
-
journalctl
是一个用于查询 systemd 日志的工具。 -
--list-boots
: 列出系统的所有启动记录。完整的输出是这个样子的:
``` $ journalctl --list-boots
-136 6e7ae03aa0a4887a6 Mon 2020-10-12 00:59:31 +03—Mon 2020-10-12 01:02:06 +03 -135 5e8f616769a4413b1 Mon 2020-10-12 01:02:38 +03—Mon 2020-10-12 02:55:47 +03 -134 7b839631c654dba8e Mon 2020-10-12 02:56:29 +03—Wed 2020-10-14 00:16:38 +03 .. -3 539bf36b695fd69b3 Wed 2021-01-27 10:25:02 +03—Wed 2021-01-27 20:46:49 +03 -2 d16424126db2a34b6 Wed 2021-01-27 20:47:43 +03—Wed 2021-01-27 23:53:16 +03 -1 d4ca25900037bb9a1 Thu 2021-01-28 10:15:03 +03—Fri 2021-01-29 20:48:03 +03 0 041a418db54e4fabc6 Fri 2021-01-29 20:48:41 +03—Sat 2021-01-30 20:57:10 +03 ```
-
awk '{ print $1 }'
: 打印出前面那个命令输出的每行的第一个字段,即启动记录编号 -
xargs -I{}
: 用前一步过滤出来的启动记录编号,逐个构建后续的journalctl命令并运行。 -
journalctl --utc --no-pager -b {} -kqg 'killed process' -o verbose --output-fields=MESSAGE`
- 这一段都是传递给 xargs 的命令。
- --utc:将消息中的时间转换为UTC。当处理来自其它系统的日志的时候,这个参数能确保我们得到含义一致的时间。
- --no-pager:不将输出传递给分页程序,直接输出到终端。
- -b {}:使用 {}(由 xargs 替换为启动序列标识符)指定要查询的启动序列。
- -kqg 'killed process' 这其实是三个命令选项的合并:
- -k 使用
_TRANSPORT=kernel
过滤消息,也就是过滤出内核事件 - -q 过滤掉提示性的消息
- -g 'killed progress' 以正则表达式过滤
- -k 使用
- -o verbose:以详细格式输出。
- --output-fields=MESSAGE:仅输出与消息相关的字段。