RDS MySQL空间不足问题

RDS MySQL实例的空间使用率是日常需要重点关注的监控项之一,如果实例的存储空间不足,会导致严重后果,例如数据库无法写入、数据库无法备份、存储空间扩容任务耗时过长等。本文介绍查看空间使用情况的方式,以及各种空间问题的原因和解决方案。

查看空间使用情况

RDS MySQL实例存储空间包含用户数据库数据、系统数据库数据、各类日志和临时表文件等,您可以通过RDS标准监控查看存储空间使用情况。

  1. 登录RDS控制台,单击实例ID进入实例详情页。

  2. 监控与报警功能中选择标准监控,通过MySQL存储空间使用量视图查看实例存储空间使用情况。

  3. 您可以单击视图标题旁的image标志,查看视图内各参数含义。详情请参见查看监控信息

image

解决方案概述

实例存储空间不足的直接原因是实例内各类文件的堆积。您需要在查看实例存储空间情况时,重点关注以下文件的空间使用量,根据不同的文件类型选择不同的解决方案。

文件名称

标准监控中对应参数名

空间分析中对应参数名

解决方案

临时文件

temp_file_size

临时文件数据量

临时文件堆积导致空间不足

Binlog文件

binlog_size

binlog使用量

Binlog(本地日志)文件堆积导致空间不足

undo log文件

undolog_size

undo log使用量

系统文件堆积导致空间不足

general log文件

general_log_size

常规日志使用量

常规日志文件堆积导致空间不足

用户数据文件

user_data_size

用户数据库使用量

用户数据文件堆积导致空间不足

除上述文件之外,您还需关注实例的空间碎片与数据库索引:

重要

紧急情况下,建议您优先手动扩容磁盘,尽快解锁实例,业务访问恢复后再根据文件堆积情况清理存储空间。一般情况下,实例会在磁盘扩容后五分钟左右解锁。

临时文件堆积导致空间不足

MySQL实例可能会由于查询语句的排序、分组、关联表产生的临时表文件,或者大事务未提交前产生的binlog cache文件,导致实例磁盘空间满。为避免数据丢失,RDS会将实例锁定,在锁定之后,将无法进行写入操作。

解决方案:详情请参见RDS MySQL临时文件堆积解决办法

  • MySQL 5.7及以下实例:建议您重启实例,系统会自动删除临时文件。

  • MySQL 8.0实例:实例锁定时会结束所有用户会话并开始自动回滚,系统会在回滚结束后自动释放临时文件。

  • 如果实例长时间未自动解锁,您需要通过show processlist命令查看所有会话状态,找到状态为Copy to tmp tableSending data等的会话,并使用kill命令手动结束。

Binlog(本地日志)文件堆积导致空间不足

MySQL实例可能会由于大事务快速生成Binlog文件,导致实例空间满,为避免数据丢失,会对实例进行自动锁定,磁盘锁定之后,将无法进行写入操作。

解决方案:详情请参见MySQL Binlog文件堆积解决办法

  • 一键上传Binlog:您可以使用RDS的一键上传Binlog功能,将RDS实例存储空间中的Binlog文件上传至OSS中保存,上传完成后RDS将自动删除已上传的Binlog文件。

  • 修改本地日志保留策略:您可以在RDS控制台备份恢复 > 备份设置 > 本地日志保留策略中修改本地日志的保留时长、最大存储空间占有率、可用存储空间等参数。实例中本地日志存储量达到设定阈值后,系统将按时间顺序从最早的本地日志开始删除,直到本地日志存储量低于阈值。

空间碎片堆积导致空间不足

InnoDB是按页(Page)管理表空间的。当使用deleteupdate语句删除或更新数据时,该命令只会将记录的位置或数据页标记为“可复用”,而磁盘文件的大小并不会改变,即表空间不会直接回收。当原空间无法复用时,会形成实例空间碎片,占用实例存储空间。

解决方案:详情请参见MySQL空间碎片堆积解决办法

  • 通过命令行整理空间碎片:您可以使用optimize table命令整理表空间碎片。

  • 通过DMS优化数据表:您可以登录RDS MySQL实例,在DMS控制台中右键单击任意表名并选择批量操作表,勾选需要空间碎片整理的表名,并选择表维护 > 优化表

  • 开启空间碎片自动回收:您可以在RDS控制台的自治服务 > 一键诊断 > 自治中心中单击自治功能开关,开启自治功能后,可以在优化和限流页签中开启空间碎片自动回收功能,详情请参见空间碎片自动回收

系统文件堆积导致空间不足

系统文件过大主要是由于undo文件过大。当存在对InnoDB表长时间不结束的查询语句,而且在查询过程中表有大量的数据变化时,系统会生成大量的undo信息,占用大量存储空间,导致存储空间耗尽。为避免数据丢失,RDS会自动锁定实例,实例运行状态显示为锁定中

解决方案:详情请参见MySQL系统文件堆积解决办法

  • MySQL 8.0:系统会自动清理undo文件。

  • MySQL 5.7

    • 实例innodb_undo_tablespaces参数取值为2时,表示实例允许使用独立的undo表空间存储undo数据,可以进行清理。当undo文件大小超过innodb_max_undo_log_size参数值且其中的日志不再被任何活动的事务所需要时,系统会对undo文件进行truncate操作,清理过大的文件并释放空间。

    • 实例innodb_undo_tablespaces参数取值为0时,表示不使用独立的undo表空间,undo文件存储在系统表空间ibdata1中,不可以进行清理。您可以新建实例并迁移数据或将数据库版本升级至MySQL 8.0,详情请参见升级数据库版本

  • MySQL 5.5、MySQL 5.6:不支持清理undo文件,建议将实例升级为MySQL 5.7版本的高可用系列实例或MySQL 8.0实例。

    说明

    MySQL 5.7高可用系列实例的innodb_undo_tablespaces参数取值为2,允许使用独立的undo表空间存储undo数据,可以清理undo文件。

常规日志文件堆积导致空间不足

当RDS MySQL开启了general log后,该文件记录了用户的所有操作,包括每条SQL语句的执行细节,无论是查询、插入、更新还是删除操作。当访问量大或者长时间不清理general log文件时,会占用大量的存储空间,导致存储空间耗尽。

解决方案:详情请参见MySQL general log文件堆积解决办法

  • 关闭常规日志采集:关闭general log(运行参数值设为OFF),以防止产生新的日志。详情请参见设置实例参数

  • 删除常规日志文件:您可以登录RDS实例并执行TRUNCATE TABLE mysql.general_log;命令删除常规日志。

  • 建议只在调试或跟踪问题时临时开启general log,使用完成之后请及时关闭general log。

用户数据文件堆积导致空间不足

用户数据文件长时间未整理或在表结构中使用blobtext和较长的varchar字段会占用大量的实例存储空间进而导致存储空间满的问题。为避免数据丢失,RDS MySQL会对实例进行自动锁定,锁定之后将无法进行写入操作。

解决方案:详情请参见RDS MySQL数据文件堆积解决办法

  • 删除无用数据:使用droptruncate命令清理无用数据。

  • 压缩数据:对于一些大字段数据,您可以先进行数据压缩,再传入数据库存储,减少存储空间使用量。

索引文件堆积导致空间不足

数据库索引会以文件形式存储在磁盘中,当您使用了不合理的索引策略或创建了大量的二级索引,会导致索引文件过大或堆积,造成实例存储空间不足。

解决方案

  • 选择合适的字段创建索引:除主键索引外,建议您选择在被频繁查询、需要排序或经常用于表间连接的字段上创建索引。同时,建议您考虑创建联合索引而非单列索引,节约磁盘空间。

  • 删除无用索引:对于长时间不使用的索引或无用索引,可以考虑删除以节约磁盘空间。同时,也建议您优化数据结构,减少二级索引数量。