MySQL无内存占用率指标,需通过performance_schema查全局/线程内存及OS RSS趋势;须启用instruments与consumers,重点关注memory/innodb/mem0mem、temptable和thd内存,结合OS日志与配置排查隐性泄漏。

MySQL 本身没有“内存占用率”这个指标——它不按百分比汇报内存使用,而是靠你主动查 performance_schema 里各模块的实时分配量。真要监控,得盯住三类东西:全局事件内存、线程级内存、OS 层 RSS 增长趋势。泄漏感大多不是 C 堆泄漏,而是配置失当或连接堆积。
确认 performance_schema 是否真正启用内存监控
很多人以为 SHOW VARIABLES LIKE 'performance_schema' 返回 ON 就完事了,其实只是开关开了,内存 instruments 和 consumers 可能还关着。
- 必须执行:
UPDATE performance_schema.setup_instruments SET ENABLED = 'YES' WHERE NAME LIKE 'memory/%'; - 同时打开 consumers:
UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME IN ('global_instrumentation', 'thread_instrumentation'); - 验证是否就绪:
SHOW ENGINE PERFORMANCE_SCHEMA STATUS,只看最后一行是不是OK;不是就重启 mysqld 或检查启动参数是否含--performance-schema=ON
查全局内存大户:memory_summary_global_by_event_name
这是定位“谁在狂吃内存”的第一把刀。别只看当前值,HIGH_NUMBER_OF_BYTES_USED(峰值)比 CURRENT_NUMBER_OF_BYTES_USED 更关键——持续上涨说明没释放。
- 重点关注:
memory/innodb/mem0mem(InnoDB 内部结构,非 buffer pool)、memory/temptable/allocator(内存临时表)、memory/sql/thd(每个连接的线程上下文) - 如果
memory/innodb/mem0mem高位不降,配合SHOW ENGINE INNODB STATUS看SEMAPHORES和TRANSACTIONS区块,常是未提交事务或锁等待堆积导致字典缓存/锁结构膨胀 -
memory/temptable/*异常高?立刻查tmp_table_size和max_heap_table_size,设成 2G 不是“更稳”,是鼓励引擎把大结果全塞进内存
按线程追凶:找到长期不释放的连接
很多“泄漏”其实是应用端连接池没配好,连上几百个空闲连接,每个都带着 sort_buffer_size、read_buffer_size 等线程级 buffer,RSS 就默默涨上去了。
- 执行:
SELECT thread_id, user, event_name, sys.format_bytes(CURRENT_NUMBER_OF_BYTES_USED) AS memory_used FROM performance_schema.memory_summary_by_thread_by_event_name WHERE CURRENT_NUMBER_OF_BYTES_USED > 1024*1024 ORDER BY CURRENT_NUMBER_OF_BYTES_USED DESC LIMIT 10; - 对照
information_schema.processlist,看thread_id对应的是不是应用连接、状态是不是Sleep却占着几 MB 内存 - 线程 ID 很大(比如 > 100)且
user是业务账号?基本可锁定为应用连接未正确 close 或连接池 leak
别漏掉 OS 层和配置陷阱
MySQL 进程 RSS 持续涨,但 performance_schema 里没明显大户?问题可能在外部。
- 用
dmesg -T | grep -i "killed process"确认是否被 OOM Killer 杀过;再看/var/log/messages或journalctl -u mysqld有没有 “Out of memory” 记录 - 查
free -g和cat /proc/meminfo | grep -E "(MemAvailable|SwapTotal|SwapFree)",确认是不是系统整体缺内存,而非 MySQL 单独问题 - 检查
innodb_buffer_pool_size是否设到物理内存 70% 以上,又开了transparent_hugepage=always,会导致 THP 分配失败后 fallback 到大量小页,加剧 malloc 碎片
真正难排查的不是 memory/innodb/mem0mem 高,而是它涨得慢、每天只多 10MB,三个月后突然 OOM——这种必须结合历史 HIGH_NUMBER_OF_BYTES_USED 趋势和应用变更节奏交叉比对,否则容易当成“正常波动”放过。


















