为什么我的“使用的字节数”在我的Amazon Aurora群集上总是增加?


11

我有一个Amazon(AWS)Aurora数据库集群,而且每天都[Billed] Volume Bytes Used在增加。

随时间推移使用的CloudWatch的VolumeBytes指标

我已经使用表格检查了所有表格(在该群集中所有数据库中)的大小INFORMATION_SCHEMA.TABLES

SELECT ROUND(SUM(data_length)/1024/1024/1024) AS data_in_gb, ROUND(SUM(index_length)/1024/1024/1024) AS index_in_gb, ROUND(SUM(data_free)/1024/1024/1024) AS free_in_gb FROM INFORMATION_SCHEMA.TABLES;
+------------+-------------+------------+
| data_in_gb | index_in_gb | free_in_gb |
+------------+-------------+------------+
| 30         | 4           | 19         |
+------------+-------------+------------+

总计:53GB

那么,为什么此时我要向我收取近75GB的费用呢?

我了解到,永远无法释放已调配的空间,就像普通MySQL服务器上的ibdata文件永远不会缩小一样。我可以。这是有记录的,可以接受。

我的问题是,每天结算的空间会增加。而且我确定我不会暂时使用75GB的空间。如果我要做这样的事情,我会明白的。就像我通过删除表中的行,删除表,甚至删除数据库释放的存储空间从未被重复使用。

我已经多次联系过AWS(高级)支持,但始终无法很好地解释为什么。
我已经收到建议OPTIMIZE TABLE在有很多表free_space(每个INFORMATION_SCHEMA.TABLES表)的表上运行,或者检查InnoDB历史记录的长度,以确保删除的数据仍不保留在回滚段中(参考:MVCC) ,然后重新启动实例以确保回滚段为空。
这些都没有帮助。

Answers:


19

这里有很多事情在起作用...

  1. 每个表都存储在自己的表空间中

    默认情况下,Aurora群集的参数组(名为default.aurora5.6)定义了innodb_file_per_table = ON。这意味着每个表都存储在Aurora存储群集上的单独文件中。您可以使用此查询查看每个表使用哪个表空间:

    SELECT name, space FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES;

    注意:我尚未尝试更改innodb_file_per_tableOFF。也许会有所帮助..?

  2. 通过删除表空间释放的存储空间不会重新使用

    报价AWS高级支持:

    由于Aurora存储引擎的独特设计可以提高其性能和容错能力,因此Aurora没有与标准MySQL相同的功能来对每个表的文件空间进行碎片整理。

    不幸的是,当前Aurora没有像标准MySQL那样缩小表空间的方法,并且所有分段空间都需要收费,因为它包含在VolumeBytesUsed中。
    Aurora无法以与标准MySQL相同的方式回收已删除表的空间的原因是,表的数据以与具有单个存储卷的标准MySQL数据库完全不同的方式存储。

    如果将表或行放在Aurora中,则由于这种复杂的设计,空间不会再在Auroras群集卷上回收。
    这种无法回收少量存储空间的做法是为了获得Auroras群集存储量的额外性能提升以及Aurora的极大容错能力而做出的牺牲。

    但是有一些晦涩的方法可以重复利用其中一些浪费的空间...
    再次引用AWS高级支持:

    一旦您的总数据集超过一定大小(大约160 GB),您就可以开始以160 GB的块回收空间以供重复使用,例如,如果您的Aurora群集卷中有400 GB且DROP 160 GB或更多表,那么Aurora可以自动重用160 GB的数据。但是,回收此空间可能很慢。
    需要一次释放大量数据的原因是由于Auroras作为企业级数据库引擎的独特设计,与无法在此规模上使用的标准MySQL不同。

  3. 优化表是邪恶的!

    由于Aurora基于MySQL 5.6,因此OPTIMIZE TABLE被映射到ALTER TABLE ... FORCE,从而重建表以更新索引统计信息并释放聚集索引中的未使用空间。实际上,与一起innodb_file_per_table = ON意味着运行OPTIMIZE TABLE会创建一个新的表空间文件,并删除旧的表空间文件。由于删除表空间文件不会释放它正在使用的存储空间,因此这OPTIMIZE TABLE将始终导致配置更多的存储空间。哎哟!

    参考:https : //dev.mysql.com/doc/refman/5.6/en/optimize-table.html#optimize-table-innodb-details

  4. 使用临时表

    默认情况下,Aurora实例的参数组(名为default.aurora5.6)定义了default_tmp_storage_engine = InnoDB。这意味着每次创建TEMPORARY表时,它都会与所有常规表一起存储在Aurora存储集群中。这意味着将提供新的空间来容纳这些表,从而增加已使用的总VolumeBytes。
    解决方案非常简单:将default_tmp_storage_engine参数值更改为MyISAM。这将强制Aurora TEMPORARY在实例的本地存储上创建表。
    注意:实例的本地存储空间有限;请参阅Free Local StorageCloudWatch上的指标以查看您的实例有多少存储。较大(成本较高)的实例具有更多的本地存储。

    参考:还没有;当前的Amazon Aurora文档没有提及这一点。我要求AWS支持团队更新文档,如果有的话,将更新我的答案。


1
这是一个伟大的答案,yowch,这些都是一些主要的注意事项。很高兴我看到了这一点。
ceejayoz

同上。注意,对于一个MySQL报告的大小为54 GB的数据库,一台数据库服务器的最大容量为300 GB。例如日志表,索引表等)。
geerlingguy

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.