MySQL内存使用率高问题排查与解决方案:

目录标题

      • **一、问题现象**
      • **二、核心排查步骤**
        • **1. 参数检查**
        • **2. 内存使用分析**
        • **3. 存储过程/函数/视图检查**
        • **4. 操作系统级检查**
      • **三、解决方案**
        • **1. 调整MySQL配置**
        • **2. 关闭透明大页(THP)**
        • **3. 优化查询与存储过程**
        • **4. 硬件与环境优化**
      • **四、总结**

MySQL内存使用率高问题排查与解决方案:

一、问题现象

  • 内存占用异常 :通过top命令发现MySQL进程(mysqld)占用了90.7%的物理内存(56.5G/62G)。
  • 系统负载:CPU使用率较低(1.3%),但内存几乎耗尽。

二、核心排查步骤

1. 参数检查
  • MySQL版本:8.0.39(未开启慢查询日志)。

  • 关键内存参数

    sql 复制代码
    SHOW VARIABLES LIKE 'innodb_buffer_pool_size';  -- 12G(配置较低,建议调整为总内存的70%~80%)
    SHOW VARIABLES LIKE 'tmp_table_size';           -- 16M(临时表内存限制过小)
  • 临时文件路径/tmp(建议改为专用目录以避免性能问题)。

2. 内存使用分析
  • 全局内存统计

    sql 复制代码
    SELECT SUM(CAST(replace(current_alloc,'MiB','') AS DECIMAL(10,2))) 
    FROM sys.memory_global_by_current_bytes 
    WHERE current_alloc LIKE '%MiB%';

    结果:总内存使用约1933.69MB。

  • 分事件内存占用

    sql 复制代码
    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;

    关键发现

    • memory/innodb/buf_buf_pool占用13.29GB(InnoDB缓冲池)。
    • memory/group_rpl/Gcs_xcom::xcom_cache占用1024MB(复制相关缓存)。
  • 用户级内存统计

    sql 复制代码
    SELECT user, event_name, current_number_of_bytes_used/1024/1024 AS MB_USED
    FROM performance_schema.memory_summary_by_account_by_event_name
    WHERE host <> "localhost"
    ORDER BY MB_USED DESC LIMIT 10;

    发现 :特定用户(如zqzh)在memory/temptable/physical_ram中占用65MB。

3. 存储过程/函数/视图检查
  • 存储过程与函数

    sql 复制代码
    SELECT Routine_schema, Routine_type 
    FROM information_schema.Routines 
    WHERE Routine_schema NOT IN ('mysql','information_schema','performance_schema','sys');

    结果 :多个业务库存在大量存储过程和函数(如bpcbsc等)。

  • 视图与触发器

    sql 复制代码
    SELECT TABLE_SCHEMA, COUNT(TABLE_NAME) FROM information_schema.VIEWS;
    SELECT TRIGGER_SCHEMA, COUNT(*) FROM information_schema.triggers;

    结果:视图和触发器数量较少,非主要内存消耗源。

4. 操作系统级检查
  • 进程内存占用

    bash 复制代码
    ps -eo user,pid,vsz,rss | grep mysqld

    结果mysqld进程虚拟内存(VIRT)96.2G,物理内存(RES)56.5G。

  • 内存映射分析

    bash 复制代码
    pmap -d <mysql_pid> | tail -1

    关键指标

    • writeable/private:进程实际占用的私有内存(持续增长可能提示内存泄漏)。
  • 透明大页(THP)检查

    bash 复制代码
    cat /sys/kernel/mm/transparent_hugepage/enabled

    结果:THP处于开启状态(可能导致内存分配效率低下)。

三、解决方案

1. 调整MySQL配置
  • 增加InnoDB缓冲池

    ini 复制代码
    innodb_buffer_pool_size = 48G  -- 根据总内存(62G)调整为77%
  • 优化临时表内存

    ini 复制代码
    tmp_table_size = 256M
    max_heap_table_size = 256M
2. 关闭透明大页(THP)
  • 临时关闭

    bash 复制代码
    echo never > /sys/kernel/mm/transparent_hugepage/enabled
    echo never > /sys/kernel/mm/transparent_hugepage/defrag
  • 永久关闭
    /etc/rc.local中添加:

    bash 复制代码
    if test -f /sys/kernel/mm/transparent_hugepage/enabled; then
        echo never > /sys/kernel/mm/transparent_hugepage/enabled
    fi
    if test -f /sys/kernel/mm/transparent_hugepage/defrag; then
        echo never > /sys/kernel/mm/transparent_hugepage/defrag
    fi
3. 优化查询与存储过程
  • 分析慢查询:开启慢查询日志,定位低效SQL。
  • 减少存储过程依赖:将复杂逻辑移至应用层,避免存储过程内存泄漏。
4. 硬件与环境优化
  • 增加物理内存:若业务需求增长,考虑升级服务器内存。
  • 迁移临时文件目录 :将tmpdir设置为专用高速存储路径。

四、总结

  • 核心问题:MySQL内存使用率高主要由InnoDB缓冲池配置不足、THP机制效率低下及存储过程/函数内存占用引起。
  • 解决重点:调整缓冲池大小、关闭THP、优化查询逻辑。
  • 后续监控 :通过sys.memory_global_by_current_bytespmap持续观察内存变化。

通过以上步骤,可显著降低MySQL内存占用并提升稳定性。

相关推荐
欧先生^_^25 分钟前
Linux内核可配置的参数
linux·服务器·数据库
问道飞鱼26 分钟前
【数据库知识】Mysql进阶-高可用MHA(Master High Availability)方案
数据库·mysql·adb·高可用·mha
tiging27 分钟前
centos7.x下,使用宝塔进行主从复制的原理和实践
数据库·mysql·adb·主从复制
wangcheng86991 小时前
Oracle常用函数-日期时间类型
数据库·sql·oracle
zizisuo1 小时前
面试篇:Spring Security
网络·数据库·安全
一只fish1 小时前
MySQL 8.0 OCP 1Z0-908 题目解析(2)
数据库·mysql
StarRocks_labs1 小时前
从InfluxDB到StarRocks:Grab实现Spark监控平台10倍性能提升
大数据·数据库·starrocks·分布式·spark·iris·物化视图
搞不懂语言的程序员2 小时前
Redis的Pipeline和Lua脚本适用场景是什么?使用时需要注意什么?
数据库·redis·lua
王RuaRua2 小时前
[数据结构]5. 栈-Stack
linux·数据结构·数据库·链表
Lw老王要学习3 小时前
Linux数据库篇、第一章_02_MySQL的使用增删改查
linux·运维·数据库·mysql·云计算·it