现场是这样的。两核四 G 的实例上 MySQL 每隔两三天就消失一次,systemctl 显示服务已停止,业务侧报连接被拒绝,手动拉起后能撑一阵又复发。

原因不止一个,得分开看。物理内存只有四 G,缓冲池按默认值配到了接近一半,再加上 PHP 就超了;系统完全没有配交换分区,内存一紧张内核就直接挑占用最大的进程下手;容器限额和宿主机统计口径不一致,实际可用内存被高估。

先在内核日志里确认被杀的是哪个进程

dmesg -T | grep -i 'killed process'

然后看当时的内存与交换使用

free -h && vmstat 1 5

再往下把缓冲池压到实际内存的六成以内

grep -n innodb_buffer_pool_size /etc/my.cnf

降低关键进程被选中的概率

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

怎么算真的好了,看的是同一批现象。连续运行一周不再出现被杀记录,数据库常驻内存稳定在实例规格之内,业务连接不再中断。

补一句。调大交换分区只是把崩溃往后推,缓冲池超过物理内存迟早还会被杀;用监控把峰值记下来比事后猜更可靠。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。

作者 9823189