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内存占用并提升稳定性。

相关推荐
wmm_会飞的@鱼5 分钟前
FlexSim-汽车零部件仓库布局优化与仿真
服务器·前端·网络·数据库·数学建模·汽车
Antonio9158 分钟前
【Redis】Redis 数据存储原理和结构
数据库·redis·缓存
看天走路吃雪糕30 分钟前
墨者:SQL手工注入漏洞测试(MySQL数据库)
数据库·mysql·sql注入·墨者靶场
看天走路吃雪糕39 分钟前
墨者:通过手工解决SQL手工注入漏洞测试(PostgreSQL数据库)
数据库·sql·postgresql·sql注入·墨者靶场
看天走路吃雪糕1 小时前
墨者:SQL注入漏洞测试(布尔盲注)
数据库·sql·sqlmap·墨者学院·布尔盲注
*愿风载尘*1 小时前
ksql连接数据库免输入密码交互
数据库·后端
追风少年浪子彦1 小时前
mybatis-plus实体类主键生成策略
java·数据库·spring·mybatis·mybatis-plus
溟洵1 小时前
Qt 窗口 工具栏QToolBar、状态栏StatusBar
开发语言·前端·数据库·c++·后端·qt
problc2 小时前
大模型API和秘钥获取地址
数据库·redis·缓存
Antonio9152 小时前
【Redis】Linux 配置Redis
linux·数据库·redis