云数据库 MySQL
  • 产品发布记录
  • 新手引导
  • 产品简介

  • 购买指南

  • 操作指南

  • 最佳实践

  • 性能白皮书
  • 故障处理

    • 连接相关

    • 性能相关

      • CPU利用率过高
      • 内存使用率过高
        • 问题描述
        • 常见原因
          • 共享内存
          • Session 私有内存
      • IOPS使用率过高
    • MySQL修改密码策略
  • API文档

  • 常见问题

  • 服务条款
  • 词汇表
  • 联系我们
  • MySQL
  • 故障处理
  • 性能相关
云数据库 MySQL

云数据库 RDS MySQL 是首云基于高性能 SSD 存储、高性能云主机和开源数据库 MySQL 打造的一款稳定可靠、可弹性伸缩的关系型数据库。提供了容灾、备份恢复、账户权限、监控告警等一系列等功能。方便您轻松自由地管理数据库。

  • 产品简介
    • 产品概述

    • 产品优势

    • 应用场景

    • 数据库架构

    • 功能差异列表

    • 产品实例

    • 区域与虚拟数据中心

  • 购买指南
    • 计费概述

    • 购买方式

    • 欠费说明

    • 退费说明

    • 调整实例费用说明

    • 备份空间收费说明

  • 操作指南
    • 使用限制

    • 操作总览

    • 管理实例

    • 只读实例

    • 账号管理

    • 数据库管理

    • 参数配置

    • 备份恢复

    • 监控报警

    • 标签管理

    • 慢日志下载

  • 最佳实践
    • 云数据库MySQL使用规范

    • 配置自动重连

    • MyISAM转换InnoDB引擎限制

    • 在线修改大表结构

    • 使用物理备份恢复至自建数据库

    • 使用逻辑备份恢复至自建数据库

  • 故障处理
    • 连接相关

    • 性能相关

    • MySQL修改密码策略

  • API文档
    • 认证方式

    • API概览

    • 实例相关接口

    • 账号相关接口

    • 备份相关接口

    • 只读实例相关接口

    • 监控相关接口

    • 参数相关接口

    • 错误码

  • 常见问题
    • 计费相关

    • 数据库备份相关

    • 数据库恢复相关

    • 连接登录

    • 参数修改

    • 账号权限

    • 性能内存

    • 功能特性

    • 控制台相关

内存使用率过高

最后更新时间:2021-12-03 生成PDF文件 | 前往GitHub编辑

# 问题描述

RDS的内存是重要的性能参数,常常出现由于异常的 SQL 请求以及待优化的数据库导致内存利用率升高的情况,严重时还会出现由于 OOM 导致实例发生 HA 切换的情况。

# 常见原因

MySQL 的内存大体可以分为共享内存和 session 私有内存两部分,下面将详细介绍各部分的构成。

# 共享内存

执行如下命令,即可查询示例的共享内存分配情况:

show variables where variable_name in ( 'innodb_buffer_pool_size','innodb_log_buffer_size','innodb_additional_mem_pool_size','key_buffer_size'
,'query_cache_size' );
1
2

如下是内存规格为 4C8G 的 RDS MySQL (版本5.7) 实例的共享内存分配情况的查询结果:

+-------------------------+------------+
| Variable_name           | Value      |
+-------------------------+------------+
| innodb_buffer_pool_size | 4294967296 |
| innodb_log_buffer_size  | 33554432   |
| key_buffer_size         | 8388608    |
| query_cache_size        | 1048576    |
+-------------------------+------------+
1
2
3
4
5
6
7
8

参数说明:

  • innodb_buffer_pool_size

    该部分缓存是 Innodb 引擎重要的缓存区域,是通过内存来弥补物理数据文件的重要手段,在 MySQL 上会采用实例规格配置的 75% 作为该部分大小。其中主要包含数据页、索引页、undo 页、insert buffer、自适应哈希索引、锁信息以及数据字典等信息。在进行 SQL 读和写的操作时,首先并不是对物理数据文件操作,而是先对 buffer_pool 进行操作,然后再通过 checkpoint 等机制写回数据文件。该空间的优点是可以提升数据库的性能、加快 SQL 运行速度,缺点是故障恢复速度较慢。

  • innodb_log_buffer_size

    该部分主要存放 redo log 的信息,在 RDS 上会设置 32 M 的大小。InnoDB 会首先将 redo log 写在这里,然后按照一定频率将其刷新回重做日志文件中。该空间不需要太大,因为一般情况下该部分缓存会以较快频率刷新至 redo log(Master Thread 会每秒刷新、事务提交时会刷新、其空间少于 1/2 时同样会刷新)。

  • key_buffer_size

    该部分是 MyISAM 表的重要缓存区域,所有实例统一为 8 M。该部分主要存放 MyISAM 表的键。MyISAM 表不同于 InnoDB 表,其缓存的索引缓存是放在 key_buffer 中的,而数据缓存则存储于操作系统的内存中。RDS 的系统是 MyISAM 引擎的,因此在 RDS 中是给予该部分一定量的空间的。

  • query_cache_size

    该部分是对查询结果做缓存以减少解析 SQL 和执行 SQL 的花销,在 MySQL 上关闭了该部分的缓存。主要适合于读多写少的应用场景,因为它是按照 SQL 语句的 hash 值进行缓存的,当表数据发生变化后即失效。

# Session 私有内存

共享内存中介绍的内存空间是实例创建时即分配的内存空间,并且是所有连接共享的。而出现 OOM 异常的实例都是由于下面各个连接私有的内存造成的。

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

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' );
1

查询结果如下(如下为 MySQL5.7 测试实例配置):

+----------------------+----------+
| Variable_name        | Value    |
+----------------------+----------+
| binlog_cache_size    | 32768    |
| join_buffer_size     | 262144   |
| read_buffer_size     | 131072   |
| read_rnd_buffer_size | 262144   |
| sort_buffer_size     | 262144   |
| tmp_table_size       | 16777216 |
+----------------------+----------+
共返回 6 记录,花费(0.23 sec)
1
2
3
4
5
6
7
8
9
10
11

参数说明:

  • read_buffer_size&read_rnd_buffer_size

    分别存放了对顺序和随机扫描(例如按照排序的顺序访问)的缓存,MySQL 给每个 session 设置 384 K 的大小。当 thread 进行顺序或随机扫描数据时会首先扫描该 buffer 空间以避免更多的物理读。

  • sort_buffer_size

    需要执行 order by 和 group by 的 SQL 都会分配 sort_buffer,用于存储排序的中间结果,在 MySQL 上设置 256K。在排序过程中,若存储量大于 sort_buffer_size,则会在磁盘生成临时表以完成操作。在 Linux 系统中,当分配空间大于 2 M 时会使用 mmap() 而不是 malloc() 来进行内存分配,导致效率降低。

    [Err] 1114 - The table '/data/mysql/data3081/tmp/#sql_6197_2' is full
    
    1
  • join_buffer_size

    MySQL 仅支持 nest loop 的 join 算法,MySQL 设置 256 K 的大小。处理逻辑是驱动表的一行和非驱动表联合查找,这时就可以将非驱动表放入 join_buffer,不需要访问拥有并发保护机制的 buffer_pool。

  • binlog_cache_size

    该区域用来缓存该 thread 的 binlog 日志,MySQL 设置 32 K 的大小。在一个事务还没有 commit 之前会先将其日志存储于 binlog_cache 中,等到事务 commit 后会将其 binlog 刷回磁盘上的 binlog 文件以持久化。

  • tmp_table_size

    不同于上面各个 session 层次的 buffer,这个参数可以在控制台上修改。该参数是指用户内存临时表的大小,如果该 thread 创建的临时表超过它设置的大小会把临时表转换为磁盘上的一张 MyISAM 临时表。如果用户在执行事务时遇到类似如下这样的错误,可以考虑增大 tmp_table 的值。

    [Err] 1114 - The table '/data/mysql/data3081/tmp/#sql_6197_2' is full
    
    1
CPU利用率过高
IOPS使用率过高

← CPU利用率过高 IOPS使用率过高→

最近更新
01
产品发布记录
10-18
02
查询云数据库MySQL实例列表
10-18
03
计费概述
07-26
更多文章>

版权所有 ©2005 - 2024 Capitalonline Data Service Co., Ltd 备案序号:京ICP备06033943号 京公网安备:11010502020343号

北京首都在线科技股份有限公司(总部) 经营许可证:B1.B2-20140358 上海红之盟网络科技有限公司(首都在线全资子公司) 经营许可证:B1-20194861