更新时间:2026-07-17 GMT+08:00
分享

RDS for MySQL内存过载定位及处理建议

场景介绍

内存过载主要体现以下两个场景:

  • 场景一:内存持续缓慢上涨导致OOM。
  • 场景二:短时间内存飙升导致OOM。

可能原因

场景一(内存持续缓慢上涨导致OOM)主要包含以下原因:

  • 内存参数设置较大,导致全局或每个连接占用的session级别内存较高,且随着执行的SQL变化。

    执行如下命令,即可查询全局内存分配情况:

    ```plaintext
    show variables where variable_name in (
    'innodb_buffer_pool_size','query_cache_size'
    );
    
    ```

    执行如下命令,查询示例的Session私有内存分配情况:

    ```plaintext
    show variables where variable_name in (
    'read_buffer_size','read_rnd_buffer_size','sort_buffer_size','join_buffer_size','binlog_cache_size','tmp_table_size'
    );
    ```

    可以适当调整参数使内存稳定在合理范围(75%~90%且稳定无较大波动)。

  • 客户端连接空闲超时参数设置过大,导致出现长连接无法释放。

    首先检查客户端连接空闲超时断开的参数,比如德鲁伊连接池的**`minEvictableIdleTimeMillis`**和**`maxEvictableIdleTimeMillis`**参数,比如客户端空闲超时时间为60s,但是其连接每秒都会请求sql,不存在空闲时间,则此连接会作为长连接一直存在不释放。

    长连接在使用过程中,由于无法保证自身访问的数据量会不会出现变化、自身接收到的SQL文本长度会不会发生变化,有极大可能造成连接的私有内存块net buffer被撑大,且此内存的分配策略为复用不主动回收且随连接释放而释放,最终导致每个长连接占用大块的net buffer内存(最大1G)导致OOM。

  • 实例中存在较多的大文本存储过程,导致连接执行存储过程后内存缓慢上升不释放。

    存储过程在首次被创建时会进行语法分析和编译,生成执行计划并存储在数据库中,如果连接执行了较大文本的存储过程,被编译好的存储过程会存储在连接的sp_head:mem_root内存块中,且由于其预编译属性,此内存块会在连接释放时才进行释放,如果持续调用不同的存储过程且不释放,数据库内存会呈现上升趋势。

场景二(短时间内存飙升导致OOM)主要包含以下原因:

  • SQL文本过大导致net buffer内存占用过大以及词法分析阶段占用内存过大。

    RDS for MySQL在处理SQL文本的词法解析以及语法解析时,会将整个SQL的关键字,以及数据信息存储到对应的内存数据结构中,当SQL文本过大时,会占用大量内存导致内存极速上升引发OOM。

    常见大SQL主要分为以下几类:

    • 类型一: In方式的查询条件中包含大量的查询值导致SQL文本过大。

      SQL举例:

      select column from table where column2 in (a1,a2,a3,a4,a5,a6…aN);
    • 类型二:单条insert插入行数过多导致SQL文本过大。

      SQL举例:

      insert into large_data_table values(1,’张三’),(2,’李四’),...(500000,’xxx’)
    • 类型三:单条insert涉及文本较长字段,例如:longtext、text、blob、json类型字段。

      SQL举例:

      insert into large_text_table values(1,’xxxx...’),(2,’xxx...’);
  • SQL结果集存在超大单行记录导致瞬时消耗大量内存。

    RDS for MySQL在返回结果时,会按照net_buffer_size缓存大小来分批读取结果并发送结果,但缓存的最小单元为单行,如果存在单行结果很大,比如单行记录存在longtext、text、blob、json字段,会导致内存极速上升引发OOM。

    SQL举例:

    select * from large_text_table limit 1;

    被查询表结构中存在大字段longtext,并且存储了1GB数据,单条SQL占用内存大小。

对业务的影响

OOM会导致数据库宕机,通常会导致1分钟以内的连接中断。

处理建议

  • 出现过载异常前的建议:
    • 排查客户端驱动以及连接池的空闲超时断开参数是否合理。
    • 排查业务中的长文本SQL,长文本SQL通常为代码生成,建议设置SQL文本长度的最大值来做拦截。
    • 尽量使用业务逻辑代理存储过程。
  • 过载异常中的建议:

    针对内存缓慢上升的场景,建议杀掉长连接会话,释放部分内存。详见管理实时会话

相关文档