mysql如何分析内存占用过高_mysql内存异常排查

5次阅读

MySQL 内存占用高需从配置、运行时行为及外部环境三方面排查:调优 innodb_buffer_pool_size(42G–50G)、tmp_table_size/max_heap_table_size(256M–1G)、max_connections(按峰值×1.5);用 performance_schema 定位内存消费者;监控长事务、大查询、多语句及 Group Replication 等隐性开销;确保 tmpdir 独立且容器内存限制充足。

mysql 如何分析内存占用过高_mysql 内存异常排查

查关键配置参数

内存占用 高,往往从配置开始。重点关注几个核心参数:

  • innodb_buffer_pool_size:InnoDB 缓冲池大小,通常应设为物理内存的 60%–80%。比如 62G 内存服务器,设 12G 就明显偏低(易引发频繁刷盘),设 64G 又可能超限(有 OOM 风险);合理值应在 42G–50G 之间。
  • tmp_table_sizemax_heap_table_size:两者需保持一致,控制内存临时表上限。16M 太小,复杂 JOIN 或 GROUP BY 易溢出到磁盘,反而拖慢并增加 I / O 压力;建议调至 256M–1G(视单次查询数据量而定)。
  • max_connections:若设为 5000 但实际活跃连接仅 20 个,每个连接仍会预分配 sort_buffer、join_buffer 等,造成隐性浪费。建议按峰值连接数×1.5 预留,再结合线程池使用。

看实时内存分布

别只信 top 里的mysql d 进程 RSS 值——那是总驻留内存,要拆开看谁在“吃”:

  • 运行:SELECT event_name, sys.format_bytes(CURRENT_NUMBER_OF_BYTES_USED) FROM performance_schema.memory_summary_global_by_event_name ORDER BY CURRENT_NUMBER_OF_BYTES_USED DESC LIMIT 10; ——快速定位前 10 大内存消费者,如 memory/innodb/buf_buf_pool 占 13GB 属正常,但 memory/sql/Query_cachememory/temptable/physical_ram异常飙升就要警惕。
  • 查用户级消耗:SELECT user, host, SUM(current_number_of_bytes_used)/1024/1024 AS MB FROM performance_schema.memory_summary_by_account_by_event_name GROUP BY user, host ORDER BY MB DESC LIMIT 5; ——发现某业务账号持续占 65MB 以上,大概率存在未关闭游标、长事务或低效批量操作。
  • 确认全局用量:SELECT SUM(CAST(REPLACE(current_alloc,’MiB’,”) AS DECIMAL(10,2))) FROM sys.memory_global_by_current_bytes WHERE current_alloc LIKE ‘%MiB%’; ——若结果远低于 top 显示值(如仅 2GB vs top 报 56GB),说明大量内存由非 PFS 追踪路径分配(如 JIT 解析、复制缓存、jemalloc 内部碎片等)。

盯连接与 SQL 行为

很多内存暴涨不是配置问题,而是运行时行为触发:

  • 执行 SHOW FULL PROCESSLIST;,过滤StateSending dataCopying to tmp table或长时间 Locked 的线程,这类 SQL 常伴随大排序、大分组、全表 JOIN,极易耗尽 tmp_table_size 限制并转入磁盘临时表,同时拉高内存峰值。
  • 注意 Command 列为 QueryTime超过 60 秒的连接,可能是未提交事务持有 undo 页、锁等待堆积,导致 buffer pool 中脏页无法及时刷出、历史版本链持续膨胀。
  • 警惕客户端一次性发送多语句(multiple statements)或超长 bulk insert(如单条 INSERT 含上万 VALUES)。这类操作在 SQL 解析、语法树构建阶段就会预分配大量内存,且释放滞后。

排查特殊组件与外部影响

有些内存占用藏得深,不在常规 SQL 路径里:

  • Group Replication / XtraDB Cluster:如 memory/group_rpl/Gcs_xcom::xcom_cache 占 1GB,说明集群通信缓存积压,检查网络延迟、节点同步延迟或事务冲突率是否升高。
  • 存储过程 / 函数密集调用 :大量动态 SQL 拼接、嵌套循环、未释放的游标,会在每个会话的thd::main_mem_root 中累积分配,重启连接才能清理。
  • 临时目录位置 :默认 /tmp 可能空间小或被其他进程挤占,导致磁盘临时表写入失败,MySQL 被迫重试或扩大内存缓冲——务必用tmpdir = /data/mysql/tmp 指向独立大容量分区。
  • 容器或 cgroup 限制 :Docker 中若设置了--memory=4g 但 MySQL 配置了 12G buffer pool,系统会 OOM kill mysqld;需确保容器内存 limit ≥ MySQL 最大理论内存(buffer_pool + max_connections × per_thread_buffers)。
星耀云
版权声明:本站原创文章,由 星耀云 2026-01-03发表,共计2146字。
转载说明:转载本网站任何内容,请按照转载方式正确书写本站原文地址。本站提供的一切软件、教程和内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。
text=ZqhQzanResources