performance_schema一开就吃几百MB内存,因其默认预分配events_statements_history_long等长历史表各128MB+,且启动即占用;需禁用非必要consumers/instruments、调小history_size、确认配置文件路径生效。

performance_schema为什么一开就吃几百MB内存
MySQL 8.0 默认全量启用 performance_schema 的 instruments 和 consumers,尤其 events_statements_history_long、events_transactions_history_long 这类长历史表,单个默认分配 128MB+ 内存。它们不是按需分配,而是启动即预分配——哪怕你从不查这些表,内存也早被占住。
常见错误现象:mysqld 进程 RSS 突然多出 300–500MB,SHOW PROCESSLIST 看不到异常连接,但 sys.memory_global_total 显示 performance_schema 占比超 40%。
- 查真实占用:
SELECT * FROM performance_schema.memory_summary_global_by_event_name WHERE event_name LIKE 'memory/performance_schema/%' ORDER BY SUM_ALLOCATED DESC LIMIT 10; - 关掉非调试用 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 - 禁用非核心 instruments(运行时生效,重启失效):
UPDATE performance_schema.setup_instruments SET ENABLED = 'NO' WHERE NAME LIKE 'statement/sql/%' AND NAME NOT IN ('statement/sql/select','statement/sql/insert','statement/sql/update','statement/sql/delete');
升级后 performance_schema 配置没生效的典型原因
很多 DBA 在宝塔或手动改了 /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 参数。
- 确认实际加载的配置:
ps aux | grep mysqld | grep -o '\-\-defaults-file=[^ ]*';若无输出,说明走默认路径,此时/etc/my.cnf存在就会覆盖宝塔改的文件 - 最稳妥做法:删掉或重命名
/etc/my.cnf,然后确保/www/server/mysql/my.cnf顶部有[mysqld]段落,并把performance_schema相关参数放进去 - 改完别直接重启,先校验语法:
mysqld --defaults-file=/www/server/mysql/my.cnf --verbose --help 2>/dev/null | head -5,不报错再systemctl restart mysqld
哪些 performance_schema 参数必须关,哪些可以留
不是所有 instrument 都值得保留。OLTP 场景下,95% 的诊断需求靠 statement/sql/select、wait/io/file、wait/lock/table 就够了。其他全是内存黑洞。
- 必须关(默认开、高内存、低价值):
events_statements_history_long、events_transactions_history_long、events_waits_history_long - 建议关(调试期开,上线后关):
events_statements_history(短历史,默认 10 行/线程,但线程多时仍可观)、events_stages_history_long - 可保留(低开销、高价值):
events_statements_current、events_waits_current、memory/innodb/*、memory/sql/* - 注意:
performance_schema_max_sql_text_length默认 1024,够用;别调到 4096 或更高,否则每个语句内存翻 4 倍
关了 performance_schema 会影响监控吗
不影响基础监控。sys 库里大部分视图(如 schema_table_statistics、host_summary)依赖的是 performance_schema 的底层数据,但只要保留 events_statements_current 和 events_waits_current,这些视图依然能工作。真正丢的是“过去 5 分钟谁执行了慢 SQL”这种回溯能力——而生产环境更该依赖慢日志 + pt-query-digest,不是靠 P_S 历史表撑着。
容易被忽略的一点:关闭 performance_schema 后,SHOW ENGINE INNODB STATUS 输出里的 TRANSACTIONS 部分会变简略(比如看不到具体锁等待链),但核心死锁信息、事务状态、undo log 大小仍完整。真要深挖锁问题,还是得看 information_schema.INNODB_TRX + INNODB_LOCK_WAITS。


















