这类问题我又碰上了一次。内存紧张时内核总是挑数据库下手,占用更少的小服务反而活着,每次都要人工拉起,业务中断时间很长。
这类报错背后常见的原因有几处,逐个排除就行。内核按内存占用和评分挑选被杀进程;关键进程没有降低自己的被杀优先级;其他服务单个占用少但数量多,反而更安全。
上来先看当前评分
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
命令输出我都留了记录,免得改完记不清原来的值。
改之前先确认了最近有没有人动过配置,避免白查一遍。
改完先别撤,确认这几项。再次出现内存压力时被杀的是低优先级任务,数据库保持运行。
评分只能降低被选中的概率,不能免疫;给关键服务设内存上限并留出余量才是根本办法。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。