为什么我的“使用的卷字节”在我的Amazon Aurora群集上始终在增加?

我有一个亚马逊(AWS)Aurora数据库集群,并且每天使用的[Billed] Volume Bytes Used都在增加。

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

我已经使用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?

我知道预configuration的空间永远不能被释放,就像常规MySQL服务器上的ibdata文件永远不会缩小一样。 我很确定。 这是有logging的,可以接受的。

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

我多次联系了AWS(高级)支持,并且始终无法得到一个很好的解释。
我收到了一些build议,在有很多free_space (每INFORMATION_SCHEMA.TABLES表)的表上运行OPTIMIZE TABLE ,或者检查InnoDB的历史长度,以确保删除的数据不会保留在回滚中段(ref: MVCC ),并重新启动实例以确保回滚段被清空。
没有一个帮助。

有很多事情在这里玩…

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

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

    SELECT name, space FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES;

    注意:我没有尝试将innodb_file_per_table更改为OFF 。 也许这会帮助..?

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

    引用AWS高级支持:

    由于Aurora存储引擎的独特devise,以提高其性能和容错能力,Aurora没有像标准MySQL一样对每个表文件进行碎片整理的function。

    目前Aurora不幸的是没有办法像标准的MySQL那样缩小表空间,而且所有的碎片空间都被收费,因为它包含在VolumeBytesUsed中。
    Aurora无法以与标准MySQL相同的方式回收掉表的空间的原因是,表的数据以完全不同的方式存储在具有单个存储卷的标准MySQL数据库中。

    如果在Aurora中删除表或行,则由于这种复杂的devise,则不会在Aurora群集卷上回收该空间。
    这种无法回收less量存储空间是为了获得Aurora集群存储卷的额外性能收益以及极大地改善了Aurora的容错性而做出的牺牲。

    但是,有一些晦涩的方式来重新使用一些浪费的空间…
    再次引用AWS高级支持:

    一旦您的总数据集超过了一定的大小(大约160 GB),您就可以开始回收160 GB块中的空间以供重复使用,例如,如果您的Aurora群集卷中有400 GB的空间,则可以使用Aurora可以删除的160 GB或更多的表自动重新使用160 GB的数据。 但是回收这个空间可能会很慢。
    需要一次性释放大量数据的原因是由于Aurora独特的devise作为企业规模的数据库引擎,不像标准的MySQL那样不能在这个规模上使用。

  3. 优化表是邪恶的!

    由于Aurora基于MySQL 5.6,因此OPTIMIZE TABLE被映射到ALTER TABLE ... FORCE ,它将重build表来更新索引统计信息并释放聚簇索引中未使用的空间。 有效地,与innodb_file_per_table = ON ,这意味着运行OPTIMIZE TABLE创build一个新的表空间文件,并删除旧的表空间文件。 由于删除一个表空间文件不会释放它正在使用的存储空间,这意味着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 。 这意味着每次创buildTEMPORARY表时,它都会与我所有的常规表一起存储在Aurora存储群集上。 这意味着新的空间被configuration来保存这些表,因此增加了VolumeBytesUsed的总数。
    解决scheme很简单:将default_tmp_storage_engine参数值更改为MyISAM 。 这将强制Aurora在实例本地存储上创buildTEMPORARY表。
    值得注意的是:这些实例的本地存储是有限的。 请参阅CloudWatch上的“ Free Local Storage度量标准,以查看实例具有多less存储空间。 更大(更昂贵)的实例具有更多的本地存储。

    Ref:none yet; 目前的亚马逊极光文档没有提到这一点。 我要求AWS支持团队更新文档,并会一旦更新我的答案。