最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如何解决MySQL 8.0升级后由于内存分配机制变化导致的OOM频繁重启?
时间:2026-08-11 07:54:49 编辑:袖梨 来源:一聚教程网
MySQL 8.0升级后OOM的根本原因是innodb_buffer_pool_size默认按内存自动推导且存在chunk对齐机制,叠加performance_schema全开预占内存,需同时配置chunk_size、instances、关闭P_S高耗consumer并禁用buffer_pool_load_at_startup。
为什么MySQL 8.0升级后一启动就OOM?
根本不是“新版本更吃内存”,而是innodb_buffer_pool_size默认行为从“保守固定值”变成“按物理内存自动推导”,再叠加performance_schema全开,默认吃掉300–500MB,两者一碰就超4G机器的可用内存边界。你看到SHOW VARIABLES里是1G,实际RSS可能飙到3.2G——因为InnoDB向上对齐分配,且events_statements_history_long等表启动即占128MB+。
怎么让buffer pool真正按你写的数分配?
MySQL 8.0.22+会动态算innodb_buffer_pool_chunk_size,若你没显式设,它可能算出256MB chunk × 8 instances = 2GB,哪怕你配了innodb_buffer_pool_size = 1280M,也会被强制对齐到2GB。结果就是配置失效、OOM照旧。
- 必须在
my.cnf中同时写死:innodb_buffer_pool_chunk_size = 128M(推荐,1M整数倍) - 同步调整
innodb_buffer_pool_instances,确保innodb_buffer_pool_size / (128 * 1024 * 1024 * innodb_buffer_pool_instances)是整数(例如设1280M,instances只能选2或4或8) - 删掉旧的
ib_logfile0和ib_logfile1(路径通常是/www/server/data/或/var/lib/mysql/),否则启动报错
performance_schema不关,调再小的buffer pool也没用
它不是“可选插件”,而是默认全开、启动即预分配内存的重量级组件。重点关掉两个最耗内存的consumer:
- 执行:
UPDATE performance_schema.setup_consumers SET ENABLED = 'NO' WHERE NAME IN ('events_statements_history_long', 'events_transactions_history_long'); - 在
my.cnf里加两行限制大小:performance_schema_events_statements_history_long_size = 10000(默认20000),performance_schema_events_transactions_history_long_size = 10000 - 验证当前P_S内存占用:
SELECT * FROM performance_schema.memory_summary_global_by_event_name WHERE event_name LIKE 'memory/performance_schema/%' ORDER BY SUM_ALLOCATED DESC LIMIT 5;
别漏掉buffer pool dump预热这个“隐形炸弹”
MySQL 8.0默认开启innodb_buffer_pool_dump_at_shutdown和innodb_buffer_pool_load_at_startup。重启后几秒内RSS陡增,不是泄漏,是后台线程疯狂加载上次dump的ib_buffer_pool文件——如果这文件有800MB,而你只配了1G buffer pool,它照样硬塞。
- 临时禁用:
SET GLOBAL innodb_buffer_pool_load_at_startup = OFF; - 永久禁用:在
my.cnf中加innodb_buffer_pool_load_at_startup = OFF - 调小dump比例(如果还想保留部分预热):
innodb_buffer_pool_dump_pct = 10(默认25) - 删掉旧
ib_buffer_pool文件(同数据目录下),避免残留大文件干扰
真正卡点不在参数名本身,而在“chunk size × instances”必须整除你写的buffer pool size,以及P_S consumer关闭必须落地到SQL+配置双生效——少一步,OOM就还在门口等着。