设innodb_buffer_pool_size为物理内存的62%(如16GB机配10G)可避免OOM,因其占RSS 70%+;需扣减OS及其他进程内存,且必须是128MB×instances的整数倍,混部时须关闭innodb_dedicated_server手动控制。

innodb_buffer_pool_size设多大才不触发OOM
这是MySQL 8.0内存占用的绝对主因,占进程RSS的70%+。设小了频繁读盘拖慢查询,设大了直接被OOM killer杀掉进程——日志里搜Out of memory: Kill process mysqld就能确认。
实操建议:
- 16GB内存服务器:设
innodb_buffer_pool_size = 10G(62%),留4–5GB给OS、binlog线程等 - ≤4GB小内存机:别超
1G,否则mysqld极易被OOM kill - 必须是
innodb_buffer_pool_chunk_size × innodb_buffer_pool_instances的整数倍(默认chunk=128MB),否则启动时自动向下取整 - 单位写
1G或512M,别用字节数——易错且难读
为什么改了my.cnf但内存没降下来
90%是因为MySQL根本没读你改的那个文件。MySQL 8.0按固定顺序加载配置:/etc/my.cnf → /etc/mysql/my.cnf → /usr/etc/my.cnf → ~/.my.cnf,而宝塔等面板常写入/www/server/mysql/my.cnf——这个路径不在默认列表里。
实操建议:
- 查真实加载路径:
ps aux | grep mysqld | grep -o '\-\-defaults-file=[^ ]*',没输出就说明走默认路径 - 删/重命名
/etc/my.cnf(如有),再改/www/server/mysql/my.cnf - 改完先校验语法:
mysqld --defaults-file=/www/server/mysql/my.cnf --verbose --help 2>/dev/null | head -5,不报错才重启 - 重启后验证:
mysql -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"
max_connections和wait_timeout必须配对调
单调max_connections只是“堵漏”,不配wait_timeout会导致空闲连接长期霸占内存,每个连接还额外分配sort_buffer_size等线程级缓冲区。
实操建议:
- 16GB+生产环境:
max_connections = 2000+wait_timeout = 300(5分钟) -
wait_timeout和interactive_timeout必须设成一样值,否则CLI会话行为异常 - 小内存机(≤4GB):
max_connections = 300+wait_timeout = 180,同时把sort_buffer_size = 256K,避免100个连接吃掉近40MB
哪些参数写了也白写,甚至引发警告
MySQL 8.0已移除的功能,硬写进去不仅无效,还可能让启动失败或产生警告日志。
实操建议:
-
query_cache_type和query_cache_size:8.0彻底删除,设任何值都无效,还会报Unknown variable -
key_buffer_size:InnoDB表完全不用它,设太高纯属浪费内存;建议固定为16M -
tmp_table_size和max_heap_table_size:必须设成相等值,否则GROUP BY或ORDER BY会悄悄落到磁盘临时表,性能断崖下跌
innodb_dedicated_server=ON这个开关——它会根据物理内存自动设buffer pool,但假设服务器专用于MySQL。混部环境下(比如跑着Redis、Nginx),它极可能设错值,务必手动关掉并自己控制。


















