为什么我的 Amazon RDS for MySQL 数据库实例使用的存储超出预期?

2 分钟阅读
0

我的 Amazon Relational Database Service (Amazon RDS) for MySQL DB 数据库实例使用的空间超出预期。为什么会发生这种情况,我该如何优化磁盘存储?

解决方法

您可以使用 FreeStorageSpace Amazon CloudWatch 指标来监控RDS 数据库实例的可用存储空间。但是 FreeStorageSpace 未描述数据库实例是如何消耗存储空间的。

可使用以下策略回收存储空间:

运行 OPTIMIZE TABLE

表会消耗一些未被使用的空间,但是 Amazon RDS 还是会将这些空间分配给表。如果 innodb_file_per_table 已开启(默认情况下处于开启状态),那么您可以使用 OPTIMIZE TABLE 回收该空间。OPTIMIZE TABLE 适用于 InnoDB、MyISAM 和 ARCHIVE 表。虽然 Amazon RDS 接受 OPTIMIZE TABLE 命令,但其实际运行 ALTER TABLE...FORCE 命令。发生这种情况时,您会收到类似于以下内容的警告消息:“表不支持优化,而是执行重新创建 + 分析。” 有关更多信息,请参阅 MySQL 文档中的 OPTIMIZE TABLE

要检查是否有碎片,请运行如下查询:

SELECT
 table_name,
 data_length,
 max_data_length,
 index_length,
 data_free
FROM
 information_schema.tables 
WHERE table_schema='schema_name'
;

data_free 列突出显示分配给表且未主动使用的空闲空间量。您可以使用 OPTIMIZE TABLE 来回收这个空间。 根据 Amazon RDS 默认的 innodb_file_per_table 配置设置,如果在单独的表空间中创建表,则 OPTIMIZE TABLE 有效。有关更多信息,请参阅 MySQL 文档中的File-per-table tablespaces

减少应用程序表存储

要查看数据库实例上的应用程序表使用了多少存储空间,请运行如下查询:

SELECT 
 table_schema,
 SUM(data_length + index_length + data_free)/1024/1024 AS total_mb,
 SUM(data_length)/1024/1024 AS data_mb,
 SUM(index_length)/1024/1024 AS index_mb,
 SUM(data_free)/1024/1024 AS free_mb,
 COUNT(*) AS tables,
 CURDATE() AS today 
FROM 
 information_schema.tables
 GROUP BY table_schema
 ORDER BY 2 DESC
;

要找到数据库实例上的最大应用程序表,请运行如下查询:

SELECT 
 table_schema,
 table_name,
 (data_length + index_length + data_free)/1024/1024 AS total_mb,
 (data_length)/1024/1024 AS data_mb,
 (index_length)/1024/1024 AS index_mb,
 (data_free)/1024/1024 AS free_mb,
 CURDATE() AS today
FROM 
 information_schema.tables
 ORDER BY 3 DESC
;

**注意:**如果数据库包含的表具有长度可变的列,并且列长度超过了 768 字节,则无法计算单独数据库和表使用的存储总量。例如,这包括 BLOB、TEXT、VARCHAR 或 VARBINARY。

减少二进制日志存储

添加只读副本会导致源实例的二进制日志使用额外的存储。如需查明源实例上的二进制日志使用了多少存储,请检查 BinLogDiskUsage CloudWatch 指标。如果出现大量增长,则可能表明一个或多个只读副本未同步。

减少或关闭一般日志及慢速查询日志存储

当您关闭常规日志和慢速查询日志参数时,您的实例开始存储这些日志。它还存储这些日志的备份。如需轮换这些文件并控制磁盘用量,请参阅 mysql.rds_rotate_general_logmysql.rds_rotate_slow_log

**注意:**当您不主动使用一般查询日志和慢速查询日志进行故障排除时,请将其关闭。

管理或减少 InnoDB 系统表空间大小

系统表空间包含 InnoDB 数据字典和撤消空间,其大小从 10 MB 起。分配了空间之后,文件始终最少保持此大小,不过长时间运行的事务会消耗更多的可用存储。

默认情况下,Amazon RDS 将 innodb_file_per_table 设置为 1。这意味着每个表空间的数据都存储在其自己的 .ibd 文件中。如需回收标记为可供相关表重用的空间,请使用 OPTIMIZE TABLE 来调整各表的表空间文件大小或者删除表。

如果 innodb_file_per_table 设置为 0,则所有表空间也将分配到系统表空间。删除表或索引,或者删除或截断系统表空间中所分配表的数据,可以将之前占据的空间标记为可重用。但是,innodb_file_per_table 不会为文件系统释放任何空间。

由于无法就地缩小系统表空间,因此请导出当前数据库的数据。然后将数据导入新实例。为减少停机时间,请将新的 MySQL 实例配置为源 Amazon RDS 实例的副本。当副本与源 Amazon RDS 实例同步时,切换到新实例。

**注意:**从快照还原或者创建只读副本无助于从系统表空间中回收空间。这是因为这两种方法均使用包含系统表空间的源实例存储卷的快照。


相关信息

Amazon RDS 数据库实例存储空间用尽 修改 Amazon RDS 数据库实例

如何排查使用 Amazon RDS for MySQL 时出现的“MySQL HA_ERR_RECORD_FILE_FULL”错误?

相关视频

AWS 官方
AWS 官方已更新 2 年前