MySQL查询被KILL掉通常因超时机制(如wait_timeout、max_execution_time)或OOM Killer触发;dmesg可确认是否OOM;max_execution_time仅对SELECT生效且不释放锁,应谨慎使用。

MySQL查询被KILL掉是因为连接超时还是OOM?
高负载下查询中断,八成不是“卡死”,而是被MySQL自己或系统主动终止。得先分清是wait_timeout、max_execution_time这类超时机制干的,还是Linux OOM Killer把mysqld进程杀掉了。查dmesg -T | grep -i "killed process",如果看到mysqld出现在输出里,那就是内存真不够用了,调参数没用,得先保命。
max_execution_time设太高反而更危险
这个参数看着是“防长查询”,但设成0(禁用)或几万毫秒,容易让慢查询霸占线程、拖垮整个连接池。尤其在OLTP场景下,一个SELECT ... JOIN卡住30秒,可能连带阻塞几十个新请求。真正该做的是:对已知慢的业务SQL加MAX_EXECUTION_TIME提示,而不是全局放开:
SELECT /*+ MAX_EXECUTION_TIME(5000) */ id, name FROM orders WHERE ...
-
max_execution_time只对SELECT生效,UPDATE/DELETE无效 - 它不释放锁,超时后事务仍处于活跃状态,可能造成隐式锁等待
- 和
innodb_lock_wait_timeout是两套机制,别混淆
innodb_buffer_pool_size不能无脑拉到物理内存80%
很多人看到“建议设为总内存70%~80%”就照搬,结果在48G机器上配了38G,却忘了OS还要缓存文件、网络栈、其他进程。MySQL真能用满?不一定。看SHOW ENGINE INNODB STATUS里的Buffer pool hit rate,长期低于99.5%才说明真缺;再看Innodb_buffer_pool_read_requests与Innodb_buffer_pool_reads比值,大于1000才算健康。否则就是堆了内存也白搭,还挤占了page cache,让磁盘IO更抖。
- SSD机器可以稍激进,HDD务必保守,留足OS缓存空间
- 启用了
innodb_buffer_pool_instances > 1时,总大小必须是实例数的整数倍,否则MySQL会自动向下取整,悄悄缩水 - 动态调整
SET GLOBAL innodb_buffer_pool_size = ...要求MySQL 5.7.5+且启用innodb_buffer_pool_resize_status
swap对MySQL就是慢性毒药
哪怕只开1G swap,一旦mysqld开始换页,响应延迟就从毫秒级跳到百毫秒甚至秒级,而且不可预测。Linux默认swappiness=60,必须改:sysctl vm.swappiness=1,并写入/etc/sysctl.conf。更彻底的是关掉swap分区:swapoff -a,同时确认/etc/fstab里注释掉swap行。
这事容易被忽略——监控看到内存使用率才60%,就以为没事,其实buffer pool刚触发minor page fault,还没爆,但性能曲线已经歪了。


















