RDS MySQL实例的空间使用率是日常需要重点关注的监控项之一,如果实例的存储空间不足,会导致严重后果,例如数据库无法写入、数据库无法备份、存储空间扩容任务耗时过长等。本文介绍查看空间使用情况的方式,以及各种空间问题的原因和解决方案。
查看空间使用情况
RDS MySQL实例存储空间包含用户数据库数据、系统数据库数据、各类日志和临时表文件等,您可以通过RDS标准监控查看存储空间使用情况。
解决方案概述
实例存储空间不足的直接原因是实例内各类文件的堆积。您需要在查看实例存储空间情况时,重点关注以下文件的空间使用量,根据不同的文件类型选择不同的解决方案。
文件名称 | 标准监控中对应参数名 | 空间分析中对应参数名 | 解决方案 |
临时文件 |
|
| |
Binlog文件 |
|
| |
undo log文件 |
|
| |
general log文件 |
|
| |
用户数据文件 |
|
|
除上述文件之外,您还需关注实例的空间碎片与数据库索引:
空间碎片堆积也会造成可用存储空间不足,详情请参见空间碎片堆积导致空间不足。
当数据库使用了不合理的索引策略时,会造成索引文件堆积,进而引发实例空间不足问题,详情请参见索引文件堆积导致空间不足。
紧急情况下,建议您优先手动扩容磁盘,尽快解锁实例,业务访问恢复后再根据文件堆积情况清理存储空间。一般情况下,实例会在磁盘扩容后五分钟左右解锁。
临时文件堆积导致空间不足
MySQL实例可能会由于查询语句的排序、分组、关联表产生的临时表文件,或者大事务未提交前产生的binlog cache文件,导致实例磁盘空间满。为避免数据丢失,RDS会将实例锁定,在锁定之后,将无法进行写入操作。
解决方案:详情请参见RDS MySQL临时文件堆积解决办法。
MySQL 5.7及以下实例:建议您重启实例,系统会自动删除临时文件。
MySQL 8.0实例:实例锁定时会结束所有用户会话并开始自动回滚,系统会在回滚结束后自动释放临时文件。
如果实例长时间未自动解锁,您需要通过
show processlist
命令查看所有会话状态,找到状态为Copy to tmp table
、Sending data
等的会话,并使用kill
命令手动结束。
Binlog(本地日志)文件堆积导致空间不足
MySQL实例可能会由于大事务快速生成Binlog文件,导致实例空间满,为避免数据丢失,会对实例进行自动锁定,磁盘锁定之后,将无法进行写入操作。
解决方案:详情请参见MySQL Binlog文件堆积解决办法。
一键上传Binlog:您可以使用RDS的一键上传Binlog功能,将RDS实例存储空间中的Binlog文件上传至OSS中保存,上传完成后RDS将自动删除已上传的Binlog文件。
修改本地日志保留策略:您可以在RDS控制台的 中修改本地日志的保留时长、最大存储空间占有率、可用存储空间等参数。实例中本地日志存储量达到设定阈值后,系统将按时间顺序从最早的本地日志开始删除,直到本地日志存储量低于阈值。
空间碎片堆积导致空间不足
InnoDB是按页(Page)管理表空间的。当使用delete
或update
语句删除或更新数据时,该命令只会将记录的位置或数据页标记为“可复用”,而磁盘文件的大小并不会改变,即表空间不会直接回收。当原空间无法复用时,会形成实例空间碎片,占用实例存储空间。
解决方案:详情请参见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。
用户数据文件堆积导致空间不足
用户数据文件长时间未整理或在表结构中使用blob
、text
和较长的varchar
字段会占用大量的实例存储空间进而导致存储空间满的问题。为避免数据丢失,RDS MySQL会对实例进行自动锁定,锁定之后将无法进行写入操作。
解决方案:详情请参见RDS MySQL数据文件堆积解决办法。
删除无用数据:使用
drop
或truncate
命令清理无用数据。压缩数据:对于一些大字段数据,您可以先进行数据压缩,再传入数据库存储,减少存储空间使用量。
索引文件堆积导致空间不足
数据库索引会以文件形式存储在磁盘中,当您使用了不合理的索引策略或创建了大量的二级索引,会导致索引文件过大或堆积,造成实例存储空间不足。
解决方案:
选择合适的字段创建索引:除主键索引外,建议您选择在被频繁查询、需要排序或经常用于表间连接的字段上创建索引。同时,建议您考虑创建联合索引而非单列索引,节约磁盘空间。
删除无用索引:对于长时间不使用的索引或无用索引,可以考虑删除以节约磁盘空间。同时,也建议您优化数据结构,减少二级索引数量。