这类问题我又碰上了一次。内存紧张时内核总是挑数据库下手,占用更少的小服务反而活着,每次都要人工拉起,业务中断时间很长。

这类报错背后常见的原因有几处,逐个排除就行。内核按内存占用和评分挑选被杀进程;关键进程没有降低自己的被杀优先级;其他服务单个占用少但数量多,反而更安全。

上来先看当前评分

cat /proc/$(pidof mysqld)/oom_score

降低关键进程评分

echo -800 > /proc/$(pidof mysqld)/oom_score_adj

再往下写进服务配置持久化

grep -n OOMScoreAdjust /etc/systemd/system/mysqld.service

等前面都确认过,再核对生效结果

systemctl show mysqld -p OOMScoreAdjust

命令输出我都留了记录,免得改完记不清原来的值。

改之前先确认了最近有没有人动过配置,避免白查一遍。

改完先别撤,确认这几项。再次出现内存压力时被杀的是低优先级任务,数据库保持运行。

评分只能降低被选中的概率,不能免疫;给关键服务设内存上限并留出余量才是根本办法。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。

作者 9823189