mysql运行中突然重启大概率是被oom killer杀掉的,应先执行dmesg -t | grep -i "killed process.*mysqld"确认,再交叉验证系统日志,而非查看空白的error.log。

MySQL运行中突然重启,大概率不是它自己崩了,而是被 Linux 内核的 OOM Killer 主动杀掉的。 查 error.log 通常一片空白,真正线索藏在 dmesg 里。
怎么看 dmesg 是否记录了 mysqld 被杀
直接执行:dmesg -T | grep -i "killed process.*mysqld"。如果输出类似:
[Tue May 5 14:23:18 2026] Out of memory: Kill process 12345 (mysqld) score 892 or sacrifice child
那就 100% 是 OOM Killer 下的手。注意看时间戳,和 MySQL 实际重启时间是否吻合。
-
score值越高,越容易被选中;同时间对比其他进程 score,能判断是不是 mysqld 独占内存 - 再交叉验证:
grep -i "oom\|kill" /var/log/syslog(Ubuntu/Debian)或grep -i "oom\|kill" /var/log/messages(RHEL/CentOS) - 别只信
free -h的 free 行——重点看Available字段,它才反映真实可用内存
为什么 innodb_buffer_pool_size 设大了反而更危险
这个参数是 MySQL 内存消耗的大头,但它不是“申请多少用多少”,而是启动时就尝试 mmap 一大块虚拟内存。一旦系统物理内存吃紧,OOM Killer 会优先干掉占用 RSS 高、运行久、优先级低的进程——mysqld 几乎必中。
- 宝塔默认设为物理内存的 50%–70%,但在 2G/4G 小内存机器上,还跑着 Nginx、PHP、Redis,很容易超限
-
cat /proc/$(pgrep mysqld)/status | grep VmRSS可看当前实际驻留内存,若接近总内存 80%,风险极高 - swap 长期为 0 会加速触发 OOM;但开 swap 不是万能解药,只是买点缓冲时间
systemd 和 OOM 的关系不能忽略
很多人以为 MySQL 自己重启了,其实是 systemd 在背后兜底拉起。它看到进程退出(哪怕是被 kill -9),只要退出码非 0,就按 Restart=on-failure 策略重试——于是你看到“闪退又自启”的假象。
- 查真实策略:
systemctl show mysqld | grep -E "(Restart|StartLimit)" - 若
StartLimitBurst=5且 1 分钟内崩了 5 次,systemd 会进入抑制状态,后续不再拉起,但面板可能仍显示“正在运行” - 临时限制内存上限(比调小
innodb_buffer_pool_size更快见效):systemctl edit mysqld,加:[Service] MemoryAccounting=true MemoryLimit=2G
磁盘满或 I/O 卡死也会伪装成 OOM
当 /var/lib/mysql 所在分区 df -h 显示 100%,MySQL 写 binlog 或刷脏页失败,可能触发 watchdog 或自我保护式退出。错误日志里常出现:
InnoDB: Error: Write to file ./ibdata1 failed at offsetFailed to write the transaction log-
Cannot allocate memory for the buffer pool(注意:这行报错不一定是真缺内存,也可能是磁盘满导致 mmap 失败) - 用
iostat -x 1看%util > 90%且await > 100ms,说明磁盘已成瓶颈,尤其机械盘或低配云盘
最隐蔽的点:OOM Killer 杀进程时,不会等 MySQL 把错误写进 error.log——它直接终止进程,连 flush 日志的机会都没有。所以,dmesg 不是备选方案,是第一现场。











