我正在尝试减少MySQL 5.6.23的RDS实例中表的磁盘空间使用量。它是一个InnoDB表,大约有800万行和30列。其中一些列的类型为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界面报告的磁盘空间没有减少。为什么没有这个释放磁盘空间?
答案 0 :(得分:4)
当您将列值设置为NULL时,InnoDB必须重新组织记录存储,以减少表使用的磁盘空间总量。如果你的虚拟ALTER TABLE不足以让MySQL注意到它的短路方式使它实际重建表,或者手动删除,重新创建和重新插入记录,你应该会看到减少。 OPTIMIZE TABLE
也应该这样做。
答案 1 :(得分:0)
Sasha的回答可能适用也可能不适用。
将列设置为NULL
后,所有已释放的块都可用于将来INSERTs
/ UPDATEs
。但释放的块不会返回给操作系统。块是否被释放取决于很多细节。
TEXT
字段的磁盘空间量取决于文本量和Row_format(&#34; Compact&#34;等)。 TEXT
列可以完全或部分存储在与其余数据分开的块中。
如果您的表是在innodb_file_per_table
ON
时创建的,则OPTIMIZE TABLE
会将可用空间返回给操作系统。并且SHOW TABLE STATUS
会显示值的减少。
如果innodb_file_per_table
为OFF
,则ibdata1
中会释放空间,但该文件不会缩小。它只能通过转储所有表来缩小;停止mysqld;删除ibdata1;重新开始;重装。 (哎呀。)OPTIMIZE TABLE
会在Data_free
内增加ibdata1
。
(假设关闭)这将使表格更易于管理,但在未收缩的ibdata1
中留下大量可用空间:
SET innodb_file_per_table = ON;
ALTER TABLE foo ENGINE=InnoDB;
如果您因其他原因预计ibdata1会增长;这可能是明智的做法。否则,它只会使磁盘空间问题变得更糟。