是,MySQL 5.7 启动时若未显式配置 innodb_buffer_pool_size,会按物理内存的 75% 自动分配,远超小内存机器承受能力,是导致 OOM 的最常见原因。

查 innodb_buffer_pool_size 是不是被自动拉高了
MySQL 5.7 启动时若没在配置文件里显式设 innodb_buffer_pool_size,会按物理内存的 75% 自动分配(比如 8GB 机器分 6GB),而 5.6 默认只用 128MB。这是最常见、最直接的爆内存原因。
- 连上 MySQL 执行
SELECT @@innodb_buffer_pool_size / 1024 / 1024 AS mb;,看返回值是否远超你预期(如显示 6291456000 就是约 6GB) - 对比
free -h输出,确认该值是否超过总内存的 60% 且没给系统留余量(尤其小内存机器如 512MB 或 1GB) - 别信
SHOW VARIABLES里看到的值就是“生效值”——得去配置文件里找有没有写死,没写就等于交给 MySQL 自动猜
关掉 performance_schema 和调低 table_open_cache
这两个参数在 5.7 里默认更激进,尤其对小内存环境是隐形杀手。关掉 performance_schema 能立竿见影省下 100–200MB;table_open_cache 设太高会导致句柄和内存双涨。
- 在
[mysqld]段加performance_schema = off(5.7 支持,且不影响基础功能) - 把
table_open_cache从默认 4000+ 降到256或400(视实际库表数量定,512MB 机器建议 ≤256) - 顺手删掉已弃用的
query_cache_type和query_cache_size(5.7 虽未移除但已不推荐,开反而抢内存)
检查每个连接的内存放大效应
innodb_buffer_pool_size 是全局的,但 sort_buffer_size、join_buffer_size 这些是每连接分配的。如果 max_connections 设成 1000,哪怕只有 20 个活跃连接,MySQL 仍可能为所有连接预留内存空间。
- 执行
SELECT @@max_connections, @@sort_buffer_size, @@join_buffer_size;,算单连接理论内存:(sort_buffer_size+join_buffer_size+read_buffer_size+thread_stack) ×max_connections - 把
max_connections从 1000 降到200或更低(根据真实并发调整) - 把
sort_buffer_size从默认 256KB 降到1M(够用就行,别设 4M 或 8M) - 确认
tmp_table_size和max_heap_table_size不超过 32M(否则大结果集易触发磁盘临时表或 OOM)
别在线改 innodb_buffer_pool_size 就以为完事了
执行 SET GLOBAL innodb_buffer_pool_size = 2G; 可能失败或无效,不是语法错,而是底层约束没满足。
- 新值必须是
innodb_buffer_pool_chunk_size的整数倍(默认 128MB,所以 2G 合法,1.5G 不合法 → 会被向下取整到 1.40625G) -
innodb_buffer_pool_instances必须 ≥1(小内存机器可设为 1,但不能删或设 0) - 真正生效要靠配置文件重启,
SET GLOBAL只是临时尝试,且部分版本不支持运行时缩容 - 改完配置后务必用
ps aux | grep mysqld看 RSS 是否回落,再结合dmesg | grep -i "oom\|kill"确认没被系统杀过
内存问题从来不是单点参数的事,innodb_buffer_pool_size 是开关,但 max_connections、table_open_cache、performance_schema 这几个一起动,才真正决定你能不能在 1GB 机器上跑稳 MySQL 5.7。


















