确认MySQL被OOM Killer杀死需先执行dmesg -T | grep -i "killed process",若输出含mysqld和Out of memory即可确定;再结合/var/log/messages或journalctl验证,并排查云厂商静默重启可能。

MySQL进程被OOM Killer干掉怎么确认
直接看系统日志,dmesg -T | grep -i "killed process" 是最快路径。如果输出里有 mysqld 和 Out of memory,基本就是它了。别急着调参数,先确认是不是真被 OOM Killer 杀的——有些云厂商会静默重启实例,日志里没痕迹,得同步查 /var/log/messages 或 journalctl -b | grep -i oom。
常见错误现象:MySQL突然断连、systemctl status mysqld 显示 failed 但无报错、error log 里最后一条是正常 shutdown(其实是假的)。
-
dmesg输出中mysqld出现在 “Killed process” 行右侧,且前面有内存分配失败提示(如pgtables_bytes超限) - 云主机控制台出现“实例异常终止”,但 MySQL error log 没有 crash 相关堆栈
-
cat /proc/$(pidof mysqld)/status | grep VmRSS查到 RSS 远超你配置的innodb_buffer_pool_size,说明有其他内存大户在吃资源
innodb_buffer_pool_size 设多大才不踩坑
不是“越大越好”,而是“不能超过可用物理内存减去系统和其他进程所需”。很多线上事故源于把 innodb_buffer_pool_size 设成总内存的 75%,却忘了 OS 缓存、连接线程栈、临时表、排序缓冲区(sort_buffer_size)、join 缓冲区(join_buffer_size)全算在 mysqld 进程 RSS 里。
使用场景:4 核 16GB 的独占 MySQL 实例,建议起步值为 10G;如果是容器或和 Redis/Nginx 共机,必须往下压,比如 6G,并监控 VmRSS。
- 用
ps aux --sort=-%mem | head -5看 mysqld 实际 RSS 占比,持续高于 90% 就危险 -
innodb_buffer_pool_size必须是128M的整数倍,否则启动时会被向下取整(例如设15G实际生效14.875G) - 开启
innodb_buffer_pool_dump_at_shutdown和innodb_buffer_pool_load_at_startup会额外增加启动阶段内存峰值,OOM 高发期
Linux 内核的 vm.swappiness 和 oom_score_adj 怎么调
vm.swappiness=1 不是银弹,它只影响内核回收 page cache 的倾向,对 mysqld 这种长期持有大量匿名内存的进程效果有限。真正关键的是 oom_score_adj:给 mysqld 进程打低分,让 OOM Killer 优先杀其他进程。
性能影响:把 vm.swappiness 设为 0 可能导致 swap 完全不用,但万一内存真的耗尽,内核会更激进地 kill 进程;设为 1 是平衡点,既避免频繁 swap,又保留一点缓冲余地。
- 临时生效:
echo -1000 > /proc/$(pidof mysqld)/oom_score_adj(-1000 表示永不 kill) - 永久生效:在 systemd service 文件里加
OOMScoreAdjust=-1000,然后systemctl daemon-reload && systemctl restart mysqld -
vm.swappiness改完需sysctl -p或重启生效,但注意某些云主机禁止修改该值(如 AWS EC2 的某些 AMI)
怎么验证调整后还不会被杀
别等下次出事才验证。用 stress-ng 模拟内存压力,观察 mysqld 是否存活,同时紧盯 cat /proc/$(pidof mysqld)/status | grep VmRSS 和 dmesg -T 实时输出。
容易被忽略的地方:MySQL 8.0+ 默认启用 innodb_dedicated_server,它会自动根据物理内存设 buffer pool,但不会管你有没有开 swap、有没有其他服务共存——这个“智能”在混部环境里反而是隐患。
- 执行
stress-ng --vm 2 --vm-bytes 8G --timeout 60s(模拟 8GB 内存压力 60 秒),期间反复检查 mysqld 是否仍在运行 - 查
SELECT @@innodb_buffer_pool_size, @@innodb_dedicated_server,如果后者为ON且你没做混部隔离,建议显式关闭并手动设innodb_buffer_pool_size - 容器环境务必检查 cgroup memory limit,
docker inspect或kubectl describe pod里的memory.limit_in_bytes才是真实天花板,MySQL 自己看不到










