我的消息日志中抛出以下报告:
kernel: Out of memory: Kill process 9163 (mysqld) score 511 or sacrifice child
kernel: Killed process 9163, UID 27, (mysqld) total-vm:2457368kB, anon-rss:816780kB, file-rss:4kB
httpd
如果这个问题是针对的,mysqld
或者postfix
但我很好奇如何继续调试该问题,这并不重要。
我怎样才能获得更多关于为什么 PID 9163 被杀死的信息,我不确定 linux 是否在某处保留了终止 PID 的历史记录。
如果您的消息日志文件中出现这种情况,您将如何逐步解决此问题?
# free -m
total used free shared buffers cached
Mem: 1655 934 721 0 10 52
-/+ buffers/cache: 871 784
Swap: 109 6 103`
答案1
在此发生之前,内核将记录一堆内容,但其中大部分可能不会记录在 中/var/log/messages
,具体取决于您的(r)syslogd
配置方式。尝试:
grep oom /var/log/*
grep total_vm /var/log/*
前者应该出现很多次,而后者只出现一两个地方。这就是您要查看的文件。
在也包含total_vm
.在该行之前三十秒到一分钟(可能更多,可能更少),您会发现类似以下内容:
kernel: foobar invoked oom-killer: gfp_mask=0x201da, order=0, oom_score_adj=0
您还应该在该行和“内存不足”行之间找到一个表,其标题如下:
[ pid ] uid tgid total_vm rss nr_ptes swapents oom_score_adj name
这可能不会告诉您比您已经知道的更多的信息,但这些字段是:
- PID进程 ID。
- uid用户身份。
- tgid线程组 ID。
- 总虚拟机数虚拟内存使用(以 4 kB 页为单位)
- RSS常驻内存使用(以 4 kB 页为单位)
- nr_ptes页表条目
- 交换货币交换条目
- oom_score_adj通常为 0;较低的数字表示调用 OOM Killer 时进程终止的可能性较小。
你基本上可以忽略nr_ptes
,swapents
尽管我相信这些是决定谁被杀的因素。这不一定是使用最多内存的进程,但很可能是。有关选择过程的更多信息,看这里。基本上,最终获得最高 oom 分数的进程将被终止——这是“内存不足”行上报告的“分数”;不幸的是,其他分数没有报告,但该表提供了一些因素方面的线索。
再说一次,这可能只会说明一个显而易见的事实:系统内存不足并被mysqld
选择死亡因为杀死它会释放最多的资源。这并不一定意味着mysqld
做错了什么。您可以查看该表,看看当时是否有其他任何问题,但可能没有任何明显的罪魁祸首:系统可能会耗尽内存,仅仅是因为您错误判断或错误配置了正在运行的进程。
答案2
关键在于消息本身 -内存不足。当 Linux 内核缺乏虚拟内存(物理 RAM 加交换)时,它会开始杀死进程,这正是这里发生的情况。看起来mysqld
使用了超过 2GB 的虚拟内存。
系统有多少 RAM 和交换空间?我会考虑添加额外的内存,或者如果不可能的话,添加额外的交换空间。作为至少防止进程终止的快速修复,您可以添加交换文件。
更新:查看您拥有的 RAM 量,您可以立即看到问题所在。你有大约 1.6GB 的 RAM 和 100MB 的交换空间,但 MySQL 使用的 RAM 比这多得多。这解释了为什么您会看到进程被终止。