确认mysql被oom killer杀掉需运行dmesg -t | grep -i "killed process",若输出含"out of memory: kill process"及mysqld或对应pid,且时间与systemctl status mysqld显示的宕机时间吻合,即可确定。

MySQL进程被OOM Killer干掉怎么确认
系统杀掉MySQL,大概率是触发了OOM Killer。它不会留情面,只看谁占内存多、谁优先级低——MySQL这种吃内存大户首当其冲。
关键动作是立刻查日志,不是重启服务,不是改配置,先定位是不是OOM在作祟:
- 运行
dmesg -T | grep -i "killed process",找带Out of memory: Kill process的时间戳行 - 如果输出里有
mysqld或进程PID,基本坐实是OOM Killer动的手 - 注意时间:和MySQL挂掉的时间是否吻合(
systemctl status mysqld看最近的Active状态变化) - 别只看
/var/log/messages,有些发行版(如CentOS 7+)默认不记录OOM事件到那里,dmesg才是唯一可靠来源
为什么OOM Killer会盯上mysqld
MySQL本身不“坏”,但它默认配置对内存很贪婪:比如innodb_buffer_pool_size设成物理内存的70%–80%,而系统没给它留够余量给内核、其他服务、甚至glibc malloc的碎片开销。
常见组合拳导致OOM:
- 容器环境跑MySQL但没设
memory limit或设得过大,宿主机OOM后统一清算 - 开启了
tmp_table_size和max_heap_table_size过高,大GROUP BY/ORDER BY临时表直接爆内存 - 启用了
query_cache_type=1(MySQL 5.7及以前),缓存失效时锁竞争+内存抖动严重 - 系统开了
vm.swappiness=60(默认值),内核宁愿swap也不及时回收cache,最后逼出OOM
怎么调参避免再被kill
目标不是让MySQL少吃点,而是让它“吃得明白、退得及时”。重点压三个参数:
- 把
innodb_buffer_pool_size严格控制在物理内存的50%–60%,且必须预留至少2GB给系统和其他进程 - 将
tmp_table_size和max_heap_table_size统一设为64M(别超过128M),大结果集交给磁盘临时表,总比OOM强 - 关闭查询缓存:
query_cache_type=0(MySQL 5.7起默认禁用,但老配置可能还开着) - 容器部署务必加限制:
docker run --memory=4g --memory-reservation=3g,避免超卖
注意:innodb_buffer_pool_size 修改后必须重启mysqld才生效,热修改无效;其他参数可动态SET,但仅影响新连接。
检查systemd内存限制和OOMScoreAdj
很多人忘了systemd自己也管内存。如果MySQL用systemd管理,它可能被套了双重枷锁:
- 查当前限制:
systemctl show mysqld | grep Memory,留意MemoryLimit是否为infinity(无限制)还是某个具体值 - 检查OOM倾向:
cat /proc/$(pidof mysqld)/oom_score_adj,数值越正越容易被杀;MySQL默认是0,但某些发行版模板会设成1000(最高风险) - 修复方法:在
/etc/systemd/system/mysqld.service.d/override.conf里加:[Service] OOMScoreAdjust=-500
然后运行systemctl daemon-reload && systemctl restart mysqld
OOMScoreAdjust调太低(如-1000)反而会让mysqld在真正内存危机时“赖着不死”,拖垮整个系统——-500是兼顾生存与责任的平衡点。
实际排查中,最常被跳过的一步是确认dmesg输出里那个被杀进程的PID是否真对应当前mysqld主进程,而不是某个残留的旧实例——多实例共存或未彻底清理的场景下,这点很容易误判。











