刚启动mysql rss突增300–500mb并非内存泄漏或配置错误,而是mysql 8.0启动时为events_statements_history_long等长历史表预分配各128mb+内存且mmap锁定;需通过/etc/my.cnf中调小performance_schema_events_statements_history_long_size等参数并重启生效,运行时set global无法释放已分配内存。

为什么刚启动MySQL就看到RSS多出300–500MB
不是内存泄漏,也不是配置写错了——是MySQL 8.0启动时就为events_statements_history_long、events_transactions_history_long这类表预分配了各128MB+内存,且用mmap锁定,不随查询活跃度变化。哪怕你从没查过performance_schema里的任何一张表,这部分内存也早已被划走。
典型现象:mysqld进程RSS突增、SHOW PROCESSLIST无异常连接、但执行SELECT * FROM sys.memory_global_total会发现memory/performance_schema/占比超40%。
哪些配置项真正控制P_S内存开销
关键不是“开不开”,而是“开多少”。以下参数必须写进/etc/my.cnf的[mysqld]段并重启才生效:
-
performance_schema_events_statements_history_long_size = 10000(默认20000) performance_schema_events_transactions_history_long_size = 10000-
performance_schema_max_digest_length = 256(默认4096,每条SQL摘要省约3.7KB) -
performance_schema_max_sql_text_length = 1024(默认4096) -
performance_schema_max_statement_stack = 10(默认30) -
performance_schema_max_file_instances = 1000(默认不限,库表多时极易飙到GB级)
注意:SET GLOBAL无法释放已分配内存——P_S的内存是启动时一次性mmap的,运行时不可归还OS。
为什么改了/www/server/mysql/my.cnf却没生效
MySQL 8.0只认固定路径:优先读/etc/my.cnf → /etc/mysql/my.cnf → /usr/etc/my.cnf → ~/.my.cnf。/www/server/mysql/my.cnf不在默认列表里,除非显式加--defaults-file参数启动。
实操建议:
- 确认配置实际加载路径:
mysqld --verbose --help 2>/dev/null | grep "Default options" - 把所有P_S相关参数挪到
/etc/my.cnf的[mysqld]段 - 校验语法:
mysqld --defaults-file=/etc/my.cnf --validate-config(8.0.23+支持)或用mysqld --defaults-file=/etc/my.cnf --verbose --help | head -5看是否报错 - 重启前删掉旧的
ib_buffer_pool文件(路径如/var/lib/mysql/ib_buffer_pool),避免预热干扰判断
关掉非必要consumer比调参数更立竿见影
禁用长历史表采集,能立刻停掉对应内存的持续填充(虽然已分配内存不会释放,但后续不再增长):
- 运行时执行:
UPDATE performance_schema.setup_consumers SET ENABLED = 'NO' WHERE NAME IN ('events_statements_history_long', 'events_transactions_history_long'); - 同时关掉非核心instruments:
UPDATE performance_schema.setup_instruments SET ENABLED = 'NO' WHERE NAME LIKE 'wait/synch/%' OR NAME LIKE 'stage/sql/%'; - 检查效果:
SELECT * FROM performance_schema.memory_summary_global_by_event_name WHERE event_name LIKE 'memory/performance_schema/%' ORDER BY SUM_ALLOCATED DESC LIMIT 5;
真正要彻底释放那几百MB,只有两个办法:改配置+重启,或者临时设SET GLOBAL performance_schema = OFF(不推荐生产环境长期用)。
容易被忽略的是:buffer pool预热和P_S内存叠加后,RSS可能在启动后几秒内跳涨一倍,但这不是问题本身,而是两个独立机制共同作用的结果——得分开调,不能只盯一个。











