【问题标题】:Setting TEXT values to null does not reduce disk space usage of MySQL table将 TEXT 值设置为 null 不会减少 MySQL 表的磁盘空间使用量
【发布时间】:2016-02-18 02:07:05
【问题描述】:

我正在尝试减少 MySQL 5.6.23 的 RDS 实例中表的磁盘空间使用量。这是一个包含大约 800 万行和 30 列的 InnoDB 表。其中几个列的类型为TEXT NULL DEFAULT NULL。表如此之大的原因之一是因为不是从该表中删除行,而是通过名为“已删除”的标志列将它们标记为已删除。

阅读有关存储要求的 MySQL 文档后:

http://dev.mysql.com/doc/refman/5.7/en/storage-requirements.html

似乎TEXT 字段所需的存储取决于字段中文本的长度,而不是固定大小 (L + 2 bytes, where L < 2^16 and where L is the length of the value in bytes)。因此,尽管我在其他地方读到这些字段实际上是固定宽度的,但我处理了大约 50,000 行标记为已删除并将它们的所有 TEXT 列值设置为 null。

但是,MySQL 客户端或 AWS 控制台 RDS 界面报告的磁盘空间没有减少。为什么这没有释放磁盘空间?

【问题讨论】:

    标签: mysql amazon-web-services innodb diskspace rds


    【解决方案1】:

    Sasha 的回答可能适用,也可能不适用。

    将列设置为NULL 后,任何已释放的块都可用于将来的INSERTs / UPDATEs。但是释放的块不会返回给操作系统。块是否被释放取决于很多细节。

    TEXT 字段的磁盘空间量取决于文本量和 Row_format(“压缩”等)。 TEXT 列可以全部或部分存储在与其余数据分开的块中。

    如果您的表是在innodb_file_per_tableON 时创建的,那么OPTIMIZE TABLE 会将可用空间还给操作系统。而SHOW TABLE STATUS 的值会有所下降。

    如果innodb_file_per_tableOFF,则在ibdata1 中留下释放的空间,但该文件不会缩小。只能通过dump all tables来缩小;停止mysqld;删除 ibdata1;重新开始;重新加载。 (糟糕。)OPTIMIZE TABLE 将在 ibdata1 内增加 Data_free

    (假设关闭)这将使表格更易于管理,但在未缩小的ibdata1 中留下大量可用空间:

    SET innodb_file_per_table = ON;
    ALTER TABLE foo ENGINE=InnoDB;
    

    如果您出于其他原因预计 ibdata1 会增长;这可能是明智的做法。否则只会让磁盘空间问题变得更糟。

    【讨论】:

      【解决方案2】:

      当您将列值设置为 NULL 时,InnoDB 将不得不重新组织记录存储以减少表使用的磁盘空间总量。如果您的虚拟 ALTER TABLE 不足以让 MySQL 注意到一种短路方式来使其实际重建表,或者手动删除、重新创建和重新插入记录,您应该会看到减少。 OPTIMIZE TABLE 也应该这样做。

      【讨论】:

        猜你喜欢
        • 2012-10-23
        • 1970-01-01
        • 2011-05-12
        • 2015-10-04
        • 2022-01-09
        • 2019-11-14
        • 1970-01-01
        • 1970-01-01
        • 2020-10-08
        相关资源
        最近更新 更多