performance_schema=on但memory_summary_global_by_event_name为空,是因为memory/* instruments未启用;必须在my.cnf中配置performance-schema-instrument='memory/%=on'并重启mysql,再查current_number_of_bytes_used定位实时内存占用。

performance_schema=ON 但 memory_summary_global_by_event_name 为空?
这不是 bug,是两级开关没全开。MySQL 的内存监控必须同时满足两个条件:Performance Schema 引擎本身启用 + memory/* 类 instruments 显式开启。只设 performance_schema=ON,memory_summary_global_by_event_name 表一定为空。
先确认引擎是否真就绪:
- 执行
SHOW ENGINES,检查PERFORMANCE_SCHEMA行的Support值是否为YES - 执行
USE performance_schema; SHOW TABLES LIKE 'memory%';,看是否有表名匹配(如memory_summary_global_by_event_name) - 若表存在但查不到数据,跳到下一步验证 instruments
如何永久启用 memory instruments?
不能靠 SET GLOBAL 动态开启 —— MySQL 明确禁止运行时启用 memory/* 采集器,必须重启生效。
编辑 my.cnf(Linux)或 my.ini(Windows),在 [mysqld] 段落下添加:
performance-schema-instrument='memory/%=ON'
重启 MySQL 后验证是否加载成功:
-
SELECT COUNT(*) FROM performance_schema.setup_instruments WHERE NAME LIKE 'memory/%' AND ENABLED = 'YES';应返回几十行以上 - 若为 0,说明配置未生效,检查配置文件路径、段落是否写错、有无拼写错误(比如漏了末尾的
=ON) - 注意:
memory/performance_schema/%是硬编码内置的,无法关闭,其余都依赖该配置
查内存占用该用哪张表?CURRENT_NUMBER_OF_BYTES_USED 是什么?
启用后主查 performance_schema.memory_summary_global_by_event_name,但要注意字段含义:
-
CURRENT_NUMBER_OF_BYTES_USED:当前被该事件类型持有的字节数 —— 这是最接近“实时内存占用”的指标,不是历史累计值 -
TOTAL_NUMBER_OF_BYTES_ALLOCATED:包含已释放的总分配量,适合看模块长期倾向,不适合判断当前压力 -
CURRENT_NUMBER_OF_ALLOCATIONS:当前未释放的分配次数,辅助判断是否存在泄漏苗头
常用查询示例(按当前占用降序):
SELECT EVENT_NAME, CURRENT_NUMBER_OF_BYTES_USED, CURRENT_NUMBER_OF_ALLOCATIONS FROM performance_schema.memory_summary_global_by_event_name WHERE CURRENT_NUMBER_OF_BYTES_USED > 0 ORDER BY CURRENT_NUMBER_OF_BYTES_USED DESC LIMIT 10;
重点关注:memory/innodb/buf_pool(Buffer Pool 实际使用)、memory/sql/THD(每个连接开销)、memory/sql/TMP_TABLE(临时表内存)、memory/sql/filesort(排序缓冲区)
为什么 events_statements_summary_by_digest 查不到内存数据?
因为语句级 SQL 统计和内存事件是两条独立采集线。前者记录执行耗时、扫描行数等,后者按内存事件名(如 memory/sql/SELECT)聚合,不绑定 SQL 文本或 digest。
想定位某条 SQL 的内存开销,得交叉查:
- 先从
events_statements_current或events_statements_history拿到它的THREAD_ID - 再用该
THREAD_ID去查memory_summary_by_thread_by_event_name - 若要按用户维度看,换用
memory_summary_by_user_by_event_name并过滤USER字段
这种分离设计意味着:你看到一条慢查询,它的内存消耗可能分散在 parse、filesort、TMP_TABLE 多个事件里,必须手动关联才能归因。











